objdump.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * objdump
  3. *
  4. * dump information about an object file. Until there is other documentation,
  5. * refer to the manual page dump(1) in the system 5 program's reference manual
  6. */
  7. #include <stdio.h>
  8. #ifndef COFF_ENCAPSULATE
  9. #include "a.out.gnu.h"
  10. #else
  11. #include "a.out.encap.h"
  12. #endif
  13. char *malloc();
  14. int nsyms;
  15. struct nlist *symtbl;
  16. char *strtbl;
  17. int strsize;
  18. read_symbols (execp, f)
  19. struct exec *execp;
  20. FILE *f;
  21. {
  22. int i;
  23. struct nlist *sp;
  24. if (symtbl)
  25. return;
  26. nsyms = execp->a_syms / sizeof (struct nlist);
  27. if (nsyms == 0)
  28. return;
  29. symtbl = (struct nlist *)malloc (nsyms * sizeof (struct nlist));
  30. if (symtbl == NULL) {
  31. fprintf (stderr, "can't malloc for %d symbols\n",
  32. nsyms);
  33. exit (1);
  34. }
  35. fseek (f, N_STROFF(*execp), 0);
  36. if (fread ((char *)&strsize, sizeof strsize, 1, f) != 1) {
  37. fprintf (stderr, "can't get string table size\n");
  38. exit (1);
  39. }
  40. strtbl = malloc (strsize);
  41. if (strtbl == NULL) {
  42. fprintf (stderr, "can't malloc %d bytes for string table\n");
  43. exit (1);
  44. }
  45. fseek (f, N_STROFF (*execp), 0);
  46. if (fread (strtbl, 1, strsize, f) != strsize) {
  47. fprintf (stderr, "error reading string table\n");
  48. exit (1);
  49. }
  50. fseek (f, N_SYMOFF (*execp), 0);
  51. if (fread ((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) {
  52. fprintf (stderr, "error reading symbol table\n");
  53. exit (1);
  54. }
  55. for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
  56. if (sp->n_un.n_strx < 0 || sp->n_un.n_strx > strsize)
  57. sp->n_un.n_name = "<bad string table index>";
  58. else
  59. sp->n_un.n_name = strtbl + sp->n_un.n_strx;
  60. }
  61. }
  62. free_symbols ()
  63. {
  64. if (symtbl)
  65. free (symtbl);
  66. symtbl = NULL;
  67. if (strtbl)
  68. free (strtbl);
  69. strtbl = NULL;
  70. }
  71. usage ()
  72. {
  73. fprintf (stderr, "usage: dump [-h] [-n] [-r] [-t] obj ...\n");
  74. exit (1);
  75. }
  76. int hflag;
  77. int nflag;
  78. int rflag;
  79. int tflag;
  80. main (argc, argv)
  81. char **argv;
  82. {
  83. int c;
  84. extern char *optarg;
  85. extern int optind;
  86. int seenflag = 0;
  87. while ((c = getopt (argc, argv, "hnrt")) != EOF) {
  88. seenflag = 1;
  89. switch (c) {
  90. case 't': tflag = 1; break;
  91. case 'r': rflag = 1; break;
  92. case 'n': nflag = 1; break;
  93. case 'h': hflag = 1; break;
  94. default:
  95. usage ();
  96. }
  97. }
  98. if (seenflag == 0 || optind == argc)
  99. usage ();
  100. while (optind < argc)
  101. doit (argv[optind++]);
  102. }
  103. doit (name)
  104. char *name;
  105. {
  106. FILE *f;
  107. struct exec exec;
  108. printf ("%s:\n", name);
  109. f = fopen (name, "r");
  110. if (f == NULL) {
  111. fprintf (stderr, "can't open %s\n", name);
  112. return;
  113. }
  114. #ifdef HEADER_SEEK
  115. HEADER_SEEK (f);
  116. #endif
  117. if (fread ((char *)&exec, sizeof exec, 1, f) != 1) {
  118. fprintf (stderr, "can't read header for %s\n", name);
  119. return;
  120. }
  121. if (N_BADMAG (exec)) {
  122. fprintf (stderr, "%s is not an object file\n", name);
  123. return;
  124. }
  125. if (hflag)
  126. dump_header (&exec);
  127. if (nflag)
  128. dump_nstuff (&exec);
  129. if (tflag)
  130. dump_sym (&exec, f);
  131. if (rflag)
  132. dump_reloc (&exec, f);
  133. free_symbols ();
  134. }
  135. dump_header (execp)
  136. struct exec *execp;
  137. {
  138. int x;
  139. printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic & 0xffff);
  140. #ifdef COFF_ENCAPSULATE
  141. printf ("machtype: %d ", execp->a_machtype);
  142. printf ("flags: 0x%x ", execp->a_flags);
  143. #endif
  144. printf ("text 0x%x ", execp->a_text);
  145. printf ("data 0x%x ", execp->a_data);
  146. printf ("bss 0x%x\n", execp->a_bss);
  147. printf ("nsyms %d", execp->a_syms / sizeof (struct nlist));
  148. x = execp->a_syms % sizeof (struct nlist);
  149. if (x)
  150. printf (" (+ %d bytes)", x);
  151. printf (" entry 0x%x ", execp->a_entry);
  152. printf ("trsize 0x%x ", execp->a_trsize);
  153. printf ("drsize 0x%x\n", execp->a_drsize);
  154. }
  155. dump_nstuff (execp)
  156. struct exec *execp;
  157. {
  158. printf ("N_BADMAG %d\n", N_BADMAG (*execp));
  159. printf ("N_TXTOFF 0x%x\n", N_TXTOFF (*execp));
  160. printf ("N_SYMOFF 0x%x\n", N_SYMOFF (*execp));
  161. printf ("N_STROFF 0x%x\n", N_STROFF (*execp));
  162. printf ("N_TXTADDR 0x%x\n", N_TXTADDR (*execp));
  163. printf ("N_DATADDR 0x%x\n", N_DATADDR (*execp));
  164. }
  165. dump_sym (execp, f)
  166. struct exec *execp;
  167. FILE *f;
  168. {
  169. int i;
  170. struct nlist *sp;
  171. read_symbols (execp, f);
  172. if (nsyms == 0) {
  173. printf ("no symbols\n");
  174. return;
  175. }
  176. printf ("%3s: %4s %5s %4s %8s\n",
  177. "#", "type", "other", "desc", "val");
  178. for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
  179. printf ("%3d: %4x %5x %4x %8x %s\n",
  180. i, sp->n_type, sp->n_other, sp->n_desc, sp->n_value,
  181. sp->n_un.n_name);
  182. }
  183. }
  184. dump_reloc (execp, f)
  185. struct exec *execp;
  186. FILE *f;
  187. {
  188. read_symbols (execp, f);
  189. if (execp->a_trsize) {
  190. printf ("text reloc\n");
  191. dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize);
  192. }
  193. if (execp->a_drsize) {
  194. printf ("data reloc\n");
  195. dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize);
  196. }
  197. }
  198. dump_reloc1 (execp, f, off, size)
  199. struct exec *execp;
  200. FILE *f;
  201. {
  202. int nreloc;
  203. struct relocation_info reloc;
  204. int i;
  205. nreloc = size / sizeof (struct relocation_info);
  206. printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym");
  207. fseek (f, off, 0);
  208. for (i = 0; i < nreloc; i++) {
  209. if (fread ((char *)&reloc, sizeof reloc, 1, f) != 1) {
  210. fprintf (stderr, "error reading reloc\n");
  211. return;
  212. }
  213. printf ("%3d: %3d %8x ", i, 1 << reloc.r_length,
  214. reloc.r_address);
  215. if (reloc.r_extern) {
  216. printf ("%4d ", reloc.r_symbolnum);
  217. if (reloc.r_symbolnum < nsyms)
  218. printf ("%s ",
  219. symtbl[reloc.r_symbolnum].n_un.n_name);
  220. } else {
  221. printf (" ");
  222. switch (reloc.r_symbolnum & ~N_EXT) {
  223. case N_TEXT: printf (".text "); break;
  224. case N_DATA: printf (".data "); break;
  225. case N_BSS: printf (".bss "); break;
  226. case N_ABS: printf (".abs "); break;
  227. default: printf ("base %x ", reloc.r_symbolnum); break;
  228. }
  229. }
  230. if (reloc.r_pcrel) printf ("PCREL ");
  231. #if 0
  232. if (reloc.r_pad) printf ("PAD %x ", reloc.r_pad);
  233. #endif
  234. printf ("\n");
  235. }
  236. }