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