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