Annotation of gcc/mips-tdump.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.