home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / mips-tdump.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  41KB  |  1,520 lines

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