OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [mips-tdump.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.