OSDN Git Service

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