coffdump.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. /* Coff file dumper.
  2. Copyright (C) 1994-2022 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 <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. break;
  243. case coff_where_entag:
  244. printf ("ENTAG");
  245. break;
  246. case coff_where_typedef:
  247. printf ("TYPEDEF");
  248. break;
  249. default:
  250. abort ();
  251. }
  252. nl ();
  253. tab (-1);
  254. }
  255. static void
  256. dump_coff_visible (struct coff_visible *p)
  257. {
  258. tab (1);
  259. switch (p->type)
  260. {
  261. case coff_vis_ext_def:
  262. printf ("coff_vis_ext_def");
  263. break;
  264. case coff_vis_ext_ref:
  265. printf ("coff_vis_ext_ref");
  266. break;
  267. case coff_vis_int_def:
  268. printf ("coff_vis_int_def");
  269. break;
  270. case coff_vis_common:
  271. printf ("coff_vis_common");
  272. break;
  273. case coff_vis_auto:
  274. printf ("coff_vis_auto");
  275. break;
  276. case coff_vis_autoparam:
  277. printf ("coff_vis_autoparam");
  278. break;
  279. case coff_vis_regparam:
  280. printf ("coff_vis_regparam");
  281. break;
  282. case coff_vis_register:
  283. printf ("coff_vis_register");
  284. break;
  285. case coff_vis_tag:
  286. printf ("coff_vis_tag");
  287. break;
  288. case coff_vis_member_of_struct:
  289. printf ("coff_vis_member_of_struct");
  290. break;
  291. case coff_vis_member_of_enum:
  292. printf ("coff_vis_member_of_enum");
  293. break;
  294. default:
  295. abort ();
  296. }
  297. nl ();
  298. tab (-1);
  299. }
  300. static void
  301. dump_coff_symbol (struct coff_symbol *p)
  302. {
  303. tab (1);
  304. printf (_("List of symbols"));
  305. nl ();
  306. while (p)
  307. {
  308. tab (1);
  309. tab (1);
  310. printf (_("Symbol %s, tag %d, number %d"), p->name, p->tag, p->number);
  311. nl ();
  312. tab (-1);
  313. tab (1);
  314. printf (_("Type"));
  315. nl ();
  316. dump_coff_type (p->type);
  317. tab (-1);
  318. tab (1);
  319. printf (_("Where"));
  320. dump_coff_where (p->where);
  321. tab (-1);
  322. tab (1);
  323. printf (_("Visible"));
  324. dump_coff_visible (p->visible);
  325. tab (-1);
  326. p = p->next;
  327. tab (-1);
  328. }
  329. tab (-1);
  330. }
  331. static void
  332. dump_coff_scope (struct coff_scope *p)
  333. {
  334. if (p)
  335. {
  336. tab (1);
  337. printf ("%s %" BFD_VMA_FMT "x ",
  338. _("List of blocks "), (bfd_vma) (uintptr_t) p);
  339. if (p->sec)
  340. printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1);
  341. nl ();
  342. tab (0);
  343. printf ("*****************");
  344. nl ();
  345. while (p)
  346. {
  347. tab (0);
  348. printf (_("vars %d"), p->nvars);
  349. nl ();
  350. dump_coff_symbol (p->vars_head);
  351. printf (_("blocks"));
  352. nl ();
  353. dump_coff_scope (p->list_head);
  354. nl ();
  355. p = p->next;
  356. }
  357. tab (0);
  358. printf ("*****************");
  359. nl ();
  360. tab (-1);
  361. }
  362. }
  363. static void
  364. dump_coff_sfile (struct coff_sfile *p)
  365. {
  366. tab (1);
  367. printf (_("List of source files"));
  368. nl ();
  369. while (p)
  370. {
  371. tab (0);
  372. printf (_("Source file %s"), p->name);
  373. nl ();
  374. dump_coff_scope (p->scope);
  375. p = p->next;
  376. }
  377. tab (-1);
  378. }
  379. static void
  380. dump_coff_section (struct coff_section *ptr)
  381. {
  382. unsigned int i;
  383. tab (1);
  384. printf (_("section %s %d %d address %x size %x number %d nrelocs %u"),
  385. ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
  386. ptr->number, ptr->nrelocs);
  387. nl ();
  388. for (i = 0; i < ptr->nrelocs; i++)
  389. {
  390. struct coff_reloc * r = ptr->relocs + i;
  391. tab (0);
  392. printf ("(%x %s %x)",
  393. r->offset,
  394. /* PR 17512: file: 0a38fb7c. */
  395. r->symbol == NULL ? _("<no sym>") : r->symbol->name,
  396. r->addend);
  397. nl ();
  398. }
  399. tab (-1);
  400. }
  401. static void
  402. coff_dump (struct coff_ofile *ptr)
  403. {
  404. int i;
  405. printf ("Coff dump");
  406. nl ();
  407. printf (_("#sources %d"), ptr->nsources);
  408. nl ();
  409. dump_coff_sfile (ptr->source_head);
  410. for (i = 0; i < ptr->nsections; i++)
  411. dump_coff_section (ptr->sections + i);
  412. }
  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. #ifdef HAVE_LC_MESSAGES
  442. setlocale (LC_MESSAGES, "");
  443. #endif
  444. setlocale (LC_CTYPE, "");
  445. bindtextdomain (PACKAGE, LOCALEDIR);
  446. textdomain (PACKAGE);
  447. program_name = av[0];
  448. xmalloc_set_program_name (program_name);
  449. bfd_set_error_program_name (program_name);
  450. expandargv (&ac, &av);
  451. while ((opt = getopt_long (ac, av, "HhVv", long_options,
  452. (int *) NULL))
  453. != EOF)
  454. {
  455. switch (opt)
  456. {
  457. case 'H':
  458. case 'h':
  459. show_usage (stdout, 0);
  460. break;
  461. case 'v':
  462. case 'V':
  463. print_version ("coffdump");
  464. exit (0);
  465. case 0:
  466. break;
  467. default:
  468. show_usage (stderr, 1);
  469. break;
  470. }
  471. }
  472. if (optind < ac)
  473. {
  474. input_file = av[optind];
  475. }
  476. if (!input_file)
  477. fatal (_("no input file specified"));
  478. abfd = bfd_openr (input_file, 0);
  479. if (!abfd)
  480. bfd_fatal (input_file);
  481. if (! bfd_check_format_matches (abfd, bfd_object, &matching))
  482. {
  483. bfd_nonfatal (input_file);
  484. if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
  485. {
  486. list_matching_formats (matching);
  487. free (matching);
  488. }
  489. exit (1);
  490. }
  491. tree = coff_grok (abfd);
  492. if (tree)
  493. {
  494. coff_dump (tree);
  495. printf ("\n");
  496. }
  497. return 0;
  498. }