source: trunk/third/gcc/mips-tdump.c @ 8834

Revision 8834, 41.8 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
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
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING.  If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, 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__
56typedef void *PTR_T;
57typedef const void *CPTR_T;
58#define __proto(x) x
59#else
60
61#if defined(_STDIO_H_) || defined(__STDIO_H__)          /* Ultrix 4.0, SGI */
62typedef void *PTR_T;
63typedef void *CPTR_T;
64
65#else
66typedef char *PTR_T;                                    /* Ultrix 3.1 */
67typedef 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
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
100typedef 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
129typedef 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
161typedef 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
173typedef 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
206typedef 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
220typedef 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
228/* Keep track of the active scopes.  */
229typedef 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
236struct filehdr global_hdr;      /* a.out header */
237
238int      errors         = 0;    /* # of errors */
239int      want_aux       = 0;    /* print aux table */
240int      want_line      = 0;    /* print line numbers */
241int      want_rfd       = 0;    /* print relative file desc's */
242int      want_scope     = 0;    /* print scopes for every symbol */
243int      tfile          = 0;    /* no global header file */
244int      tfile_fd;              /* file descriptor of .T file */
245off_t    tfile_offset;          /* current offset in .T file */
246scope_t *cur_scope      = 0;    /* list of active scopes */
247scope_t *free_scope     = 0;    /* list of freed scopes */
248HDRR     sym_hdr;               /* symbolic header */
249char    *l_strings;             /* local strings */
250char    *e_strings;             /* external strings */
251SYMR    *l_symbols;             /* local symbols */
252EXTR    *e_symbols;             /* external symbols */
253LINER   *lines;                 /* line numbers */
254DNR     *dense_nums;            /* dense numbers */
255OPTR    *opt_symbols;           /* optimization symbols */
256AUXU    *aux_symbols;           /* Auxiliary symbols */
257char    *aux_used;              /* map of which aux syms are used */
258FDR     *file_desc;             /* file tables */
259ulong   *rfile_desc;            /* relative file tables */
260PDR     *proc_desc;             /* procedure tables */
261
262/* Forward reference for functions.  */
263PTR_T read_seek         __proto((PTR_T, size_t, off_t, const char *));
264void  read_tfile        __proto((void));
265void  print_global_hdr  __proto((struct filehdr *));
266void  print_sym_hdr     __proto((HDRR *));
267void  print_file_desc   __proto((FDR *, int));
268void  print_symbol      __proto((SYMR *, int, char *, AUXU *, int, FDR *));
269void  print_aux         __proto((AUXU, int, int));
270void  emit_aggregate    __proto((char *, AUXU, AUXU, const char *, FDR *));
271char *st_to_string      __proto((st_t));
272char *sc_to_string      __proto((sc_t));
273char *glevel_to_string  __proto((glevel_t));
274char *lang_to_string    __proto((lang_t));
275char *type_to_string    __proto((AUXU *, int, FDR *));
276
277#ifndef __alpha
278extern PTR_T    malloc  __proto((size_t));
279extern PTR_T    calloc  __proto((size_t, size_t));
280extern PTR_T    realloc __proto((PTR_T, size_t));
281extern void     free    __proto((PTR_T));
282#endif
283
284extern char *optarg;
285extern int   optind;
286extern 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},
291struct {short code; char string[10];} stab_names[]  = {
292#include "stab.def"
293#undef __define_stab
294};
295
296
297/* Read some bytes at a specified location, and return a pointer.  */
298
299PTR_T
300read_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
331/* Convert language code to string format.  */
332
333char *
334lang_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
354/* Convert storage class to string.  */
355
356char *
357sc_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
392/* Convert symbol type to string.  */
393
394char *
395st_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
433/* Convert debug level to string.  */
434
435char *
436glevel_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
451/* Convert the type information to string format.  */
452
453char *
454type_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
764/* Print out the global file header for object files.  */
765
766void
767print_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
819/* Print out the symbolic header.  */
820
821void
822print_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
893/* Print out a symbol.  */
894
895void
896print_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
1072/* Print out a word from the aux. table in various formats.  */
1073
1074void
1075print_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
1098/* Write aggregate information to a string.  */
1099
1100void
1101emit_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
1137/* Print out information about a file descriptor, and the symbols,
1138   procedures, and line numbers within it.  */
1139
1140void
1141print_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
1363/* Read in the portions of the .T file that we will print out.  */
1364
1365void
1366read_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
1464
1465int
1466main (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
1592void
1593fancy_abort ()
1594{
1595  fprintf (stderr, "mips-tdump internal error");
1596  exit (1);
1597}
1598
1599void
1600fatal(s)
1601char *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
1609PTR_T
1610xmalloc (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}
Note: See TracBrowser for help on using the repository browser.