ashow.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * show - make the contents of an ACK object file human readable.
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <stdarg.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <out.h>
  10. #include "object.h"
  11. #define OK 0 /* Return value of gethead if Orl Korekt. */
  12. #define BMASK 0xFF /* To extract least significant 8 bits from an int. */
  13. void show(struct outhead *headp);
  14. void showflags(unsigned int flagword);
  15. void showsect();
  16. void showname(struct outname *namep);
  17. void error(char *format, ...);
  18. void showrelo();
  19. /* ARGSUSED */
  20. #define prog argv[0]
  21. int main(int argc, char *argv[])
  22. {
  23. char **arg = argv;
  24. struct outhead header;
  25. while (*++arg) {
  26. if (! rd_open(*arg)) {
  27. error("%s: cannot read %s\n", prog, *arg);
  28. continue;
  29. }
  30. rd_ohead(&header);
  31. if (BADMAGIC(header)) {
  32. error("%s: %s not an ACK object file\n", prog, *arg);
  33. } else {
  34. printf("%s:\n", *arg);
  35. show(&header);
  36. }
  37. rd_close();
  38. }
  39. }
  40. /*
  41. * Read an ACK object file from `fp' and show it in a human readable way.
  42. * NB. The header has already been read and is in the struct outhead `headp'
  43. * points to.
  44. */
  45. void show(struct outhead *headp)
  46. {
  47. int i;
  48. struct outname *np;
  49. struct outname *name; /* Dynamically allocated name-array. */
  50. char *string;/* Base of string area. */
  51. extern char *myalloc();
  52. printf("Version %d\n", headp->oh_stamp);
  53. showflags((unsigned) headp->oh_flags);
  54. /*
  55. * Show all sections.
  56. */
  57. for (i = 0; i < headp->oh_nsect; i++) {
  58. printf("Section %d:\n", i);
  59. showsect();
  60. }
  61. /*
  62. * Show relocation information.
  63. */
  64. for (i = 0; i < headp->oh_nrelo; i++) {
  65. printf("Relocation record %d:\n", i);
  66. showrelo();
  67. }
  68. /*
  69. * We get all struct outname's and the strings in core first.
  70. */
  71. name = (struct outname *) myalloc(headp->oh_nname * SZ_NAME);
  72. string = myalloc((unsigned) headp->oh_nchar);
  73. rd_name(name, headp->oh_nname);
  74. for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
  75. if (np->on_foff != 0) {
  76. np->on_foff -= OFF_CHAR(*headp);
  77. if (np->on_foff >= headp->oh_nchar || np->on_foff < 0) {
  78. np->on_mptr = "????";
  79. }
  80. else np->on_mptr = string + np->on_foff;
  81. }
  82. }
  83. /*
  84. * Transfer strings from file to core.
  85. */
  86. rd_string(string, headp->oh_nchar);
  87. /*
  88. * Now we can show all names.
  89. */
  90. for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
  91. printf("Name %ld:\n",(long)(np - name));
  92. showname(np);
  93. }
  94. }
  95. /*
  96. * Show flags from header.
  97. */
  98. void showflags(unsigned int flagword)
  99. {
  100. if (flagword & HF_LINK) printf("unresolved references left\n");
  101. }
  102. /*
  103. * Show a section.
  104. */
  105. void showsect()
  106. {
  107. struct outsect section;
  108. rd_sect(&section, 1);
  109. printf("\tstartaddress in machine\t%ld\n", section.os_base);
  110. printf("\tsection size in machine\t%ld\n", section.os_size);
  111. printf("\tstartaddress in file\t%ld\n", section.os_foff);
  112. printf("\tsection size in file\t%ld\n", section.os_flen);
  113. printf("\tsection alignment\t%ld\n", section.os_lign);
  114. }
  115. /*
  116. * Show a relocation record.
  117. */
  118. void showrelo()
  119. {
  120. struct outrelo relrec;
  121. rd_relo(&relrec, 1);
  122. switch (relrec.or_type & RELSZ) {
  123. case RELO1:
  124. printf("\t1 byte\n");
  125. break;
  126. case RELO2:
  127. printf("\t2 bytes\n");
  128. break;
  129. case RELO4:
  130. printf("\t4 bytes\n");
  131. break;
  132. default:
  133. error("\tunexpected relocation length\n");
  134. break;
  135. }
  136. if (relrec.or_type & RELPC) printf("\tpc relative\n");
  137. if (relrec.or_type & RELBR) printf("\tbytes reversed\n");
  138. if (relrec.or_type & RELWR) printf("\twords reversed\n");
  139. printf("\treferencing section\t%d\n", (relrec.or_sect & BMASK) - S_MIN);
  140. printf("\treferenced symbol index\t%d\n", relrec.or_nami);
  141. printf("\treferencing address\t%ld\n", relrec.or_addr);
  142. }
  143. /*
  144. * Show the name in the struct `namep' points to.
  145. */
  146. void showname(struct outname *namep)
  147. {
  148. if (namep->on_mptr)
  149. printf("\t%s\n", namep->on_mptr);
  150. else
  151. printf("\tno name\n");
  152. switch (namep->on_type & S_TYP) {
  153. case S_UND:
  154. printf("\tundefined\n");
  155. break;
  156. case S_ABS:
  157. printf("\tabsolute\n");
  158. break;
  159. case S_CRS:
  160. printf("\tcross reference\n");
  161. default:
  162. printf("\tin section %d\n", (namep->on_type & S_TYP) - S_MIN);
  163. break;
  164. }
  165. if (namep->on_type & S_EXT) printf("\texternal\n");
  166. if (namep->on_type & S_STB) {
  167. printf("\tstab 0x%x\n", namep->on_type >> 8);
  168. printf("\tdesc 0x%x\n", namep->on_desc);
  169. }
  170. else switch (namep->on_type & S_ETC) {
  171. case S_SCT:
  172. printf("\tsection name\n"); break;
  173. case S_LIN:
  174. printf("\thll source line item\n"); break;
  175. case S_FIL:
  176. printf("\thll source file item\n"); break;
  177. case S_MOD:
  178. printf("\tass src file item\n"); break;
  179. case S_COM:
  180. printf("\tcommon\n"); break;
  181. case 0:
  182. break;
  183. default:
  184. printf("\tstab 0x%x\n", namep->on_type >> 8);
  185. printf("\tdesc 0x%x\n", namep->on_desc);
  186. }
  187. printf("\tvalue %ld\n", namep->on_valu);
  188. }
  189. /*
  190. * Core allocation via malloc() but fatal if no core.
  191. */
  192. char *myalloc(unsigned int u)
  193. {
  194. register char *rcp;
  195. rcp = malloc(u);
  196. if (rcp == (char *) 0) {
  197. error("Out of core\n");
  198. exit(1);
  199. }
  200. return rcp;
  201. }
  202. /* VARARGS1 */
  203. void error(char *format, ...)
  204. {
  205. va_list ap;
  206. fflush(stdout);
  207. va_start(ap, format);
  208. vfprintf(stderr, format, ap);
  209. va_end(ap);
  210. }
  211. void rd_fatal()
  212. {
  213. error("Error in reading the object file\n");
  214. exit(1);
  215. }