OSDN Git Service

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