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