ashow.c 4.9 KB

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