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