OSDN Git Service

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