OSDN Git Service

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