coffdump.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /* Coff file dumper.
  2. Copyright (C) 1994-2015 Free Software Foundation, Inc.
  3. This file is part of GNU Binutils.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at
  7. your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  15. MA 02110-1301, USA. */
  16. /* Written by Steve Chamberlain <sac@cygnus.com>
  17. This module reads a type tree generated by coffgrok and prints
  18. it out so we can test the grokker. */
  19. #include "sysdep.h"
  20. #include "bfd.h"
  21. #include "bfd_stdint.h"
  22. #include "libiberty.h"
  23. #include "bucomm.h"
  24. #include "coffgrok.h"
  25. #include "getopt.h"
  26. static int atnl;
  27. static void tab (int);
  28. static void nl (void);
  29. static void dump_coff_lines (struct coff_line *);
  30. static void dump_coff_type (struct coff_type *);
  31. static void dump_coff_where (struct coff_where *);
  32. static void dump_coff_visible (struct coff_visible *);
  33. static void dump_coff_scope (struct coff_scope *);
  34. static void dump_coff_sfile (struct coff_sfile *);
  35. static void dump_coff_section (struct coff_section *);
  36. static void show_usage (FILE *, int);
  37. extern int main (int, char **);
  38. static void
  39. tab (int x)
  40. {
  41. static int indent;
  42. int i;
  43. if (atnl)
  44. {
  45. if (x < 0)
  46. {
  47. printf (")");
  48. indent += x;
  49. return;
  50. }
  51. else
  52. {
  53. printf ("\n");
  54. atnl = 0;
  55. }
  56. }
  57. if (x == -1)
  58. {
  59. for (i = 0; i < indent; i++)
  60. printf (" ");
  61. indent += x;
  62. printf (")");
  63. return;
  64. }
  65. indent += x;
  66. for (i = 0; i < indent; i++)
  67. printf (" ");
  68. if (x)
  69. {
  70. printf ("(");
  71. }
  72. }
  73. static void
  74. nl (void)
  75. {
  76. atnl = 1;
  77. }
  78. static void
  79. dump_coff_lines (struct coff_line *p)
  80. {
  81. int i;
  82. int online = 0;
  83. tab (1);
  84. printf (_("#lines %d "),p->nlines);
  85. for (i = 0; i < p->nlines; i++)
  86. {
  87. printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
  88. online++;
  89. if (online > 6)
  90. {
  91. nl ();
  92. tab (0);
  93. online = 0;
  94. }
  95. }
  96. nl ();
  97. tab (-1);
  98. }
  99. static void
  100. dump_coff_type (struct coff_type *p)
  101. {
  102. tab (1);
  103. printf (_("size %d "), p->size);
  104. switch (p->type)
  105. {
  106. case coff_secdef_type:
  107. printf (_("section definition at %x size %x\n"),
  108. p->u.asecdef.address,
  109. p->u.asecdef.size);
  110. nl ();
  111. break;
  112. case coff_pointer_type:
  113. printf (_("pointer to"));
  114. nl ();
  115. dump_coff_type (p->u.pointer.points_to);
  116. break;
  117. case coff_array_type:
  118. printf (_("array [%d] of"), p->u.array.dim);
  119. nl ();
  120. dump_coff_type (p->u.array.array_of);
  121. break;
  122. case coff_function_type:
  123. printf (_("function returning"));
  124. nl ();
  125. dump_coff_type (p->u.function.function_returns);
  126. dump_coff_lines (p->u.function.lines);
  127. printf (_("arguments"));
  128. nl ();
  129. dump_coff_scope (p->u.function.parameters);
  130. tab (0);
  131. printf (_("code"));
  132. nl ();
  133. dump_coff_scope (p->u.function.code);
  134. tab(0);
  135. break;
  136. case coff_structdef_type:
  137. printf (_("structure definition"));
  138. nl ();
  139. dump_coff_scope (p->u.astructdef.elements);
  140. break;
  141. case coff_structref_type:
  142. if (!p->u.aenumref.ref)
  143. printf (_("structure ref to UNKNOWN struct"));
  144. else
  145. printf (_("structure ref to %s"), p->u.aenumref.ref->name);
  146. break;
  147. case coff_enumref_type:
  148. printf (_("enum ref to %s"), p->u.astructref.ref->name);
  149. break;
  150. case coff_enumdef_type:
  151. printf (_("enum definition"));
  152. nl ();
  153. dump_coff_scope (p->u.aenumdef.elements);
  154. break;
  155. case coff_basic_type:
  156. switch (p->u.basic)
  157. {
  158. case T_NULL:
  159. printf ("NULL");
  160. break;
  161. case T_VOID:
  162. printf ("VOID");
  163. break;
  164. case T_CHAR:
  165. printf ("CHAR");
  166. break;
  167. case T_SHORT:
  168. printf ("SHORT");
  169. break;
  170. case T_INT:
  171. printf ("INT ");
  172. break;
  173. case T_LONG:
  174. printf ("LONG");
  175. break;
  176. case T_FLOAT:
  177. printf ("FLOAT");
  178. break;
  179. case T_DOUBLE:
  180. printf ("DOUBLE");
  181. break;
  182. case T_STRUCT:
  183. printf ("STRUCT");
  184. break;
  185. case T_UNION:
  186. printf ("UNION");
  187. break;
  188. case T_ENUM:
  189. printf ("ENUM");
  190. break;
  191. case T_MOE:
  192. printf ("MOE ");
  193. break;
  194. case T_UCHAR:
  195. printf ("UCHAR");
  196. break;
  197. case T_USHORT:
  198. printf ("USHORT");
  199. break;
  200. case T_UINT:
  201. printf ("UINT");
  202. break;
  203. case T_ULONG:
  204. printf ("ULONG");
  205. break;
  206. case T_LNGDBL:
  207. printf ("LNGDBL");
  208. break;
  209. default:
  210. abort ();
  211. }
  212. }
  213. nl ();
  214. tab (-1);
  215. }
  216. static void
  217. dump_coff_where (struct coff_where *p)
  218. {
  219. tab (1);
  220. switch (p->where)
  221. {
  222. case coff_where_stack:
  223. printf (_("Stack offset %x"), p->offset);
  224. break;
  225. case coff_where_memory:
  226. printf (_("Memory section %s+%x"), p->section->name, p->offset);
  227. break;
  228. case coff_where_register:
  229. printf (_("Register %d"), p->offset);
  230. break;
  231. case coff_where_member_of_struct:
  232. printf (_("Struct Member offset %x"), p->offset);
  233. break;
  234. case coff_where_member_of_enum:
  235. printf (_("Enum Member offset %x"), p->offset);
  236. break;
  237. case coff_where_unknown:
  238. printf (_("Undefined symbol"));
  239. break;
  240. case coff_where_strtag:
  241. printf ("STRTAG");
  242. case coff_where_entag:
  243. printf ("ENTAG");
  244. break;
  245. case coff_where_typedef:
  246. printf ("TYPEDEF");
  247. break;
  248. default:
  249. abort ();
  250. }
  251. nl ();
  252. tab (-1);
  253. }
  254. static void
  255. dump_coff_visible (struct coff_visible *p)
  256. {
  257. tab (1);
  258. switch (p->type)
  259. {
  260. case coff_vis_ext_def:
  261. printf ("coff_vis_ext_def");
  262. break;
  263. case coff_vis_ext_ref:
  264. printf ("coff_vis_ext_ref");
  265. break;
  266. case coff_vis_int_def:
  267. printf ("coff_vis_int_def");
  268. break;
  269. case coff_vis_common:
  270. printf ("coff_vis_common");
  271. break;
  272. case coff_vis_auto:
  273. printf ("coff_vis_auto");
  274. break;
  275. case coff_vis_autoparam:
  276. printf ("coff_vis_autoparam");
  277. break;
  278. case coff_vis_regparam:
  279. printf ("coff_vis_regparam");
  280. break;
  281. case coff_vis_register:
  282. printf ("coff_vis_register");
  283. break;
  284. case coff_vis_tag:
  285. printf ("coff_vis_tag");
  286. break;
  287. case coff_vis_member_of_struct:
  288. printf ("coff_vis_member_of_struct");
  289. break;
  290. case coff_vis_member_of_enum:
  291. printf ("coff_vis_member_of_enum");
  292. break;
  293. default:
  294. abort ();
  295. }
  296. nl ();
  297. tab (-1);
  298. }
  299. static void
  300. dump_coff_symbol (struct coff_symbol *p)
  301. {
  302. tab (1);
  303. printf (_("List of symbols"));
  304. nl ();
  305. while (p)
  306. {
  307. tab (1);
  308. tab (1);
  309. printf (_("Symbol %s, tag %d, number %d"), p->name, p->tag, p->number);
  310. nl ();
  311. tab (-1);
  312. tab (1);
  313. printf (_("Type"));
  314. nl ();
  315. dump_coff_type (p->type);
  316. tab (-1);
  317. tab (1);
  318. printf (_("Where"));
  319. dump_coff_where (p->where);
  320. tab (-1);
  321. tab (1);
  322. printf (_("Visible"));
  323. dump_coff_visible (p->visible);
  324. tab (-1);
  325. p = p->next;
  326. tab (-1);
  327. }
  328. tab (-1);
  329. }
  330. static void
  331. dump_coff_scope (struct coff_scope *p)
  332. {
  333. if (p)
  334. {
  335. tab (1);
  336. printf ("%s %" BFD_VMA_FMT "x ",
  337. _("List of blocks "), (bfd_vma) (uintptr_t) p);
  338. if (p->sec)
  339. printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1);
  340. nl ();
  341. tab (0);
  342. printf ("*****************");
  343. nl ();
  344. while (p)
  345. {
  346. tab (0);
  347. printf (_("vars %d"), p->nvars);
  348. nl ();
  349. dump_coff_symbol (p->vars_head);
  350. printf (_("blocks"));
  351. nl ();
  352. dump_coff_scope (p->list_head);
  353. nl ();
  354. p = p->next;
  355. }
  356. tab (0);
  357. printf ("*****************");
  358. nl ();
  359. tab (-1);
  360. }
  361. }
  362. static void
  363. dump_coff_sfile (struct coff_sfile *p)
  364. {
  365. tab (1);
  366. printf (_("List of source files"));
  367. nl ();
  368. while (p)
  369. {
  370. tab (0);
  371. printf (_("Source file %s"), p->name);
  372. nl ();
  373. dump_coff_scope (p->scope);
  374. p = p->next;
  375. }
  376. tab (-1);
  377. }
  378. static void
  379. dump_coff_section (struct coff_section *ptr)
  380. {
  381. unsigned int i;
  382. tab (1);
  383. printf (_("section %s %d %d address %x size %x number %d nrelocs %u"),
  384. ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
  385. ptr->number, ptr->nrelocs);
  386. nl ();
  387. for (i = 0; i < ptr->nrelocs; i++)
  388. {
  389. struct coff_reloc * r = ptr->relocs + i;
  390. tab (0);
  391. printf ("(%x %s %x)",
  392. r->offset,
  393. /* PR 17512: file: 0a38fb7c. */
  394. r->symbol == NULL ? _("<no sym>") : r->symbol->name,
  395. r->addend);
  396. nl ();
  397. }
  398. tab (-1);
  399. }
  400. static void
  401. coff_dump (struct coff_ofile *ptr)
  402. {
  403. int i;
  404. printf ("Coff dump");
  405. nl ();
  406. printf (_("#sources %d"), ptr->nsources);
  407. nl ();
  408. dump_coff_sfile (ptr->source_head);
  409. for (i = 0; i < ptr->nsections; i++)
  410. dump_coff_section (ptr->sections + i);
  411. }
  412. char * program_name;
  413. static void
  414. show_usage (FILE *file, int status)
  415. {
  416. fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
  417. fprintf (file, _(" Print a human readable interpretation of a COFF object file\n"));
  418. fprintf (file, _(" The options are:\n\
  419. @<file> Read options from <file>\n\
  420. -h --help Display this information\n\
  421. -v --version Display the program's version\n\
  422. \n"));
  423. if (REPORT_BUGS_TO[0] && status == 0)
  424. fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
  425. exit (status);
  426. }
  427. int
  428. main (int ac, char **av)
  429. {
  430. bfd *abfd;
  431. struct coff_ofile *tree;
  432. char **matching;
  433. char *input_file = NULL;
  434. int opt;
  435. static struct option long_options[] =
  436. {
  437. { "help", no_argument, 0, 'h' },
  438. { "version", no_argument, 0, 'V' },
  439. { NULL, no_argument, 0, 0 }
  440. };
  441. #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  442. setlocale (LC_MESSAGES, "");
  443. #endif
  444. #if defined (HAVE_SETLOCALE)
  445. setlocale (LC_CTYPE, "");
  446. #endif
  447. bindtextdomain (PACKAGE, LOCALEDIR);
  448. textdomain (PACKAGE);
  449. program_name = av[0];
  450. xmalloc_set_program_name (program_name);
  451. bfd_set_error_program_name (program_name);
  452. expandargv (&ac, &av);
  453. while ((opt = getopt_long (ac, av, "HhVv", long_options,
  454. (int *) NULL))
  455. != EOF)
  456. {
  457. switch (opt)
  458. {
  459. case 'H':
  460. case 'h':
  461. show_usage (stdout, 0);
  462. break;
  463. case 'v':
  464. case 'V':
  465. print_version ("coffdump");
  466. exit (0);
  467. case 0:
  468. break;
  469. default:
  470. show_usage (stderr, 1);
  471. break;
  472. }
  473. }
  474. if (optind < ac)
  475. {
  476. input_file = av[optind];
  477. }
  478. if (!input_file)
  479. fatal (_("no input file specified"));
  480. abfd = bfd_openr (input_file, 0);
  481. if (!abfd)
  482. bfd_fatal (input_file);
  483. if (! bfd_check_format_matches (abfd, bfd_object, &matching))
  484. {
  485. bfd_nonfatal (input_file);
  486. if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
  487. {
  488. list_matching_formats (matching);
  489. free (matching);
  490. }
  491. exit (1);
  492. }
  493. tree = coff_grok (abfd);
  494. if (tree)
  495. {
  496. coff_dump (tree);
  497. printf ("\n");
  498. }
  499. return 0;
  500. }