OSDN Git Service

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