ashow.c 5.0 KB

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