2002-11-21 Phil Edwards <pme@gcc.gnu.org>
[official-gcc.git] / gcc / mips-tdump.c
blobd7040d95b70aecc1091464768ddbc49a8e082139
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 GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
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.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #ifdef index
27 #undef index
28 #endif
29 #ifndef CROSS_COMPILE
30 #include <a.out.h>
31 #else
32 #include "mips/a.out.h"
33 #endif /* CROSS_COMPILE */
35 #ifndef MIPS_IS_STAB
36 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
37 and mips-tdump.c to print them out. This is used on the Alpha,
38 which does not include mips.h.
40 These must match the corresponding definitions in gdb/mipsread.c.
41 Unfortunately, gcc and gdb do not currently share any directories. */
43 #define CODE_MASK 0x8F300
44 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
45 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
46 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
47 #endif
49 #define uchar unsigned char
50 #define ushort unsigned short
51 #define uint unsigned int
52 #define ulong unsigned long
55 /* Redefinition of storage classes as an enumeration for better
56 debugging. */
58 #ifndef stStaParam
59 #define stStaParam 16 /* Fortran static parameters */
60 #endif
62 #ifndef btVoid
63 #define btVoid 26 /* void basic type */
64 #endif
66 typedef enum sc {
67 sc_Nil = scNil, /* no storage class */
68 sc_Text = scText, /* text symbol */
69 sc_Data = scData, /* initialized data symbol */
70 sc_Bss = scBss, /* un-initialized data symbol */
71 sc_Register = scRegister, /* value of symbol is register number */
72 sc_Abs = scAbs, /* value of symbol is absolute */
73 sc_Undefined = scUndefined, /* who knows? */
74 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
75 sc_Bits = scBits, /* this is a bit field */
76 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
77 sc_RegImage = scRegImage, /* register value saved on stack */
78 sc_Info = scInfo, /* symbol contains debugger information */
79 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
80 sc_SData = scSData, /* load time only small data */
81 sc_SBss = scSBss, /* load time only small common */
82 sc_RData = scRData, /* load time only read only data */
83 sc_Var = scVar, /* Var parameter (fortran,pascal) */
84 sc_Common = scCommon, /* common variable */
85 sc_SCommon = scSCommon, /* small common */
86 sc_VarRegister = scVarRegister, /* Var parameter in a register */
87 sc_Variant = scVariant, /* Variant record */
88 sc_SUndefined = scSUndefined, /* small undefined(external) data */
89 sc_Init = scInit, /* .init section symbol */
90 sc_Max = scMax /* Max storage class+1 */
91 } sc_t;
93 /* Redefinition of symbol type. */
95 typedef enum st {
96 st_Nil = stNil, /* Nuthin' special */
97 st_Global = stGlobal, /* external symbol */
98 st_Static = stStatic, /* static */
99 st_Param = stParam, /* procedure argument */
100 st_Local = stLocal, /* local variable */
101 st_Label = stLabel, /* label */
102 st_Proc = stProc, /* " " Procedure */
103 st_Block = stBlock, /* beginning of block */
104 st_End = stEnd, /* end (of anything) */
105 st_Member = stMember, /* member (of anything - struct/union/enum */
106 st_Typedef = stTypedef, /* type definition */
107 st_File = stFile, /* file name */
108 st_RegReloc = stRegReloc, /* register relocation */
109 st_Forward = stForward, /* forwarding address */
110 st_StaticProc = stStaticProc, /* load time only static procs */
111 st_StaParam = stStaParam, /* Fortran static parameters */
112 st_Constant = stConstant, /* const */
113 #ifdef stStruct
114 st_Struct = stStruct, /* struct */
115 st_Union = stUnion, /* union */
116 st_Enum = stEnum, /* enum */
117 #endif
118 st_Str = stStr, /* string */
119 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
120 st_Expr = stExpr, /* 2+2 vs. 4 */
121 st_Type = stType, /* post-coercion SER */
122 st_Max = stMax /* max type+1 */
123 } st_t;
125 /* Redefinition of type qualifiers. */
127 typedef enum tq {
128 tq_Nil = tqNil, /* bt is what you see */
129 tq_Ptr = tqPtr, /* pointer */
130 tq_Proc = tqProc, /* procedure */
131 tq_Array = tqArray, /* duh */
132 tq_Far = tqFar, /* longer addressing - 8086/8 land */
133 tq_Vol = tqVol, /* volatile */
134 tq_Max = tqMax /* Max type qualifier+1 */
135 } tq_t;
137 /* Redefinition of basic types. */
139 typedef enum bt {
140 bt_Nil = btNil, /* undefined */
141 bt_Adr = btAdr, /* address - integer same size as pointer */
142 bt_Char = btChar, /* character */
143 bt_UChar = btUChar, /* unsigned character */
144 bt_Short = btShort, /* short */
145 bt_UShort = btUShort, /* unsigned short */
146 bt_Int = btInt, /* int */
147 bt_UInt = btUInt, /* unsigned int */
148 bt_Long = btLong, /* long */
149 bt_ULong = btULong, /* unsigned long */
150 bt_Float = btFloat, /* float (real) */
151 bt_Double = btDouble, /* Double (real) */
152 bt_Struct = btStruct, /* Structure (Record) */
153 bt_Union = btUnion, /* Union (variant) */
154 bt_Enum = btEnum, /* Enumerated */
155 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
156 bt_Range = btRange, /* subrange of int */
157 bt_Set = btSet, /* pascal sets */
158 bt_Complex = btComplex, /* fortran complex */
159 bt_DComplex = btDComplex, /* fortran double complex */
160 bt_Indirect = btIndirect, /* forward or unnamed typedef */
161 bt_FixedDec = btFixedDec, /* Fixed Decimal */
162 bt_FloatDec = btFloatDec, /* Float Decimal */
163 bt_String = btString, /* Varying Length Character String */
164 bt_Bit = btBit, /* Aligned Bit String */
165 bt_Picture = btPicture, /* Picture */
166 bt_Void = btVoid, /* void */
167 bt_Max = btMax /* Max basic type+1 */
168 } bt_t;
170 /* Redefinition of the language codes. */
172 typedef enum lang {
173 lang_C = langC,
174 lang_Pascal = langPascal,
175 lang_Fortran = langFortran,
176 lang_Assembler = langAssembler,
177 lang_Machine = langMachine,
178 lang_Nil = langNil,
179 lang_Ada = langAda,
180 lang_Pl1 = langPl1,
181 lang_Cobol = langCobol
182 } lang_t;
184 /* Redefinition of the debug level codes. */
186 typedef enum glevel {
187 glevel_0 = GLEVEL_0,
188 glevel_1 = GLEVEL_1,
189 glevel_2 = GLEVEL_2,
190 glevel_3 = GLEVEL_3
191 } glevel_t;
194 /* Keep track of the active scopes. */
195 typedef struct scope {
196 struct scope *prev; /* previous scope */
197 ulong open_sym; /* symbol opening scope */
198 sc_t sc; /* storage class */
199 st_t st; /* symbol type */
200 } scope_t;
202 struct filehdr global_hdr; /* a.out header */
204 int errors = 0; /* # of errors */
205 int want_aux = 0; /* print aux table */
206 int want_line = 0; /* print line numbers */
207 int want_rfd = 0; /* print relative file desc's */
208 int want_scope = 0; /* print scopes for every symbol */
209 int tfile = 0; /* no global header file */
210 int tfile_fd; /* file descriptor of .T file */
211 off_t tfile_offset; /* current offset in .T file */
212 scope_t *cur_scope = 0; /* list of active scopes */
213 scope_t *free_scope = 0; /* list of freed scopes */
214 HDRR sym_hdr; /* symbolic header */
215 char *l_strings; /* local strings */
216 char *e_strings; /* external strings */
217 SYMR *l_symbols; /* local symbols */
218 EXTR *e_symbols; /* external symbols */
219 LINER *lines; /* line numbers */
220 DNR *dense_nums; /* dense numbers */
221 OPTR *opt_symbols; /* optimization symbols */
222 AUXU *aux_symbols; /* Auxiliary symbols */
223 char *aux_used; /* map of which aux syms are used */
224 FDR *file_desc; /* file tables */
225 ulong *rfile_desc; /* relative file tables */
226 PDR *proc_desc; /* procedure tables */
228 /* Forward reference for functions. */
229 static PTR read_seek PARAMS ((PTR, size_t, off_t, const char *));
230 static void read_tfile PARAMS ((void));
231 static void print_global_hdr PARAMS ((struct filehdr *));
232 static void print_sym_hdr PARAMS ((HDRR *));
233 static void print_file_desc PARAMS ((FDR *, int));
234 static void print_symbol PARAMS ((SYMR *, int, const char *, AUXU *, int, FDR *));
235 static void print_aux PARAMS ((AUXU, int, int));
236 static void emit_aggregate PARAMS ((char *, AUXU, AUXU, const char *, FDR *));
237 static const char *st_to_string PARAMS ((st_t));
238 static const char *sc_to_string PARAMS ((sc_t));
239 static const char *glevel_to_string PARAMS ((glevel_t));
240 static const char *lang_to_string PARAMS ((lang_t));
241 static const char *type_to_string PARAMS ((AUXU *, int, FDR *));
243 extern char *optarg;
244 extern int optind;
245 extern int opterr;
247 /* Create a table of debugging stab-codes and corresponding names. */
249 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
250 const struct {const short code; const char string[10];} stab_names[] = {
251 #include "stab.def"
252 #undef __define_stab
256 /* Read some bytes at a specified location, and return a pointer. */
258 static PTR
259 read_seek (ptr, size, offset, context)
260 PTR ptr; /* pointer to buffer or NULL */
261 size_t size; /* # bytes to read */
262 off_t offset; /* offset to read at */
263 const char *context; /* context for error message */
265 long read_size = 0;
267 if (size == 0) /* nothing to read */
268 return ptr;
270 if (!ptr)
271 ptr = xmalloc (size);
273 if ((tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
274 || (read_size = read (tfile_fd, ptr, size)) < 0)
276 perror (context);
277 exit (1);
280 if (read_size != (long) size)
282 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
283 context, read_size, (long) size);
284 exit (1);
287 tfile_offset = offset + size;
288 return ptr;
292 /* Convert language code to string format. */
294 static const char *
295 lang_to_string (lang)
296 lang_t lang;
298 switch (lang)
300 case langC: return "C";
301 case langPascal: return "Pascal";
302 case langFortran: return "Fortran";
303 case langAssembler: return "Assembler";
304 case langMachine: return "Machine";
305 case langNil: return "Nil";
306 case langAda: return "Ada";
307 case langPl1: return "Pl1";
308 case langCobol: return "Cobol";
311 return "Unknown language";
315 /* Convert storage class to string. */
317 static const char *
318 sc_to_string(storage_class)
319 sc_t storage_class;
321 switch(storage_class)
323 case sc_Nil: return "Nil";
324 case sc_Text: return "Text";
325 case sc_Data: return "Data";
326 case sc_Bss: return "Bss";
327 case sc_Register: return "Register";
328 case sc_Abs: return "Abs";
329 case sc_Undefined: return "Undefined";
330 case sc_CdbLocal: return "CdbLocal";
331 case sc_Bits: return "Bits";
332 case sc_CdbSystem: return "CdbSystem";
333 case sc_RegImage: return "RegImage";
334 case sc_Info: return "Info";
335 case sc_UserStruct: return "UserStruct";
336 case sc_SData: return "SData";
337 case sc_SBss: return "SBss";
338 case sc_RData: return "RData";
339 case sc_Var: return "Var";
340 case sc_Common: return "Common";
341 case sc_SCommon: return "SCommon";
342 case sc_VarRegister: return "VarRegister";
343 case sc_Variant: return "Variant";
344 case sc_SUndefined: return "SUndefined";
345 case sc_Init: return "Init";
346 case sc_Max: return "Max";
349 return "???";
353 /* Convert symbol type to string. */
355 static const char *
356 st_to_string(symbol_type)
357 st_t symbol_type;
359 switch(symbol_type)
361 case st_Nil: return "Nil";
362 case st_Global: return "Global";
363 case st_Static: return "Static";
364 case st_Param: return "Param";
365 case st_Local: return "Local";
366 case st_Label: return "Label";
367 case st_Proc: return "Proc";
368 case st_Block: return "Block";
369 case st_End: return "End";
370 case st_Member: return "Member";
371 case st_Typedef: return "Typedef";
372 case st_File: return "File";
373 case st_RegReloc: return "RegReloc";
374 case st_Forward: return "Forward";
375 case st_StaticProc: return "StaticProc";
376 case st_Constant: return "Constant";
377 case st_StaParam: return "StaticParam";
378 #ifdef stStruct
379 case st_Struct: return "Struct";
380 case st_Union: return "Union";
381 case st_Enum: return "Enum";
382 #endif
383 case st_Str: return "String";
384 case st_Number: return "Number";
385 case st_Expr: return "Expr";
386 case st_Type: return "Type";
387 case st_Max: return "Max";
390 return "???";
394 /* Convert debug level to string. */
396 static const char *
397 glevel_to_string (g_level)
398 glevel_t g_level;
400 switch(g_level)
402 case GLEVEL_0: return "G0";
403 case GLEVEL_1: return "G1";
404 case GLEVEL_2: return "G2";
405 case GLEVEL_3: return "G3";
408 return "??";
412 /* Convert the type information to string format. */
414 static const char *
415 type_to_string (aux_ptr, index, fdp)
416 AUXU *aux_ptr;
417 int index;
418 FDR *fdp;
420 AUXU u;
421 struct qual {
422 tq_t type;
423 int low_bound;
424 int high_bound;
425 int stride;
426 } qualifiers[7];
428 bt_t basic_type;
429 int i;
430 static char buffer1[1024];
431 static char buffer2[1024];
432 char *p1 = buffer1;
433 char *p2 = buffer2;
434 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
436 for (i = 0; i < 7; i++)
438 qualifiers[i].low_bound = 0;
439 qualifiers[i].high_bound = 0;
440 qualifiers[i].stride = 0;
443 used_ptr[index] = 1;
444 u = aux_ptr[index++];
445 if (u.isym == -1)
446 return "-1 (no type)";
448 basic_type = (bt_t) u.ti.bt;
449 qualifiers[0].type = (tq_t) u.ti.tq0;
450 qualifiers[1].type = (tq_t) u.ti.tq1;
451 qualifiers[2].type = (tq_t) u.ti.tq2;
452 qualifiers[3].type = (tq_t) u.ti.tq3;
453 qualifiers[4].type = (tq_t) u.ti.tq4;
454 qualifiers[5].type = (tq_t) u.ti.tq5;
455 qualifiers[6].type = tq_Nil;
458 * Go get the basic type.
460 switch (basic_type)
462 case bt_Nil: /* undefined */
463 strcpy (p1, "nil");
464 break;
466 case bt_Adr: /* address - integer same size as pointer */
467 strcpy (p1, "address");
468 break;
470 case bt_Char: /* character */
471 strcpy (p1, "char");
472 break;
474 case bt_UChar: /* unsigned character */
475 strcpy (p1, "unsigned char");
476 break;
478 case bt_Short: /* short */
479 strcpy (p1, "short");
480 break;
482 case bt_UShort: /* unsigned short */
483 strcpy (p1, "unsigned short");
484 break;
486 case bt_Int: /* int */
487 strcpy (p1, "int");
488 break;
490 case bt_UInt: /* unsigned int */
491 strcpy (p1, "unsigned int");
492 break;
494 case bt_Long: /* long */
495 strcpy (p1, "long");
496 break;
498 case bt_ULong: /* unsigned long */
499 strcpy (p1, "unsigned long");
500 break;
502 case bt_Float: /* float (real) */
503 strcpy (p1, "float");
504 break;
506 case bt_Double: /* Double (real) */
507 strcpy (p1, "double");
508 break;
510 /* Structures add 1-2 aux words:
511 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
512 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
514 case bt_Struct: /* Structure (Record) */
515 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
516 used_ptr[index] = 1;
517 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
518 used_ptr[++index] = 1;
520 index++; /* skip aux words */
521 break;
523 /* Unions add 1-2 aux words:
524 1st word is [ST_RFDESCAPE, offset] pointer to union def;
525 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
527 case bt_Union: /* Union */
528 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
529 used_ptr[index] = 1;
530 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
531 used_ptr[++index] = 1;
533 index++; /* skip aux words */
534 break;
536 /* Enumerations add 1-2 aux words:
537 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
538 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
540 case bt_Enum: /* Enumeration */
541 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
542 used_ptr[index] = 1;
543 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
544 used_ptr[++index] = 1;
546 index++; /* skip aux words */
547 break;
549 case bt_Typedef: /* defined via a typedef, isymRef points */
550 strcpy (p1, "typedef");
551 break;
553 case bt_Range: /* subrange of int */
554 strcpy (p1, "subrange");
555 break;
557 case bt_Set: /* pascal sets */
558 strcpy (p1, "set");
559 break;
561 case bt_Complex: /* fortran complex */
562 strcpy (p1, "complex");
563 break;
565 case bt_DComplex: /* fortran double complex */
566 strcpy (p1, "double complex");
567 break;
569 case bt_Indirect: /* forward or unnamed typedef */
570 strcpy (p1, "forward/unnamed typedef");
571 break;
573 case bt_FixedDec: /* Fixed Decimal */
574 strcpy (p1, "fixed decimal");
575 break;
577 case bt_FloatDec: /* Float Decimal */
578 strcpy (p1, "float decimal");
579 break;
581 case bt_String: /* Varying Length Character String */
582 strcpy (p1, "string");
583 break;
585 case bt_Bit: /* Aligned Bit String */
586 strcpy (p1, "bit");
587 break;
589 case bt_Picture: /* Picture */
590 strcpy (p1, "picture");
591 break;
593 case bt_Void: /* Void */
594 strcpy (p1, "void");
595 break;
597 default:
598 sprintf (p1, "Unknown basic type %d", (int) basic_type);
599 break;
602 p1 += strlen (buffer1);
605 * If this is a bitfield, get the bitsize.
607 if (u.ti.fBitfield)
609 int bitsize;
611 used_ptr[index] = 1;
612 bitsize = aux_ptr[index++].width;
613 sprintf (p1, " : %d", bitsize);
614 p1 += strlen (buffer1);
619 * Deal with any qualifiers.
621 if (qualifiers[0].type != tq_Nil)
624 * Snarf up any array bounds in the correct order. Arrays
625 * store 5 successive words in the aux. table:
626 * word 0 RNDXR to type of the bounds (ie, int)
627 * word 1 Current file descriptor index
628 * word 2 low bound
629 * word 3 high bound (or -1 if [])
630 * word 4 stride size in bits
632 for (i = 0; i < 7; i++)
634 if (qualifiers[i].type == tq_Array)
636 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
637 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
638 qualifiers[i].stride = aux_ptr[index+4].width;
639 used_ptr[index] = 1;
640 used_ptr[index+1] = 1;
641 used_ptr[index+2] = 1;
642 used_ptr[index+3] = 1;
643 used_ptr[index+4] = 1;
644 index += 5;
649 * Now print out the qualifiers.
651 for (i = 0; i < 6; i++)
653 switch (qualifiers[i].type)
655 case tq_Nil:
656 case tq_Max:
657 break;
659 case tq_Ptr:
660 strcpy (p2, "ptr to ");
661 p2 += sizeof ("ptr to ")-1;
662 break;
664 case tq_Vol:
665 strcpy (p2, "volatile ");
666 p2 += sizeof ("volatile ")-1;
667 break;
669 case tq_Far:
670 strcpy (p2, "far ");
671 p2 += sizeof ("far ")-1;
672 break;
674 case tq_Proc:
675 strcpy (p2, "func. ret. ");
676 p2 += sizeof ("func. ret. ");
677 break;
679 case tq_Array:
681 int first_array = i;
682 int j;
684 /* Print array bounds reversed (ie, in the order the C
685 programmer writes them). C is such a fun language.... */
687 while (i < 5 && qualifiers[i+1].type == tq_Array)
688 i++;
690 for (j = i; j >= first_array; j--)
692 strcpy (p2, "array [");
693 p2 += sizeof ("array [")-1;
694 if (qualifiers[j].low_bound != 0)
695 sprintf (p2,
696 "%ld:%ld {%ld bits}",
697 (long) qualifiers[j].low_bound,
698 (long) qualifiers[j].high_bound,
699 (long) qualifiers[j].stride);
701 else if (qualifiers[j].high_bound != -1)
702 sprintf (p2,
703 "%ld {%ld bits}",
704 (long) (qualifiers[j].high_bound + 1),
705 (long) (qualifiers[j].stride));
707 else
708 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
710 p2 += strlen (p2);
711 strcpy (p2, "] of ");
712 p2 += sizeof ("] of ")-1;
715 break;
720 strcpy (p2, buffer1);
721 return buffer2;
725 /* Print out the global file header for object files. */
727 static void
728 print_global_hdr (ptr)
729 struct filehdr *ptr;
731 char *time = ctime ((time_t *)&ptr->f_timdat);
732 ushort flags = ptr->f_flags;
734 printf("Global file header:\n");
735 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
736 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
737 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
738 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
739 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
740 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
741 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
743 if ((flags & F_RELFLG) != 0)
744 printf (", F_RELFLG");
746 if ((flags & F_EXEC) != 0)
747 printf (", F_EXEC");
749 if ((flags & F_LNNO) != 0)
750 printf (", F_LNNO");
752 if ((flags & F_LSYMS) != 0)
753 printf (", F_LSYMS");
755 if ((flags & F_MINMAL) != 0)
756 printf (", F_MINMAL");
758 if ((flags & F_UPDATE) != 0)
759 printf (", F_UPDATE");
761 if ((flags & F_SWABD) != 0)
762 printf (", F_SWABD");
764 if ((flags & F_AR16WR) != 0)
765 printf (", F_AR16WR");
767 if ((flags & F_AR32WR) != 0)
768 printf (", F_AR32WR");
770 if ((flags & F_AR32W) != 0)
771 printf (", F_AR32W");
773 if ((flags & F_PATCH) != 0)
774 printf (", F_PATCH/F_NODF");
776 printf ("\n\n");
780 /* Print out the symbolic header. */
782 static void
783 print_sym_hdr (sym_ptr)
784 HDRR *sym_ptr;
786 int width = 20;
788 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
789 sym_ptr->magic & 0xffff,
790 (sym_ptr->vstamp & 0xffff) >> 8,
791 sym_ptr->vstamp & 0xff);
793 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
794 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
796 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
797 (long) sym_ptr->cbLineOffset,
798 (long) sym_ptr->cbLine,
799 (long) sym_ptr->cbLine,
800 (int) sym_ptr->ilineMax);
802 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
803 (long) sym_ptr->cbDnOffset,
804 (long) sym_ptr->idnMax,
805 (long) (sym_ptr->idnMax * sizeof (DNR)));
807 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
808 (long) sym_ptr->cbPdOffset,
809 (long) sym_ptr->ipdMax,
810 (long) (sym_ptr->ipdMax * sizeof (PDR)));
812 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
813 (long) sym_ptr->cbSymOffset,
814 (long) sym_ptr->isymMax,
815 (long) (sym_ptr->isymMax * sizeof (SYMR)));
817 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
818 (long) sym_ptr->cbOptOffset,
819 (long) sym_ptr->ioptMax,
820 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
822 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
823 (long) sym_ptr->cbAuxOffset,
824 (long) sym_ptr->iauxMax,
825 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
827 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
828 (long) sym_ptr->cbSsOffset,
829 (long) sym_ptr->issMax,
830 (long) sym_ptr->issMax);
832 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
833 (long) sym_ptr->cbSsExtOffset,
834 (long) sym_ptr->issExtMax,
835 (long) sym_ptr->issExtMax);
837 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
838 (long) sym_ptr->cbFdOffset,
839 (long) sym_ptr->ifdMax,
840 (long) (sym_ptr->ifdMax * sizeof (FDR)));
842 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
843 (long) sym_ptr->cbRfdOffset,
844 (long) sym_ptr->crfd,
845 (long) (sym_ptr->crfd * sizeof (ulong)));
847 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
848 (long) sym_ptr->cbExtOffset,
849 (long) sym_ptr->iextMax,
850 (long) (sym_ptr->iextMax * sizeof (EXTR)));
854 /* Print out a symbol. */
856 static void
857 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
858 SYMR *sym_ptr;
859 int number;
860 const char *strbase;
861 AUXU *aux_base;
862 int ifd;
863 FDR *fdp;
865 sc_t storage_class = (sc_t) sym_ptr->sc;
866 st_t symbol_type = (st_t) sym_ptr->st;
867 ulong index = sym_ptr->index;
868 char *used_ptr = aux_used + (aux_base - aux_symbols);
869 scope_t *scope_ptr;
871 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
873 if (aux_base != (AUXU *) 0 && index != indexNil)
874 switch (symbol_type)
876 case st_Nil:
877 case st_Label:
878 break;
880 case st_File:
881 case st_Block:
882 printf (" End+1 symbol: %ld\n", index);
883 if (want_scope)
885 if (free_scope == (scope_t *) 0)
886 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
887 else
889 scope_ptr = free_scope;
890 free_scope = scope_ptr->prev;
892 scope_ptr->open_sym = number;
893 scope_ptr->st = symbol_type;
894 scope_ptr->sc = storage_class;
895 scope_ptr->prev = cur_scope;
896 cur_scope = scope_ptr;
898 break;
900 case st_End:
901 if (storage_class == sc_Text || storage_class == sc_Info)
902 printf (" First symbol: %ld\n", index);
903 else
905 used_ptr[index] = 1;
906 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
909 if (want_scope)
911 if (cur_scope == (scope_t *) 0)
912 printf (" Can't pop end scope\n");
913 else
915 scope_ptr = cur_scope;
916 cur_scope = scope_ptr->prev;
917 scope_ptr->prev = free_scope;
918 free_scope = scope_ptr;
921 break;
923 case st_Proc:
924 case st_StaticProc:
925 if (MIPS_IS_STAB(sym_ptr))
927 else if (ifd == -1) /* local symbol */
929 used_ptr[index] = used_ptr[index+1] = 1;
930 printf (" End+1 symbol: %-7ld Type: %s\n",
931 (long) aux_base[index].isym,
932 type_to_string (aux_base, index+1, fdp));
934 else /* global symbol */
935 printf (" Local symbol: %ld\n", index);
937 if (want_scope)
939 if (free_scope == (scope_t *) 0)
940 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
941 else
943 scope_ptr = free_scope;
944 free_scope = scope_ptr->prev;
946 scope_ptr->open_sym = number;
947 scope_ptr->st = symbol_type;
948 scope_ptr->sc = storage_class;
949 scope_ptr->prev = cur_scope;
950 cur_scope = scope_ptr;
952 break;
954 #ifdef stStruct
955 case st_Struct:
956 case st_Union:
957 case st_Enum:
958 printf (" End+1 symbol: %lu\n", index);
959 break;
960 #endif
962 default:
963 if (!MIPS_IS_STAB (sym_ptr))
965 used_ptr[index] = 1;
966 printf (" Type: %s\n",
967 type_to_string (aux_base, index, fdp));
969 break;
972 if (want_scope)
974 printf (" Scopes: ");
975 if (cur_scope == (scope_t *) 0)
976 printf (" none\n");
977 else
979 for (scope_ptr = cur_scope;
980 scope_ptr != (scope_t *) 0;
981 scope_ptr = scope_ptr->prev)
983 const char *class;
984 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
985 class = "func.";
986 else if (scope_ptr->st == st_File)
987 class = "file";
988 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
989 class = "block";
990 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
991 class = "type";
992 else
993 class = "???";
995 printf (" %ld [%s]", scope_ptr->open_sym, class);
997 printf ("\n");
1001 printf (" Value: %-13ld ",
1002 (long)sym_ptr->value);
1003 if (ifd == -1)
1004 printf ("String index: %ld\n", (long)sym_ptr->iss);
1005 else
1006 printf ("String index: %-11ld Ifd: %d\n",
1007 (long)sym_ptr->iss, ifd);
1009 printf (" Symbol type: %-11sStorage class: %-11s",
1010 st_to_string (symbol_type), sc_to_string (storage_class));
1012 if (MIPS_IS_STAB(sym_ptr))
1014 int i = ARRAY_SIZE (stab_names);
1015 const char *stab_name = "stab";
1016 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1018 while (--i >= 0)
1019 if (stab_names[i].code == code)
1021 stab_name = stab_names[i].string;
1022 break;
1024 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1026 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1027 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1028 else
1029 printf ("Index: %ld\n", (long)sym_ptr->index);
1034 /* Print out a word from the aux. table in various formats. */
1036 static void
1037 print_aux (u, auxi, used)
1038 AUXU u;
1039 int auxi;
1040 int used;
1042 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1043 (used) ? " " : "* ",
1044 auxi,
1045 (long) u.isym,
1046 (long) u.rndx.rfd,
1047 (long) u.rndx.index,
1048 u.ti.bt,
1049 u.ti.fBitfield,
1050 u.ti.continued,
1051 u.ti.tq0,
1052 u.ti.tq1,
1053 u.ti.tq2,
1054 u.ti.tq3,
1055 u.ti.tq4,
1056 u.ti.tq5);
1060 /* Write aggregate information to a string. */
1062 static void
1063 emit_aggregate (string, u, u2, which, fdp)
1064 char *string;
1065 AUXU u;
1066 AUXU u2;
1067 const char *which;
1068 FDR *fdp;
1070 unsigned int ifd = u.rndx.rfd;
1071 unsigned int index = u.rndx.index;
1072 const char *name;
1074 if (ifd == ST_RFDESCAPE)
1075 ifd = u2.isym;
1077 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1078 struct return type of a procedure compiled without -g. */
1079 if (ifd == 0xffffffff
1080 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
1081 name = "<undefined>";
1082 else if (index == indexNil)
1083 name = "<no name>";
1084 else
1086 if (fdp == 0 || sym_hdr.crfd == 0)
1087 fdp = &file_desc[ifd];
1088 else
1089 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1090 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1093 sprintf (string,
1094 "%s %s { ifd = %u, index = %u }",
1095 which, name, ifd, index);
1099 /* Print out information about a file descriptor, and the symbols,
1100 procedures, and line numbers within it. */
1102 static void
1103 print_file_desc (fdp, number)
1104 FDR *fdp;
1105 int number;
1107 char *str_base;
1108 AUXU *aux_base;
1109 int symi, pdi;
1110 int width = 20;
1111 char *used_base;
1113 str_base = l_strings + fdp->issBase;
1114 aux_base = aux_symbols + fdp->iauxBase;
1115 used_base = aux_used + (aux_base - aux_symbols);
1117 printf ("\nFile #%d, \"%s\"\n\n",
1118 number,
1119 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
1121 printf (" Name index = %-10ld Readin = %s\n",
1122 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1124 printf (" Merge = %-10s Endian = %s\n",
1125 (fdp->fMerge) ? "Yes" : "No",
1126 (fdp->fBigendian) ? "BIG" : "LITTLE");
1128 printf (" Debug level = %-10s Language = %s\n",
1129 glevel_to_string (fdp->glevel),
1130 lang_to_string((lang_t) fdp->lang));
1132 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1134 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1135 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1137 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1138 width, "Local strings",
1139 (ulong) fdp->issBase,
1140 (ulong) fdp->cbSs,
1141 (ulong) fdp->cbSs,
1142 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1144 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1145 width, "Local symbols",
1146 (ulong) fdp->isymBase,
1147 (ulong) fdp->csym,
1148 (ulong) (fdp->csym * sizeof (SYMR)),
1149 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1151 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1152 width, "Line numbers",
1153 (ulong) fdp->cbLineOffset,
1154 (ulong) fdp->cline,
1155 (ulong) fdp->cbLine,
1156 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1158 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1159 width, "Optimization symbols",
1160 (ulong) fdp->ioptBase,
1161 (ulong) fdp->copt,
1162 (ulong) (fdp->copt * sizeof (OPTR)),
1163 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1165 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1166 width, "Procedures",
1167 (ulong) fdp->ipdFirst,
1168 (ulong) fdp->cpd,
1169 (ulong) (fdp->cpd * sizeof (PDR)),
1170 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1172 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1173 width, "Auxiliary symbols",
1174 (ulong) fdp->iauxBase,
1175 (ulong) fdp->caux,
1176 (ulong) (fdp->caux * sizeof (AUXU)),
1177 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1179 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1180 width, "Relative Files",
1181 (ulong) fdp->rfdBase,
1182 (ulong) fdp->crfd,
1183 (ulong) (fdp->crfd * sizeof (ulong)),
1184 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1187 if (want_scope && cur_scope != (scope_t *) 0)
1188 printf ("\n Warning scope does not start at 0!\n");
1191 * print the info about the symbol table.
1193 printf ("\n There are %lu local symbols, starting at %lu\n",
1194 (ulong) fdp->csym,
1195 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1197 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1198 print_symbol (&l_symbols[symi],
1199 symi - fdp->isymBase,
1200 str_base,
1201 aux_base,
1203 fdp);
1205 if (want_scope && cur_scope != (scope_t *) 0)
1206 printf ("\n Warning scope does not end at 0!\n");
1209 * print the aux. table if desired.
1212 if (want_aux && fdp->caux != 0)
1214 int auxi;
1216 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1217 (ulong) fdp->caux,
1218 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1220 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1221 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1225 * print the relative file descriptors.
1227 if (want_rfd && fdp->crfd != 0)
1229 ulong *rfd_ptr, i;
1231 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1232 (ulong) fdp->crfd,
1233 (ulong) fdp->rfdBase);
1235 rfd_ptr = rfile_desc + fdp->rfdBase;
1236 for (i = 0; i < (ulong) fdp->crfd; i++)
1238 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1239 rfd_ptr++;
1244 * do the procedure descriptors.
1246 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1247 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1249 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1251 PDR *proc_ptr = &proc_desc[pdi];
1252 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1254 if (l_symbols != 0)
1255 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1256 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1257 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1259 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1260 (long) proc_ptr->regmask,
1261 (long) proc_ptr->regoffset,
1262 (long) proc_ptr->fregmask,
1263 (long) proc_ptr->fregoffset);
1265 printf ("\t .frame $%d,%ld,$%d\n",
1266 (int) proc_ptr->framereg,
1267 (long) proc_ptr->frameoffset,
1268 (int) proc_ptr->pcreg);
1270 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1271 (long) proc_ptr->iopt,
1272 (long) proc_ptr->isym);
1274 printf ("\t First line # = %-11ld Last line # = %ld\n",
1275 (long) proc_ptr->lnLow,
1276 (long) proc_ptr->lnHigh);
1278 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1279 (long) proc_ptr->cbLineOffset,
1280 (long) proc_ptr->adr);
1283 * print the line number entries.
1286 if (want_line && fdp->cline != 0)
1288 int delta, count;
1289 long cur_line = proc_ptr->lnLow;
1290 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1291 + fdp->cbLineOffset);
1292 uchar *line_end;
1294 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1295 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1296 else /* not last proc. */
1297 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1298 + fdp->cbLineOffset);
1300 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1301 (ulong) (line_end - line_ptr),
1302 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1304 while (line_ptr < line_end)
1305 { /* sign extend nibble */
1306 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1307 count = (*line_ptr & 0xf) + 1;
1308 if (delta != -8)
1309 line_ptr++;
1310 else
1312 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1313 delta = (delta ^ 0x8000) - 0x8000;
1314 line_ptr += 3;
1317 cur_line += delta;
1318 printf ("\t Line %11ld, delta %5d, count %2d\n",
1319 cur_line,
1320 delta,
1321 count);
1328 /* Read in the portions of the .T file that we will print out. */
1330 static void
1331 read_tfile ()
1333 short magic;
1334 off_t sym_hdr_offset = 0;
1336 (void) read_seek ((PTR) &magic, sizeof (magic), (off_t) 0, "Magic number");
1337 if (!tfile)
1339 /* Print out the global header, since this is not a T-file. */
1341 (void) read_seek ((PTR) &global_hdr, sizeof (global_hdr), (off_t) 0,
1342 "Global file header");
1344 print_global_hdr (&global_hdr);
1346 if (global_hdr.f_symptr == 0)
1348 printf ("No symbolic header, Goodbye!\n");
1349 exit (1);
1352 sym_hdr_offset = global_hdr.f_symptr;
1355 (void) read_seek ((PTR) &sym_hdr,
1356 sizeof (sym_hdr),
1357 sym_hdr_offset,
1358 "Symbolic header");
1360 print_sym_hdr (&sym_hdr);
1362 lines = (LINER *) read_seek (NULL,
1363 sym_hdr.cbLine,
1364 sym_hdr.cbLineOffset,
1365 "Line numbers");
1367 dense_nums = (DNR *) read_seek (NULL,
1368 sym_hdr.idnMax * sizeof (DNR),
1369 sym_hdr.cbDnOffset,
1370 "Dense numbers");
1372 proc_desc = (PDR *) read_seek (NULL,
1373 sym_hdr.ipdMax * sizeof (PDR),
1374 sym_hdr.cbPdOffset,
1375 "Procedure tables");
1377 l_symbols = (SYMR *) read_seek (NULL,
1378 sym_hdr.isymMax * sizeof (SYMR),
1379 sym_hdr.cbSymOffset,
1380 "Local symbols");
1382 opt_symbols = (OPTR *) read_seek (NULL,
1383 sym_hdr.ioptMax * sizeof (OPTR),
1384 sym_hdr.cbOptOffset,
1385 "Optimization symbols");
1387 aux_symbols = (AUXU *) read_seek (NULL,
1388 sym_hdr.iauxMax * sizeof (AUXU),
1389 sym_hdr.cbAuxOffset,
1390 "Auxiliary symbols");
1392 if (sym_hdr.iauxMax > 0)
1393 aux_used = xcalloc (sym_hdr.iauxMax, 1);
1395 l_strings = (char *) read_seek (NULL,
1396 sym_hdr.issMax,
1397 sym_hdr.cbSsOffset,
1398 "Local string table");
1400 e_strings = (char *) read_seek (NULL,
1401 sym_hdr.issExtMax,
1402 sym_hdr.cbSsExtOffset,
1403 "External string table");
1405 file_desc = (FDR *) read_seek (NULL,
1406 sym_hdr.ifdMax * sizeof (FDR),
1407 sym_hdr.cbFdOffset,
1408 "File tables");
1410 rfile_desc = (ulong *) read_seek (NULL,
1411 sym_hdr.crfd * sizeof (ulong),
1412 sym_hdr.cbRfdOffset,
1413 "Relative file tables");
1415 e_symbols = (EXTR *) read_seek (NULL,
1416 sym_hdr.iextMax * sizeof (EXTR),
1417 sym_hdr.cbExtOffset,
1418 "External symbols");
1423 extern int main PARAMS ((int, char **));
1426 main (argc, argv)
1427 int argc;
1428 char **argv;
1430 int i, opt;
1433 * Process arguments
1435 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1436 switch (opt)
1438 default: errors++; break;
1439 case 'a': want_aux++; break; /* print aux table */
1440 case 'l': want_line++; break; /* print line numbers */
1441 case 'r': want_rfd++; break; /* print relative fd's */
1442 case 's': want_scope++; break; /* print scope info */
1443 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1446 if (errors || optind != argc - 1)
1448 fprintf (stderr, "Calling Sequence:\n");
1449 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1450 fprintf (stderr, "\n");
1451 fprintf (stderr, "switches:\n");
1452 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1453 fprintf (stderr, "\t-l Print out line numbers.\n");
1454 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1455 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1456 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1457 return 1;
1461 * Open and process the input file.
1463 tfile_fd = open (argv[optind], O_RDONLY);
1464 if (tfile_fd < 0)
1466 perror (argv[optind]);
1467 return 1;
1470 read_tfile ();
1473 * Print any global aux words if any.
1475 if (want_aux)
1477 long last_aux_in_use;
1479 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1481 printf ("\nGlobal auxiliary entries before first file:\n");
1482 for (i = 0; i < file_desc[0].iauxBase; i++)
1483 print_aux (aux_symbols[i], 0, aux_used[i]);
1486 if (sym_hdr.ifdMax == 0)
1487 last_aux_in_use = 0;
1488 else
1489 last_aux_in_use
1490 = (file_desc[sym_hdr.ifdMax-1].iauxBase
1491 + file_desc[sym_hdr.ifdMax-1].caux - 1);
1493 if (last_aux_in_use < sym_hdr.iauxMax-1)
1495 printf ("\nGlobal auxiliary entries after last file:\n");
1496 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1497 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1502 * Print the information for each file.
1504 for (i = 0; i < sym_hdr.ifdMax; i++)
1505 print_file_desc (&file_desc[i], i);
1508 * Print the external symbols.
1510 want_scope = 0; /* scope info is meaning for extern symbols */
1511 printf ("\nThere are %lu external symbols, starting at %lu\n",
1512 (ulong) sym_hdr.iextMax,
1513 (ulong) sym_hdr.cbExtOffset);
1515 for(i = 0; i < sym_hdr.iextMax; i++)
1516 print_symbol (&e_symbols[i].asym, i, e_strings,
1517 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1518 e_symbols[i].ifd,
1519 &file_desc[e_symbols[i].ifd]);
1522 * Print unused aux symbols now.
1525 if (want_aux)
1527 int first_time = 1;
1529 for (i = 0; i < sym_hdr.iauxMax; i++)
1531 if (! aux_used[i])
1533 if (first_time)
1535 printf ("\nThe following auxiliary table entries were unused:\n\n");
1536 first_time = 0;
1539 printf (" #%-5d %11ld 0x%08lx %s\n",
1541 (long) aux_symbols[i].isym,
1542 (long) aux_symbols[i].isym,
1543 type_to_string (aux_symbols, i, (FDR *) 0));
1548 return 0;