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