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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [mips-tdump.c] - Blame information for rev 867

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

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

powered by: WebSVN 2.1.0

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