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