📄 mips-tdump.c
字号:
/* Read and manage MIPS symbol tables from object modules. Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. Contributed by hartzell@boulder.colorado.edu, Rewritten by meissner@osf.org.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#include <stdio.h>#include <sys/types.h>#include <sys/file.h>#include <time.h>#include <fcntl.h>#include <errno.h>#include "config.h"#ifdef index#undef index#undef rindex#endif#ifndef CROSS_COMPILE#include <a.out.h>#else#include "mips/a.out.h"#endif /* CROSS_COMPILE */#ifndef MIPS_IS_STAB/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for and mips-tdump.c to print them out. This is used on the Alpha, which does not include mips.h. These must match the corresponding definitions in gdb/mipsread.c. Unfortunately, gcc and gdb do not currently share any directories. */#define CODE_MASK 0x8F300#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)#define MIPS_MARK_STAB(code) ((code)+CODE_MASK)#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)#endif#ifdef __STDC__typedef void *PTR_T;typedef const void *CPTR_T;#define __proto(x) x#else#if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */typedef void *PTR_T;typedef void *CPTR_T;#elsetypedef char *PTR_T; /* Ultrix 3.1 */typedef char *CPTR_T;#endif#define __proto(x) ()#define const#endif#define uchar unsigned char#define ushort unsigned short#define uint unsigned int#define ulong unsigned long/* Do to size_t being defined in sys/types.h and different in stddef.h, we have to do this by hand..... Note, these types are correct for MIPS based systems, and may not be correct for other systems. */#define size_t uint#define ptrdiff_t int/* Redefinition of of storage classes as an enumeration for better debugging. */#ifndef stStaParam#define stStaParam 16 /* Fortran static parameters */#endif#ifndef btVoid#define btVoid 26 /* void basic type */#endiftypedef enum sc { sc_Nil = scNil, /* no storage class */ sc_Text = scText, /* text symbol */ sc_Data = scData, /* initialized data symbol */ sc_Bss = scBss, /* un-initialized data symbol */ sc_Register = scRegister, /* value of symbol is register number */ sc_Abs = scAbs, /* value of symbol is absolute */ sc_Undefined = scUndefined, /* who knows? */ sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ sc_Bits = scBits, /* this is a bit field */ sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */ sc_RegImage = scRegImage, /* register value saved on stack */ sc_Info = scInfo, /* symbol contains debugger information */ sc_UserStruct = scUserStruct, /* addr in struct user for current process */ sc_SData = scSData, /* load time only small data */ sc_SBss = scSBss, /* load time only small common */ sc_RData = scRData, /* load time only read only data */ sc_Var = scVar, /* Var parameter (fortran,pascal) */ sc_Common = scCommon, /* common variable */ sc_SCommon = scSCommon, /* small common */ sc_VarRegister = scVarRegister, /* Var parameter in a register */ sc_Variant = scVariant, /* Variant record */ sc_SUndefined = scSUndefined, /* small undefined(external) data */ sc_Init = scInit, /* .init section symbol */ sc_Max = scMax /* Max storage class+1 */} sc_t;/* Redefinition of symbol type. */typedef enum st { st_Nil = stNil, /* Nuthin' special */ st_Global = stGlobal, /* external symbol */ st_Static = stStatic, /* static */ st_Param = stParam, /* procedure argument */ st_Local = stLocal, /* local variable */ st_Label = stLabel, /* label */ st_Proc = stProc, /* " " Procedure */ st_Block = stBlock, /* beginning of block */ st_End = stEnd, /* end (of anything) */ st_Member = stMember, /* member (of anything - struct/union/enum */ st_Typedef = stTypedef, /* type definition */ st_File = stFile, /* file name */ st_RegReloc = stRegReloc, /* register relocation */ st_Forward = stForward, /* forwarding address */ st_StaticProc = stStaticProc, /* load time only static procs */ st_StaParam = stStaParam, /* Fortran static parameters */ st_Constant = stConstant, /* const */#ifdef stStruct st_Struct = stStruct, /* struct */ st_Union = stUnion, /* union */ st_Enum = stEnum, /* enum */#endif st_Str = stStr, /* string */ st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ st_Expr = stExpr, /* 2+2 vs. 4 */ st_Type = stType, /* post-coercion SER */ st_Max = stMax /* max type+1 */} st_t;/* Redefinition of type qualifiers. */typedef enum tq { tq_Nil = tqNil, /* bt is what you see */ tq_Ptr = tqPtr, /* pointer */ tq_Proc = tqProc, /* procedure */ tq_Array = tqArray, /* duh */ tq_Far = tqFar, /* longer addressing - 8086/8 land */ tq_Vol = tqVol, /* volatile */ tq_Max = tqMax /* Max type qualifier+1 */} tq_t;/* Redefinition of basic types. */typedef enum bt { bt_Nil = btNil, /* undefined */ bt_Adr = btAdr, /* address - integer same size as pointer */ bt_Char = btChar, /* character */ bt_UChar = btUChar, /* unsigned character */ bt_Short = btShort, /* short */ bt_UShort = btUShort, /* unsigned short */ bt_Int = btInt, /* int */ bt_UInt = btUInt, /* unsigned int */ bt_Long = btLong, /* long */ bt_ULong = btULong, /* unsigned long */ bt_Float = btFloat, /* float (real) */ bt_Double = btDouble, /* Double (real) */ bt_Struct = btStruct, /* Structure (Record) */ bt_Union = btUnion, /* Union (variant) */ bt_Enum = btEnum, /* Enumerated */ bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ bt_Range = btRange, /* subrange of int */ bt_Set = btSet, /* pascal sets */ bt_Complex = btComplex, /* fortran complex */ bt_DComplex = btDComplex, /* fortran double complex */ bt_Indirect = btIndirect, /* forward or unnamed typedef */ bt_FixedDec = btFixedDec, /* Fixed Decimal */ bt_FloatDec = btFloatDec, /* Float Decimal */ bt_String = btString, /* Varying Length Character String */ bt_Bit = btBit, /* Aligned Bit String */ bt_Picture = btPicture, /* Picture */ bt_Void = btVoid, /* void */ bt_Max = btMax /* Max basic type+1 */} bt_t;/* Redefinition of the language codes. */typedef enum lang { lang_C = langC, lang_Pascal = langPascal, lang_Fortran = langFortran, lang_Assembler = langAssembler, lang_Machine = langMachine, lang_Nil = langNil, lang_Ada = langAda, lang_Pl1 = langPl1, lang_Cobol = langCobol} lang_t;/* Redefinition of the debug level codes. */typedef enum glevel { glevel_0 = GLEVEL_0, glevel_1 = GLEVEL_1, glevel_2 = GLEVEL_2, glevel_3 = GLEVEL_3} glevel_t;/* Keep track of the active scopes. */typedef struct scope { struct scope *prev; /* previous scope */ ulong open_sym; /* symbol opening scope */ sc_t sc; /* storage class */ st_t st; /* symbol type */} scope_t;struct filehdr global_hdr; /* a.out header */int errors = 0; /* # of errors */int want_aux = 0; /* print aux table */int want_line = 0; /* print line numbers */int want_rfd = 0; /* print relative file desc's */int want_scope = 0; /* print scopes for every symbol */int tfile = 0; /* no global header file */int tfile_fd; /* file descriptor of .T file */off_t tfile_offset; /* current offset in .T file */scope_t *cur_scope = 0; /* list of active scopes */scope_t *free_scope = 0; /* list of freed scopes */HDRR sym_hdr; /* symbolic header */char *l_strings; /* local strings */char *e_strings; /* external strings */SYMR *l_symbols; /* local symbols */EXTR *e_symbols; /* external symbols */LINER *lines; /* line numbers */DNR *dense_nums; /* dense numbers */OPTR *opt_symbols; /* optimization symbols */AUXU *aux_symbols; /* Auxiliary symbols */char *aux_used; /* map of which aux syms are used */FDR *file_desc; /* file tables */ulong *rfile_desc; /* relative file tables */PDR *proc_desc; /* procedure tables *//* Forward reference for functions. */PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));void read_tfile __proto((void));void print_global_hdr __proto((struct filehdr *));void print_sym_hdr __proto((HDRR *));void print_file_desc __proto((FDR *, int));void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));void print_aux __proto((AUXU, int, int));void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));char *st_to_string __proto((st_t));char *sc_to_string __proto((sc_t));char *glevel_to_string __proto((glevel_t));char *lang_to_string __proto((lang_t));char *type_to_string __proto((AUXU *, int, FDR *));#ifndef __alphaextern PTR_T malloc __proto((size_t));extern PTR_T calloc __proto((size_t, size_t));extern PTR_T realloc __proto((PTR_T, size_t));extern void free __proto((PTR_T));#endifextern char *optarg;extern int optind;extern int opterr;/* Create a table of debugging stab-codes and corresponding names. */#define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},struct {short code; char string[10];} stab_names[] = {#include "stab.def"#undef __define_stab};/* Read some bytes at a specified location, and return a pointer. */PTR_Tread_seek (ptr, size, offset, context) PTR_T ptr; /* pointer to buffer or NULL */ size_t size; /* # bytes to read */ off_t offset; /* offset to read at */ const char *context; /* context for error message */{ long read_size = 0; if (size == 0) /* nothing to read */ return ptr; if ((ptr == (PTR_T)0 && (ptr = malloc (size)) == (PTR_T)0) || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1) || (read_size = read (tfile_fd, ptr, size)) < 0) { perror (context); exit (1); } if (read_size != size) { fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n", context, read_size, (long) size); exit (1); } tfile_offset = offset + size; return ptr;}/* Convert language code to string format. */char *lang_to_string (lang) lang_t lang;{ switch (lang) { case langC: return "C"; case langPascal: return "Pascal"; case langFortran: return "Fortran"; case langAssembler: return "Assembler"; case langMachine: return "Machine"; case langNil: return "Nil"; case langAda: return "Ada"; case langPl1: return "Pl1"; case langCobol: return "Cobol"; } return "Unknown language";}/* Convert storage class to string. */char *sc_to_string(storage_class) sc_t storage_class;{ switch(storage_class) { case sc_Nil: return "Nil"; case sc_Text: return "Text"; case sc_Data: return "Data"; case sc_Bss: return "Bss"; case sc_Register: return "Register"; case sc_Abs: return "Abs"; case sc_Undefined: return "Undefined"; case sc_CdbLocal: return "CdbLocal"; case sc_Bits: return "Bits"; case sc_CdbSystem: return "CdbSystem"; case sc_RegImage: return "RegImage"; case sc_Info: return "Info"; case sc_UserStruct: return "UserStruct"; case sc_SData: return "SData"; case sc_SBss: return "SBss"; case sc_RData: return "RData"; case sc_Var: return "Var"; case sc_Common: return "Common"; case sc_SCommon: return "SCommon"; case sc_VarRegister: return "VarRegister"; case sc_Variant: return "Variant"; case sc_SUndefined: return "SUndefined"; case sc_Init: return "Init"; case sc_Max: return "Max"; } return "???";}/* Convert symbol type to string. */char *st_to_string(symbol_type) st_t symbol_type;{ switch(symbol_type) { case st_Nil: return "Nil"; case st_Global: return "Global"; case st_Static: return "Static"; case st_Param: return "Param"; case st_Local: return "Local"; case st_Label: return "Label"; case st_Proc: return "Proc"; case st_Block: return "Block"; case st_End: return "End"; case st_Member: return "Member"; case st_Typedef: return "Typedef"; case st_File: return "File"; case st_RegReloc: return "RegReloc"; case st_Forward: return "Forward"; case st_StaticProc: return "StaticProc"; case st_Constant: return "Constant"; case st_StaParam: return "StaticParam";#ifdef stStruct case st_Struct: return "Struct"; case st_Union: return "Union"; case st_Enum: return "Enum";#endif case st_Str: return "String"; case st_Number: return "Number"; case st_Expr: return "Expr"; case st_Type: return "Type"; case st_Max: return "Max"; } return "???";}/* Convert debug level to string. */char *glevel_to_string (g_level) glevel_t g_level;{ switch(g_level) { case GLEVEL_0: return "G0"; case GLEVEL_1: return "G1"; case GLEVEL_2: return "G2"; case GLEVEL_3: return "G3"; } return "??";} /* Convert the type information to string format. */char *type_to_string (aux_ptr, index, fdp) AUXU *aux_ptr; int index; FDR *fdp;{ AUXU u; struct qual { tq_t type; int low_bound; int high_bound; int stride; } qualifiers[7]; bt_t basic_type; int i; static char buffer1[1024]; static char buffer2[1024]; char *p1 = buffer1; char *p2 = buffer2; char *used_ptr = aux_used + (aux_ptr - aux_symbols); for (i = 0; i < 7; i++) { qualifiers[i].low_bound = 0; qualifiers[i].high_bound = 0; qualifiers[i].stride = 0; } used_ptr[index] = 1; u = aux_ptr[index++]; if (u.isym == -1) return "-1 (no type)"; basic_type = (bt_t) u.ti.bt; qualifiers[0].type = (tq_t) u.ti.tq0; qualifiers[1].type = (tq_t) u.ti.tq1; qualifiers[2].type = (tq_t) u.ti.tq2; qualifiers[3].type = (tq_t) u.ti.tq3; qualifiers[4].type = (tq_t) u.ti.tq4; qualifiers[5].type = (tq_t) u.ti.tq5; qualifiers[6].type = tq_Nil; /* * Go get the basic type. */ switch (basic_type) { case bt_Nil: /* undefined */ strcpy (p1, "nil"); break; case bt_Adr: /* address - integer same size as pointer */ strcpy (p1, "address"); break; case bt_Char: /* character */ strcpy (p1, "char"); break; case bt_UChar: /* unsigned character */ strcpy (p1, "unsigned char"); break; case bt_Short: /* short */ strcpy (p1, "short"); break; case bt_UShort: /* unsigned short */ strcpy (p1, "unsigned short"); break; case bt_Int: /* int */ strcpy (p1, "int"); break; case bt_UInt: /* unsigned int */ strcpy (p1, "unsigned int"); break; case bt_Long: /* long */ strcpy (p1, "long"); break; case bt_ULong: /* unsigned long */ strcpy (p1, "unsigned long"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -