OSDN Git Service

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