OSDN Git Service

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