home *** CD-ROM | disk | FTP | other *** search
/ OpenStep (Enterprise) / OpenStepENTCD.toast / OEDEV / GNUSRC.Z / mips-tdump.c < prev    next >
C/C++ Source or Header  |  1995-12-29  |  43KB  |  1,618 lines

  1. /* Read and manage MIPS symbol tables from object modules.
  2.    Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
  3.    Contributed by hartzell@boulder.colorado.edu,
  4.    Rewritten by meissner@osf.org.
  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, 59 Temple Place - Suite 330,
  21. Boston, MA 02111-1307, USA.  */
  22.  
  23. #include <stdio.h>
  24. #include <sys/types.h>
  25. #include <sys/file.h>
  26. #include <time.h>
  27. #include <fcntl.h>
  28. #include <errno.h>
  29. #include "config.h"
  30.  
  31. #ifdef index
  32. #undef index
  33. #undef rindex
  34. #endif
  35. #ifndef CROSS_COMPILE
  36. #include <a.out.h>
  37. #else
  38. #include "mips/a.out.h"
  39. #endif /* CROSS_COMPILE */
  40.  
  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.  
  55. #ifdef __STDC__
  56. typedef void *PTR_T;
  57. typedef const void *CPTR_T;
  58. #define __proto(x) x
  59. #else
  60.  
  61. #if defined(_STDIO_H_) || defined(__STDIO_H__)        /* Ultrix 4.0, SGI */
  62. typedef void *PTR_T;
  63. typedef void *CPTR_T;
  64.  
  65. #else
  66. typedef char *PTR_T;                    /* Ultrix 3.1 */
  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.  
  79.  
  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.  
  89. /* Redefinition of of storage classes as an enumeration for better
  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 */
  137.   st_Block    = stBlock,    /* beginning of block */
  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 */
  147. #ifdef stStruct
  148.   st_Struct    = stStruct,    /* struct */
  149.   st_Union    = stUnion,    /* union */
  150.   st_Enum    = stEnum,    /* enum */
  151. #endif
  152.   st_Str    = stStr,    /* string */
  153.   st_Number    = stNumber,    /* pure number (ie. 4 NOR 2+2) */
  154.   st_Expr    = stExpr,    /* 2+2 vs. 4 */
  155.   st_Type    = stType,    /* post-coercion SER */
  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 */
  243. int     tfile        = 0;    /* no global header file */
  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 */
  256. AUXU    *aux_symbols;        /* Auxiliary symbols */
  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));
  268. void  print_symbol    __proto((SYMR *, int, char *, AUXU *, int, FDR *));
  269. void  print_aux        __proto((AUXU, int, int));
  270. void  emit_aggregate    __proto((char *, AUXU, AUXU, const char *, FDR *));
  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));
  275. char *type_to_string    __proto((AUXU *, int, FDR *));
  276.  
  277. #ifndef __alpha
  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));
  282. #endif
  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";
  417. #ifdef stStruct
  418.     case st_Struct:    return "Struct";
  419.     case st_Union:    return "Union";
  420.     case st_Enum:    return "Enum";
  421. #endif
  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 *
  454. type_to_string (aux_ptr, index, fdp)
  455.      AUXU *aux_ptr;
  456.      int index;
  457.      FDR *fdp;
  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) */
  554.       emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
  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 */
  567.       emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
  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 */
  580.       emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
  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 */
  609.       strcpy (p1, "forward/unnamed typedef");
  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
  664.        * store 5 successive words in the aux. table:
  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. {
  770.   char *time = ctime ((time_t *)&ptr->f_timdat);
  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);
  780.   printf("    %-*s 0x%x",     24, "flags",             (ushort) flags);
  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.  
  835.   printf("    %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
  836.      (long)sym_ptr->cbLineOffset,
  837.      (long)sym_ptr->cbLine,
  838.      (long)sym_ptr->cbLine,
  839.      (int)sym_ptr->ilineMax);
  840.  
  841.   printf("    %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
  842.      (long)sym_ptr->cbDnOffset,
  843.      (long)sym_ptr->idnMax,
  844.      (long)(sym_ptr->idnMax * sizeof (DNR)));
  845.  
  846.   printf("    %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
  847.      (long)sym_ptr->cbPdOffset,
  848.      (long)sym_ptr->ipdMax,
  849.      (long)(sym_ptr->ipdMax * sizeof (PDR)));
  850.  
  851.   printf("    %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
  852.      (long)sym_ptr->cbSymOffset,
  853.      (long)sym_ptr->isymMax,
  854.      (long)(sym_ptr->isymMax * sizeof (SYMR)));
  855.  
  856.   printf("    %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
  857.      (long)sym_ptr->cbOptOffset,
  858.      (long)sym_ptr->ioptMax,
  859.      (long)(sym_ptr->ioptMax * sizeof (OPTR)));
  860.  
  861.   printf("    %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
  862.      (long)sym_ptr->cbAuxOffset,
  863.      (long)sym_ptr->iauxMax,
  864.      (long)(sym_ptr->iauxMax * sizeof (AUXU)));
  865.  
  866.   printf("    %-*s %11ld %11ld %11ld\n", width, "Local Strings",
  867.      (long)sym_ptr->cbSsOffset,
  868.      (long)sym_ptr->issMax,
  869.      (long)sym_ptr->issMax);
  870.  
  871.   printf("    %-*s %11ld %11ld %11ld\n", width, "External Strings",
  872.      (long)sym_ptr->cbSsExtOffset,
  873.      (long)sym_ptr->issExtMax,
  874.      (long)sym_ptr->issExtMax);
  875.  
  876.   printf("    %-*s %11ld %11ld %11ld\n", width, "File Tables",
  877.      (long)sym_ptr->cbFdOffset,
  878.      (long)sym_ptr->ifdMax,
  879.      (long)(sym_ptr->ifdMax * sizeof (FDR)));
  880.  
  881.   printf("    %-*s %11ld %11ld %11ld\n", width, "Relative Files",
  882.      (long)sym_ptr->cbRfdOffset,
  883.      (long)sym_ptr->crfd,
  884.      (long)(sym_ptr->crfd * sizeof (ulong)));
  885.  
  886.   printf("    %-*s %11ld %11ld %11ld\n", width, "External Symbols",
  887.      (long)sym_ptr->cbExtOffset,
  888.      (long)sym_ptr->iextMax,
  889.      (long)(sym_ptr->iextMax * sizeof (EXTR)));
  890. }
  891.  
  892.  
  893. /* Print out a symbol.  */
  894.  
  895. void
  896. print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
  897.      SYMR *sym_ptr;
  898.      int number;
  899.      char *strbase;
  900.      AUXU *aux_base;
  901.      int ifd;
  902.      FDR *fdp;
  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",
  970.             aux_base[index].isym,
  971.             type_to_string (aux_base, index+1, fdp));
  972.       }
  973.     else            /* global symbol */
  974.       printf ("      Local symbol: %ld\n", index);
  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.  
  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.  
  1001.       default:
  1002.     if (!MIPS_IS_STAB (sym_ptr))
  1003.       {
  1004.         used_ptr[index] = 1;
  1005.         printf ("      Type: %s\n",
  1006.             type_to_string (aux_base, index, fdp));
  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.  
  1034.           printf (" %ld [%s]", scope_ptr->open_sym, class);
  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
  1101. emit_aggregate (string, u, u2, which, fdp)
  1102.      char *string;
  1103.      AUXU u;
  1104.      AUXU u2;
  1105.      const char *which;
  1106.      FDR *fdp;
  1107. {
  1108.   unsigned int ifd = u.rndx.rfd;
  1109.   unsigned int index = u.rndx.index;
  1110.   const char *name;
  1111.   
  1112.   if (ifd == ST_RFDESCAPE)
  1113.     ifd = u2.isym;
  1114.   
  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.   
  1131.   sprintf (string,
  1132.        "%s %s { ifd = %u, index = %u }",
  1133.        which, name, ifd, index);
  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.  
  1157.   printf ("    Name index  = %-10ld Readin      = %s\n",
  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.  
  1180.   printf("    %-*s %11lu %11lu %11lu %11lu\n",
  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,
  1191.      (ulong) fdp->cbLine,
  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.  
  1201.   printf("    %-*s %11lu %11lu %11lu %11lu\n",
  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,
  1238.           -1,
  1239.           fdp);
  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.  
  1271.       rfd_ptr = rfile_desc + fdp->rfdBase;
  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;
  1325.       uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
  1326.                  + fdp->cbLineOffset);
  1327.       uchar *line_end;
  1328.  
  1329.       if (pdi == fdp->cpd + fdp->ipdFirst - 1)    /* last procedure */
  1330.         line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
  1331.       else                        /* not last proc. */
  1332.         line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
  1333.             + fdp->cbLineOffset);
  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");
  1372.   if (!tfile)
  1373.     {
  1374.       /* Print out the global header, since this is not a T-file.  */
  1375.  
  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,
  1425.                     "Auxiliary symbols");
  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.    */
  1475.   while ((opt = getopt (argc, argv, "alrst")) != EOF)
  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 */
  1483.       case 't': tfile++;    break;    /* this is a tfile (without header), and not a .o */
  1484.       }
  1485.  
  1486.   if (errors || optind != argc - 1)
  1487.     {
  1488.       fprintf (stderr, "Calling Sequence:\n");
  1489.       fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
  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");
  1496.       fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
  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,
  1558.           e_symbols[i].ifd,
  1559.           &file_desc[e_symbols[i].ifd]);
  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,
  1583.               type_to_string (aux_symbols, i, (FDR *) 0));
  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. }
  1618.