X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fmips-tdump.c;h=f39b5a310f6a431ceb837356da3144e4aed0ca4f;hp=a650a51283873f0054b313aee803ff5cf448d60d;hb=c75a2739c2dd84336557e95cf655eceb163fc341;hpb=3eb8bff5821c5365e8c6bec5084655744937ec97 diff --git a/gcc/mips-tdump.c b/gcc/mips-tdump.c index a650a512838..f39b5a310f6 100644 --- a/gcc/mips-tdump.c +++ b/gcc/mips-tdump.c @@ -1,81 +1,54 @@ /* Read and manage MIPS symbol tables from object modules. - Source originally from hartzell@boulder.colorado.edu - Rewritten by: meissner@osf.org - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2003, 2004, + 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Contributed by hartzell@boulder.colorado.edu, + Rewritten by meissner@osf.org. -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, 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 of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include -#include -#include -#include -#include "config.h" +along with GCC; see the file COPYING3. If not see +. */ -#ifndef CROSS_COMPILE -#include -#else -#include "symconst.h" -#define LANGUAGE_C -#include "sym.h" -#include "filehdr.h" -#define ST_RFDESCAPE 0xfff +#include "config.h" +#include "system.h" +#include "version.h" +#ifdef index +#undef index #endif +#include -#ifdef __STDC__ -typedef void *PTR_T; -typedef const void *CPTR_T; -#define __proto(x) x -#else +/* Include getopt.h for the sake of getopt_long. */ +#include "getopt.h" -#if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */ -typedef void *PTR_T; -typedef void *CPTR_T; +/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for + mips-tdump.c to print them out. -#else -typedef char *PTR_T; /* Ultrix 3.1 */ -typedef char *CPTR_T; -#endif + These must match the corresponding definitions in gdb/mipsread.c. + Unfortunately, gcc and gdb do not currently share any directories. */ -#define __proto(x) () -#define const -#endif +#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) #define uchar unsigned char #define ushort unsigned short #define uint unsigned int #define ulong unsigned long -#ifdef index -#undef index -#undef rindex -#endif - - -/* 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 +/* Redefinition of storage classes as an enumeration for better debugging. */ #ifndef stStaParam @@ -133,8 +106,13 @@ typedef enum st { 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_Number = stNumber, /* pure number (i.e. 4 NOR 2+2) */ st_Expr = stExpr, /* 2+2 vs. 4 */ st_Type = stType, /* post-coercion SER */ st_Max = stMax /* max type+1 */ @@ -224,6 +202,9 @@ 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 version = 0; /* print version # */ +int verbose = 0; 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 */ @@ -243,25 +224,19 @@ 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)); -void print_aux __proto((AUXU, int, int)); -void emit_aggregate __proto((char *, AUXU, AUXU, const char *)); -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)); - -extern 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)); -extern char *ctime __proto((time_t *)); +static void *read_seek (void *, size_t, off_t, const char *); +static void read_tfile (void); +static void print_global_hdr (struct filehdr *); +static void print_sym_hdr (HDRR *); +static void print_file_desc (FDR *, int); +static void print_symbol (SYMR *, int, const char *, AUXU *, int, FDR *); +static void print_aux (AUXU, int, int); +static void emit_aggregate (char *, AUXU, AUXU, const char *, FDR *); +static const char *st_to_string (st_t); +static const char *sc_to_string (sc_t); +static const char *glevel_to_string (glevel_t); +static const char *lang_to_string (lang_t); +static const char *type_to_string (AUXU *, int, FDR *); extern char *optarg; extern int optind; @@ -270,35 +245,44 @@ 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[] = { +const struct {const short code; const char string[10];} stab_names[] = { #include "stab.def" #undef __define_stab }; +/* Command line options for getopt_long. */ + +static const struct option options[] = +{ + { "version", 0, 0, 'V' }, + { "verbose", 0, 0, 'v' }, + { 0, 0, 0, 0 } +}; -/* Read some bytes at a specified location, and return a pointer. */ - -PTR_T -read_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 */ +/* Read some bytes at a specified location, and return a pointer. + Read_seek takes a pointer PTR to a buffer or NULL and reads SIZE + bytes from offset OFFSET. In case of errors CONTEXT is used as + error message. */ + +static void * +read_seek (void *ptr, size_t size, off_t offset, const char *context) { 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) + if (!ptr) + ptr = xmalloc (size); + + if ((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) + if (read_size != (long) size) { fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n", context, read_size, (long) size); @@ -312,9 +296,8 @@ read_seek (ptr, size, offset, context) /* Convert language code to string format. */ -char * -lang_to_string (lang) - lang_t lang; +static const char * +lang_to_string (lang_t lang) { switch (lang) { @@ -335,9 +318,8 @@ lang_to_string (lang) /* Convert storage class to string. */ -char * -sc_to_string(storage_class) - sc_t storage_class; +static const char * +sc_to_string (sc_t storage_class) { switch(storage_class) { @@ -373,9 +355,8 @@ sc_to_string(storage_class) /* Convert symbol type to string. */ -char * -st_to_string(symbol_type) - st_t symbol_type; +static const char * +st_to_string (st_t symbol_type) { switch(symbol_type) { @@ -396,6 +377,11 @@ st_to_string(symbol_type) 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"; @@ -409,9 +395,8 @@ st_to_string(symbol_type) /* Convert debug level to string. */ -char * -glevel_to_string (g_level) - glevel_t g_level; +static const char * +glevel_to_string (glevel_t g_level) { switch(g_level) { @@ -423,14 +408,12 @@ glevel_to_string (g_level) return "??"; } - + /* Convert the type information to string format. */ -char * -type_to_string (aux_ptr, index) - AUXU *aux_ptr; - int index; +static const char * +type_to_string (AUXU *aux_ptr, int index, FDR *fdp) { AUXU u; struct qual { @@ -527,7 +510,7 @@ type_to_string (aux_ptr, index) 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ case bt_Struct: /* Structure (Record) */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct"); + emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp); used_ptr[index] = 1; if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) used_ptr[++index] = 1; @@ -540,7 +523,7 @@ type_to_string (aux_ptr, index) 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ case bt_Union: /* Union */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union"); + emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp); used_ptr[index] = 1; if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) used_ptr[++index] = 1; @@ -553,7 +536,7 @@ type_to_string (aux_ptr, index) 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ case bt_Enum: /* Enumeration */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum"); + emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp); used_ptr[index] = 1; if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) used_ptr[++index] = 1; @@ -582,7 +565,7 @@ type_to_string (aux_ptr, index) break; case bt_Indirect: /* forward or unnamed typedef */ - strcpy (p1, "forward/unamed typedef"); + strcpy (p1, "forward/unnamed typedef"); break; case bt_FixedDec: /* Fixed Decimal */ @@ -638,7 +621,7 @@ type_to_string (aux_ptr, index) /* * Snarf up any array bounds in the correct order. Arrays * store 5 successive words in the aux. table: - * word 0 RNDXR to type of the bounds (ie, int) + * word 0 RNDXR to type of the bounds (i.e., int) * word 1 Current file descriptor index * word 2 low bound * word 3 high bound (or -1 if []) @@ -696,8 +679,8 @@ type_to_string (aux_ptr, index) int first_array = i; int j; - /* Print array bounds reversed (ie, in the order the C - programmer writes them). C is such a fun language.... */ + /* Print array bounds reversed (i.e., in the order the C + programmer writes them). C is such a fun language.... */ while (i < 5 && qualifiers[i+1].type == tq_Array) i++; @@ -739,11 +722,10 @@ type_to_string (aux_ptr, index) /* Print out the global file header for object files. */ -void -print_global_hdr (ptr) - struct filehdr *ptr; +static void +print_global_hdr (struct filehdr *ptr) { - char *time = ctime ((off_t *)&ptr->f_timdat); + char *time = ctime ((time_t *)&ptr->f_timdat); ushort flags = ptr->f_flags; printf("Global file header:\n"); @@ -753,7 +735,7 @@ print_global_hdr (ptr) printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr); printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms); printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr); - printf(" %-*s 0x%lx", 24, "flags", (ushort) flags); + printf(" %-*s 0x%x", 24, "flags", (ushort) flags); if ((flags & F_RELFLG) != 0) printf (", F_RELFLG"); @@ -794,9 +776,8 @@ print_global_hdr (ptr) /* Print out the symbolic header. */ -void -print_sym_hdr (sym_ptr) - HDRR *sym_ptr; +static void +print_sym_hdr (HDRR *sym_ptr) { int width = 20; @@ -808,50 +789,69 @@ print_sym_hdr (sym_ptr) printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes"); printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n"); - printf(" %-*s %11ld %11d %11d [%d]\n", width, "Line numbers", - sym_ptr->cbLineOffset, sym_ptr->cbLine, sym_ptr->cbLine, sym_ptr->ilineMax); - - printf(" %-*s %11ld %11d %11d\n", width, "Dense numbers", - sym_ptr->cbDnOffset, sym_ptr->idnMax, sym_ptr->idnMax * sizeof (DNR)); - - printf(" %-*s %11ld %11d %11d\n", width, "Procedures Tables", - sym_ptr->cbPdOffset, sym_ptr->ipdMax, sym_ptr->ipdMax * sizeof (PDR)); - - printf(" %-*s %11ld %11d %11d\n", width, "Local Symbols", - sym_ptr->cbSymOffset, sym_ptr->isymMax, sym_ptr->isymMax * sizeof (SYMR)); - - printf(" %-*s %11ld %11d %11d\n", width, "Optimization Symbols", - sym_ptr->cbOptOffset, sym_ptr->ioptMax, sym_ptr->ioptMax * sizeof (OPTR)); - - printf(" %-*s %11ld %11d %11d\n", width, "Auxiliary Symbols", - sym_ptr->cbAuxOffset, sym_ptr->iauxMax, sym_ptr->iauxMax * sizeof (AUXU)); - - printf(" %-*s %11ld %11d %11d\n", width, "Local Strings", - sym_ptr->cbSsOffset, sym_ptr->issMax, sym_ptr->issMax); - - printf(" %-*s %11ld %11d %11d\n", width, "External Strings", - sym_ptr->cbSsExtOffset, sym_ptr->issExtMax, sym_ptr->issExtMax); - - printf(" %-*s %11ld %11d %11d\n", width, "File Tables", - sym_ptr->cbFdOffset, sym_ptr->ifdMax, sym_ptr->ifdMax * sizeof (FDR)); - - printf(" %-*s %11ld %11d %11d\n", width, "Relative Files", - sym_ptr->cbRfdOffset, sym_ptr->crfd, sym_ptr->crfd * sizeof (ulong)); - - printf(" %-*s %11ld %11d %11d\n", width, "External Symbols", - sym_ptr->cbExtOffset, sym_ptr->iextMax, sym_ptr->iextMax * sizeof (EXTR)); + printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers", + (long) sym_ptr->cbLineOffset, + (long) sym_ptr->cbLine, + (long) sym_ptr->cbLine, + (int) sym_ptr->ilineMax); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers", + (long) sym_ptr->cbDnOffset, + (long) sym_ptr->idnMax, + (long) (sym_ptr->idnMax * sizeof (DNR))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables", + (long) sym_ptr->cbPdOffset, + (long) sym_ptr->ipdMax, + (long) (sym_ptr->ipdMax * sizeof (PDR))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols", + (long) sym_ptr->cbSymOffset, + (long) sym_ptr->isymMax, + (long) (sym_ptr->isymMax * sizeof (SYMR))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols", + (long) sym_ptr->cbOptOffset, + (long) sym_ptr->ioptMax, + (long) (sym_ptr->ioptMax * sizeof (OPTR))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols", + (long) sym_ptr->cbAuxOffset, + (long) sym_ptr->iauxMax, + (long) (sym_ptr->iauxMax * sizeof (AUXU))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings", + (long) sym_ptr->cbSsOffset, + (long) sym_ptr->issMax, + (long) sym_ptr->issMax); + + printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings", + (long) sym_ptr->cbSsExtOffset, + (long) sym_ptr->issExtMax, + (long) sym_ptr->issExtMax); + + printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables", + (long) sym_ptr->cbFdOffset, + (long) sym_ptr->ifdMax, + (long) (sym_ptr->ifdMax * sizeof (FDR))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files", + (long) sym_ptr->cbRfdOffset, + (long) sym_ptr->crfd, + (long) (sym_ptr->crfd * sizeof (ulong))); + + printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols", + (long) sym_ptr->cbExtOffset, + (long) sym_ptr->iextMax, + (long) (sym_ptr->iextMax * sizeof (EXTR))); } /* Print out a symbol. */ -void -print_symbol (sym_ptr, number, strbase, aux_base, ifd) - SYMR *sym_ptr; - int number; - char *strbase; - AUXU *aux_base; - int ifd; +static void +print_symbol (SYMR *sym_ptr, int number, const char *strbase, AUXU *aux_base, + int ifd, FDR *fdp) { sc_t storage_class = (sc_t) sym_ptr->sc; st_t symbol_type = (st_t) sym_ptr->st; @@ -861,7 +861,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase); - if (aux_base != (AUXU *)0 && index != indexNil) + if (aux_base != (AUXU *) 0 && index != indexNil) switch (symbol_type) { case st_Nil: @@ -873,8 +873,8 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) printf (" End+1 symbol: %ld\n", index); if (want_scope) { - if (free_scope == (scope_t *)0) - scope_ptr = (scope_t *) malloc (sizeof (scope_t)); + if (free_scope == (scope_t *) 0) + scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); else { scope_ptr = free_scope; @@ -894,12 +894,12 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) else { used_ptr[index] = 1; - printf (" First symbol: %ld\n", aux_base[index].isym); + printf (" First symbol: %ld\n", (long) aux_base[index].isym); } if (want_scope) { - if (cur_scope == (scope_t *)0) + if (cur_scope == (scope_t *) 0) printf (" Can't pop end scope\n"); else { @@ -919,19 +919,16 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) { used_ptr[index] = used_ptr[index+1] = 1; printf (" End+1 symbol: %-7ld Type: %s\n", - aux_base[index].isym, type_to_string (aux_base, index+1)); + (long) aux_base[index].isym, + type_to_string (aux_base, index+1, fdp)); } else /* global symbol */ - { - used_ptr[index] = 1; - printf (" Type: %s\n", - type_to_string (aux_base, index)); - } + printf (" Local symbol: %ld\n", index); if (want_scope) { - if (free_scope == (scope_t *)0) - scope_ptr = (scope_t *) malloc (sizeof (scope_t)); + if (free_scope == (scope_t *) 0) + scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); else { scope_ptr = free_scope; @@ -945,12 +942,20 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) } break; +#ifdef stStruct + case st_Struct: + case st_Union: + case st_Enum: + printf (" End+1 symbol: %lu\n", index); + break; +#endif + default: if (!MIPS_IS_STAB (sym_ptr)) { used_ptr[index] = 1; printf (" Type: %s\n", - type_to_string (aux_base, index)); + type_to_string (aux_base, index, fdp)); } break; } @@ -958,27 +963,27 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) if (want_scope) { printf (" Scopes: "); - if (cur_scope == (scope_t *)0) + if (cur_scope == (scope_t *) 0) printf (" none\n"); else { for (scope_ptr = cur_scope; - scope_ptr != (scope_t *)0; + scope_ptr != (scope_t *) 0; scope_ptr = scope_ptr->prev) { - char *class; + const char *sclass; if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc) - class = "func."; + sclass = "func."; else if (scope_ptr->st == st_File) - class = "file"; + sclass = "file"; else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text) - class = "block"; + sclass = "block"; else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info) - class = "type"; + sclass = "type"; else - class = "???"; + sclass = "???"; - printf (" %d [%s]", scope_ptr->open_sym, class); + printf (" %ld [%s]", scope_ptr->open_sym, sclass); } printf ("\n"); } @@ -997,9 +1002,10 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) if (MIPS_IS_STAB(sym_ptr)) { - register int i = sizeof(stab_names) / sizeof(stab_names[0]); - char *stab_name = "stab"; + int i = ARRAY_SIZE (stab_names); + const char *stab_name = "stab"; short code = MIPS_UNMARK_STAB(sym_ptr->index); + while (--i >= 0) if (stab_names[i].code == code) { @@ -1018,11 +1024,8 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd) /* Print out a word from the aux. table in various formats. */ -void -print_aux (u, auxi, used) - AUXU u; - int auxi; - int used; +static void +print_aux (AUXU u, int auxi, int used) { printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n", (used) ? " " : "* ", @@ -1044,55 +1047,59 @@ print_aux (u, auxi, used) /* Write aggregate information to a string. */ -void -emit_aggregate (string, u, u2, which) - char *string; - AUXU u; - AUXU u2; - const char *which; +static void +emit_aggregate (char *string, AUXU u, AUXU u2, const char *which, FDR *fdp) { - int ifd = u.rndx.rfd; - int index = u.rndx.index; - int sym_base, ss_base; - int name; - + unsigned int ifd = u.rndx.rfd; + unsigned int index = u.rndx.index; + const char *name; + if (ifd == ST_RFDESCAPE) ifd = u2.isym; - sym_base = file_desc[ifd].isymBase; - ss_base = file_desc[ifd].issBase; - - name = (index == indexNil) ? 0 : l_symbols[index + sym_base].iss; + /* An ifd of -1 is an opaque type. An escaped index of 0 is a + struct return type of a procedure compiled without -g. */ + if (ifd == 0xffffffff + || (u.rndx.rfd == ST_RFDESCAPE && index == 0)) + name = ""; + else if (index == indexNil) + name = ""; + else + { + if (fdp == 0 || sym_hdr.crfd == 0) + fdp = &file_desc[ifd]; + else + fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]]; + name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss]; + } + sprintf (string, - "%s %s { ifd = %d, index = %d }", - which, - (name == 0) ? "/* no name */" : &l_strings[ ss_base + name ], - ifd, - index); + "%s %s { ifd = %u, index = %u }", + which, name, ifd, index); } /* Print out information about a file descriptor, and the symbols, procedures, and line numbers within it. */ -void -print_file_desc (fdp, number) - FDR *fdp; - int number; +static void +print_file_desc (FDR *fdp, int number) { char *str_base; AUXU *aux_base; int symi, pdi; int width = 20; char *used_base; - - str_base = l_strings + fdp->issBase; + + str_base = l_strings + fdp->issBase; aux_base = aux_symbols + fdp->iauxBase; used_base = aux_used + (aux_base - aux_symbols); - printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss); + printf ("\nFile #%d, \"%s\"\n\n", + number, + fdp->rss != issNil ? str_base + fdp->rss : ""); - printf (" Name index = %-10d Readin = %s\n", + printf (" Name index = %-10ld Readin = %s\n", (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No"); printf (" Merge = %-10s Endian = %s\n", @@ -1100,7 +1107,7 @@ print_file_desc (fdp, number) (fdp->fBigendian) ? "BIG" : "LITTLE"); printf (" Debug level = %-10s Language = %s\n", - glevel_to_string (fdp->glevel), + glevel_to_string ((glevel_t) fdp->glevel), lang_to_string((lang_t) fdp->lang)); printf (" Adr = 0x%08lx\n\n", (long) fdp->adr); @@ -1115,7 +1122,7 @@ print_file_desc (fdp, number) (ulong) fdp->cbSs, (ulong) (fdp->issBase + sym_hdr.cbSsOffset)); - printf(" %-*s %11lu %11u %11u %11lu\n", + printf(" %-*s %11lu %11lu %11lu %11lu\n", width, "Local symbols", (ulong) fdp->isymBase, (ulong) fdp->csym, @@ -1126,7 +1133,7 @@ print_file_desc (fdp, number) width, "Line numbers", (ulong) fdp->cbLineOffset, (ulong) fdp->cline, - (ulong) fdp->cline, + (ulong) fdp->cbLine, (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset)); printf(" %-*s %11lu %11lu %11lu %11lu\n", @@ -1136,7 +1143,7 @@ print_file_desc (fdp, number) (ulong) (fdp->copt * sizeof (OPTR)), (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset)); - printf(" %-*s %11llu %11lu %11lu %11lu\n", + printf(" %-*s %11lu %11lu %11lu %11lu\n", width, "Procedures", (ulong) fdp->ipdFirst, (ulong) fdp->cpd, @@ -1158,10 +1165,10 @@ print_file_desc (fdp, number) (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset)); - if (want_scope && cur_scope != (scope_t *)0) + if (want_scope && cur_scope != (scope_t *) 0) printf ("\n Warning scope does not start at 0!\n"); - /* + /* * print the info about the symbol table. */ printf ("\n There are %lu local symbols, starting at %lu\n", @@ -1173,9 +1180,10 @@ print_file_desc (fdp, number) symi - fdp->isymBase, str_base, aux_base, - -1); + -1, + fdp); - if (want_scope && cur_scope != (scope_t *)0) + if (want_scope && cur_scope != (scope_t *) 0) printf ("\n Warning scope does not end at 0!\n"); /* @@ -1205,15 +1213,15 @@ print_file_desc (fdp, number) (ulong) fdp->crfd, (ulong) fdp->rfdBase); - rfd_ptr = rfile_desc + fdp->rfdBase * sizeof (ulong); - for (i = 0; i < fdp->crfd; i++) + rfd_ptr = rfile_desc + fdp->rfdBase; + for (i = 0; i < (ulong) fdp->crfd; i++) { printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr); rfd_ptr++; } } - /* + /* * do the procedure descriptors. */ printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd); @@ -1224,9 +1232,10 @@ print_file_desc (fdp, number) PDR *proc_ptr = &proc_desc[pdi]; printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst)); - printf ("\t Name index = %-11ld Name = \"%s\"\n", - (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss, - l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base); + if (l_symbols != 0) + printf ("\t Name index = %-11ld Name = \"%s\"\n", + (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss, + l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base); printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n", (long) proc_ptr->regmask, @@ -1259,14 +1268,15 @@ print_file_desc (fdp, number) { int delta, count; long cur_line = proc_ptr->lnLow; - uchar *line_ptr = ((uchar *)lines) + proc_ptr->cbLineOffset; + uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset + + fdp->cbLineOffset); uchar *line_end; if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ - line_end = ((uchar *)lines) + fdp->cbLine + fdp->ilineBase; - else /* not last proc. */ - line_end = ((uchar *)lines) + proc_desc[pdi+1].cbLineOffset; - + line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset; + else /* not last proc. */ + line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset + + fdp->cbLineOffset); printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n", (ulong) (line_end - line_ptr), @@ -1298,20 +1308,18 @@ print_file_desc (fdp, number) /* Read in the portions of the .T file that we will print out. */ -void -read_tfile __proto((void)) +static void +read_tfile (void) { short magic; off_t sym_hdr_offset = 0; - /* Determine if this is a .T file (which has no file header), or some - sort of object file (which does have a file header) via the magic - number. */ - (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t)0, "Magic number"); - if (magic == MIPSELMAGIC || magic == MIPSEBMAGIC) + read_seek (&magic, sizeof (magic), 0, "Magic number"); + if (!tfile) { - (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t)0, - "Global file header"); + /* Print out the global header, since this is not a T-file. */ + + read_seek (&global_hdr, sizeof (global_hdr), 0, "Global file header"); print_global_hdr (&global_hdr); @@ -1324,92 +1332,63 @@ read_tfile __proto((void)) sym_hdr_offset = global_hdr.f_symptr; } - (void) read_seek ((PTR_T) &sym_hdr, - sizeof (sym_hdr), - sym_hdr_offset, - "Symbolic header"); + read_seek (&sym_hdr, sizeof (sym_hdr), sym_hdr_offset, "Symbolic header"); print_sym_hdr (&sym_hdr); - lines = (LINER *) read_seek ((PTR_T)0, - sym_hdr.cbLine, - sym_hdr.cbLineOffset, + lines = (LINER *) read_seek (NULL, sym_hdr.cbLine, sym_hdr.cbLineOffset, "Line numbers"); - dense_nums = (DNR *) read_seek ((PTR_T)0, - sym_hdr.idnMax * sizeof (DNR), - sym_hdr.cbDnOffset, - "Dense numbers"); + dense_nums = (DNR *) read_seek (NULL, sym_hdr.idnMax * sizeof (DNR), + sym_hdr.cbDnOffset, "Dense numbers"); - proc_desc = (PDR *) read_seek ((PTR_T)0, - sym_hdr.ipdMax * sizeof (PDR), - sym_hdr.cbPdOffset, - "Procedure tables"); + proc_desc = (PDR *) read_seek (NULL, sym_hdr.ipdMax * sizeof (PDR), + sym_hdr.cbPdOffset, "Procedure tables"); - l_symbols = (SYMR *) read_seek ((PTR_T)0, - sym_hdr.isymMax * sizeof (SYMR), - sym_hdr.cbSymOffset, - "Local symbols"); + l_symbols = (SYMR *) read_seek (NULL, sym_hdr.isymMax * sizeof (SYMR), + sym_hdr.cbSymOffset, "Local symbols"); - opt_symbols = (OPTR *) read_seek ((PTR_T)0, - sym_hdr.ioptMax * sizeof (OPTR), + opt_symbols = (OPTR *) read_seek (NULL, sym_hdr.ioptMax * sizeof (OPTR), sym_hdr.cbOptOffset, "Optimization symbols"); - aux_symbols = (AUXU *) read_seek ((PTR_T)0, - sym_hdr.iauxMax * sizeof (AUXU), - sym_hdr.cbAuxOffset, - "Auxiliary symbols"); + aux_symbols = (AUXU *) read_seek (NULL, sym_hdr.iauxMax * sizeof (AUXU), + sym_hdr.cbAuxOffset, "Auxiliary symbols"); if (sym_hdr.iauxMax > 0) - { - aux_used = calloc (sym_hdr.iauxMax, 1); - if (aux_used == (char *)0) - { - perror ("calloc"); - exit (1); - } - } + aux_used = (char *) xcalloc (sym_hdr.iauxMax, 1); - l_strings = (char *) read_seek ((PTR_T)0, - sym_hdr.issMax, - sym_hdr.cbSsOffset, - "Local string table"); + l_strings = (char *) read_seek (NULL, sym_hdr.issMax, + sym_hdr.cbSsOffset, "Local string table"); - e_strings = (char *) read_seek ((PTR_T)0, - sym_hdr.issExtMax, + e_strings = (char *) read_seek (NULL, sym_hdr.issExtMax, sym_hdr.cbSsExtOffset, "External string table"); - file_desc = (FDR *) read_seek ((PTR_T)0, - sym_hdr.ifdMax * sizeof (FDR), - sym_hdr.cbFdOffset, - "File tables"); + file_desc = (FDR *) read_seek (NULL, sym_hdr.ifdMax * sizeof (FDR), + sym_hdr.cbFdOffset, "File tables"); - rfile_desc = (ulong *) read_seek ((PTR_T)0, - sym_hdr.crfd * sizeof (ulong), + rfile_desc = (ulong *) read_seek (NULL, sym_hdr.crfd * sizeof (ulong), sym_hdr.cbRfdOffset, "Relative file tables"); - e_symbols = (EXTR *) read_seek ((PTR_T)0, - sym_hdr.iextMax * sizeof (EXTR), - sym_hdr.cbExtOffset, - "External symbols"); + e_symbols = (EXTR *) read_seek (NULL, sym_hdr.iextMax * sizeof (EXTR), + sym_hdr.cbExtOffset, "External symbols"); } +extern int main (int, char **); + int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { int i, opt; /* * Process arguments */ - while ((opt = getopt (argc, argv, "alrs")) != EOF) + while ((opt = getopt_long (argc, argv, "alrsvt", options, NULL)) != -1) switch (opt) { default: errors++; break; @@ -1417,18 +1396,40 @@ main (argc, argv) case 'l': want_line++; break; /* print line numbers */ case 'r': want_rfd++; break; /* print relative fd's */ case 's': want_scope++; break; /* print scope info */ + case 'v': verbose++; break; /* print version # */ + case 'V': version++; break; /* print version # */ + case 't': tfile++; break; /* this is a tfile (without header), + and not a .o */ } - if (errors || optind != argc - 1) + if (version) + { + printf ("mips-tdump %s%s\n", pkgversion_string, version_string); + fputs ("Copyright (C) 2011 Free Software Foundation, Inc.\n", stdout); + fputs ("This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n", + stdout); + exit (0); + } + + if (optind != argc - 1) + errors++; + + if (verbose || errors) + fprintf (stderr, "mips-tdump (GCC) %s\n", version_string); + + if (errors) { fprintf (stderr, "Calling Sequence:\n"); - fprintf (stderr, "\t%0 [-alrs] \n", argv[0]); + fprintf (stderr, "\t%s [-alrst] \n", argv[0]); fprintf (stderr, "\n"); fprintf (stderr, "switches:\n"); fprintf (stderr, "\t-a Print out auxiliary table.\n"); fprintf (stderr, "\t-l Print out line numbers.\n"); fprintf (stderr, "\t-r Print out relative file descriptors.\n"); fprintf (stderr, "\t-s Print out the current scopes for an item.\n"); + fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); + fprintf (stderr, "\t-v Print program version.\n"); return 1; } @@ -1461,9 +1462,9 @@ main (argc, argv) if (sym_hdr.ifdMax == 0) last_aux_in_use = 0; else - last_aux_in_use = - file_desc[sym_hdr.ifdMax-1].iauxBase + - file_desc[sym_hdr.ifdMax-1].caux - 1; + last_aux_in_use + = (file_desc[sym_hdr.ifdMax-1].iauxBase + + file_desc[sym_hdr.ifdMax-1].caux - 1); if (last_aux_in_use < sym_hdr.iauxMax-1) { @@ -1479,7 +1480,7 @@ main (argc, argv) for (i = 0; i < sym_hdr.ifdMax; i++) print_file_desc (&file_desc[i], i); - /* + /* * Print the external symbols. */ want_scope = 0; /* scope info is meaning for extern symbols */ @@ -1490,7 +1491,8 @@ main (argc, argv) for(i = 0; i < sym_hdr.iextMax; i++) print_symbol (&e_symbols[i].asym, i, e_strings, aux_symbols + file_desc[e_symbols[i].ifd].iauxBase, - e_symbols[i].ifd); + e_symbols[i].ifd, + &file_desc[e_symbols[i].ifd]); /* * Print unused aux symbols now. @@ -1514,38 +1516,10 @@ main (argc, argv) i, (long) aux_symbols[i].isym, (long) aux_symbols[i].isym, - type_to_string (aux_symbols, i)); + type_to_string (aux_symbols, i, (FDR *) 0)); } } } return 0; } - - -void -fancy_abort () -{ - fprintf (stderr, "mips-tdump internal error"); - exit (1); -} - -void -fatal(s) -char *s; -{ - fprintf(stderr, "%s\n", s); - exit(1); -} - -/* Same as `malloc' but report error if no memory available. */ - -PTR_T -xmalloc (size) - unsigned size; -{ - register PTR_T value = malloc (size); - if (value == 0) - fatal ("Virtual memory exhausted."); - return value; -}