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