|
|
1.1 ! root 1: /* Read and manage MIPS symbol tables from object modules. ! 2: Source originally from [email protected] ! 3: Rewritten by: [email protected] ! 4: Copyright (C) 1991 Free Software Foundation, Inc. ! 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> ! 25: #include <fcntl.h> ! 26: #include <errno.h> ! 27: #include "config.h" ! 28: ! 29: #ifdef index ! 30: #undef index ! 31: #undef rindex ! 32: #endif ! 33: #ifndef CROSS_COMPILE ! 34: #include <a.out.h> ! 35: #else ! 36: #include "mips/a.out.h" ! 37: #endif /* CROSS_COMPILE */ ! 38: ! 39: #ifndef MIPS_IS_STAB ! 40: /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for ! 41: and mips-tdump.c to print them out. This is used on the Alpha, ! 42: which does not include mips.h. ! 43: ! 44: These must match the corresponding definitions in gdb/mipsread.c. ! 45: Unfortunately, gcc and gdb do not currently share any directories. */ ! 46: ! 47: #define CODE_MASK 0x8F300 ! 48: #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) ! 49: #define MIPS_MARK_STAB(code) ((code)+CODE_MASK) ! 50: #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) ! 51: #endif ! 52: ! 53: #ifdef __STDC__ ! 54: typedef void *PTR_T; ! 55: typedef const void *CPTR_T; ! 56: #define __proto(x) x ! 57: #else ! 58: ! 59: #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */ ! 60: typedef void *PTR_T; ! 61: typedef void *CPTR_T; ! 62: ! 63: #else ! 64: typedef char *PTR_T; /* Ultrix 3.1 */ ! 65: typedef char *CPTR_T; ! 66: #endif ! 67: ! 68: #define __proto(x) () ! 69: #define const ! 70: #endif ! 71: ! 72: #define uchar unsigned char ! 73: #define ushort unsigned short ! 74: #define uint unsigned int ! 75: #define ulong unsigned long ! 76: ! 77: ! 78: /* Do to size_t being defined in sys/types.h and different ! 79: in stddef.h, we have to do this by hand..... Note, these ! 80: types are correct for MIPS based systems, and may not be ! 81: correct for other systems. */ ! 82: ! 83: #define size_t uint ! 84: #define ptrdiff_t int ! 85: ! 86: ! 87: /* Redefinition of of storage classes as an enumeration for better ! 88: debugging. */ ! 89: ! 90: #ifndef stStaParam ! 91: #define stStaParam 16 /* Fortran static parameters */ ! 92: #endif ! 93: ! 94: #ifndef btVoid ! 95: #define btVoid 26 /* void basic type */ ! 96: #endif ! 97: ! 98: typedef enum sc { ! 99: sc_Nil = scNil, /* no storage class */ ! 100: sc_Text = scText, /* text symbol */ ! 101: sc_Data = scData, /* initialized data symbol */ ! 102: sc_Bss = scBss, /* un-initialized data symbol */ ! 103: sc_Register = scRegister, /* value of symbol is register number */ ! 104: sc_Abs = scAbs, /* value of symbol is absolute */ ! 105: sc_Undefined = scUndefined, /* who knows? */ ! 106: sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ ! 107: sc_Bits = scBits, /* this is a bit field */ ! 108: sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */ ! 109: sc_RegImage = scRegImage, /* register value saved on stack */ ! 110: sc_Info = scInfo, /* symbol contains debugger information */ ! 111: sc_UserStruct = scUserStruct, /* addr in struct user for current process */ ! 112: sc_SData = scSData, /* load time only small data */ ! 113: sc_SBss = scSBss, /* load time only small common */ ! 114: sc_RData = scRData, /* load time only read only data */ ! 115: sc_Var = scVar, /* Var parameter (fortran,pascal) */ ! 116: sc_Common = scCommon, /* common variable */ ! 117: sc_SCommon = scSCommon, /* small common */ ! 118: sc_VarRegister = scVarRegister, /* Var parameter in a register */ ! 119: sc_Variant = scVariant, /* Variant record */ ! 120: sc_SUndefined = scSUndefined, /* small undefined(external) data */ ! 121: sc_Init = scInit, /* .init section symbol */ ! 122: sc_Max = scMax /* Max storage class+1 */ ! 123: } sc_t; ! 124: ! 125: /* Redefinition of symbol type. */ ! 126: ! 127: typedef enum st { ! 128: st_Nil = stNil, /* Nuthin' special */ ! 129: st_Global = stGlobal, /* external symbol */ ! 130: st_Static = stStatic, /* static */ ! 131: st_Param = stParam, /* procedure argument */ ! 132: st_Local = stLocal, /* local variable */ ! 133: st_Label = stLabel, /* label */ ! 134: st_Proc = stProc, /* " " Procedure */ ! 135: st_Block = stBlock, /* beginning of block */ ! 136: st_End = stEnd, /* end (of anything) */ ! 137: st_Member = stMember, /* member (of anything - struct/union/enum */ ! 138: st_Typedef = stTypedef, /* type definition */ ! 139: st_File = stFile, /* file name */ ! 140: st_RegReloc = stRegReloc, /* register relocation */ ! 141: st_Forward = stForward, /* forwarding address */ ! 142: st_StaticProc = stStaticProc, /* load time only static procs */ ! 143: st_StaParam = stStaParam, /* Fortran static parameters */ ! 144: st_Constant = stConstant, /* const */ ! 145: st_Str = stStr, /* string */ ! 146: st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ ! 147: st_Expr = stExpr, /* 2+2 vs. 4 */ ! 148: st_Type = stType, /* post-coercion SER */ ! 149: st_Max = stMax /* max type+1 */ ! 150: } st_t; ! 151: ! 152: /* Redefinition of type qualifiers. */ ! 153: ! 154: typedef enum tq { ! 155: tq_Nil = tqNil, /* bt is what you see */ ! 156: tq_Ptr = tqPtr, /* pointer */ ! 157: tq_Proc = tqProc, /* procedure */ ! 158: tq_Array = tqArray, /* duh */ ! 159: tq_Far = tqFar, /* longer addressing - 8086/8 land */ ! 160: tq_Vol = tqVol, /* volatile */ ! 161: tq_Max = tqMax /* Max type qualifier+1 */ ! 162: } tq_t; ! 163: ! 164: /* Redefinition of basic types. */ ! 165: ! 166: typedef enum bt { ! 167: bt_Nil = btNil, /* undefined */ ! 168: bt_Adr = btAdr, /* address - integer same size as pointer */ ! 169: bt_Char = btChar, /* character */ ! 170: bt_UChar = btUChar, /* unsigned character */ ! 171: bt_Short = btShort, /* short */ ! 172: bt_UShort = btUShort, /* unsigned short */ ! 173: bt_Int = btInt, /* int */ ! 174: bt_UInt = btUInt, /* unsigned int */ ! 175: bt_Long = btLong, /* long */ ! 176: bt_ULong = btULong, /* unsigned long */ ! 177: bt_Float = btFloat, /* float (real) */ ! 178: bt_Double = btDouble, /* Double (real) */ ! 179: bt_Struct = btStruct, /* Structure (Record) */ ! 180: bt_Union = btUnion, /* Union (variant) */ ! 181: bt_Enum = btEnum, /* Enumerated */ ! 182: bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ ! 183: bt_Range = btRange, /* subrange of int */ ! 184: bt_Set = btSet, /* pascal sets */ ! 185: bt_Complex = btComplex, /* fortran complex */ ! 186: bt_DComplex = btDComplex, /* fortran double complex */ ! 187: bt_Indirect = btIndirect, /* forward or unnamed typedef */ ! 188: bt_FixedDec = btFixedDec, /* Fixed Decimal */ ! 189: bt_FloatDec = btFloatDec, /* Float Decimal */ ! 190: bt_String = btString, /* Varying Length Character String */ ! 191: bt_Bit = btBit, /* Aligned Bit String */ ! 192: bt_Picture = btPicture, /* Picture */ ! 193: bt_Void = btVoid, /* void */ ! 194: bt_Max = btMax /* Max basic type+1 */ ! 195: } bt_t; ! 196: ! 197: /* Redefinition of the language codes. */ ! 198: ! 199: typedef enum lang { ! 200: lang_C = langC, ! 201: lang_Pascal = langPascal, ! 202: lang_Fortran = langFortran, ! 203: lang_Assembler = langAssembler, ! 204: lang_Machine = langMachine, ! 205: lang_Nil = langNil, ! 206: lang_Ada = langAda, ! 207: lang_Pl1 = langPl1, ! 208: lang_Cobol = langCobol ! 209: } lang_t; ! 210: ! 211: /* Redefinition of the debug level codes. */ ! 212: ! 213: typedef enum glevel { ! 214: glevel_0 = GLEVEL_0, ! 215: glevel_1 = GLEVEL_1, ! 216: glevel_2 = GLEVEL_2, ! 217: glevel_3 = GLEVEL_3 ! 218: } glevel_t; ! 219: ! 220: ! 221: /* Keep track of the active scopes. */ ! 222: typedef struct scope { ! 223: struct scope *prev; /* previous scope */ ! 224: ulong open_sym; /* symbol opening scope */ ! 225: sc_t sc; /* storage class */ ! 226: st_t st; /* symbol type */ ! 227: } scope_t; ! 228: ! 229: struct filehdr global_hdr; /* a.out header */ ! 230: ! 231: int errors = 0; /* # of errors */ ! 232: int want_aux = 0; /* print aux table */ ! 233: int want_line = 0; /* print line numbers */ ! 234: int want_rfd = 0; /* print relative file desc's */ ! 235: int want_scope = 0; /* print scopes for every symbol */ ! 236: int tfile = 0; /* no global header file */ ! 237: int tfile_fd; /* file descriptor of .T file */ ! 238: off_t tfile_offset; /* current offset in .T file */ ! 239: scope_t *cur_scope = 0; /* list of active scopes */ ! 240: scope_t *free_scope = 0; /* list of freed scopes */ ! 241: HDRR sym_hdr; /* symbolic header */ ! 242: char *l_strings; /* local strings */ ! 243: char *e_strings; /* external strings */ ! 244: SYMR *l_symbols; /* local symbols */ ! 245: EXTR *e_symbols; /* external symbols */ ! 246: LINER *lines; /* line numbers */ ! 247: DNR *dense_nums; /* dense numbers */ ! 248: OPTR *opt_symbols; /* optimization symbols */ ! 249: AUXU *aux_symbols; /* Auxiliary symbols */ ! 250: char *aux_used; /* map of which aux syms are used */ ! 251: FDR *file_desc; /* file tables */ ! 252: ulong *rfile_desc; /* relative file tables */ ! 253: PDR *proc_desc; /* procedure tables */ ! 254: ! 255: /* Forward reference for functions. */ ! 256: PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *)); ! 257: void read_tfile __proto((void)); ! 258: void print_global_hdr __proto((struct filehdr *)); ! 259: void print_sym_hdr __proto((HDRR *)); ! 260: void print_file_desc __proto((FDR *, int)); ! 261: void print_symbol __proto((SYMR *, int, char *, AUXU *, int)); ! 262: void print_aux __proto((AUXU, int, int)); ! 263: void emit_aggregate __proto((char *, AUXU, AUXU, const char *)); ! 264: char *st_to_string __proto((st_t)); ! 265: char *sc_to_string __proto((sc_t)); ! 266: char *glevel_to_string __proto((glevel_t)); ! 267: char *lang_to_string __proto((lang_t)); ! 268: char *type_to_string __proto((AUXU *, int)); ! 269: ! 270: #ifndef __alpha ! 271: extern PTR_T malloc __proto((size_t)); ! 272: extern PTR_T calloc __proto((size_t, size_t)); ! 273: extern PTR_T realloc __proto((PTR_T, size_t)); ! 274: extern void free __proto((PTR_T)); ! 275: #endif ! 276: extern char *ctime __proto((time_t *)); ! 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 ! 652: * store 5 successive words in the aux. table: ! 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: { ! 758: char *time = ctime ((time_t *)&ptr->f_timdat); ! 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); ! 768: printf(" %-*s 0x%lx", 24, "flags", (ushort) flags); ! 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: ! 823: printf(" %-*s %11ld %11d %11d [%d]\n", width, "Line numbers", ! 824: (long)sym_ptr->cbLineOffset, ! 825: (long)sym_ptr->cbLine, ! 826: (long)sym_ptr->cbLine, ! 827: (int)sym_ptr->ilineMax); ! 828: ! 829: printf(" %-*s %11ld %11d %11d\n", width, "Dense numbers", ! 830: (long)sym_ptr->cbDnOffset, ! 831: (long)sym_ptr->idnMax, ! 832: (long)(sym_ptr->idnMax * sizeof (DNR))); ! 833: ! 834: printf(" %-*s %11ld %11d %11d\n", width, "Procedures Tables", ! 835: (long)sym_ptr->cbPdOffset, ! 836: (long)sym_ptr->ipdMax, ! 837: (long)(sym_ptr->ipdMax * sizeof (PDR))); ! 838: ! 839: printf(" %-*s %11ld %11d %11d\n", width, "Local Symbols", ! 840: (long)sym_ptr->cbSymOffset, ! 841: (long)sym_ptr->isymMax, ! 842: (long)(sym_ptr->isymMax * sizeof (SYMR))); ! 843: ! 844: printf(" %-*s %11ld %11d %11d\n", width, "Optimization Symbols", ! 845: (long)sym_ptr->cbOptOffset, ! 846: (long)sym_ptr->ioptMax, ! 847: (long)(sym_ptr->ioptMax * sizeof (OPTR))); ! 848: ! 849: printf(" %-*s %11ld %11d %11d\n", width, "Auxiliary Symbols", ! 850: (long)sym_ptr->cbAuxOffset, ! 851: (long)sym_ptr->iauxMax, ! 852: (long)(sym_ptr->iauxMax * sizeof (AUXU))); ! 853: ! 854: printf(" %-*s %11ld %11d %11d\n", width, "Local Strings", ! 855: (long)sym_ptr->cbSsOffset, ! 856: (long)sym_ptr->issMax, ! 857: (long)sym_ptr->issMax); ! 858: ! 859: printf(" %-*s %11ld %11d %11d\n", width, "External Strings", ! 860: (long)sym_ptr->cbSsExtOffset, ! 861: (long)sym_ptr->issExtMax, ! 862: (long)sym_ptr->issExtMax); ! 863: ! 864: printf(" %-*s %11ld %11d %11d\n", width, "File Tables", ! 865: (long)sym_ptr->cbFdOffset, ! 866: (long)sym_ptr->ifdMax, ! 867: (long)(sym_ptr->ifdMax * sizeof (FDR))); ! 868: ! 869: printf(" %-*s %11ld %11d %11d\n", width, "Relative Files", ! 870: (long)sym_ptr->cbRfdOffset, ! 871: (long)sym_ptr->crfd, ! 872: (long)(sym_ptr->crfd * sizeof (ulong))); ! 873: ! 874: printf(" %-*s %11ld %11d %11d\n", width, "External Symbols", ! 875: (long)sym_ptr->cbExtOffset, ! 876: (long)sym_ptr->iextMax, ! 877: (long)(sym_ptr->iextMax * sizeof (EXTR))); ! 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 */ ! 960: { ! 961: used_ptr[index] = 1; ! 962: printf (" Type: %s\n", ! 963: type_to_string (aux_base, index)); ! 964: } ! 965: ! 966: if (want_scope) ! 967: { ! 968: if (free_scope == (scope_t *)0) ! 969: scope_ptr = (scope_t *) malloc (sizeof (scope_t)); ! 970: else ! 971: { ! 972: scope_ptr = free_scope; ! 973: free_scope = scope_ptr->prev; ! 974: } ! 975: scope_ptr->open_sym = number; ! 976: scope_ptr->st = symbol_type; ! 977: scope_ptr->sc = storage_class; ! 978: scope_ptr->prev = cur_scope; ! 979: cur_scope = scope_ptr; ! 980: } ! 981: break; ! 982: ! 983: default: ! 984: if (!MIPS_IS_STAB (sym_ptr)) ! 985: { ! 986: used_ptr[index] = 1; ! 987: printf (" Type: %s\n", ! 988: type_to_string (aux_base, index)); ! 989: } ! 990: break; ! 991: } ! 992: ! 993: if (want_scope) ! 994: { ! 995: printf (" Scopes: "); ! 996: if (cur_scope == (scope_t *)0) ! 997: printf (" none\n"); ! 998: else ! 999: { ! 1000: for (scope_ptr = cur_scope; ! 1001: scope_ptr != (scope_t *)0; ! 1002: scope_ptr = scope_ptr->prev) ! 1003: { ! 1004: char *class; ! 1005: if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc) ! 1006: class = "func."; ! 1007: else if (scope_ptr->st == st_File) ! 1008: class = "file"; ! 1009: else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text) ! 1010: class = "block"; ! 1011: else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info) ! 1012: class = "type"; ! 1013: else ! 1014: class = "???"; ! 1015: ! 1016: printf (" %d [%s]", scope_ptr->open_sym, class); ! 1017: } ! 1018: printf ("\n"); ! 1019: } ! 1020: } ! 1021: ! 1022: printf (" Value: %-13ld ", ! 1023: (long)sym_ptr->value); ! 1024: if (ifd == -1) ! 1025: printf ("String index: %ld\n", (long)sym_ptr->iss); ! 1026: else ! 1027: printf ("String index: %-11ld Ifd: %d\n", ! 1028: (long)sym_ptr->iss, ifd); ! 1029: ! 1030: printf (" Symbol type: %-11sStorage class: %-11s", ! 1031: st_to_string (symbol_type), sc_to_string (storage_class)); ! 1032: ! 1033: if (MIPS_IS_STAB(sym_ptr)) ! 1034: { ! 1035: register int i = sizeof(stab_names) / sizeof(stab_names[0]); ! 1036: char *stab_name = "stab"; ! 1037: short code = MIPS_UNMARK_STAB(sym_ptr->index); ! 1038: while (--i >= 0) ! 1039: if (stab_names[i].code == code) ! 1040: { ! 1041: stab_name = stab_names[i].string; ! 1042: break; ! 1043: } ! 1044: printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name); ! 1045: } ! 1046: else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil) ! 1047: printf ("Index: %ld (line#)\n", (long)sym_ptr->index); ! 1048: else ! 1049: printf ("Index: %ld\n", (long)sym_ptr->index); ! 1050: ! 1051: } ! 1052: ! 1053: ! 1054: /* Print out a word from the aux. table in various formats. */ ! 1055: ! 1056: void ! 1057: print_aux (u, auxi, used) ! 1058: AUXU u; ! 1059: int auxi; ! 1060: int used; ! 1061: { ! 1062: printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n", ! 1063: (used) ? " " : "* ", ! 1064: auxi, ! 1065: (long) u.isym, ! 1066: (long) u.rndx.rfd, ! 1067: (long) u.rndx.index, ! 1068: u.ti.bt, ! 1069: u.ti.fBitfield, ! 1070: u.ti.continued, ! 1071: u.ti.tq0, ! 1072: u.ti.tq1, ! 1073: u.ti.tq2, ! 1074: u.ti.tq3, ! 1075: u.ti.tq4, ! 1076: u.ti.tq5); ! 1077: } ! 1078: ! 1079: ! 1080: /* Write aggregate information to a string. */ ! 1081: ! 1082: void ! 1083: emit_aggregate (string, u, u2, which) ! 1084: char *string; ! 1085: AUXU u; ! 1086: AUXU u2; ! 1087: const char *which; ! 1088: { ! 1089: int ifd = u.rndx.rfd; ! 1090: int index = u.rndx.index; ! 1091: int sym_base, ss_base; ! 1092: int name; ! 1093: ! 1094: if (ifd == ST_RFDESCAPE) ! 1095: ifd = u2.isym; ! 1096: ! 1097: sym_base = file_desc[ifd].isymBase; ! 1098: ss_base = file_desc[ifd].issBase; ! 1099: ! 1100: name = (index == indexNil) ? 0 : l_symbols[index + sym_base].iss; ! 1101: sprintf (string, ! 1102: "%s %s { ifd = %d, index = %d }", ! 1103: which, ! 1104: (name == 0) ? "/* no name */" : &l_strings[ ss_base + name ], ! 1105: ifd, ! 1106: index); ! 1107: } ! 1108: ! 1109: ! 1110: /* Print out information about a file descriptor, and the symbols, ! 1111: procedures, and line numbers within it. */ ! 1112: ! 1113: void ! 1114: print_file_desc (fdp, number) ! 1115: FDR *fdp; ! 1116: int number; ! 1117: { ! 1118: char *str_base; ! 1119: AUXU *aux_base; ! 1120: int symi, pdi; ! 1121: int width = 20; ! 1122: char *used_base; ! 1123: ! 1124: str_base = l_strings + fdp->issBase; ! 1125: aux_base = aux_symbols + fdp->iauxBase; ! 1126: used_base = aux_used + (aux_base - aux_symbols); ! 1127: ! 1128: printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss); ! 1129: ! 1130: printf (" Name index = %-10d Readin = %s\n", ! 1131: (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No"); ! 1132: ! 1133: printf (" Merge = %-10s Endian = %s\n", ! 1134: (fdp->fMerge) ? "Yes" : "No", ! 1135: (fdp->fBigendian) ? "BIG" : "LITTLE"); ! 1136: ! 1137: printf (" Debug level = %-10s Language = %s\n", ! 1138: glevel_to_string (fdp->glevel), ! 1139: lang_to_string((lang_t) fdp->lang)); ! 1140: ! 1141: printf (" Adr = 0x%08lx\n\n", (long) fdp->adr); ! 1142: ! 1143: printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset"); ! 1144: printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======"); ! 1145: ! 1146: printf(" %-*s %11lu %11lu %11lu %11lu\n", ! 1147: width, "Local strings", ! 1148: (ulong) fdp->issBase, ! 1149: (ulong) fdp->cbSs, ! 1150: (ulong) fdp->cbSs, ! 1151: (ulong) (fdp->issBase + sym_hdr.cbSsOffset)); ! 1152: ! 1153: printf(" %-*s %11lu %11u %11u %11lu\n", ! 1154: width, "Local symbols", ! 1155: (ulong) fdp->isymBase, ! 1156: (ulong) fdp->csym, ! 1157: (ulong) (fdp->csym * sizeof (SYMR)), ! 1158: (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset)); ! 1159: ! 1160: printf(" %-*s %11lu %11lu %11lu %11lu\n", ! 1161: width, "Line numbers", ! 1162: (ulong) fdp->cbLineOffset, ! 1163: (ulong) fdp->cline, ! 1164: (ulong) fdp->cline, ! 1165: (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset)); ! 1166: ! 1167: printf(" %-*s %11lu %11lu %11lu %11lu\n", ! 1168: width, "Optimization symbols", ! 1169: (ulong) fdp->ioptBase, ! 1170: (ulong) fdp->copt, ! 1171: (ulong) (fdp->copt * sizeof (OPTR)), ! 1172: (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset)); ! 1173: ! 1174: printf(" %-*s %11llu %11lu %11lu %11lu\n", ! 1175: width, "Procedures", ! 1176: (ulong) fdp->ipdFirst, ! 1177: (ulong) fdp->cpd, ! 1178: (ulong) (fdp->cpd * sizeof (PDR)), ! 1179: (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset)); ! 1180: ! 1181: printf(" %-*s %11lu %11lu %11lu %11lu\n", ! 1182: width, "Auxiliary symbols", ! 1183: (ulong) fdp->iauxBase, ! 1184: (ulong) fdp->caux, ! 1185: (ulong) (fdp->caux * sizeof (AUXU)), ! 1186: (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset)); ! 1187: ! 1188: printf(" %-*s %11lu %11lu %11lu %11lu\n", ! 1189: width, "Relative Files", ! 1190: (ulong) fdp->rfdBase, ! 1191: (ulong) fdp->crfd, ! 1192: (ulong) (fdp->crfd * sizeof (ulong)), ! 1193: (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset)); ! 1194: ! 1195: ! 1196: if (want_scope && cur_scope != (scope_t *)0) ! 1197: printf ("\n Warning scope does not start at 0!\n"); ! 1198: ! 1199: /* ! 1200: * print the info about the symbol table. ! 1201: */ ! 1202: printf ("\n There are %lu local symbols, starting at %lu\n", ! 1203: (ulong) fdp->csym, ! 1204: (ulong) (fdp->isymBase + sym_hdr.cbSymOffset)); ! 1205: ! 1206: for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++) ! 1207: print_symbol (&l_symbols[symi], ! 1208: symi - fdp->isymBase, ! 1209: str_base, ! 1210: aux_base, ! 1211: -1); ! 1212: ! 1213: if (want_scope && cur_scope != (scope_t *)0) ! 1214: printf ("\n Warning scope does not end at 0!\n"); ! 1215: ! 1216: /* ! 1217: * print the aux. table if desired. ! 1218: */ ! 1219: ! 1220: if (want_aux && fdp->caux != 0) ! 1221: { ! 1222: int auxi; ! 1223: ! 1224: printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n", ! 1225: (ulong) fdp->caux, ! 1226: (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset)); ! 1227: ! 1228: for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++) ! 1229: print_aux (aux_base[auxi], auxi, used_base[auxi]); ! 1230: } ! 1231: ! 1232: /* ! 1233: * print the relative file descriptors. ! 1234: */ ! 1235: if (want_rfd && fdp->crfd != 0) ! 1236: { ! 1237: ulong *rfd_ptr, i; ! 1238: ! 1239: printf ("\n There are %lu relative file descriptors, starting at %lu.\n", ! 1240: (ulong) fdp->crfd, ! 1241: (ulong) fdp->rfdBase); ! 1242: ! 1243: rfd_ptr = rfile_desc + fdp->rfdBase; ! 1244: for (i = 0; i < fdp->crfd; i++) ! 1245: { ! 1246: printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr); ! 1247: rfd_ptr++; ! 1248: } ! 1249: } ! 1250: ! 1251: /* ! 1252: * do the procedure descriptors. ! 1253: */ ! 1254: printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd); ! 1255: printf ("starting at %lu.\n", (ulong) fdp->ipdFirst); ! 1256: ! 1257: for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++) ! 1258: { ! 1259: PDR *proc_ptr = &proc_desc[pdi]; ! 1260: printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst)); ! 1261: ! 1262: printf ("\t Name index = %-11ld Name = \"%s\"\n", ! 1263: (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss, ! 1264: l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base); ! 1265: ! 1266: printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n", ! 1267: (long) proc_ptr->regmask, ! 1268: (long) proc_ptr->regoffset, ! 1269: (long) proc_ptr->fregmask, ! 1270: (long) proc_ptr->fregoffset); ! 1271: ! 1272: printf ("\t .frame $%d,%ld,$%d\n", ! 1273: (int) proc_ptr->framereg, ! 1274: (long) proc_ptr->frameoffset, ! 1275: (int) proc_ptr->pcreg); ! 1276: ! 1277: printf ("\t Opt. start = %-11ld Symbols start = %ld\n", ! 1278: (long) proc_ptr->iopt, ! 1279: (long) proc_ptr->isym); ! 1280: ! 1281: printf ("\t First line # = %-11ld Last line # = %ld\n", ! 1282: (long) proc_ptr->lnLow, ! 1283: (long) proc_ptr->lnHigh); ! 1284: ! 1285: printf ("\t Line Offset = %-11ld Address = 0x%08lx\n", ! 1286: (long) proc_ptr->cbLineOffset, ! 1287: (long) proc_ptr->adr); ! 1288: ! 1289: /* ! 1290: * print the line number entries. ! 1291: */ ! 1292: ! 1293: if (want_line && fdp->cline != 0) ! 1294: { ! 1295: int delta, count; ! 1296: long cur_line = proc_ptr->lnLow; ! 1297: uchar *line_ptr = ((uchar *)lines) + proc_ptr->cbLineOffset; ! 1298: uchar *line_end; ! 1299: ! 1300: if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ ! 1301: line_end = ((uchar *)lines) + fdp->cbLine + fdp->ilineBase; ! 1302: else /* not last proc. */ ! 1303: line_end = ((uchar *)lines) + proc_desc[pdi+1].cbLineOffset; ! 1304: ! 1305: ! 1306: printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n", ! 1307: (ulong) (line_end - line_ptr), ! 1308: (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset)); ! 1309: ! 1310: while (line_ptr < line_end) ! 1311: { /* sign extend nibble */ ! 1312: delta = ((*line_ptr >> 4) ^ 0x8) - 0x8; ! 1313: count = (*line_ptr & 0xf) + 1; ! 1314: if (delta != -8) ! 1315: line_ptr++; ! 1316: else ! 1317: { ! 1318: delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff); ! 1319: delta = (delta ^ 0x8000) - 0x8000; ! 1320: line_ptr += 3; ! 1321: } ! 1322: ! 1323: cur_line += delta; ! 1324: printf ("\t Line %11ld, delta %5d, count %2d\n", ! 1325: cur_line, ! 1326: delta, ! 1327: count); ! 1328: } ! 1329: } ! 1330: } ! 1331: } ! 1332: ! 1333: ! 1334: /* Read in the portions of the .T file that we will print out. */ ! 1335: ! 1336: void ! 1337: read_tfile __proto((void)) ! 1338: { ! 1339: short magic; ! 1340: off_t sym_hdr_offset = 0; ! 1341: ! 1342: (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t)0, "Magic number"); ! 1343: if (!tfile) ! 1344: { ! 1345: /* Print out the global header, since this is not a T-file. */ ! 1346: ! 1347: (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t)0, ! 1348: "Global file header"); ! 1349: ! 1350: print_global_hdr (&global_hdr); ! 1351: ! 1352: if (global_hdr.f_symptr == 0) ! 1353: { ! 1354: printf ("No symbolic header, Goodbye!\n"); ! 1355: exit (1); ! 1356: } ! 1357: ! 1358: sym_hdr_offset = global_hdr.f_symptr; ! 1359: } ! 1360: ! 1361: (void) read_seek ((PTR_T) &sym_hdr, ! 1362: sizeof (sym_hdr), ! 1363: sym_hdr_offset, ! 1364: "Symbolic header"); ! 1365: ! 1366: print_sym_hdr (&sym_hdr); ! 1367: ! 1368: lines = (LINER *) read_seek ((PTR_T)0, ! 1369: sym_hdr.cbLine, ! 1370: sym_hdr.cbLineOffset, ! 1371: "Line numbers"); ! 1372: ! 1373: dense_nums = (DNR *) read_seek ((PTR_T)0, ! 1374: sym_hdr.idnMax * sizeof (DNR), ! 1375: sym_hdr.cbDnOffset, ! 1376: "Dense numbers"); ! 1377: ! 1378: proc_desc = (PDR *) read_seek ((PTR_T)0, ! 1379: sym_hdr.ipdMax * sizeof (PDR), ! 1380: sym_hdr.cbPdOffset, ! 1381: "Procedure tables"); ! 1382: ! 1383: l_symbols = (SYMR *) read_seek ((PTR_T)0, ! 1384: sym_hdr.isymMax * sizeof (SYMR), ! 1385: sym_hdr.cbSymOffset, ! 1386: "Local symbols"); ! 1387: ! 1388: opt_symbols = (OPTR *) read_seek ((PTR_T)0, ! 1389: sym_hdr.ioptMax * sizeof (OPTR), ! 1390: sym_hdr.cbOptOffset, ! 1391: "Optimization symbols"); ! 1392: ! 1393: aux_symbols = (AUXU *) read_seek ((PTR_T)0, ! 1394: sym_hdr.iauxMax * sizeof (AUXU), ! 1395: sym_hdr.cbAuxOffset, ! 1396: "Auxiliary symbols"); ! 1397: ! 1398: if (sym_hdr.iauxMax > 0) ! 1399: { ! 1400: aux_used = calloc (sym_hdr.iauxMax, 1); ! 1401: if (aux_used == (char *)0) ! 1402: { ! 1403: perror ("calloc"); ! 1404: exit (1); ! 1405: } ! 1406: } ! 1407: ! 1408: l_strings = (char *) read_seek ((PTR_T)0, ! 1409: sym_hdr.issMax, ! 1410: sym_hdr.cbSsOffset, ! 1411: "Local string table"); ! 1412: ! 1413: e_strings = (char *) read_seek ((PTR_T)0, ! 1414: sym_hdr.issExtMax, ! 1415: sym_hdr.cbSsExtOffset, ! 1416: "External string table"); ! 1417: ! 1418: file_desc = (FDR *) read_seek ((PTR_T)0, ! 1419: sym_hdr.ifdMax * sizeof (FDR), ! 1420: sym_hdr.cbFdOffset, ! 1421: "File tables"); ! 1422: ! 1423: rfile_desc = (ulong *) read_seek ((PTR_T)0, ! 1424: sym_hdr.crfd * sizeof (ulong), ! 1425: sym_hdr.cbRfdOffset, ! 1426: "Relative file tables"); ! 1427: ! 1428: e_symbols = (EXTR *) read_seek ((PTR_T)0, ! 1429: sym_hdr.iextMax * sizeof (EXTR), ! 1430: sym_hdr.cbExtOffset, ! 1431: "External symbols"); ! 1432: } ! 1433: ! 1434: ! 1435: ! 1436: int ! 1437: main (argc, argv) ! 1438: int argc; ! 1439: char **argv; ! 1440: { ! 1441: int i, opt; ! 1442: ! 1443: /* ! 1444: * Process arguments ! 1445: */ ! 1446: while ((opt = getopt (argc, argv, "alrst")) != EOF) ! 1447: switch (opt) ! 1448: { ! 1449: default: errors++; break; ! 1450: case 'a': want_aux++; break; /* print aux table */ ! 1451: case 'l': want_line++; break; /* print line numbers */ ! 1452: case 'r': want_rfd++; break; /* print relative fd's */ ! 1453: case 's': want_scope++; break; /* print scope info */ ! 1454: case 't': tfile++; break; /* this is a tfile (without header), and not a .o */ ! 1455: } ! 1456: ! 1457: if (errors || optind != argc - 1) ! 1458: { ! 1459: fprintf (stderr, "Calling Sequence:\n"); ! 1460: fprintf (stderr, "\t%0 [-alrst] <object-or-T-file>\n", argv[0]); ! 1461: fprintf (stderr, "\n"); ! 1462: fprintf (stderr, "switches:\n"); ! 1463: fprintf (stderr, "\t-a Print out auxiliary table.\n"); ! 1464: fprintf (stderr, "\t-l Print out line numbers.\n"); ! 1465: fprintf (stderr, "\t-r Print out relative file descriptors.\n"); ! 1466: fprintf (stderr, "\t-s Print out the current scopes for an item.\n"); ! 1467: fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); ! 1468: return 1; ! 1469: } ! 1470: ! 1471: /* ! 1472: * Open and process the input file. ! 1473: */ ! 1474: tfile_fd = open (argv[optind], O_RDONLY); ! 1475: if (tfile_fd < 0) ! 1476: { ! 1477: perror (argv[optind]); ! 1478: return 1; ! 1479: } ! 1480: ! 1481: read_tfile (); ! 1482: ! 1483: /* ! 1484: * Print any global aux words if any. ! 1485: */ ! 1486: if (want_aux) ! 1487: { ! 1488: long last_aux_in_use; ! 1489: ! 1490: if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0) ! 1491: { ! 1492: printf ("\nGlobal auxiliary entries before first file:\n"); ! 1493: for (i = 0; i < file_desc[0].iauxBase; i++) ! 1494: print_aux (aux_symbols[i], 0, aux_used[i]); ! 1495: } ! 1496: ! 1497: if (sym_hdr.ifdMax == 0) ! 1498: last_aux_in_use = 0; ! 1499: else ! 1500: last_aux_in_use = ! 1501: file_desc[sym_hdr.ifdMax-1].iauxBase + ! 1502: file_desc[sym_hdr.ifdMax-1].caux - 1; ! 1503: ! 1504: if (last_aux_in_use < sym_hdr.iauxMax-1) ! 1505: { ! 1506: printf ("\nGlobal auxiliary entries after last file:\n"); ! 1507: for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++) ! 1508: print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]); ! 1509: } ! 1510: } ! 1511: ! 1512: /* ! 1513: * Print the information for each file. ! 1514: */ ! 1515: for (i = 0; i < sym_hdr.ifdMax; i++) ! 1516: print_file_desc (&file_desc[i], i); ! 1517: ! 1518: /* ! 1519: * Print the external symbols. ! 1520: */ ! 1521: want_scope = 0; /* scope info is meaning for extern symbols */ ! 1522: printf ("\nThere are %lu external symbols, starting at %lu\n", ! 1523: (ulong) sym_hdr.iextMax, ! 1524: (ulong) sym_hdr.cbExtOffset); ! 1525: ! 1526: for(i = 0; i < sym_hdr.iextMax; i++) ! 1527: print_symbol (&e_symbols[i].asym, i, e_strings, ! 1528: aux_symbols + file_desc[e_symbols[i].ifd].iauxBase, ! 1529: e_symbols[i].ifd); ! 1530: ! 1531: /* ! 1532: * Print unused aux symbols now. ! 1533: */ ! 1534: ! 1535: if (want_aux) ! 1536: { ! 1537: int first_time = 1; ! 1538: ! 1539: for (i = 0; i < sym_hdr.iauxMax; i++) ! 1540: { ! 1541: if (! aux_used[i]) ! 1542: { ! 1543: if (first_time) ! 1544: { ! 1545: printf ("\nThe following auxiliary table entries were unused:\n\n"); ! 1546: first_time = 0; ! 1547: } ! 1548: ! 1549: printf (" #%-5d %11ld 0x%08lx %s\n", ! 1550: i, ! 1551: (long) aux_symbols[i].isym, ! 1552: (long) aux_symbols[i].isym, ! 1553: type_to_string (aux_symbols, i)); ! 1554: } ! 1555: } ! 1556: } ! 1557: ! 1558: return 0; ! 1559: } ! 1560: ! 1561: ! 1562: void ! 1563: fancy_abort () ! 1564: { ! 1565: fprintf (stderr, "mips-tdump internal error"); ! 1566: exit (1); ! 1567: } ! 1568: ! 1569: void ! 1570: fatal(s) ! 1571: char *s; ! 1572: { ! 1573: fprintf(stderr, "%s\n", s); ! 1574: exit(1); ! 1575: } ! 1576: ! 1577: /* Same as `malloc' but report error if no memory available. */ ! 1578: ! 1579: PTR_T ! 1580: xmalloc (size) ! 1581: unsigned size; ! 1582: { ! 1583: register PTR_T value = malloc (size); ! 1584: if (value == 0) ! 1585: fatal ("Virtual memory exhausted."); ! 1586: return value; ! 1587: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.