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