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