1/* Read and manage MIPS symbol tables from object modules. 2 Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4 Contributed by hartzell@boulder.colorado.edu, 5 Rewritten by meissner@osf.org. 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 3, or (at your option) any later 12version. 13 14GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15WARRANTY; without even the implied warranty of MERCHANTABILITY or 16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17for more details. 18 19You should have received a copy of the GNU General Public License 20along with GCC; see the file COPYING3. If not see 21<http://www.gnu.org/licenses/>. */ 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "tm.h" 27#include "version.h" 28#ifdef index 29#undef index 30#endif 31#ifndef CROSS_DIRECTORY_STRUCTURE 32#include <a.out.h> 33#else 34#include "mips/a.out.h" 35#endif /* CROSS_DIRECTORY_STRUCTURE */ 36 37/* Include getopt.h for the sake of getopt_long. */ 38#include "getopt.h" 39 40#ifndef MIPS_IS_STAB 41/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for 42 and mips-tdump.c to print them out. This is used on the Alpha, 43 which does not include mips.h. 44 45 These must match the corresponding definitions in gdb/mipsread.c. 46 Unfortunately, gcc and gdb do not currently share any directories. */ 47 48#define CODE_MASK 0x8F300 49#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) 50#define MIPS_MARK_STAB(code) ((code)+CODE_MASK) 51#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) 52#endif 53 54#define uchar unsigned char 55#define ushort unsigned short 56#define uint unsigned int 57#define ulong unsigned long 58 59 60/* Redefinition of storage classes as an enumeration for better 61 debugging. */ 62 63#ifndef stStaParam 64#define stStaParam 16 /* Fortran static parameters */ 65#endif 66 67#ifndef btVoid 68#define btVoid 26 /* void basic type */ 69#endif 70 71typedef enum sc { 72 sc_Nil = scNil, /* no storage class */ 73 sc_Text = scText, /* text symbol */ 74 sc_Data = scData, /* initialized data symbol */ 75 sc_Bss = scBss, /* un-initialized data symbol */ 76 sc_Register = scRegister, /* value of symbol is register number */ 77 sc_Abs = scAbs, /* value of symbol is absolute */ 78 sc_Undefined = scUndefined, /* who knows? */ 79 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ 80 sc_Bits = scBits, /* this is a bit field */ 81 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */ 82 sc_RegImage = scRegImage, /* register value saved on stack */ 83 sc_Info = scInfo, /* symbol contains debugger information */ 84 sc_UserStruct = scUserStruct, /* addr in struct user for current process */ 85 sc_SData = scSData, /* load time only small data */ 86 sc_SBss = scSBss, /* load time only small common */ 87 sc_RData = scRData, /* load time only read only data */ 88 sc_Var = scVar, /* Var parameter (fortran,pascal) */ 89 sc_Common = scCommon, /* common variable */ 90 sc_SCommon = scSCommon, /* small common */ 91 sc_VarRegister = scVarRegister, /* Var parameter in a register */ 92 sc_Variant = scVariant, /* Variant record */ 93 sc_SUndefined = scSUndefined, /* small undefined(external) data */ 94 sc_Init = scInit, /* .init section symbol */ 95 sc_Max = scMax /* Max storage class+1 */ 96} sc_t; 97 98/* Redefinition of symbol type. */ 99 100typedef enum st { 101 st_Nil = stNil, /* Nuthin' special */ 102 st_Global = stGlobal, /* external symbol */ 103 st_Static = stStatic, /* static */ 104 st_Param = stParam, /* procedure argument */ 105 st_Local = stLocal, /* local variable */ 106 st_Label = stLabel, /* label */ 107 st_Proc = stProc, /* " " Procedure */ 108 st_Block = stBlock, /* beginning of block */ 109 st_End = stEnd, /* end (of anything) */ 110 st_Member = stMember, /* member (of anything - struct/union/enum */ 111 st_Typedef = stTypedef, /* type definition */ 112 st_File = stFile, /* file name */ 113 st_RegReloc = stRegReloc, /* register relocation */ 114 st_Forward = stForward, /* forwarding address */ 115 st_StaticProc = stStaticProc, /* load time only static procs */ 116 st_StaParam = stStaParam, /* Fortran static parameters */ 117 st_Constant = stConstant, /* const */ 118#ifdef stStruct 119 st_Struct = stStruct, /* struct */ 120 st_Union = stUnion, /* union */ 121 st_Enum = stEnum, /* enum */ 122#endif 123 st_Str = stStr, /* string */ 124 st_Number = stNumber, /* pure number (i.e. 4 NOR 2+2) */ 125 st_Expr = stExpr, /* 2+2 vs. 4 */ 126 st_Type = stType, /* post-coercion SER */ 127 st_Max = stMax /* max type+1 */ 128} st_t; 129 130/* Redefinition of type qualifiers. */ 131 132typedef enum tq { 133 tq_Nil = tqNil, /* bt is what you see */ 134 tq_Ptr = tqPtr, /* pointer */ 135 tq_Proc = tqProc, /* procedure */ 136 tq_Array = tqArray, /* duh */ 137 tq_Far = tqFar, /* longer addressing - 8086/8 land */ 138 tq_Vol = tqVol, /* volatile */ 139 tq_Max = tqMax /* Max type qualifier+1 */ 140} tq_t; 141 142/* Redefinition of basic types. */ 143 144typedef enum bt { 145 bt_Nil = btNil, /* undefined */ 146 bt_Adr = btAdr, /* address - integer same size as pointer */ 147 bt_Char = btChar, /* character */ 148 bt_UChar = btUChar, /* unsigned character */ 149 bt_Short = btShort, /* short */ 150 bt_UShort = btUShort, /* unsigned short */ 151 bt_Int = btInt, /* int */ 152 bt_UInt = btUInt, /* unsigned int */ 153 bt_Long = btLong, /* long */ 154 bt_ULong = btULong, /* unsigned long */ 155 bt_Float = btFloat, /* float (real) */ 156 bt_Double = btDouble, /* Double (real) */ 157 bt_Struct = btStruct, /* Structure (Record) */ 158 bt_Union = btUnion, /* Union (variant) */ 159 bt_Enum = btEnum, /* Enumerated */ 160 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ 161 bt_Range = btRange, /* subrange of int */ 162 bt_Set = btSet, /* pascal sets */ 163 bt_Complex = btComplex, /* fortran complex */ 164 bt_DComplex = btDComplex, /* fortran double complex */ 165 bt_Indirect = btIndirect, /* forward or unnamed typedef */ 166 bt_FixedDec = btFixedDec, /* Fixed Decimal */ 167 bt_FloatDec = btFloatDec, /* Float Decimal */ 168 bt_String = btString, /* Varying Length Character String */ 169 bt_Bit = btBit, /* Aligned Bit String */ 170 bt_Picture = btPicture, /* Picture */ 171 bt_Void = btVoid, /* void */ 172 bt_Max = btMax /* Max basic type+1 */ 173} bt_t; 174 175/* Redefinition of the language codes. */ 176 177typedef enum lang { 178 lang_C = langC, 179 lang_Pascal = langPascal, 180 lang_Fortran = langFortran, 181 lang_Assembler = langAssembler, 182 lang_Machine = langMachine, 183 lang_Nil = langNil, 184 lang_Ada = langAda, 185 lang_Pl1 = langPl1, 186 lang_Cobol = langCobol 187} lang_t; 188 189/* Redefinition of the debug level codes. */ 190 191typedef enum glevel { 192 glevel_0 = GLEVEL_0, 193 glevel_1 = GLEVEL_1, 194 glevel_2 = GLEVEL_2, 195 glevel_3 = GLEVEL_3 196} glevel_t; 197 198 199/* Keep track of the active scopes. */ 200typedef struct scope { 201 struct scope *prev; /* previous scope */ 202 ulong open_sym; /* symbol opening scope */ 203 sc_t sc; /* storage class */ 204 st_t st; /* symbol type */ 205} scope_t; 206 207struct filehdr global_hdr; /* a.out header */ 208 209int errors = 0; /* # of errors */ 210int want_aux = 0; /* print aux table */ 211int want_line = 0; /* print line numbers */ 212int want_rfd = 0; /* print relative file desc's */ 213int want_scope = 0; /* print scopes for every symbol */ 214int tfile = 0; /* no global header file */ 215int version = 0; /* print version # */ 216int verbose = 0; 217int tfile_fd; /* file descriptor of .T file */ 218off_t tfile_offset; /* current offset in .T file */ 219scope_t *cur_scope = 0; /* list of active scopes */ 220scope_t *free_scope = 0; /* list of freed scopes */ 221HDRR sym_hdr; /* symbolic header */ 222char *l_strings; /* local strings */ 223char *e_strings; /* external strings */ 224SYMR *l_symbols; /* local symbols */ 225EXTR *e_symbols; /* external symbols */ 226LINER *lines; /* line numbers */ 227DNR *dense_nums; /* dense numbers */ 228OPTR *opt_symbols; /* optimization symbols */ 229AUXU *aux_symbols; /* Auxiliary symbols */ 230char *aux_used; /* map of which aux syms are used */ 231FDR *file_desc; /* file tables */ 232ulong *rfile_desc; /* relative file tables */ 233PDR *proc_desc; /* procedure tables */ 234 235/* Forward reference for functions. */ 236static void *read_seek (void *, size_t, off_t, const char *); 237static void read_tfile (void); 238static void print_global_hdr (struct filehdr *); 239static void print_sym_hdr (HDRR *); 240static void print_file_desc (FDR *, int); 241static void print_symbol (SYMR *, int, const char *, AUXU *, int, FDR *); 242static void print_aux (AUXU, int, int); 243static void emit_aggregate (char *, AUXU, AUXU, const char *, FDR *); 244static const char *st_to_string (st_t); 245static const char *sc_to_string (sc_t); 246static const char *glevel_to_string (glevel_t); 247static const char *lang_to_string (lang_t); 248static const char *type_to_string (AUXU *, int, FDR *); 249 250extern char *optarg; 251extern int optind; 252extern int opterr; 253 254/* Create a table of debugging stab-codes and corresponding names. */ 255 256#define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING}, 257const struct {const short code; const char string[10];} stab_names[] = { 258#include "stab.def" 259#undef __define_stab 260}; 261 262/* Command line options for getopt_long. */ 263 264static const struct option options[] = 265{ 266 { "version", 0, 0, 'V' }, 267 { "verbose", 0, 0, 'v' }, 268 { 0, 0, 0, 0 } 269}; 270 271/* Read some bytes at a specified location, and return a pointer. 272 Read_seek takes a pointer PTR to a buffer or NULL and reads SIZE 273 bytes from offset OFFSET. In case of errors CONTEXT is used as 274 error message. */ 275 276static void * 277read_seek (void *ptr, size_t size, off_t offset, const char *context) 278{ 279 long read_size = 0; 280 281 if (size == 0) /* nothing to read */ 282 return ptr; 283 284 if (!ptr) 285 ptr = xmalloc (size); 286 287 if ((tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1) 288 || (read_size = read (tfile_fd, ptr, size)) < 0) 289 { 290 perror (context); 291 exit (1); 292 } 293 294 if (read_size != (long) size) 295 { 296 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n", 297 context, read_size, (long) size); 298 exit (1); 299 } 300 301 tfile_offset = offset + size; 302 return ptr; 303} 304 305 306/* Convert language code to string format. */ 307 308static const char * 309lang_to_string (lang_t lang) 310{ 311 switch (lang) 312 { 313 case langC: return "C"; 314 case langPascal: return "Pascal"; 315 case langFortran: return "Fortran"; 316 case langAssembler: return "Assembler"; 317 case langMachine: return "Machine"; 318 case langNil: return "Nil"; 319 case langAda: return "Ada"; 320 case langPl1: return "Pl1"; 321 case langCobol: return "Cobol"; 322 } 323 324 return "Unknown language"; 325} 326 327 328/* Convert storage class to string. */ 329 330static const char * 331sc_to_string (sc_t storage_class) 332{ 333 switch(storage_class) 334 { 335 case sc_Nil: return "Nil"; 336 case sc_Text: return "Text"; 337 case sc_Data: return "Data"; 338 case sc_Bss: return "Bss"; 339 case sc_Register: return "Register"; 340 case sc_Abs: return "Abs"; 341 case sc_Undefined: return "Undefined"; 342 case sc_CdbLocal: return "CdbLocal"; 343 case sc_Bits: return "Bits"; 344 case sc_CdbSystem: return "CdbSystem"; 345 case sc_RegImage: return "RegImage"; 346 case sc_Info: return "Info"; 347 case sc_UserStruct: return "UserStruct"; 348 case sc_SData: return "SData"; 349 case sc_SBss: return "SBss"; 350 case sc_RData: return "RData"; 351 case sc_Var: return "Var"; 352 case sc_Common: return "Common"; 353 case sc_SCommon: return "SCommon"; 354 case sc_VarRegister: return "VarRegister"; 355 case sc_Variant: return "Variant"; 356 case sc_SUndefined: return "SUndefined"; 357 case sc_Init: return "Init"; 358 case sc_Max: return "Max"; 359 } 360 361 return "???"; 362} 363 364 365/* Convert symbol type to string. */ 366 367static const char * 368st_to_string (st_t symbol_type) 369{ 370 switch(symbol_type) 371 { 372 case st_Nil: return "Nil"; 373 case st_Global: return "Global"; 374 case st_Static: return "Static"; 375 case st_Param: return "Param"; 376 case st_Local: return "Local"; 377 case st_Label: return "Label"; 378 case st_Proc: return "Proc"; 379 case st_Block: return "Block"; 380 case st_End: return "End"; 381 case st_Member: return "Member"; 382 case st_Typedef: return "Typedef"; 383 case st_File: return "File"; 384 case st_RegReloc: return "RegReloc"; 385 case st_Forward: return "Forward"; 386 case st_StaticProc: return "StaticProc"; 387 case st_Constant: return "Constant"; 388 case st_StaParam: return "StaticParam"; 389#ifdef stStruct 390 case st_Struct: return "Struct"; 391 case st_Union: return "Union"; 392 case st_Enum: return "Enum"; 393#endif 394 case st_Str: return "String"; 395 case st_Number: return "Number"; 396 case st_Expr: return "Expr"; 397 case st_Type: return "Type"; 398 case st_Max: return "Max"; 399 } 400 401 return "???"; 402} 403 404 405/* Convert debug level to string. */ 406 407static const char * 408glevel_to_string (glevel_t g_level) 409{ 410 switch(g_level) 411 { 412 case GLEVEL_0: return "G0"; 413 case GLEVEL_1: return "G1"; 414 case GLEVEL_2: return "G2"; 415 case GLEVEL_3: return "G3"; 416 } 417 418 return "??"; 419} 420 421 422/* Convert the type information to string format. */ 423 424static const char * 425type_to_string (AUXU *aux_ptr, int index, FDR *fdp) 426{ 427 AUXU u; 428 struct qual { 429 tq_t type; 430 int low_bound; 431 int high_bound; 432 int stride; 433 } qualifiers[7]; 434 435 bt_t basic_type; 436 int i; 437 static char buffer1[1024]; 438 static char buffer2[1024]; 439 char *p1 = buffer1; 440 char *p2 = buffer2; 441 char *used_ptr = aux_used + (aux_ptr - aux_symbols); 442 443 for (i = 0; i < 7; i++) 444 { 445 qualifiers[i].low_bound = 0; 446 qualifiers[i].high_bound = 0; 447 qualifiers[i].stride = 0; 448 } 449 450 used_ptr[index] = 1; 451 u = aux_ptr[index++]; 452 if (u.isym == -1) 453 return "-1 (no type)"; 454 455 basic_type = (bt_t) u.ti.bt; 456 qualifiers[0].type = (tq_t) u.ti.tq0; 457 qualifiers[1].type = (tq_t) u.ti.tq1; 458 qualifiers[2].type = (tq_t) u.ti.tq2; 459 qualifiers[3].type = (tq_t) u.ti.tq3; 460 qualifiers[4].type = (tq_t) u.ti.tq4; 461 qualifiers[5].type = (tq_t) u.ti.tq5; 462 qualifiers[6].type = tq_Nil; 463 464 /* 465 * Go get the basic type. 466 */ 467 switch (basic_type) 468 { 469 case bt_Nil: /* undefined */ 470 strcpy (p1, "nil"); 471 break; 472 473 case bt_Adr: /* address - integer same size as pointer */ 474 strcpy (p1, "address"); 475 break; 476 477 case bt_Char: /* character */ 478 strcpy (p1, "char"); 479 break; 480 481 case bt_UChar: /* unsigned character */ 482 strcpy (p1, "unsigned char"); 483 break; 484 485 case bt_Short: /* short */ 486 strcpy (p1, "short"); 487 break; 488 489 case bt_UShort: /* unsigned short */ 490 strcpy (p1, "unsigned short"); 491 break; 492 493 case bt_Int: /* int */ 494 strcpy (p1, "int"); 495 break; 496 497 case bt_UInt: /* unsigned int */ 498 strcpy (p1, "unsigned int"); 499 break; 500 501 case bt_Long: /* long */ 502 strcpy (p1, "long"); 503 break; 504 505 case bt_ULong: /* unsigned long */ 506 strcpy (p1, "unsigned long"); 507 break; 508 509 case bt_Float: /* float (real) */ 510 strcpy (p1, "float"); 511 break; 512 513 case bt_Double: /* Double (real) */ 514 strcpy (p1, "double"); 515 break; 516 517 /* Structures add 1-2 aux words: 518 1st word is [ST_RFDESCAPE, offset] pointer to struct def; 519 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 520 521 case bt_Struct: /* Structure (Record) */ 522 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp); 523 used_ptr[index] = 1; 524 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) 525 used_ptr[++index] = 1; 526 527 index++; /* skip aux words */ 528 break; 529 530 /* Unions add 1-2 aux words: 531 1st word is [ST_RFDESCAPE, offset] pointer to union def; 532 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 533 534 case bt_Union: /* Union */ 535 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp); 536 used_ptr[index] = 1; 537 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) 538 used_ptr[++index] = 1; 539 540 index++; /* skip aux words */ 541 break; 542 543 /* Enumerations add 1-2 aux words: 544 1st word is [ST_RFDESCAPE, offset] pointer to enum def; 545 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 546 547 case bt_Enum: /* Enumeration */ 548 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp); 549 used_ptr[index] = 1; 550 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) 551 used_ptr[++index] = 1; 552 553 index++; /* skip aux words */ 554 break; 555 556 case bt_Typedef: /* defined via a typedef, isymRef points */ 557 strcpy (p1, "typedef"); 558 break; 559 560 case bt_Range: /* subrange of int */ 561 strcpy (p1, "subrange"); 562 break; 563 564 case bt_Set: /* pascal sets */ 565 strcpy (p1, "set"); 566 break; 567 568 case bt_Complex: /* fortran complex */ 569 strcpy (p1, "complex"); 570 break; 571 572 case bt_DComplex: /* fortran double complex */ 573 strcpy (p1, "double complex"); 574 break; 575 576 case bt_Indirect: /* forward or unnamed typedef */ 577 strcpy (p1, "forward/unnamed typedef"); 578 break; 579 580 case bt_FixedDec: /* Fixed Decimal */ 581 strcpy (p1, "fixed decimal"); 582 break; 583 584 case bt_FloatDec: /* Float Decimal */ 585 strcpy (p1, "float decimal"); 586 break; 587 588 case bt_String: /* Varying Length Character String */ 589 strcpy (p1, "string"); 590 break; 591 592 case bt_Bit: /* Aligned Bit String */ 593 strcpy (p1, "bit"); 594 break; 595 596 case bt_Picture: /* Picture */ 597 strcpy (p1, "picture"); 598 break; 599 600 case bt_Void: /* Void */ 601 strcpy (p1, "void"); 602 break; 603 604 default: 605 sprintf (p1, "Unknown basic type %d", (int) basic_type); 606 break; 607 } 608 609 p1 += strlen (buffer1); 610 611 /* 612 * If this is a bitfield, get the bitsize. 613 */ 614 if (u.ti.fBitfield) 615 { 616 int bitsize; 617 618 used_ptr[index] = 1; 619 bitsize = aux_ptr[index++].width; 620 sprintf (p1, " : %d", bitsize); 621 p1 += strlen (buffer1); 622 } 623 624 625 /* 626 * Deal with any qualifiers. 627 */ 628 if (qualifiers[0].type != tq_Nil) 629 { 630 /* 631 * Snarf up any array bounds in the correct order. Arrays 632 * store 5 successive words in the aux. table: 633 * word 0 RNDXR to type of the bounds (i.e., int) 634 * word 1 Current file descriptor index 635 * word 2 low bound 636 * word 3 high bound (or -1 if []) 637 * word 4 stride size in bits 638 */ 639 for (i = 0; i < 7; i++) 640 { 641 if (qualifiers[i].type == tq_Array) 642 { 643 qualifiers[i].low_bound = aux_ptr[index+2].dnLow; 644 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh; 645 qualifiers[i].stride = aux_ptr[index+4].width; 646 used_ptr[index] = 1; 647 used_ptr[index+1] = 1; 648 used_ptr[index+2] = 1; 649 used_ptr[index+3] = 1; 650 used_ptr[index+4] = 1; 651 index += 5; 652 } 653 } 654 655 /* 656 * Now print out the qualifiers. 657 */ 658 for (i = 0; i < 6; i++) 659 { 660 switch (qualifiers[i].type) 661 { 662 case tq_Nil: 663 case tq_Max: 664 break; 665 666 case tq_Ptr: 667 strcpy (p2, "ptr to "); 668 p2 += sizeof ("ptr to ")-1; 669 break; 670 671 case tq_Vol: 672 strcpy (p2, "volatile "); 673 p2 += sizeof ("volatile ")-1; 674 break; 675 676 case tq_Far: 677 strcpy (p2, "far "); 678 p2 += sizeof ("far ")-1; 679 break; 680 681 case tq_Proc: 682 strcpy (p2, "func. ret. "); 683 p2 += sizeof ("func. ret. "); 684 break; 685 686 case tq_Array: 687 { 688 int first_array = i; 689 int j; 690 691 /* Print array bounds reversed (i.e., in the order the C 692 programmer writes them). C is such a fun language.... */ 693 694 while (i < 5 && qualifiers[i+1].type == tq_Array) 695 i++; 696 697 for (j = i; j >= first_array; j--) 698 { 699 strcpy (p2, "array ["); 700 p2 += sizeof ("array [")-1; 701 if (qualifiers[j].low_bound != 0) 702 sprintf (p2, 703 "%ld:%ld {%ld bits}", 704 (long) qualifiers[j].low_bound, 705 (long) qualifiers[j].high_bound, 706 (long) qualifiers[j].stride); 707 708 else if (qualifiers[j].high_bound != -1) 709 sprintf (p2, 710 "%ld {%ld bits}", 711 (long) (qualifiers[j].high_bound + 1), 712 (long) (qualifiers[j].stride)); 713 714 else 715 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride)); 716 717 p2 += strlen (p2); 718 strcpy (p2, "] of "); 719 p2 += sizeof ("] of ")-1; 720 } 721 } 722 break; 723 } 724 } 725 } 726 727 strcpy (p2, buffer1); 728 return buffer2; 729} 730 731 732/* Print out the global file header for object files. */ 733 734static void 735print_global_hdr (struct filehdr *ptr) 736{ 737 char *time = ctime ((time_t *)&ptr->f_timdat); 738 ushort flags = ptr->f_flags; 739 740 printf("Global file header:\n"); 741 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic); 742 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns); 743 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time); 744 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr); 745 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms); 746 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr); 747 printf(" %-*s 0x%x", 24, "flags", (ushort) flags); 748 749 if ((flags & F_RELFLG) != 0) 750 printf (", F_RELFLG"); 751 752 if ((flags & F_EXEC) != 0) 753 printf (", F_EXEC"); 754 755 if ((flags & F_LNNO) != 0) 756 printf (", F_LNNO"); 757 758 if ((flags & F_LSYMS) != 0) 759 printf (", F_LSYMS"); 760 761 if ((flags & F_MINMAL) != 0) 762 printf (", F_MINMAL"); 763 764 if ((flags & F_UPDATE) != 0) 765 printf (", F_UPDATE"); 766 767 if ((flags & F_SWABD) != 0) 768 printf (", F_SWABD"); 769 770 if ((flags & F_AR16WR) != 0) 771 printf (", F_AR16WR"); 772 773 if ((flags & F_AR32WR) != 0) 774 printf (", F_AR32WR"); 775 776 if ((flags & F_AR32W) != 0) 777 printf (", F_AR32W"); 778 779 if ((flags & F_PATCH) != 0) 780 printf (", F_PATCH/F_NODF"); 781 782 printf ("\n\n"); 783} 784 785 786/* Print out the symbolic header. */ 787 788static void 789print_sym_hdr (HDRR *sym_ptr) 790{ 791 int width = 20; 792 793 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n", 794 sym_ptr->magic & 0xffff, 795 (sym_ptr->vstamp & 0xffff) >> 8, 796 sym_ptr->vstamp & 0xff); 797 798 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes"); 799 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n"); 800 801 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers", 802 (long) sym_ptr->cbLineOffset, 803 (long) sym_ptr->cbLine, 804 (long) sym_ptr->cbLine, 805 (int) sym_ptr->ilineMax); 806 807 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers", 808 (long) sym_ptr->cbDnOffset, 809 (long) sym_ptr->idnMax, 810 (long) (sym_ptr->idnMax * sizeof (DNR))); 811 812 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables", 813 (long) sym_ptr->cbPdOffset, 814 (long) sym_ptr->ipdMax, 815 (long) (sym_ptr->ipdMax * sizeof (PDR))); 816 817 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols", 818 (long) sym_ptr->cbSymOffset, 819 (long) sym_ptr->isymMax, 820 (long) (sym_ptr->isymMax * sizeof (SYMR))); 821 822 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols", 823 (long) sym_ptr->cbOptOffset, 824 (long) sym_ptr->ioptMax, 825 (long) (sym_ptr->ioptMax * sizeof (OPTR))); 826 827 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols", 828 (long) sym_ptr->cbAuxOffset, 829 (long) sym_ptr->iauxMax, 830 (long) (sym_ptr->iauxMax * sizeof (AUXU))); 831 832 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings", 833 (long) sym_ptr->cbSsOffset, 834 (long) sym_ptr->issMax, 835 (long) sym_ptr->issMax); 836 837 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings", 838 (long) sym_ptr->cbSsExtOffset, 839 (long) sym_ptr->issExtMax, 840 (long) sym_ptr->issExtMax); 841 842 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables", 843 (long) sym_ptr->cbFdOffset, 844 (long) sym_ptr->ifdMax, 845 (long) (sym_ptr->ifdMax * sizeof (FDR))); 846 847 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files", 848 (long) sym_ptr->cbRfdOffset, 849 (long) sym_ptr->crfd, 850 (long) (sym_ptr->crfd * sizeof (ulong))); 851 852 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols", 853 (long) sym_ptr->cbExtOffset, 854 (long) sym_ptr->iextMax, 855 (long) (sym_ptr->iextMax * sizeof (EXTR))); 856} 857 858 859/* Print out a symbol. */ 860 861static void 862print_symbol (SYMR *sym_ptr, int number, const char *strbase, AUXU *aux_base, 863 int ifd, FDR *fdp) 864{ 865 sc_t storage_class = (sc_t) sym_ptr->sc; 866 st_t symbol_type = (st_t) sym_ptr->st; 867 ulong index = sym_ptr->index; 868 char *used_ptr = aux_used + (aux_base - aux_symbols); 869 scope_t *scope_ptr; 870 871 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase); 872 873 if (aux_base != (AUXU *) 0 && index != indexNil) 874 switch (symbol_type) 875 { 876 case st_Nil: 877 case st_Label: 878 break; 879 880 case st_File: 881 case st_Block: 882 printf (" End+1 symbol: %ld\n", index); 883 if (want_scope) 884 { 885 if (free_scope == (scope_t *) 0) 886 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); 887 else 888 { 889 scope_ptr = free_scope; 890 free_scope = scope_ptr->prev; 891 } 892 scope_ptr->open_sym = number; 893 scope_ptr->st = symbol_type; 894 scope_ptr->sc = storage_class; 895 scope_ptr->prev = cur_scope; 896 cur_scope = scope_ptr; 897 } 898 break; 899 900 case st_End: 901 if (storage_class == sc_Text || storage_class == sc_Info) 902 printf (" First symbol: %ld\n", index); 903 else 904 { 905 used_ptr[index] = 1; 906 printf (" First symbol: %ld\n", (long) aux_base[index].isym); 907 } 908 909 if (want_scope) 910 { 911 if (cur_scope == (scope_t *) 0) 912 printf (" Can't pop end scope\n"); 913 else 914 { 915 scope_ptr = cur_scope; 916 cur_scope = scope_ptr->prev; 917 scope_ptr->prev = free_scope; 918 free_scope = scope_ptr; 919 } 920 } 921 break; 922 923 case st_Proc: 924 case st_StaticProc: 925 if (MIPS_IS_STAB(sym_ptr)) 926 ; 927 else if (ifd == -1) /* local symbol */ 928 { 929 used_ptr[index] = used_ptr[index+1] = 1; 930 printf (" End+1 symbol: %-7ld Type: %s\n", 931 (long) aux_base[index].isym, 932 type_to_string (aux_base, index+1, fdp)); 933 } 934 else /* global symbol */ 935 printf (" Local symbol: %ld\n", index); 936 937 if (want_scope) 938 { 939 if (free_scope == (scope_t *) 0) 940 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); 941 else 942 { 943 scope_ptr = free_scope; 944 free_scope = scope_ptr->prev; 945 } 946 scope_ptr->open_sym = number; 947 scope_ptr->st = symbol_type; 948 scope_ptr->sc = storage_class; 949 scope_ptr->prev = cur_scope; 950 cur_scope = scope_ptr; 951 } 952 break; 953 954#ifdef stStruct 955 case st_Struct: 956 case st_Union: 957 case st_Enum: 958 printf (" End+1 symbol: %lu\n", index); 959 break; 960#endif 961 962 default: 963 if (!MIPS_IS_STAB (sym_ptr)) 964 { 965 used_ptr[index] = 1; 966 printf (" Type: %s\n", 967 type_to_string (aux_base, index, fdp)); 968 } 969 break; 970 } 971 972 if (want_scope) 973 { 974 printf (" Scopes: "); 975 if (cur_scope == (scope_t *) 0) 976 printf (" none\n"); 977 else 978 { 979 for (scope_ptr = cur_scope; 980 scope_ptr != (scope_t *) 0; 981 scope_ptr = scope_ptr->prev) 982 { 983 const char *sclass; 984 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc) 985 sclass = "func."; 986 else if (scope_ptr->st == st_File) 987 sclass = "file"; 988 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text) 989 sclass = "block"; 990 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info) 991 sclass = "type"; 992 else 993 sclass = "???"; 994 995 printf (" %ld [%s]", scope_ptr->open_sym, sclass); 996 } 997 printf ("\n"); 998 } 999 } 1000 1001 printf (" Value: %-13ld ", 1002 (long)sym_ptr->value); 1003 if (ifd == -1) 1004 printf ("String index: %ld\n", (long)sym_ptr->iss); 1005 else 1006 printf ("String index: %-11ld Ifd: %d\n", 1007 (long)sym_ptr->iss, ifd); 1008 1009 printf (" Symbol type: %-11sStorage class: %-11s", 1010 st_to_string (symbol_type), sc_to_string (storage_class)); 1011 1012 if (MIPS_IS_STAB(sym_ptr)) 1013 { 1014 int i = ARRAY_SIZE (stab_names); 1015 const char *stab_name = "stab"; 1016 short code = MIPS_UNMARK_STAB(sym_ptr->index); 1017 1018 while (--i >= 0) 1019 if (stab_names[i].code == code) 1020 { 1021 stab_name = stab_names[i].string; 1022 break; 1023 } 1024 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name); 1025 } 1026 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil) 1027 printf ("Index: %ld (line#)\n", (long)sym_ptr->index); 1028 else 1029 printf ("Index: %ld\n", (long)sym_ptr->index); 1030 1031} 1032 1033 1034/* Print out a word from the aux. table in various formats. */ 1035 1036static void 1037print_aux (AUXU u, int auxi, int used) 1038{ 1039 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n", 1040 (used) ? " " : "* ", 1041 auxi, 1042 (long) u.isym, 1043 (long) u.rndx.rfd, 1044 (long) u.rndx.index, 1045 u.ti.bt, 1046 u.ti.fBitfield, 1047 u.ti.continued, 1048 u.ti.tq0, 1049 u.ti.tq1, 1050 u.ti.tq2, 1051 u.ti.tq3, 1052 u.ti.tq4, 1053 u.ti.tq5); 1054} 1055 1056 1057/* Write aggregate information to a string. */ 1058 1059static void 1060emit_aggregate (char *string, AUXU u, AUXU u2, const char *which, FDR *fdp) 1061{ 1062 unsigned int ifd = u.rndx.rfd; 1063 unsigned int index = u.rndx.index; 1064 const char *name; 1065 1066 if (ifd == ST_RFDESCAPE) 1067 ifd = u2.isym; 1068 1069 /* An ifd of -1 is an opaque type. An escaped index of 0 is a 1070 struct return type of a procedure compiled without -g. */ 1071 if (ifd == 0xffffffff 1072 || (u.rndx.rfd == ST_RFDESCAPE && index == 0)) 1073 name = "<undefined>"; 1074 else if (index == indexNil) 1075 name = "<no name>"; 1076 else 1077 { 1078 if (fdp == 0 || sym_hdr.crfd == 0) 1079 fdp = &file_desc[ifd]; 1080 else 1081 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]]; 1082 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss]; 1083 } 1084 1085 sprintf (string, 1086 "%s %s { ifd = %u, index = %u }", 1087 which, name, ifd, index); 1088} 1089 1090 1091/* Print out information about a file descriptor, and the symbols, 1092 procedures, and line numbers within it. */ 1093 1094static void 1095print_file_desc (FDR *fdp, int number) 1096{ 1097 char *str_base; 1098 AUXU *aux_base; 1099 int symi, pdi; 1100 int width = 20; 1101 char *used_base; 1102 1103 str_base = l_strings + fdp->issBase; 1104 aux_base = aux_symbols + fdp->iauxBase; 1105 used_base = aux_used + (aux_base - aux_symbols); 1106 1107 printf ("\nFile #%d, \"%s\"\n\n", 1108 number, 1109 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>"); 1110 1111 printf (" Name index = %-10ld Readin = %s\n", 1112 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No"); 1113 1114 printf (" Merge = %-10s Endian = %s\n", 1115 (fdp->fMerge) ? "Yes" : "No", 1116 (fdp->fBigendian) ? "BIG" : "LITTLE"); 1117 1118 printf (" Debug level = %-10s Language = %s\n", 1119 glevel_to_string ((glevel_t) fdp->glevel), 1120 lang_to_string((lang_t) fdp->lang)); 1121 1122 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr); 1123 1124 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset"); 1125 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======"); 1126 1127 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1128 width, "Local strings", 1129 (ulong) fdp->issBase, 1130 (ulong) fdp->cbSs, 1131 (ulong) fdp->cbSs, 1132 (ulong) (fdp->issBase + sym_hdr.cbSsOffset)); 1133 1134 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1135 width, "Local symbols", 1136 (ulong) fdp->isymBase, 1137 (ulong) fdp->csym, 1138 (ulong) (fdp->csym * sizeof (SYMR)), 1139 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset)); 1140 1141 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1142 width, "Line numbers", 1143 (ulong) fdp->cbLineOffset, 1144 (ulong) fdp->cline, 1145 (ulong) fdp->cbLine, 1146 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset)); 1147 1148 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1149 width, "Optimization symbols", 1150 (ulong) fdp->ioptBase, 1151 (ulong) fdp->copt, 1152 (ulong) (fdp->copt * sizeof (OPTR)), 1153 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset)); 1154 1155 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1156 width, "Procedures", 1157 (ulong) fdp->ipdFirst, 1158 (ulong) fdp->cpd, 1159 (ulong) (fdp->cpd * sizeof (PDR)), 1160 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset)); 1161 1162 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1163 width, "Auxiliary symbols", 1164 (ulong) fdp->iauxBase, 1165 (ulong) fdp->caux, 1166 (ulong) (fdp->caux * sizeof (AUXU)), 1167 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset)); 1168 1169 printf(" %-*s %11lu %11lu %11lu %11lu\n", 1170 width, "Relative Files", 1171 (ulong) fdp->rfdBase, 1172 (ulong) fdp->crfd, 1173 (ulong) (fdp->crfd * sizeof (ulong)), 1174 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset)); 1175 1176 1177 if (want_scope && cur_scope != (scope_t *) 0) 1178 printf ("\n Warning scope does not start at 0!\n"); 1179 1180 /* 1181 * print the info about the symbol table. 1182 */ 1183 printf ("\n There are %lu local symbols, starting at %lu\n", 1184 (ulong) fdp->csym, 1185 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset)); 1186 1187 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++) 1188 print_symbol (&l_symbols[symi], 1189 symi - fdp->isymBase, 1190 str_base, 1191 aux_base, 1192 -1, 1193 fdp); 1194 1195 if (want_scope && cur_scope != (scope_t *) 0) 1196 printf ("\n Warning scope does not end at 0!\n"); 1197 1198 /* 1199 * print the aux. table if desired. 1200 */ 1201 1202 if (want_aux && fdp->caux != 0) 1203 { 1204 int auxi; 1205 1206 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n", 1207 (ulong) fdp->caux, 1208 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset)); 1209 1210 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++) 1211 print_aux (aux_base[auxi], auxi, used_base[auxi]); 1212 } 1213 1214 /* 1215 * print the relative file descriptors. 1216 */ 1217 if (want_rfd && fdp->crfd != 0) 1218 { 1219 ulong *rfd_ptr, i; 1220 1221 printf ("\n There are %lu relative file descriptors, starting at %lu.\n", 1222 (ulong) fdp->crfd, 1223 (ulong) fdp->rfdBase); 1224 1225 rfd_ptr = rfile_desc + fdp->rfdBase; 1226 for (i = 0; i < (ulong) fdp->crfd; i++) 1227 { 1228 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr); 1229 rfd_ptr++; 1230 } 1231 } 1232 1233 /* 1234 * do the procedure descriptors. 1235 */ 1236 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd); 1237 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst); 1238 1239 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++) 1240 { 1241 PDR *proc_ptr = &proc_desc[pdi]; 1242 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst)); 1243 1244 if (l_symbols != 0) 1245 printf ("\t Name index = %-11ld Name = \"%s\"\n", 1246 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss, 1247 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base); 1248 1249 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n", 1250 (long) proc_ptr->regmask, 1251 (long) proc_ptr->regoffset, 1252 (long) proc_ptr->fregmask, 1253 (long) proc_ptr->fregoffset); 1254 1255 printf ("\t .frame $%d,%ld,$%d\n", 1256 (int) proc_ptr->framereg, 1257 (long) proc_ptr->frameoffset, 1258 (int) proc_ptr->pcreg); 1259 1260 printf ("\t Opt. start = %-11ld Symbols start = %ld\n", 1261 (long) proc_ptr->iopt, 1262 (long) proc_ptr->isym); 1263 1264 printf ("\t First line # = %-11ld Last line # = %ld\n", 1265 (long) proc_ptr->lnLow, 1266 (long) proc_ptr->lnHigh); 1267 1268 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n", 1269 (long) proc_ptr->cbLineOffset, 1270 (long) proc_ptr->adr); 1271 1272 /* 1273 * print the line number entries. 1274 */ 1275 1276 if (want_line && fdp->cline != 0) 1277 { 1278 int delta, count; 1279 long cur_line = proc_ptr->lnLow; 1280 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset 1281 + fdp->cbLineOffset); 1282 uchar *line_end; 1283 1284 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ 1285 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset; 1286 else /* not last proc. */ 1287 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset 1288 + fdp->cbLineOffset); 1289 1290 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n", 1291 (ulong) (line_end - line_ptr), 1292 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset)); 1293 1294 while (line_ptr < line_end) 1295 { /* sign extend nibble */ 1296 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8; 1297 count = (*line_ptr & 0xf) + 1; 1298 if (delta != -8) 1299 line_ptr++; 1300 else 1301 { 1302 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff); 1303 delta = (delta ^ 0x8000) - 0x8000; 1304 line_ptr += 3; 1305 } 1306 1307 cur_line += delta; 1308 printf ("\t Line %11ld, delta %5d, count %2d\n", 1309 cur_line, 1310 delta, 1311 count); 1312 } 1313 } 1314 } 1315} 1316 1317 1318/* Read in the portions of the .T file that we will print out. */ 1319 1320static void 1321read_tfile (void) 1322{ 1323 short magic; 1324 off_t sym_hdr_offset = 0; 1325 1326 read_seek (&magic, sizeof (magic), 0, "Magic number"); 1327 if (!tfile) 1328 { 1329 /* Print out the global header, since this is not a T-file. */ 1330 1331 read_seek (&global_hdr, sizeof (global_hdr), 0, "Global file header"); 1332 1333 print_global_hdr (&global_hdr); 1334 1335 if (global_hdr.f_symptr == 0) 1336 { 1337 printf ("No symbolic header, Goodbye!\n"); 1338 exit (1); 1339 } 1340 1341 sym_hdr_offset = global_hdr.f_symptr; 1342 } 1343 1344 read_seek (&sym_hdr, sizeof (sym_hdr), sym_hdr_offset, "Symbolic header"); 1345 1346 print_sym_hdr (&sym_hdr); 1347 1348 lines = (LINER *) read_seek (NULL, sym_hdr.cbLine, sym_hdr.cbLineOffset, 1349 "Line numbers"); 1350 1351 dense_nums = (DNR *) read_seek (NULL, sym_hdr.idnMax * sizeof (DNR), 1352 sym_hdr.cbDnOffset, "Dense numbers"); 1353 1354 proc_desc = (PDR *) read_seek (NULL, sym_hdr.ipdMax * sizeof (PDR), 1355 sym_hdr.cbPdOffset, "Procedure tables"); 1356 1357 l_symbols = (SYMR *) read_seek (NULL, sym_hdr.isymMax * sizeof (SYMR), 1358 sym_hdr.cbSymOffset, "Local symbols"); 1359 1360 opt_symbols = (OPTR *) read_seek (NULL, sym_hdr.ioptMax * sizeof (OPTR), 1361 sym_hdr.cbOptOffset, 1362 "Optimization symbols"); 1363 1364 aux_symbols = (AUXU *) read_seek (NULL, sym_hdr.iauxMax * sizeof (AUXU), 1365 sym_hdr.cbAuxOffset, "Auxiliary symbols"); 1366 1367 if (sym_hdr.iauxMax > 0) 1368 aux_used = (char *) xcalloc (sym_hdr.iauxMax, 1); 1369 1370 l_strings = (char *) read_seek (NULL, sym_hdr.issMax, 1371 sym_hdr.cbSsOffset, "Local string table"); 1372 1373 e_strings = (char *) read_seek (NULL, sym_hdr.issExtMax, 1374 sym_hdr.cbSsExtOffset, 1375 "External string table"); 1376 1377 file_desc = (FDR *) read_seek (NULL, sym_hdr.ifdMax * sizeof (FDR), 1378 sym_hdr.cbFdOffset, "File tables"); 1379 1380 rfile_desc = (ulong *) read_seek (NULL, sym_hdr.crfd * sizeof (ulong), 1381 sym_hdr.cbRfdOffset, 1382 "Relative file tables"); 1383 1384 e_symbols = (EXTR *) read_seek (NULL, sym_hdr.iextMax * sizeof (EXTR), 1385 sym_hdr.cbExtOffset, "External symbols"); 1386} 1387 1388 1389 1390extern int main (int, char **); 1391 1392int 1393main (int argc, char **argv) 1394{ 1395 int i, opt; 1396 1397 /* 1398 * Process arguments 1399 */ 1400 while ((opt = getopt_long (argc, argv, "alrsvt", options, NULL)) != -1) 1401 switch (opt) 1402 { 1403 default: errors++; break; 1404 case 'a': want_aux++; break; /* print aux table */ 1405 case 'l': want_line++; break; /* print line numbers */ 1406 case 'r': want_rfd++; break; /* print relative fd's */ 1407 case 's': want_scope++; break; /* print scope info */ 1408 case 'v': verbose++; break; /* print version # */ 1409 case 'V': version++; break; /* print version # */ 1410 case 't': tfile++; break; /* this is a tfile (without header), 1411 and not a .o */ 1412 } 1413 1414 if (version) 1415 { 1416 printf ("mips-tdump %s%s\n", pkgversion_string, version_string); 1417 fputs ("Copyright (C) 2010 Free Software Foundation, Inc.\n", stdout); 1418 fputs ("This is free software; see the source for copying conditions. There is NO\n\ 1419warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n", 1420 stdout); 1421 exit (0); 1422 } 1423 1424 if (optind != argc - 1) 1425 errors++; 1426 1427 if (verbose || errors) 1428 { 1429 fprintf (stderr, "mips-tdump (GCC) %s", version_string); 1430#ifdef TARGET_VERSION 1431 TARGET_VERSION; 1432#endif 1433 fputc ('\n', stderr); 1434 } 1435 1436 if (errors) 1437 { 1438 fprintf (stderr, "Calling Sequence:\n"); 1439 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]); 1440 fprintf (stderr, "\n"); 1441 fprintf (stderr, "switches:\n"); 1442 fprintf (stderr, "\t-a Print out auxiliary table.\n"); 1443 fprintf (stderr, "\t-l Print out line numbers.\n"); 1444 fprintf (stderr, "\t-r Print out relative file descriptors.\n"); 1445 fprintf (stderr, "\t-s Print out the current scopes for an item.\n"); 1446 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); 1447 fprintf (stderr, "\t-v Print program version.\n"); 1448 return 1; 1449 } 1450 1451 /* 1452 * Open and process the input file. 1453 */ 1454 tfile_fd = open (argv[optind], O_RDONLY); 1455 if (tfile_fd < 0) 1456 { 1457 perror (argv[optind]); 1458 return 1; 1459 } 1460 1461 read_tfile (); 1462 1463 /* 1464 * Print any global aux words if any. 1465 */ 1466 if (want_aux) 1467 { 1468 long last_aux_in_use; 1469 1470 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0) 1471 { 1472 printf ("\nGlobal auxiliary entries before first file:\n"); 1473 for (i = 0; i < file_desc[0].iauxBase; i++) 1474 print_aux (aux_symbols[i], 0, aux_used[i]); 1475 } 1476 1477 if (sym_hdr.ifdMax == 0) 1478 last_aux_in_use = 0; 1479 else 1480 last_aux_in_use 1481 = (file_desc[sym_hdr.ifdMax-1].iauxBase 1482 + file_desc[sym_hdr.ifdMax-1].caux - 1); 1483 1484 if (last_aux_in_use < sym_hdr.iauxMax-1) 1485 { 1486 printf ("\nGlobal auxiliary entries after last file:\n"); 1487 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++) 1488 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]); 1489 } 1490 } 1491 1492 /* 1493 * Print the information for each file. 1494 */ 1495 for (i = 0; i < sym_hdr.ifdMax; i++) 1496 print_file_desc (&file_desc[i], i); 1497 1498 /* 1499 * Print the external symbols. 1500 */ 1501 want_scope = 0; /* scope info is meaning for extern symbols */ 1502 printf ("\nThere are %lu external symbols, starting at %lu\n", 1503 (ulong) sym_hdr.iextMax, 1504 (ulong) sym_hdr.cbExtOffset); 1505 1506 for(i = 0; i < sym_hdr.iextMax; i++) 1507 print_symbol (&e_symbols[i].asym, i, e_strings, 1508 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase, 1509 e_symbols[i].ifd, 1510 &file_desc[e_symbols[i].ifd]); 1511 1512 /* 1513 * Print unused aux symbols now. 1514 */ 1515 1516 if (want_aux) 1517 { 1518 int first_time = 1; 1519 1520 for (i = 0; i < sym_hdr.iauxMax; i++) 1521 { 1522 if (! aux_used[i]) 1523 { 1524 if (first_time) 1525 { 1526 printf ("\nThe following auxiliary table entries were unused:\n\n"); 1527 first_time = 0; 1528 } 1529 1530 printf (" #%-5d %11ld 0x%08lx %s\n", 1531 i, 1532 (long) aux_symbols[i].isym, 1533 (long) aux_symbols[i].isym, 1534 type_to_string (aux_symbols, i, (FDR *) 0)); 1535 } 1536 } 1537 } 1538 1539 return 0; 1540} 1541