re PR testsuite/51128 (New LTO failures)
[gcc.git] / gcc / mips-tdump.c
1 /* 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 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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) 2011 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 }