|
|
1.1 root 1: /* Read and manage MIPS symbol tables from object modules. 1.1.1.8 ! root 2: Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. 1.1.1.7 root 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 1.1.1.8 ! root 20: the Free Software Foundation, 59 Temple Place - Suite 330, ! 21: Boston, MA 02111-1307, USA. */ 1.1 root 22: 23: #include <stdio.h> 24: #include <sys/types.h> 25: #include <sys/file.h> 1.1.1.7 root 26: #include <time.h> 1.1.1.2 root 27: #include <fcntl.h> 1.1 root 28: #include <errno.h> 29: #include "config.h" 30: 1.1.1.4 root 31: #ifdef index 32: #undef index 33: #undef rindex 34: #endif 35: #ifndef CROSS_COMPILE 36: #include <a.out.h> 37: #else 1.1.1.6 root 38: #include "mips/a.out.h" 39: #endif /* CROSS_COMPILE */ 1.1.1.4 root 40: 1.1.1.5 root 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: 1.1 root 55: #ifdef __STDC__ 56: typedef void *PTR_T; 57: typedef const void *CPTR_T; 58: #define __proto(x) x 59: #else 60: 1.1.1.2 root 61: #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */ 1.1 root 62: typedef void *PTR_T; 63: typedef void *CPTR_T; 64: 65: #else 1.1.1.2 root 66: typedef char *PTR_T; /* Ultrix 3.1 */ 1.1 root 67: typedef 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: 1.1.1.4 root 79: 1.1 root 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: 1.1.1.3 root 89: /* Redefinition of of storage classes as an enumeration for better 1.1 root 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: 100: typedef 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: 129: typedef 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 */ 1.1.1.3 root 137: st_Block = stBlock, /* beginning of block */ 1.1 root 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 */ 1.1.1.8 ! root 147: #ifdef stStruct ! 148: st_Struct = stStruct, /* struct */ ! 149: st_Union = stUnion, /* union */ ! 150: st_Enum = stEnum, /* enum */ ! 151: #endif 1.1 root 152: st_Str = stStr, /* string */ 153: st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ 154: st_Expr = stExpr, /* 2+2 vs. 4 */ 1.1.1.3 root 155: st_Type = stType, /* post-coercion SER */ 1.1 root 156: st_Max = stMax /* max type+1 */ 157: } st_t; 158: 159: /* Redefinition of type qualifiers. */ 160: 161: typedef 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: 173: typedef 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: 206: typedef 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: 220: typedef 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. */ 229: typedef 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: 236: struct filehdr global_hdr; /* a.out header */ 237: 238: int errors = 0; /* # of errors */ 239: int want_aux = 0; /* print aux table */ 240: int want_line = 0; /* print line numbers */ 241: int want_rfd = 0; /* print relative file desc's */ 242: int want_scope = 0; /* print scopes for every symbol */ 1.1.1.5 root 243: int tfile = 0; /* no global header file */ 1.1 root 244: int tfile_fd; /* file descriptor of .T file */ 245: off_t tfile_offset; /* current offset in .T file */ 246: scope_t *cur_scope = 0; /* list of active scopes */ 247: scope_t *free_scope = 0; /* list of freed scopes */ 248: HDRR sym_hdr; /* symbolic header */ 249: char *l_strings; /* local strings */ 250: char *e_strings; /* external strings */ 251: SYMR *l_symbols; /* local symbols */ 252: EXTR *e_symbols; /* external symbols */ 253: LINER *lines; /* line numbers */ 254: DNR *dense_nums; /* dense numbers */ 255: OPTR *opt_symbols; /* optimization symbols */ 1.1.1.3 root 256: AUXU *aux_symbols; /* Auxiliary symbols */ 1.1 root 257: char *aux_used; /* map of which aux syms are used */ 258: FDR *file_desc; /* file tables */ 259: ulong *rfile_desc; /* relative file tables */ 260: PDR *proc_desc; /* procedure tables */ 261: 262: /* Forward reference for functions. */ 263: PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *)); 264: void read_tfile __proto((void)); 265: void print_global_hdr __proto((struct filehdr *)); 266: void print_sym_hdr __proto((HDRR *)); 267: void print_file_desc __proto((FDR *, int)); 1.1.1.8 ! root 268: void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *)); 1.1 root 269: void print_aux __proto((AUXU, int, int)); 1.1.1.8 ! root 270: void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *)); 1.1 root 271: char *st_to_string __proto((st_t)); 272: char *sc_to_string __proto((sc_t)); 273: char *glevel_to_string __proto((glevel_t)); 274: char *lang_to_string __proto((lang_t)); 1.1.1.8 ! root 275: char *type_to_string __proto((AUXU *, int, FDR *)); 1.1 root 276: 1.1.1.5 root 277: #ifndef __alpha 1.1 root 278: extern PTR_T malloc __proto((size_t)); 279: extern PTR_T calloc __proto((size_t, size_t)); 280: extern PTR_T realloc __proto((PTR_T, size_t)); 281: extern void free __proto((PTR_T)); 1.1.1.5 root 282: #endif 1.1 root 283: 284: extern char *optarg; 285: extern int optind; 286: extern 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}, 291: struct {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: 299: PTR_T 300: read_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: 333: char * 334: lang_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: 356: char * 357: sc_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: 394: char * 395: st_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"; 1.1.1.8 ! root 417: #ifdef stStruct ! 418: case st_Struct: return "Struct"; ! 419: case st_Union: return "Union"; ! 420: case st_Enum: return "Enum"; ! 421: #endif 1.1 root 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: 435: char * 436: glevel_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: 453: char * 1.1.1.8 ! root 454: type_to_string (aux_ptr, index, fdp) 1.1 root 455: AUXU *aux_ptr; 456: int index; 1.1.1.8 ! root 457: FDR *fdp; 1.1 root 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) */ 1.1.1.8 ! root 554: emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp); 1.1 root 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 */ 1.1.1.8 ! root 567: emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp); 1.1 root 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 */ 1.1.1.8 ! root 580: emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp); 1.1 root 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 */ 1.1.1.8 ! root 609: strcpy (p1, "forward/unnamed typedef"); 1.1 root 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 1.1.1.3 root 664: * store 5 successive words in the aux. table: 1.1 root 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: 766: void 767: print_global_hdr (ptr) 768: struct filehdr *ptr; 769: { 1.1.1.6 root 770: char *time = ctime ((time_t *)&ptr->f_timdat); 1.1 root 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); 1.1.1.7 root 780: printf(" %-*s 0x%x", 24, "flags", (ushort) flags); 1.1 root 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: 821: void 822: print_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: 1.1.1.7 root 835: printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers", 1.1.1.5 root 836: (long)sym_ptr->cbLineOffset, 837: (long)sym_ptr->cbLine, 838: (long)sym_ptr->cbLine, 839: (int)sym_ptr->ilineMax); 1.1 root 840: 1.1.1.7 root 841: printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers", 1.1.1.5 root 842: (long)sym_ptr->cbDnOffset, 843: (long)sym_ptr->idnMax, 844: (long)(sym_ptr->idnMax * sizeof (DNR))); 1.1 root 845: 1.1.1.7 root 846: printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables", 1.1.1.5 root 847: (long)sym_ptr->cbPdOffset, 848: (long)sym_ptr->ipdMax, 849: (long)(sym_ptr->ipdMax * sizeof (PDR))); 1.1 root 850: 1.1.1.7 root 851: printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols", 1.1.1.5 root 852: (long)sym_ptr->cbSymOffset, 853: (long)sym_ptr->isymMax, 854: (long)(sym_ptr->isymMax * sizeof (SYMR))); 1.1 root 855: 1.1.1.7 root 856: printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols", 1.1.1.5 root 857: (long)sym_ptr->cbOptOffset, 858: (long)sym_ptr->ioptMax, 859: (long)(sym_ptr->ioptMax * sizeof (OPTR))); 1.1 root 860: 1.1.1.7 root 861: printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols", 1.1.1.5 root 862: (long)sym_ptr->cbAuxOffset, 863: (long)sym_ptr->iauxMax, 864: (long)(sym_ptr->iauxMax * sizeof (AUXU))); 1.1 root 865: 1.1.1.7 root 866: printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings", 1.1.1.5 root 867: (long)sym_ptr->cbSsOffset, 868: (long)sym_ptr->issMax, 869: (long)sym_ptr->issMax); 1.1 root 870: 1.1.1.7 root 871: printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings", 1.1.1.5 root 872: (long)sym_ptr->cbSsExtOffset, 873: (long)sym_ptr->issExtMax, 874: (long)sym_ptr->issExtMax); 1.1 root 875: 1.1.1.7 root 876: printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables", 1.1.1.5 root 877: (long)sym_ptr->cbFdOffset, 878: (long)sym_ptr->ifdMax, 879: (long)(sym_ptr->ifdMax * sizeof (FDR))); 1.1 root 880: 1.1.1.7 root 881: printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files", 1.1.1.5 root 882: (long)sym_ptr->cbRfdOffset, 883: (long)sym_ptr->crfd, 884: (long)(sym_ptr->crfd * sizeof (ulong))); 1.1 root 885: 1.1.1.7 root 886: printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols", 1.1.1.5 root 887: (long)sym_ptr->cbExtOffset, 888: (long)sym_ptr->iextMax, 889: (long)(sym_ptr->iextMax * sizeof (EXTR))); 1.1 root 890: } 891: 892: 893: /* Print out a symbol. */ 894: 895: void 1.1.1.8 ! root 896: print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp) 1.1 root 897: SYMR *sym_ptr; 898: int number; 899: char *strbase; 900: AUXU *aux_base; 901: int ifd; 1.1.1.8 ! root 902: FDR *fdp; 1.1 root 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", 1.1.1.8 ! root 970: aux_base[index].isym, ! 971: type_to_string (aux_base, index+1, fdp)); 1.1 root 972: } 973: else /* global symbol */ 1.1.1.7 root 974: printf (" Local symbol: %ld\n", index); 1.1 root 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: 1.1.1.8 ! root 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: 1.1 root 1001: default: 1002: if (!MIPS_IS_STAB (sym_ptr)) 1003: { 1004: used_ptr[index] = 1; 1005: printf (" Type: %s\n", 1.1.1.8 ! root 1006: type_to_string (aux_base, index, fdp)); 1.1 root 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: 1.1.1.7 root 1034: printf (" %ld [%s]", scope_ptr->open_sym, class); 1.1 root 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: 1074: void 1075: print_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: 1100: void 1.1.1.8 ! root 1101: emit_aggregate (string, u, u2, which, fdp) 1.1 root 1102: char *string; 1103: AUXU u; 1104: AUXU u2; 1105: const char *which; 1.1.1.8 ! root 1106: FDR *fdp; 1.1 root 1107: { 1.1.1.8 ! root 1108: unsigned int ifd = u.rndx.rfd; ! 1109: unsigned int index = u.rndx.index; ! 1110: const char *name; 1.1 root 1111: 1112: if (ifd == ST_RFDESCAPE) 1113: ifd = u2.isym; 1114: 1.1.1.8 ! root 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: 1.1 root 1131: sprintf (string, 1.1.1.8 ! root 1132: "%s %s { ifd = %u, index = %u }", ! 1133: which, name, ifd, index); 1.1 root 1134: } 1135: 1136: 1137: /* Print out information about a file descriptor, and the symbols, 1138: procedures, and line numbers within it. */ 1139: 1140: void 1141: print_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: 1.1.1.7 root 1157: printf (" Name index = %-10ld Readin = %s\n", 1.1 root 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: 1.1.1.7 root 1180: printf(" %-*s %11lu %11lu %11lu %11lu\n", 1.1 root 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, 1.1.1.7 root 1191: (ulong) fdp->cbLine, 1.1 root 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: 1.1.1.7 root 1201: printf(" %-*s %11lu %11lu %11lu %11lu\n", 1.1 root 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, 1.1.1.8 ! root 1238: -1, ! 1239: fdp); 1.1 root 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: 1.1.1.5 root 1271: rfd_ptr = rfile_desc + fdp->rfdBase; 1.1 root 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; 1.1.1.7 root 1325: uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset 1326: + fdp->cbLineOffset); 1.1 root 1327: uchar *line_end; 1328: 1329: if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ 1.1.1.7 root 1330: line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset; 1.1 root 1331: else /* not last proc. */ 1.1.1.7 root 1332: line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset 1333: + fdp->cbLineOffset); 1.1 root 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: 1365: void 1366: read_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"); 1.1.1.5 root 1372: if (!tfile) 1.1 root 1373: { 1.1.1.5 root 1374: /* Print out the global header, since this is not a T-file. */ 1375: 1.1 root 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, 1.1.1.3 root 1425: "Auxiliary symbols"); 1.1 root 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: 1465: int 1466: main (argc, argv) 1467: int argc; 1468: char **argv; 1469: { 1470: int i, opt; 1471: 1472: /* 1473: * Process arguments 1474: */ 1.1.1.5 root 1475: while ((opt = getopt (argc, argv, "alrst")) != EOF) 1.1 root 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 */ 1.1.1.5 root 1483: case 't': tfile++; break; /* this is a tfile (without header), and not a .o */ 1.1 root 1484: } 1485: 1486: if (errors || optind != argc - 1) 1487: { 1488: fprintf (stderr, "Calling Sequence:\n"); 1.1.1.7 root 1489: fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]); 1.1 root 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"); 1.1.1.5 root 1496: fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); 1.1 root 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, 1.1.1.8 ! root 1558: e_symbols[i].ifd, ! 1559: &file_desc[e_symbols[i].ifd]); 1.1 root 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, 1.1.1.8 ! root 1583: type_to_string (aux_symbols, i, (FDR *) 0)); 1.1 root 1584: } 1585: } 1586: } 1587: 1588: return 0; 1589: } 1590: 1591: 1592: void 1593: fancy_abort () 1594: { 1595: fprintf (stderr, "mips-tdump internal error"); 1596: exit (1); 1597: } 1598: 1599: void 1600: fatal(s) 1601: char *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: 1609: PTR_T 1610: xmalloc (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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.