coffdump.c revision 91041
1230557Sjimharris/* Coff file dumper. 2230557Sjimharris Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002 3230557Sjimharris Free Software Foundation, Inc. 4230557Sjimharris 5230557Sjimharris This file is part of GNU Binutils. 6230557Sjimharris 7230557Sjimharris This program is free software; you can redistribute it and/or modify 8230557Sjimharris it under the terms of the GNU General Public License as published by 9230557Sjimharris the Free Software Foundation; either version 2 of the License, or (at 10230557Sjimharris your option) any later version. 11230557Sjimharris 12230557Sjimharris This program is distributed in the hope that it will be useful, 13230557Sjimharris but WITHOUT ANY WARRANTY; without even the implied warranty of 14230557Sjimharris MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15230557Sjimharris GNU General Public License for more details. 16230557Sjimharris 17230557Sjimharris You should have received a copy of the GNU General Public License 18230557Sjimharris along with this program; if not, write to the Free Software 19230557Sjimharris Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20230557Sjimharris 21230557Sjimharris/* Written by Steve Chamberlain <sac@cygnus.com> 22230557Sjimharris 23230557Sjimharris This module reads a type tree generated by coffgrok and prints 24230557Sjimharris it out so we can test the grokker. */ 25230557Sjimharris 26230557Sjimharris#include <bfd.h> 27230557Sjimharris#include <libiberty.h> 28230557Sjimharris 29230557Sjimharris#include "coffgrok.h" 30230557Sjimharris#include "bucomm.h" 31230557Sjimharris#include "getopt.h" 32230557Sjimharris 33230557Sjimharrisstatic int atnl; 34230557Sjimharris 35230557Sjimharrisstatic void tab PARAMS ((int)); 36230557Sjimharrisstatic void nl PARAMS ((void)); 37230557Sjimharrisstatic void dump_coff_lines PARAMS ((struct coff_line *)); 38230557Sjimharrisstatic void dump_coff_type PARAMS ((struct coff_type *)); 39230557Sjimharrisstatic void dump_coff_where PARAMS ((struct coff_where *)); 40230557Sjimharrisstatic void dump_coff_visible PARAMS ((struct coff_visible *)); 41230557Sjimharrisextern void dump_coff_symbol PARAMS ((struct coff_symbol *)); 42230557Sjimharrisstatic void dump_coff_scope PARAMS ((struct coff_scope *)); 43230557Sjimharrisstatic void dump_coff_sfile PARAMS ((struct coff_sfile *)); 44230557Sjimharrisstatic void dump_coff_section PARAMS ((struct coff_section *)); 45230557Sjimharrisextern void coff_dump PARAMS ((struct coff_ofile *)); 46230557Sjimharrisstatic void show_usage PARAMS ((FILE *, int)); 47230557Sjimharrisextern int main PARAMS ((int, char **)); 48230557Sjimharris 49230557Sjimharrisstatic void 50230557Sjimharristab (x) 51230557Sjimharris int x; 52230557Sjimharris{ 53230557Sjimharris static int indent; 54230557Sjimharris int i; 55230557Sjimharris 56230557Sjimharris if (atnl) 57230557Sjimharris { 58230557Sjimharris if (x < 0) 59230557Sjimharris { 60230557Sjimharris printf (")"); 61230557Sjimharris indent += x; 62230557Sjimharris 63230557Sjimharris return; 64230557Sjimharris } 65230557Sjimharris else 66230557Sjimharris { 67230557Sjimharris printf ("\n"); 68230557Sjimharris atnl = 0; 69230557Sjimharris } 70230557Sjimharris } 71230557Sjimharris 72230557Sjimharris if (x == -1) 73230557Sjimharris { 74230557Sjimharris for (i = 0; i < indent; i++) 75230557Sjimharris printf (" "); 76230557Sjimharris 77230557Sjimharris indent += x; 78230557Sjimharris printf (")"); 79230557Sjimharris return; 80230557Sjimharris } 81230557Sjimharris 82230557Sjimharris indent += x; 83230557Sjimharris 84230557Sjimharris for (i = 0; i < indent; i++) 85230557Sjimharris printf (" "); 86230557Sjimharris 87230557Sjimharris if (x) 88230557Sjimharris { 89230557Sjimharris printf ("("); 90230557Sjimharris } 91230557Sjimharris} 92230557Sjimharris 93230557Sjimharrisstatic void 94230557Sjimharrisnl () 95230557Sjimharris{ 96230557Sjimharris atnl = 1; 97230557Sjimharris} 98230557Sjimharris 99230557Sjimharrisstatic void 100230557Sjimharrisdump_coff_lines (p) 101230557Sjimharris struct coff_line *p; 102230557Sjimharris{ 103230557Sjimharris int i; 104230557Sjimharris int online = 0; 105230557Sjimharris 106230557Sjimharris tab (1); 107230557Sjimharris printf (_("#lines %d "),p->nlines); 108230557Sjimharris 109230557Sjimharris for (i = 0; i < p->nlines; i++) 110230557Sjimharris { 111230557Sjimharris printf ("(%d 0x%x)", p->lines[i], p->addresses[i]); 112230557Sjimharris 113230557Sjimharris online++; 114230557Sjimharris 115230557Sjimharris if (online > 6) 116230557Sjimharris { 117230557Sjimharris nl (); 118230557Sjimharris tab (0); 119230557Sjimharris online = 0; 120230557Sjimharris } 121230557Sjimharris } 122230557Sjimharris nl (); 123230557Sjimharris tab (-1); 124230557Sjimharris} 125230557Sjimharris 126230557Sjimharrisstatic void 127230557Sjimharrisdump_coff_type (p) 128230557Sjimharris struct coff_type *p; 129230557Sjimharris{ 130230557Sjimharris tab (1); 131230557Sjimharris printf ("size %d ", p->size); 132230557Sjimharris 133230557Sjimharris switch (p->type) 134230557Sjimharris { 135230557Sjimharris case coff_secdef_type: 136230557Sjimharris printf ("section definition at %x size %x\n", 137230557Sjimharris p->u.asecdef.address, 138230557Sjimharris p->u.asecdef.size); 139230557Sjimharris nl (); 140230557Sjimharris break; 141230557Sjimharris case coff_pointer_type: 142230557Sjimharris printf ("pointer to"); 143230557Sjimharris nl (); 144230557Sjimharris dump_coff_type (p->u.pointer.points_to); 145230557Sjimharris break; 146230557Sjimharris case coff_array_type: 147230557Sjimharris printf ("array [%d] of", p->u.array.dim); 148230557Sjimharris nl (); 149230557Sjimharris dump_coff_type (p->u.array.array_of); 150230557Sjimharris break; 151230557Sjimharris case coff_function_type: 152230557Sjimharris printf ("function returning"); 153230557Sjimharris nl (); 154230557Sjimharris dump_coff_type (p->u.function.function_returns); 155230557Sjimharris dump_coff_lines (p->u.function.lines); 156230557Sjimharris printf ("arguments"); 157230557Sjimharris 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