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