* extend.texi: Improve documentation of volatile asms.
[official-gcc.git] / gcc / mips-tdump.c
blob613606f2f2b85f179a0d90b082a533b8d07638ec
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by hartzell@boulder.colorado.edu,
5 Rewritten by meissner@osf.org.
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #ifdef index
27 #undef index
28 #undef rindex
29 #endif
30 #ifndef CROSS_COMPILE
31 #include <a.out.h>
32 #else
33 #include "mips/a.out.h"
34 #endif /* CROSS_COMPILE */
36 #ifndef MIPS_IS_STAB
37 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
38 and mips-tdump.c to print them out. This is used on the Alpha,
39 which does not include mips.h.
41 These must match the corresponding definitions in gdb/mipsread.c.
42 Unfortunately, gcc and gdb do not currently share any directories. */
44 #define CODE_MASK 0x8F300
45 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
46 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
47 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
48 #endif
50 #define __proto(x) PARAMS(x)
51 typedef PTR PTR_T;
52 typedef const PTR_T CPTR_T;
54 #define uchar unsigned char
55 #define ushort unsigned short
56 #define uint unsigned int
57 #define ulong unsigned long
59 void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
60 void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
62 void
63 fatal (s)
64 const char *s;
66 fprintf (stderr, "%s\n", s);
67 exit (FATAL_EXIT_CODE);
70 /* Due to size_t being defined in sys/types.h and different
71 in stddef.h, we have to do this by hand..... Note, these
72 types are correct for MIPS based systems, and may not be
73 correct for other systems. */
75 #define size_t uint
76 #define ptrdiff_t int
79 /* Redefinition of storage classes as an enumeration for better
80 debugging. */
82 #ifndef stStaParam
83 #define stStaParam 16 /* Fortran static parameters */
84 #endif
86 #ifndef btVoid
87 #define btVoid 26 /* void basic type */
88 #endif
90 typedef enum sc {
91 sc_Nil = scNil, /* no storage class */
92 sc_Text = scText, /* text symbol */
93 sc_Data = scData, /* initialized data symbol */
94 sc_Bss = scBss, /* un-initialized data symbol */
95 sc_Register = scRegister, /* value of symbol is register number */
96 sc_Abs = scAbs, /* value of symbol is absolute */
97 sc_Undefined = scUndefined, /* who knows? */
98 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
99 sc_Bits = scBits, /* this is a bit field */
100 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
101 sc_RegImage = scRegImage, /* register value saved on stack */
102 sc_Info = scInfo, /* symbol contains debugger information */
103 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
104 sc_SData = scSData, /* load time only small data */
105 sc_SBss = scSBss, /* load time only small common */
106 sc_RData = scRData, /* load time only read only data */
107 sc_Var = scVar, /* Var parameter (fortran,pascal) */
108 sc_Common = scCommon, /* common variable */
109 sc_SCommon = scSCommon, /* small common */
110 sc_VarRegister = scVarRegister, /* Var parameter in a register */
111 sc_Variant = scVariant, /* Variant record */
112 sc_SUndefined = scSUndefined, /* small undefined(external) data */
113 sc_Init = scInit, /* .init section symbol */
114 sc_Max = scMax /* Max storage class+1 */
115 } sc_t;
117 /* Redefinition of symbol type. */
119 typedef enum st {
120 st_Nil = stNil, /* Nuthin' special */
121 st_Global = stGlobal, /* external symbol */
122 st_Static = stStatic, /* static */
123 st_Param = stParam, /* procedure argument */
124 st_Local = stLocal, /* local variable */
125 st_Label = stLabel, /* label */
126 st_Proc = stProc, /* " " Procedure */
127 st_Block = stBlock, /* beginning of block */
128 st_End = stEnd, /* end (of anything) */
129 st_Member = stMember, /* member (of anything - struct/union/enum */
130 st_Typedef = stTypedef, /* type definition */
131 st_File = stFile, /* file name */
132 st_RegReloc = stRegReloc, /* register relocation */
133 st_Forward = stForward, /* forwarding address */
134 st_StaticProc = stStaticProc, /* load time only static procs */
135 st_StaParam = stStaParam, /* Fortran static parameters */
136 st_Constant = stConstant, /* const */
137 #ifdef stStruct
138 st_Struct = stStruct, /* struct */
139 st_Union = stUnion, /* union */
140 st_Enum = stEnum, /* enum */
141 #endif
142 st_Str = stStr, /* string */
143 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
144 st_Expr = stExpr, /* 2+2 vs. 4 */
145 st_Type = stType, /* post-coercion SER */
146 st_Max = stMax /* max type+1 */
147 } st_t;
149 /* Redefinition of type qualifiers. */
151 typedef enum tq {
152 tq_Nil = tqNil, /* bt is what you see */
153 tq_Ptr = tqPtr, /* pointer */
154 tq_Proc = tqProc, /* procedure */
155 tq_Array = tqArray, /* duh */
156 tq_Far = tqFar, /* longer addressing - 8086/8 land */
157 tq_Vol = tqVol, /* volatile */
158 tq_Max = tqMax /* Max type qualifier+1 */
159 } tq_t;
161 /* Redefinition of basic types. */
163 typedef enum bt {
164 bt_Nil = btNil, /* undefined */
165 bt_Adr = btAdr, /* address - integer same size as pointer */
166 bt_Char = btChar, /* character */
167 bt_UChar = btUChar, /* unsigned character */
168 bt_Short = btShort, /* short */
169 bt_UShort = btUShort, /* unsigned short */
170 bt_Int = btInt, /* int */
171 bt_UInt = btUInt, /* unsigned int */
172 bt_Long = btLong, /* long */
173 bt_ULong = btULong, /* unsigned long */
174 bt_Float = btFloat, /* float (real) */
175 bt_Double = btDouble, /* Double (real) */
176 bt_Struct = btStruct, /* Structure (Record) */
177 bt_Union = btUnion, /* Union (variant) */
178 bt_Enum = btEnum, /* Enumerated */
179 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
180 bt_Range = btRange, /* subrange of int */
181 bt_Set = btSet, /* pascal sets */
182 bt_Complex = btComplex, /* fortran complex */
183 bt_DComplex = btDComplex, /* fortran double complex */
184 bt_Indirect = btIndirect, /* forward or unnamed typedef */
185 bt_FixedDec = btFixedDec, /* Fixed Decimal */
186 bt_FloatDec = btFloatDec, /* Float Decimal */
187 bt_String = btString, /* Varying Length Character String */
188 bt_Bit = btBit, /* Aligned Bit String */
189 bt_Picture = btPicture, /* Picture */
190 bt_Void = btVoid, /* void */
191 bt_Max = btMax /* Max basic type+1 */
192 } bt_t;
194 /* Redefinition of the language codes. */
196 typedef enum lang {
197 lang_C = langC,
198 lang_Pascal = langPascal,
199 lang_Fortran = langFortran,
200 lang_Assembler = langAssembler,
201 lang_Machine = langMachine,
202 lang_Nil = langNil,
203 lang_Ada = langAda,
204 lang_Pl1 = langPl1,
205 lang_Cobol = langCobol
206 } lang_t;
208 /* Redefinition of the debug level codes. */
210 typedef enum glevel {
211 glevel_0 = GLEVEL_0,
212 glevel_1 = GLEVEL_1,
213 glevel_2 = GLEVEL_2,
214 glevel_3 = GLEVEL_3
215 } glevel_t;
218 /* Keep track of the active scopes. */
219 typedef struct scope {
220 struct scope *prev; /* previous scope */
221 ulong open_sym; /* symbol opening scope */
222 sc_t sc; /* storage class */
223 st_t st; /* symbol type */
224 } scope_t;
226 struct filehdr global_hdr; /* a.out header */
228 int errors = 0; /* # of errors */
229 int want_aux = 0; /* print aux table */
230 int want_line = 0; /* print line numbers */
231 int want_rfd = 0; /* print relative file desc's */
232 int want_scope = 0; /* print scopes for every symbol */
233 int tfile = 0; /* no global header file */
234 int tfile_fd; /* file descriptor of .T file */
235 off_t tfile_offset; /* current offset in .T file */
236 scope_t *cur_scope = 0; /* list of active scopes */
237 scope_t *free_scope = 0; /* list of freed scopes */
238 HDRR sym_hdr; /* symbolic header */
239 char *l_strings; /* local strings */
240 char *e_strings; /* external strings */
241 SYMR *l_symbols; /* local symbols */
242 EXTR *e_symbols; /* external symbols */
243 LINER *lines; /* line numbers */
244 DNR *dense_nums; /* dense numbers */
245 OPTR *opt_symbols; /* optimization symbols */
246 AUXU *aux_symbols; /* Auxiliary symbols */
247 char *aux_used; /* map of which aux syms are used */
248 FDR *file_desc; /* file tables */
249 ulong *rfile_desc; /* relative file tables */
250 PDR *proc_desc; /* procedure tables */
252 /* Forward reference for functions. */
253 PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));
254 void read_tfile __proto((void));
255 void print_global_hdr __proto((struct filehdr *));
256 void print_sym_hdr __proto((HDRR *));
257 void print_file_desc __proto((FDR *, int));
258 void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));
259 void print_aux __proto((AUXU, int, int));
260 void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));
261 const char *st_to_string __proto((st_t));
262 const char *sc_to_string __proto((sc_t));
263 const char *glevel_to_string __proto((glevel_t));
264 const char *lang_to_string __proto((lang_t));
265 const char *type_to_string __proto((AUXU *, int, FDR *));
267 extern char *optarg;
268 extern int optind;
269 extern int opterr;
271 /* Create a table of debugging stab-codes and corresponding names. */
273 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
274 struct {short code; char string[10];} stab_names[] = {
275 #include "stab.def"
276 #undef __define_stab
280 /* Read some bytes at a specified location, and return a pointer. */
282 PTR_T
283 read_seek (ptr, size, offset, context)
284 PTR_T ptr; /* pointer to buffer or NULL */
285 size_t size; /* # bytes to read */
286 off_t offset; /* offset to read at */
287 const char *context; /* context for error message */
289 long read_size = 0;
291 if (size == 0) /* nothing to read */
292 return ptr;
294 if ((ptr == (PTR_T) 0 && (ptr = malloc (size)) == (PTR_T) 0)
295 || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
296 || (read_size = read (tfile_fd, ptr, size)) < 0)
298 perror (context);
299 exit (1);
302 if (read_size != size)
304 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
305 context, read_size, (long) size);
306 exit (1);
309 tfile_offset = offset + size;
310 return ptr;
314 /* Convert language code to string format. */
316 const char *
317 lang_to_string (lang)
318 lang_t lang;
320 switch (lang)
322 case langC: return "C";
323 case langPascal: return "Pascal";
324 case langFortran: return "Fortran";
325 case langAssembler: return "Assembler";
326 case langMachine: return "Machine";
327 case langNil: return "Nil";
328 case langAda: return "Ada";
329 case langPl1: return "Pl1";
330 case langCobol: return "Cobol";
333 return "Unknown language";
337 /* Convert storage class to string. */
339 const char *
340 sc_to_string(storage_class)
341 sc_t storage_class;
343 switch(storage_class)
345 case sc_Nil: return "Nil";
346 case sc_Text: return "Text";
347 case sc_Data: return "Data";
348 case sc_Bss: return "Bss";
349 case sc_Register: return "Register";
350 case sc_Abs: return "Abs";
351 case sc_Undefined: return "Undefined";
352 case sc_CdbLocal: return "CdbLocal";
353 case sc_Bits: return "Bits";
354 case sc_CdbSystem: return "CdbSystem";
355 case sc_RegImage: return "RegImage";
356 case sc_Info: return "Info";
357 case sc_UserStruct: return "UserStruct";
358 case sc_SData: return "SData";
359 case sc_SBss: return "SBss";
360 case sc_RData: return "RData";
361 case sc_Var: return "Var";
362 case sc_Common: return "Common";
363 case sc_SCommon: return "SCommon";
364 case sc_VarRegister: return "VarRegister";
365 case sc_Variant: return "Variant";
366 case sc_SUndefined: return "SUndefined";
367 case sc_Init: return "Init";
368 case sc_Max: return "Max";
371 return "???";
375 /* Convert symbol type to string. */
377 const char *
378 st_to_string(symbol_type)
379 st_t symbol_type;
381 switch(symbol_type)
383 case st_Nil: return "Nil";
384 case st_Global: return "Global";
385 case st_Static: return "Static";
386 case st_Param: return "Param";
387 case st_Local: return "Local";
388 case st_Label: return "Label";
389 case st_Proc: return "Proc";
390 case st_Block: return "Block";
391 case st_End: return "End";
392 case st_Member: return "Member";
393 case st_Typedef: return "Typedef";
394 case st_File: return "File";
395 case st_RegReloc: return "RegReloc";
396 case st_Forward: return "Forward";
397 case st_StaticProc: return "StaticProc";
398 case st_Constant: return "Constant";
399 case st_StaParam: return "StaticParam";
400 #ifdef stStruct
401 case st_Struct: return "Struct";
402 case st_Union: return "Union";
403 case st_Enum: return "Enum";
404 #endif
405 case st_Str: return "String";
406 case st_Number: return "Number";
407 case st_Expr: return "Expr";
408 case st_Type: return "Type";
409 case st_Max: return "Max";
412 return "???";
416 /* Convert debug level to string. */
418 const char *
419 glevel_to_string (g_level)
420 glevel_t g_level;
422 switch(g_level)
424 case GLEVEL_0: return "G0";
425 case GLEVEL_1: return "G1";
426 case GLEVEL_2: return "G2";
427 case GLEVEL_3: return "G3";
430 return "??";
434 /* Convert the type information to string format. */
436 const char *
437 type_to_string (aux_ptr, index, fdp)
438 AUXU *aux_ptr;
439 int index;
440 FDR *fdp;
442 AUXU u;
443 struct qual {
444 tq_t type;
445 int low_bound;
446 int high_bound;
447 int stride;
448 } qualifiers[7];
450 bt_t basic_type;
451 int i;
452 static char buffer1[1024];
453 static char buffer2[1024];
454 char *p1 = buffer1;
455 char *p2 = buffer2;
456 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
458 for (i = 0; i < 7; i++)
460 qualifiers[i].low_bound = 0;
461 qualifiers[i].high_bound = 0;
462 qualifiers[i].stride = 0;
465 used_ptr[index] = 1;
466 u = aux_ptr[index++];
467 if (u.isym == -1)
468 return "-1 (no type)";
470 basic_type = (bt_t) u.ti.bt;
471 qualifiers[0].type = (tq_t) u.ti.tq0;
472 qualifiers[1].type = (tq_t) u.ti.tq1;
473 qualifiers[2].type = (tq_t) u.ti.tq2;
474 qualifiers[3].type = (tq_t) u.ti.tq3;
475 qualifiers[4].type = (tq_t) u.ti.tq4;
476 qualifiers[5].type = (tq_t) u.ti.tq5;
477 qualifiers[6].type = tq_Nil;
480 * Go get the basic type.
482 switch (basic_type)
484 case bt_Nil: /* undefined */
485 strcpy (p1, "nil");
486 break;
488 case bt_Adr: /* address - integer same size as pointer */
489 strcpy (p1, "address");
490 break;
492 case bt_Char: /* character */
493 strcpy (p1, "char");
494 break;
496 case bt_UChar: /* unsigned character */
497 strcpy (p1, "unsigned char");
498 break;
500 case bt_Short: /* short */
501 strcpy (p1, "short");
502 break;
504 case bt_UShort: /* unsigned short */
505 strcpy (p1, "unsigned short");
506 break;
508 case bt_Int: /* int */
509 strcpy (p1, "int");
510 break;
512 case bt_UInt: /* unsigned int */
513 strcpy (p1, "unsigned int");
514 break;
516 case bt_Long: /* long */
517 strcpy (p1, "long");
518 break;
520 case bt_ULong: /* unsigned long */
521 strcpy (p1, "unsigned long");
522 break;
524 case bt_Float: /* float (real) */
525 strcpy (p1, "float");
526 break;
528 case bt_Double: /* Double (real) */
529 strcpy (p1, "double");
530 break;
532 /* Structures add 1-2 aux words:
533 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
534 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
536 case bt_Struct: /* Structure (Record) */
537 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
538 used_ptr[index] = 1;
539 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
540 used_ptr[++index] = 1;
542 index++; /* skip aux words */
543 break;
545 /* Unions add 1-2 aux words:
546 1st word is [ST_RFDESCAPE, offset] pointer to union def;
547 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
549 case bt_Union: /* Union */
550 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
551 used_ptr[index] = 1;
552 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
553 used_ptr[++index] = 1;
555 index++; /* skip aux words */
556 break;
558 /* Enumerations add 1-2 aux words:
559 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
560 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
562 case bt_Enum: /* Enumeration */
563 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
564 used_ptr[index] = 1;
565 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
566 used_ptr[++index] = 1;
568 index++; /* skip aux words */
569 break;
571 case bt_Typedef: /* defined via a typedef, isymRef points */
572 strcpy (p1, "typedef");
573 break;
575 case bt_Range: /* subrange of int */
576 strcpy (p1, "subrange");
577 break;
579 case bt_Set: /* pascal sets */
580 strcpy (p1, "set");
581 break;
583 case bt_Complex: /* fortran complex */
584 strcpy (p1, "complex");
585 break;
587 case bt_DComplex: /* fortran double complex */
588 strcpy (p1, "double complex");
589 break;
591 case bt_Indirect: /* forward or unnamed typedef */
592 strcpy (p1, "forward/unnamed typedef");
593 break;
595 case bt_FixedDec: /* Fixed Decimal */
596 strcpy (p1, "fixed decimal");
597 break;
599 case bt_FloatDec: /* Float Decimal */
600 strcpy (p1, "float decimal");
601 break;
603 case bt_String: /* Varying Length Character String */
604 strcpy (p1, "string");
605 break;
607 case bt_Bit: /* Aligned Bit String */
608 strcpy (p1, "bit");
609 break;
611 case bt_Picture: /* Picture */
612 strcpy (p1, "picture");
613 break;
615 case bt_Void: /* Void */
616 strcpy (p1, "void");
617 break;
619 default:
620 sprintf (p1, "Unknown basic type %d", (int) basic_type);
621 break;
624 p1 += strlen (buffer1);
627 * If this is a bitfield, get the bitsize.
629 if (u.ti.fBitfield)
631 int bitsize;
633 used_ptr[index] = 1;
634 bitsize = aux_ptr[index++].width;
635 sprintf (p1, " : %d", bitsize);
636 p1 += strlen (buffer1);
641 * Deal with any qualifiers.
643 if (qualifiers[0].type != tq_Nil)
646 * Snarf up any array bounds in the correct order. Arrays
647 * store 5 successive words in the aux. table:
648 * word 0 RNDXR to type of the bounds (ie, int)
649 * word 1 Current file descriptor index
650 * word 2 low bound
651 * word 3 high bound (or -1 if [])
652 * word 4 stride size in bits
654 for (i = 0; i < 7; i++)
656 if (qualifiers[i].type == tq_Array)
658 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
659 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
660 qualifiers[i].stride = aux_ptr[index+4].width;
661 used_ptr[index] = 1;
662 used_ptr[index+1] = 1;
663 used_ptr[index+2] = 1;
664 used_ptr[index+3] = 1;
665 used_ptr[index+4] = 1;
666 index += 5;
671 * Now print out the qualifiers.
673 for (i = 0; i < 6; i++)
675 switch (qualifiers[i].type)
677 case tq_Nil:
678 case tq_Max:
679 break;
681 case tq_Ptr:
682 strcpy (p2, "ptr to ");
683 p2 += sizeof ("ptr to ")-1;
684 break;
686 case tq_Vol:
687 strcpy (p2, "volatile ");
688 p2 += sizeof ("volatile ")-1;
689 break;
691 case tq_Far:
692 strcpy (p2, "far ");
693 p2 += sizeof ("far ")-1;
694 break;
696 case tq_Proc:
697 strcpy (p2, "func. ret. ");
698 p2 += sizeof ("func. ret. ");
699 break;
701 case tq_Array:
703 int first_array = i;
704 int j;
706 /* Print array bounds reversed (ie, in the order the C
707 programmer writes them). C is such a fun language.... */
709 while (i < 5 && qualifiers[i+1].type == tq_Array)
710 i++;
712 for (j = i; j >= first_array; j--)
714 strcpy (p2, "array [");
715 p2 += sizeof ("array [")-1;
716 if (qualifiers[j].low_bound != 0)
717 sprintf (p2,
718 "%ld:%ld {%ld bits}",
719 (long) qualifiers[j].low_bound,
720 (long) qualifiers[j].high_bound,
721 (long) qualifiers[j].stride);
723 else if (qualifiers[j].high_bound != -1)
724 sprintf (p2,
725 "%ld {%ld bits}",
726 (long) (qualifiers[j].high_bound + 1),
727 (long) (qualifiers[j].stride));
729 else
730 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
732 p2 += strlen (p2);
733 strcpy (p2, "] of ");
734 p2 += sizeof ("] of ")-1;
737 break;
742 strcpy (p2, buffer1);
743 return buffer2;
747 /* Print out the global file header for object files. */
749 void
750 print_global_hdr (ptr)
751 struct filehdr *ptr;
753 char *time = ctime ((time_t *)&ptr->f_timdat);
754 ushort flags = ptr->f_flags;
756 printf("Global file header:\n");
757 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
758 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
759 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
760 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
761 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
762 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
763 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
765 if ((flags & F_RELFLG) != 0)
766 printf (", F_RELFLG");
768 if ((flags & F_EXEC) != 0)
769 printf (", F_EXEC");
771 if ((flags & F_LNNO) != 0)
772 printf (", F_LNNO");
774 if ((flags & F_LSYMS) != 0)
775 printf (", F_LSYMS");
777 if ((flags & F_MINMAL) != 0)
778 printf (", F_MINMAL");
780 if ((flags & F_UPDATE) != 0)
781 printf (", F_UPDATE");
783 if ((flags & F_SWABD) != 0)
784 printf (", F_SWABD");
786 if ((flags & F_AR16WR) != 0)
787 printf (", F_AR16WR");
789 if ((flags & F_AR32WR) != 0)
790 printf (", F_AR32WR");
792 if ((flags & F_AR32W) != 0)
793 printf (", F_AR32W");
795 if ((flags & F_PATCH) != 0)
796 printf (", F_PATCH/F_NODF");
798 printf ("\n\n");
802 /* Print out the symbolic header. */
804 void
805 print_sym_hdr (sym_ptr)
806 HDRR *sym_ptr;
808 int width = 20;
810 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
811 sym_ptr->magic & 0xffff,
812 (sym_ptr->vstamp & 0xffff) >> 8,
813 sym_ptr->vstamp & 0xff);
815 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
816 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
818 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
819 (long) sym_ptr->cbLineOffset,
820 (long) sym_ptr->cbLine,
821 (long) sym_ptr->cbLine,
822 (int) sym_ptr->ilineMax);
824 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
825 (long) sym_ptr->cbDnOffset,
826 (long) sym_ptr->idnMax,
827 (long) (sym_ptr->idnMax * sizeof (DNR)));
829 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
830 (long) sym_ptr->cbPdOffset,
831 (long) sym_ptr->ipdMax,
832 (long) (sym_ptr->ipdMax * sizeof (PDR)));
834 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
835 (long) sym_ptr->cbSymOffset,
836 (long) sym_ptr->isymMax,
837 (long) (sym_ptr->isymMax * sizeof (SYMR)));
839 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
840 (long) sym_ptr->cbOptOffset,
841 (long) sym_ptr->ioptMax,
842 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
844 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
845 (long) sym_ptr->cbAuxOffset,
846 (long) sym_ptr->iauxMax,
847 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
849 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
850 (long) sym_ptr->cbSsOffset,
851 (long) sym_ptr->issMax,
852 (long) sym_ptr->issMax);
854 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
855 (long) sym_ptr->cbSsExtOffset,
856 (long) sym_ptr->issExtMax,
857 (long) sym_ptr->issExtMax);
859 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
860 (long) sym_ptr->cbFdOffset,
861 (long) sym_ptr->ifdMax,
862 (long) (sym_ptr->ifdMax * sizeof (FDR)));
864 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
865 (long) sym_ptr->cbRfdOffset,
866 (long) sym_ptr->crfd,
867 (long) (sym_ptr->crfd * sizeof (ulong)));
869 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
870 (long) sym_ptr->cbExtOffset,
871 (long) sym_ptr->iextMax,
872 (long) (sym_ptr->iextMax * sizeof (EXTR)));
876 /* Print out a symbol. */
878 void
879 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
880 SYMR *sym_ptr;
881 int number;
882 char *strbase;
883 AUXU *aux_base;
884 int ifd;
885 FDR *fdp;
887 sc_t storage_class = (sc_t) sym_ptr->sc;
888 st_t symbol_type = (st_t) sym_ptr->st;
889 ulong index = sym_ptr->index;
890 char *used_ptr = aux_used + (aux_base - aux_symbols);
891 scope_t *scope_ptr;
893 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
895 if (aux_base != (AUXU *) 0 && index != indexNil)
896 switch (symbol_type)
898 case st_Nil:
899 case st_Label:
900 break;
902 case st_File:
903 case st_Block:
904 printf (" End+1 symbol: %ld\n", index);
905 if (want_scope)
907 if (free_scope == (scope_t *) 0)
908 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
909 else
911 scope_ptr = free_scope;
912 free_scope = scope_ptr->prev;
914 scope_ptr->open_sym = number;
915 scope_ptr->st = symbol_type;
916 scope_ptr->sc = storage_class;
917 scope_ptr->prev = cur_scope;
918 cur_scope = scope_ptr;
920 break;
922 case st_End:
923 if (storage_class == sc_Text || storage_class == sc_Info)
924 printf (" First symbol: %ld\n", index);
925 else
927 used_ptr[index] = 1;
928 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
931 if (want_scope)
933 if (cur_scope == (scope_t *) 0)
934 printf (" Can't pop end scope\n");
935 else
937 scope_ptr = cur_scope;
938 cur_scope = scope_ptr->prev;
939 scope_ptr->prev = free_scope;
940 free_scope = scope_ptr;
943 break;
945 case st_Proc:
946 case st_StaticProc:
947 if (MIPS_IS_STAB(sym_ptr))
949 else if (ifd == -1) /* local symbol */
951 used_ptr[index] = used_ptr[index+1] = 1;
952 printf (" End+1 symbol: %-7ld Type: %s\n",
953 (long) aux_base[index].isym,
954 type_to_string (aux_base, index+1, fdp));
956 else /* global symbol */
957 printf (" Local symbol: %ld\n", index);
959 if (want_scope)
961 if (free_scope == (scope_t *) 0)
962 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
963 else
965 scope_ptr = free_scope;
966 free_scope = scope_ptr->prev;
968 scope_ptr->open_sym = number;
969 scope_ptr->st = symbol_type;
970 scope_ptr->sc = storage_class;
971 scope_ptr->prev = cur_scope;
972 cur_scope = scope_ptr;
974 break;
976 #ifdef stStruct
977 case st_Struct:
978 case st_Union:
979 case st_Enum:
980 printf (" End+1 symbol: %lu\n", index);
981 break;
982 #endif
984 default:
985 if (!MIPS_IS_STAB (sym_ptr))
987 used_ptr[index] = 1;
988 printf (" Type: %s\n",
989 type_to_string (aux_base, index, fdp));
991 break;
994 if (want_scope)
996 printf (" Scopes: ");
997 if (cur_scope == (scope_t *) 0)
998 printf (" none\n");
999 else
1001 for (scope_ptr = cur_scope;
1002 scope_ptr != (scope_t *) 0;
1003 scope_ptr = scope_ptr->prev)
1005 const char *class;
1006 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1007 class = "func.";
1008 else if (scope_ptr->st == st_File)
1009 class = "file";
1010 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1011 class = "block";
1012 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1013 class = "type";
1014 else
1015 class = "???";
1017 printf (" %ld [%s]", scope_ptr->open_sym, class);
1019 printf ("\n");
1023 printf (" Value: %-13ld ",
1024 (long)sym_ptr->value);
1025 if (ifd == -1)
1026 printf ("String index: %ld\n", (long)sym_ptr->iss);
1027 else
1028 printf ("String index: %-11ld Ifd: %d\n",
1029 (long)sym_ptr->iss, ifd);
1031 printf (" Symbol type: %-11sStorage class: %-11s",
1032 st_to_string (symbol_type), sc_to_string (storage_class));
1034 if (MIPS_IS_STAB(sym_ptr))
1036 register int i = ARRAY_SIZE (stab_names);
1037 const char *stab_name = "stab";
1038 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1039 while (--i >= 0)
1040 if (stab_names[i].code == code)
1042 stab_name = stab_names[i].string;
1043 break;
1045 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1047 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1048 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1049 else
1050 printf ("Index: %ld\n", (long)sym_ptr->index);
1055 /* Print out a word from the aux. table in various formats. */
1057 void
1058 print_aux (u, auxi, used)
1059 AUXU u;
1060 int auxi;
1061 int used;
1063 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1064 (used) ? " " : "* ",
1065 auxi,
1066 (long) u.isym,
1067 (long) u.rndx.rfd,
1068 (long) u.rndx.index,
1069 u.ti.bt,
1070 u.ti.fBitfield,
1071 u.ti.continued,
1072 u.ti.tq0,
1073 u.ti.tq1,
1074 u.ti.tq2,
1075 u.ti.tq3,
1076 u.ti.tq4,
1077 u.ti.tq5);
1081 /* Write aggregate information to a string. */
1083 void
1084 emit_aggregate (string, u, u2, which, fdp)
1085 char *string;
1086 AUXU u;
1087 AUXU u2;
1088 const char *which;
1089 FDR *fdp;
1091 unsigned int ifd = u.rndx.rfd;
1092 unsigned int index = u.rndx.index;
1093 const char *name;
1095 if (ifd == ST_RFDESCAPE)
1096 ifd = u2.isym;
1098 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1099 struct return type of a procedure compiled without -g. */
1100 if (ifd == 0xffffffff
1101 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
1102 name = "<undefined>";
1103 else if (index == indexNil)
1104 name = "<no name>";
1105 else
1107 if (fdp == 0 || sym_hdr.crfd == 0)
1108 fdp = &file_desc[ifd];
1109 else
1110 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1111 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1114 sprintf (string,
1115 "%s %s { ifd = %u, index = %u }",
1116 which, name, ifd, index);
1120 /* Print out information about a file descriptor, and the symbols,
1121 procedures, and line numbers within it. */
1123 void
1124 print_file_desc (fdp, number)
1125 FDR *fdp;
1126 int number;
1128 char *str_base;
1129 AUXU *aux_base;
1130 int symi, pdi;
1131 int width = 20;
1132 char *used_base;
1134 str_base = l_strings + fdp->issBase;
1135 aux_base = aux_symbols + fdp->iauxBase;
1136 used_base = aux_used + (aux_base - aux_symbols);
1138 printf ("\nFile #%d, \"%s\"\n\n",
1139 number,
1140 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
1142 printf (" Name index = %-10ld Readin = %s\n",
1143 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1145 printf (" Merge = %-10s Endian = %s\n",
1146 (fdp->fMerge) ? "Yes" : "No",
1147 (fdp->fBigendian) ? "BIG" : "LITTLE");
1149 printf (" Debug level = %-10s Language = %s\n",
1150 glevel_to_string (fdp->glevel),
1151 lang_to_string((lang_t) fdp->lang));
1153 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1155 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1156 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1158 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1159 width, "Local strings",
1160 (ulong) fdp->issBase,
1161 (ulong) fdp->cbSs,
1162 (ulong) fdp->cbSs,
1163 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1165 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1166 width, "Local symbols",
1167 (ulong) fdp->isymBase,
1168 (ulong) fdp->csym,
1169 (ulong) (fdp->csym * sizeof (SYMR)),
1170 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1172 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1173 width, "Line numbers",
1174 (ulong) fdp->cbLineOffset,
1175 (ulong) fdp->cline,
1176 (ulong) fdp->cbLine,
1177 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1179 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1180 width, "Optimization symbols",
1181 (ulong) fdp->ioptBase,
1182 (ulong) fdp->copt,
1183 (ulong) (fdp->copt * sizeof (OPTR)),
1184 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1186 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1187 width, "Procedures",
1188 (ulong) fdp->ipdFirst,
1189 (ulong) fdp->cpd,
1190 (ulong) (fdp->cpd * sizeof (PDR)),
1191 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1193 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1194 width, "Auxiliary symbols",
1195 (ulong) fdp->iauxBase,
1196 (ulong) fdp->caux,
1197 (ulong) (fdp->caux * sizeof (AUXU)),
1198 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1200 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1201 width, "Relative Files",
1202 (ulong) fdp->rfdBase,
1203 (ulong) fdp->crfd,
1204 (ulong) (fdp->crfd * sizeof (ulong)),
1205 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1208 if (want_scope && cur_scope != (scope_t *) 0)
1209 printf ("\n Warning scope does not start at 0!\n");
1212 * print the info about the symbol table.
1214 printf ("\n There are %lu local symbols, starting at %lu\n",
1215 (ulong) fdp->csym,
1216 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1218 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1219 print_symbol (&l_symbols[symi],
1220 symi - fdp->isymBase,
1221 str_base,
1222 aux_base,
1224 fdp);
1226 if (want_scope && cur_scope != (scope_t *) 0)
1227 printf ("\n Warning scope does not end at 0!\n");
1230 * print the aux. table if desired.
1233 if (want_aux && fdp->caux != 0)
1235 int auxi;
1237 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1238 (ulong) fdp->caux,
1239 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1241 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1242 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1246 * print the relative file descriptors.
1248 if (want_rfd && fdp->crfd != 0)
1250 ulong *rfd_ptr, i;
1252 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1253 (ulong) fdp->crfd,
1254 (ulong) fdp->rfdBase);
1256 rfd_ptr = rfile_desc + fdp->rfdBase;
1257 for (i = 0; i < (ulong) fdp->crfd; i++)
1259 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1260 rfd_ptr++;
1265 * do the procedure descriptors.
1267 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1268 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1270 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1272 PDR *proc_ptr = &proc_desc[pdi];
1273 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1275 if (l_symbols != 0)
1276 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1277 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1278 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1280 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1281 (long) proc_ptr->regmask,
1282 (long) proc_ptr->regoffset,
1283 (long) proc_ptr->fregmask,
1284 (long) proc_ptr->fregoffset);
1286 printf ("\t .frame $%d,%ld,$%d\n",
1287 (int) proc_ptr->framereg,
1288 (long) proc_ptr->frameoffset,
1289 (int) proc_ptr->pcreg);
1291 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1292 (long) proc_ptr->iopt,
1293 (long) proc_ptr->isym);
1295 printf ("\t First line # = %-11ld Last line # = %ld\n",
1296 (long) proc_ptr->lnLow,
1297 (long) proc_ptr->lnHigh);
1299 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1300 (long) proc_ptr->cbLineOffset,
1301 (long) proc_ptr->adr);
1304 * print the line number entries.
1307 if (want_line && fdp->cline != 0)
1309 int delta, count;
1310 long cur_line = proc_ptr->lnLow;
1311 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1312 + fdp->cbLineOffset);
1313 uchar *line_end;
1315 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1316 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1317 else /* not last proc. */
1318 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1319 + fdp->cbLineOffset);
1321 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1322 (ulong) (line_end - line_ptr),
1323 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1325 while (line_ptr < line_end)
1326 { /* sign extend nibble */
1327 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1328 count = (*line_ptr & 0xf) + 1;
1329 if (delta != -8)
1330 line_ptr++;
1331 else
1333 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1334 delta = (delta ^ 0x8000) - 0x8000;
1335 line_ptr += 3;
1338 cur_line += delta;
1339 printf ("\t Line %11ld, delta %5d, count %2d\n",
1340 cur_line,
1341 delta,
1342 count);
1349 /* Read in the portions of the .T file that we will print out. */
1351 void
1352 read_tfile __proto((void))
1354 short magic;
1355 off_t sym_hdr_offset = 0;
1357 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number");
1358 if (!tfile)
1360 /* Print out the global header, since this is not a T-file. */
1362 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0,
1363 "Global file header");
1365 print_global_hdr (&global_hdr);
1367 if (global_hdr.f_symptr == 0)
1369 printf ("No symbolic header, Goodbye!\n");
1370 exit (1);
1373 sym_hdr_offset = global_hdr.f_symptr;
1376 (void) read_seek ((PTR_T) &sym_hdr,
1377 sizeof (sym_hdr),
1378 sym_hdr_offset,
1379 "Symbolic header");
1381 print_sym_hdr (&sym_hdr);
1383 lines = (LINER *) read_seek ((PTR_T) 0,
1384 sym_hdr.cbLine,
1385 sym_hdr.cbLineOffset,
1386 "Line numbers");
1388 dense_nums = (DNR *) read_seek ((PTR_T) 0,
1389 sym_hdr.idnMax * sizeof (DNR),
1390 sym_hdr.cbDnOffset,
1391 "Dense numbers");
1393 proc_desc = (PDR *) read_seek ((PTR_T) 0,
1394 sym_hdr.ipdMax * sizeof (PDR),
1395 sym_hdr.cbPdOffset,
1396 "Procedure tables");
1398 l_symbols = (SYMR *) read_seek ((PTR_T) 0,
1399 sym_hdr.isymMax * sizeof (SYMR),
1400 sym_hdr.cbSymOffset,
1401 "Local symbols");
1403 opt_symbols = (OPTR *) read_seek ((PTR_T) 0,
1404 sym_hdr.ioptMax * sizeof (OPTR),
1405 sym_hdr.cbOptOffset,
1406 "Optimization symbols");
1408 aux_symbols = (AUXU *) read_seek ((PTR_T) 0,
1409 sym_hdr.iauxMax * sizeof (AUXU),
1410 sym_hdr.cbAuxOffset,
1411 "Auxiliary symbols");
1413 if (sym_hdr.iauxMax > 0)
1414 aux_used = xcalloc (sym_hdr.iauxMax, 1);
1416 l_strings = (char *) read_seek ((PTR_T) 0,
1417 sym_hdr.issMax,
1418 sym_hdr.cbSsOffset,
1419 "Local string table");
1421 e_strings = (char *) read_seek ((PTR_T) 0,
1422 sym_hdr.issExtMax,
1423 sym_hdr.cbSsExtOffset,
1424 "External string table");
1426 file_desc = (FDR *) read_seek ((PTR_T) 0,
1427 sym_hdr.ifdMax * sizeof (FDR),
1428 sym_hdr.cbFdOffset,
1429 "File tables");
1431 rfile_desc = (ulong *) read_seek ((PTR_T) 0,
1432 sym_hdr.crfd * sizeof (ulong),
1433 sym_hdr.cbRfdOffset,
1434 "Relative file tables");
1436 e_symbols = (EXTR *) read_seek ((PTR_T) 0,
1437 sym_hdr.iextMax * sizeof (EXTR),
1438 sym_hdr.cbExtOffset,
1439 "External symbols");
1444 extern int main PARAMS ((int, char **));
1447 main (argc, argv)
1448 int argc;
1449 char **argv;
1451 int i, opt;
1454 * Process arguments
1456 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1457 switch (opt)
1459 default: errors++; break;
1460 case 'a': want_aux++; break; /* print aux table */
1461 case 'l': want_line++; break; /* print line numbers */
1462 case 'r': want_rfd++; break; /* print relative fd's */
1463 case 's': want_scope++; break; /* print scope info */
1464 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1467 if (errors || optind != argc - 1)
1469 fprintf (stderr, "Calling Sequence:\n");
1470 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1471 fprintf (stderr, "\n");
1472 fprintf (stderr, "switches:\n");
1473 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1474 fprintf (stderr, "\t-l Print out line numbers.\n");
1475 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1476 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1477 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1478 return 1;
1482 * Open and process the input file.
1484 tfile_fd = open (argv[optind], O_RDONLY);
1485 if (tfile_fd < 0)
1487 perror (argv[optind]);
1488 return 1;
1491 read_tfile ();
1494 * Print any global aux words if any.
1496 if (want_aux)
1498 long last_aux_in_use;
1500 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1502 printf ("\nGlobal auxiliary entries before first file:\n");
1503 for (i = 0; i < file_desc[0].iauxBase; i++)
1504 print_aux (aux_symbols[i], 0, aux_used[i]);
1507 if (sym_hdr.ifdMax == 0)
1508 last_aux_in_use = 0;
1509 else
1510 last_aux_in_use
1511 = (file_desc[sym_hdr.ifdMax-1].iauxBase
1512 + file_desc[sym_hdr.ifdMax-1].caux - 1);
1514 if (last_aux_in_use < sym_hdr.iauxMax-1)
1516 printf ("\nGlobal auxiliary entries after last file:\n");
1517 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1518 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1523 * Print the information for each file.
1525 for (i = 0; i < sym_hdr.ifdMax; i++)
1526 print_file_desc (&file_desc[i], i);
1529 * Print the external symbols.
1531 want_scope = 0; /* scope info is meaning for extern symbols */
1532 printf ("\nThere are %lu external symbols, starting at %lu\n",
1533 (ulong) sym_hdr.iextMax,
1534 (ulong) sym_hdr.cbExtOffset);
1536 for(i = 0; i < sym_hdr.iextMax; i++)
1537 print_symbol (&e_symbols[i].asym, i, e_strings,
1538 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1539 e_symbols[i].ifd,
1540 &file_desc[e_symbols[i].ifd]);
1543 * Print unused aux symbols now.
1546 if (want_aux)
1548 int first_time = 1;
1550 for (i = 0; i < sym_hdr.iauxMax; i++)
1552 if (! aux_used[i])
1554 if (first_time)
1556 printf ("\nThe following auxiliary table entries were unused:\n\n");
1557 first_time = 0;
1560 printf (" #%-5d %11ld 0x%08lx %s\n",
1562 (long) aux_symbols[i].isym,
1563 (long) aux_symbols[i].isym,
1564 type_to_string (aux_symbols, i, (FDR *) 0));
1569 return 0;
1573 void
1574 fancy_abort ()
1576 fprintf (stderr, "mips-tdump internal error");
1577 exit (1);