Annotation of GNUtools/cc/mips-tdump.c, revision 1.1

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

unix.superglobalmegacorp.com

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