OSDN Git Service

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