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