(high_{block,function}_linenum): New variables.
[official-gcc.git] / gcc / mips-tdump.c
blob9e315031d2af11d3b09a152ae6cf9aaaa5a45559
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994 Free Software Foundation, Inc.
3 Contributed by hartzell@boulder.colorado.edu,
4 Rewritten by meissner@osf.org.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/file.h>
25 #include <time.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include "config.h"
30 #ifdef index
31 #undef index
32 #undef rindex
33 #endif
34 #ifndef CROSS_COMPILE
35 #include <a.out.h>
36 #else
37 #include "mips/a.out.h"
38 #endif /* CROSS_COMPILE */
40 #ifndef MIPS_IS_STAB
41 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
42 and mips-tdump.c to print them out. This is used on the Alpha,
43 which does not include mips.h.
45 These must match the corresponding definitions in gdb/mipsread.c.
46 Unfortunately, gcc and gdb do not currently share any directories. */
48 #define CODE_MASK 0x8F300
49 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
50 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
51 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
52 #endif
54 #ifdef __STDC__
55 typedef void *PTR_T;
56 typedef const void *CPTR_T;
57 #define __proto(x) x
58 #else
60 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
61 typedef void *PTR_T;
62 typedef void *CPTR_T;
64 #else
65 typedef char *PTR_T; /* Ultrix 3.1 */
66 typedef char *CPTR_T;
67 #endif
69 #define __proto(x) ()
70 #define const
71 #endif
73 #define uchar unsigned char
74 #define ushort unsigned short
75 #define uint unsigned int
76 #define ulong unsigned long
79 /* Do to size_t being defined in sys/types.h and different
80 in stddef.h, we have to do this by hand..... Note, these
81 types are correct for MIPS based systems, and may not be
82 correct for other systems. */
84 #define size_t uint
85 #define ptrdiff_t int
88 /* Redefinition of of storage classes as an enumeration for better
89 debugging. */
91 #ifndef stStaParam
92 #define stStaParam 16 /* Fortran static parameters */
93 #endif
95 #ifndef btVoid
96 #define btVoid 26 /* void basic type */
97 #endif
99 typedef enum sc {
100 sc_Nil = scNil, /* no storage class */
101 sc_Text = scText, /* text symbol */
102 sc_Data = scData, /* initialized data symbol */
103 sc_Bss = scBss, /* un-initialized data symbol */
104 sc_Register = scRegister, /* value of symbol is register number */
105 sc_Abs = scAbs, /* value of symbol is absolute */
106 sc_Undefined = scUndefined, /* who knows? */
107 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
108 sc_Bits = scBits, /* this is a bit field */
109 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
110 sc_RegImage = scRegImage, /* register value saved on stack */
111 sc_Info = scInfo, /* symbol contains debugger information */
112 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
113 sc_SData = scSData, /* load time only small data */
114 sc_SBss = scSBss, /* load time only small common */
115 sc_RData = scRData, /* load time only read only data */
116 sc_Var = scVar, /* Var parameter (fortran,pascal) */
117 sc_Common = scCommon, /* common variable */
118 sc_SCommon = scSCommon, /* small common */
119 sc_VarRegister = scVarRegister, /* Var parameter in a register */
120 sc_Variant = scVariant, /* Variant record */
121 sc_SUndefined = scSUndefined, /* small undefined(external) data */
122 sc_Init = scInit, /* .init section symbol */
123 sc_Max = scMax /* Max storage class+1 */
124 } sc_t;
126 /* Redefinition of symbol type. */
128 typedef enum st {
129 st_Nil = stNil, /* Nuthin' special */
130 st_Global = stGlobal, /* external symbol */
131 st_Static = stStatic, /* static */
132 st_Param = stParam, /* procedure argument */
133 st_Local = stLocal, /* local variable */
134 st_Label = stLabel, /* label */
135 st_Proc = stProc, /* " " Procedure */
136 st_Block = stBlock, /* beginning of block */
137 st_End = stEnd, /* end (of anything) */
138 st_Member = stMember, /* member (of anything - struct/union/enum */
139 st_Typedef = stTypedef, /* type definition */
140 st_File = stFile, /* file name */
141 st_RegReloc = stRegReloc, /* register relocation */
142 st_Forward = stForward, /* forwarding address */
143 st_StaticProc = stStaticProc, /* load time only static procs */
144 st_StaParam = stStaParam, /* Fortran static parameters */
145 st_Constant = stConstant, /* const */
146 st_Str = stStr, /* string */
147 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
148 st_Expr = stExpr, /* 2+2 vs. 4 */
149 st_Type = stType, /* post-coercion SER */
150 st_Max = stMax /* max type+1 */
151 } st_t;
153 /* Redefinition of type qualifiers. */
155 typedef enum tq {
156 tq_Nil = tqNil, /* bt is what you see */
157 tq_Ptr = tqPtr, /* pointer */
158 tq_Proc = tqProc, /* procedure */
159 tq_Array = tqArray, /* duh */
160 tq_Far = tqFar, /* longer addressing - 8086/8 land */
161 tq_Vol = tqVol, /* volatile */
162 tq_Max = tqMax /* Max type qualifier+1 */
163 } tq_t;
165 /* Redefinition of basic types. */
167 typedef enum bt {
168 bt_Nil = btNil, /* undefined */
169 bt_Adr = btAdr, /* address - integer same size as pointer */
170 bt_Char = btChar, /* character */
171 bt_UChar = btUChar, /* unsigned character */
172 bt_Short = btShort, /* short */
173 bt_UShort = btUShort, /* unsigned short */
174 bt_Int = btInt, /* int */
175 bt_UInt = btUInt, /* unsigned int */
176 bt_Long = btLong, /* long */
177 bt_ULong = btULong, /* unsigned long */
178 bt_Float = btFloat, /* float (real) */
179 bt_Double = btDouble, /* Double (real) */
180 bt_Struct = btStruct, /* Structure (Record) */
181 bt_Union = btUnion, /* Union (variant) */
182 bt_Enum = btEnum, /* Enumerated */
183 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
184 bt_Range = btRange, /* subrange of int */
185 bt_Set = btSet, /* pascal sets */
186 bt_Complex = btComplex, /* fortran complex */
187 bt_DComplex = btDComplex, /* fortran double complex */
188 bt_Indirect = btIndirect, /* forward or unnamed typedef */
189 bt_FixedDec = btFixedDec, /* Fixed Decimal */
190 bt_FloatDec = btFloatDec, /* Float Decimal */
191 bt_String = btString, /* Varying Length Character String */
192 bt_Bit = btBit, /* Aligned Bit String */
193 bt_Picture = btPicture, /* Picture */
194 bt_Void = btVoid, /* void */
195 bt_Max = btMax /* Max basic type+1 */
196 } bt_t;
198 /* Redefinition of the language codes. */
200 typedef enum lang {
201 lang_C = langC,
202 lang_Pascal = langPascal,
203 lang_Fortran = langFortran,
204 lang_Assembler = langAssembler,
205 lang_Machine = langMachine,
206 lang_Nil = langNil,
207 lang_Ada = langAda,
208 lang_Pl1 = langPl1,
209 lang_Cobol = langCobol
210 } lang_t;
212 /* Redefinition of the debug level codes. */
214 typedef enum glevel {
215 glevel_0 = GLEVEL_0,
216 glevel_1 = GLEVEL_1,
217 glevel_2 = GLEVEL_2,
218 glevel_3 = GLEVEL_3
219 } glevel_t;
222 /* Keep track of the active scopes. */
223 typedef struct scope {
224 struct scope *prev; /* previous scope */
225 ulong open_sym; /* symbol opening scope */
226 sc_t sc; /* storage class */
227 st_t st; /* symbol type */
228 } scope_t;
230 struct filehdr global_hdr; /* a.out header */
232 int errors = 0; /* # of errors */
233 int want_aux = 0; /* print aux table */
234 int want_line = 0; /* print line numbers */
235 int want_rfd = 0; /* print relative file desc's */
236 int want_scope = 0; /* print scopes for every symbol */
237 int tfile = 0; /* no global header file */
238 int tfile_fd; /* file descriptor of .T file */
239 off_t tfile_offset; /* current offset in .T file */
240 scope_t *cur_scope = 0; /* list of active scopes */
241 scope_t *free_scope = 0; /* list of freed scopes */
242 HDRR sym_hdr; /* symbolic header */
243 char *l_strings; /* local strings */
244 char *e_strings; /* external strings */
245 SYMR *l_symbols; /* local symbols */
246 EXTR *e_symbols; /* external symbols */
247 LINER *lines; /* line numbers */
248 DNR *dense_nums; /* dense numbers */
249 OPTR *opt_symbols; /* optimization symbols */
250 AUXU *aux_symbols; /* Auxiliary symbols */
251 char *aux_used; /* map of which aux syms are used */
252 FDR *file_desc; /* file tables */
253 ulong *rfile_desc; /* relative file tables */
254 PDR *proc_desc; /* procedure tables */
256 /* Forward reference for functions. */
257 PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));
258 void read_tfile __proto((void));
259 void print_global_hdr __proto((struct filehdr *));
260 void print_sym_hdr __proto((HDRR *));
261 void print_file_desc __proto((FDR *, int));
262 void print_symbol __proto((SYMR *, int, char *, AUXU *, int));
263 void print_aux __proto((AUXU, int, int));
264 void emit_aggregate __proto((char *, AUXU, AUXU, const char *));
265 char *st_to_string __proto((st_t));
266 char *sc_to_string __proto((sc_t));
267 char *glevel_to_string __proto((glevel_t));
268 char *lang_to_string __proto((lang_t));
269 char *type_to_string __proto((AUXU *, int));
271 #ifndef __alpha
272 extern PTR_T malloc __proto((size_t));
273 extern PTR_T calloc __proto((size_t, size_t));
274 extern PTR_T realloc __proto((PTR_T, size_t));
275 extern void free __proto((PTR_T));
276 #endif
278 extern char *optarg;
279 extern int optind;
280 extern int opterr;
282 /* Create a table of debugging stab-codes and corresponding names. */
284 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
285 struct {short code; char string[10];} stab_names[] = {
286 #include "stab.def"
287 #undef __define_stab
291 /* Read some bytes at a specified location, and return a pointer. */
293 PTR_T
294 read_seek (ptr, size, offset, context)
295 PTR_T ptr; /* pointer to buffer or NULL */
296 size_t size; /* # bytes to read */
297 off_t offset; /* offset to read at */
298 const char *context; /* context for error message */
300 long read_size = 0;
302 if (size == 0) /* nothing to read */
303 return ptr;
305 if ((ptr == (PTR_T)0 && (ptr = malloc (size)) == (PTR_T)0)
306 || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
307 || (read_size = read (tfile_fd, ptr, size)) < 0)
309 perror (context);
310 exit (1);
313 if (read_size != size)
315 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
316 context, read_size, (long) size);
317 exit (1);
320 tfile_offset = offset + size;
321 return ptr;
325 /* Convert language code to string format. */
327 char *
328 lang_to_string (lang)
329 lang_t lang;
331 switch (lang)
333 case langC: return "C";
334 case langPascal: return "Pascal";
335 case langFortran: return "Fortran";
336 case langAssembler: return "Assembler";
337 case langMachine: return "Machine";
338 case langNil: return "Nil";
339 case langAda: return "Ada";
340 case langPl1: return "Pl1";
341 case langCobol: return "Cobol";
344 return "Unknown language";
348 /* Convert storage class to string. */
350 char *
351 sc_to_string(storage_class)
352 sc_t storage_class;
354 switch(storage_class)
356 case sc_Nil: return "Nil";
357 case sc_Text: return "Text";
358 case sc_Data: return "Data";
359 case sc_Bss: return "Bss";
360 case sc_Register: return "Register";
361 case sc_Abs: return "Abs";
362 case sc_Undefined: return "Undefined";
363 case sc_CdbLocal: return "CdbLocal";
364 case sc_Bits: return "Bits";
365 case sc_CdbSystem: return "CdbSystem";
366 case sc_RegImage: return "RegImage";
367 case sc_Info: return "Info";
368 case sc_UserStruct: return "UserStruct";
369 case sc_SData: return "SData";
370 case sc_SBss: return "SBss";
371 case sc_RData: return "RData";
372 case sc_Var: return "Var";
373 case sc_Common: return "Common";
374 case sc_SCommon: return "SCommon";
375 case sc_VarRegister: return "VarRegister";
376 case sc_Variant: return "Variant";
377 case sc_SUndefined: return "SUndefined";
378 case sc_Init: return "Init";
379 case sc_Max: return "Max";
382 return "???";
386 /* Convert symbol type to string. */
388 char *
389 st_to_string(symbol_type)
390 st_t symbol_type;
392 switch(symbol_type)
394 case st_Nil: return "Nil";
395 case st_Global: return "Global";
396 case st_Static: return "Static";
397 case st_Param: return "Param";
398 case st_Local: return "Local";
399 case st_Label: return "Label";
400 case st_Proc: return "Proc";
401 case st_Block: return "Block";
402 case st_End: return "End";
403 case st_Member: return "Member";
404 case st_Typedef: return "Typedef";
405 case st_File: return "File";
406 case st_RegReloc: return "RegReloc";
407 case st_Forward: return "Forward";
408 case st_StaticProc: return "StaticProc";
409 case st_Constant: return "Constant";
410 case st_StaParam: return "StaticParam";
411 case st_Str: return "String";
412 case st_Number: return "Number";
413 case st_Expr: return "Expr";
414 case st_Type: return "Type";
415 case st_Max: return "Max";
418 return "???";
422 /* Convert debug level to string. */
424 char *
425 glevel_to_string (g_level)
426 glevel_t g_level;
428 switch(g_level)
430 case GLEVEL_0: return "G0";
431 case GLEVEL_1: return "G1";
432 case GLEVEL_2: return "G2";
433 case GLEVEL_3: return "G3";
436 return "??";
440 /* Convert the type information to string format. */
442 char *
443 type_to_string (aux_ptr, index)
444 AUXU *aux_ptr;
445 int index;
447 AUXU u;
448 struct qual {
449 tq_t type;
450 int low_bound;
451 int high_bound;
452 int stride;
453 } qualifiers[7];
455 bt_t basic_type;
456 int i;
457 static char buffer1[1024];
458 static char buffer2[1024];
459 char *p1 = buffer1;
460 char *p2 = buffer2;
461 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
463 for (i = 0; i < 7; i++)
465 qualifiers[i].low_bound = 0;
466 qualifiers[i].high_bound = 0;
467 qualifiers[i].stride = 0;
470 used_ptr[index] = 1;
471 u = aux_ptr[index++];
472 if (u.isym == -1)
473 return "-1 (no type)";
475 basic_type = (bt_t) u.ti.bt;
476 qualifiers[0].type = (tq_t) u.ti.tq0;
477 qualifiers[1].type = (tq_t) u.ti.tq1;
478 qualifiers[2].type = (tq_t) u.ti.tq2;
479 qualifiers[3].type = (tq_t) u.ti.tq3;
480 qualifiers[4].type = (tq_t) u.ti.tq4;
481 qualifiers[5].type = (tq_t) u.ti.tq5;
482 qualifiers[6].type = tq_Nil;
485 * Go get the basic type.
487 switch (basic_type)
489 case bt_Nil: /* undefined */
490 strcpy (p1, "nil");
491 break;
493 case bt_Adr: /* address - integer same size as pointer */
494 strcpy (p1, "address");
495 break;
497 case bt_Char: /* character */
498 strcpy (p1, "char");
499 break;
501 case bt_UChar: /* unsigned character */
502 strcpy (p1, "unsigned char");
503 break;
505 case bt_Short: /* short */
506 strcpy (p1, "short");
507 break;
509 case bt_UShort: /* unsigned short */
510 strcpy (p1, "unsigned short");
511 break;
513 case bt_Int: /* int */
514 strcpy (p1, "int");
515 break;
517 case bt_UInt: /* unsigned int */
518 strcpy (p1, "unsigned int");
519 break;
521 case bt_Long: /* long */
522 strcpy (p1, "long");
523 break;
525 case bt_ULong: /* unsigned long */
526 strcpy (p1, "unsigned long");
527 break;
529 case bt_Float: /* float (real) */
530 strcpy (p1, "float");
531 break;
533 case bt_Double: /* Double (real) */
534 strcpy (p1, "double");
535 break;
537 /* Structures add 1-2 aux words:
538 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
539 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
541 case bt_Struct: /* Structure (Record) */
542 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct");
543 used_ptr[index] = 1;
544 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
545 used_ptr[++index] = 1;
547 index++; /* skip aux words */
548 break;
550 /* Unions add 1-2 aux words:
551 1st word is [ST_RFDESCAPE, offset] pointer to union def;
552 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
554 case bt_Union: /* Union */
555 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union");
556 used_ptr[index] = 1;
557 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
558 used_ptr[++index] = 1;
560 index++; /* skip aux words */
561 break;
563 /* Enumerations add 1-2 aux words:
564 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
565 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
567 case bt_Enum: /* Enumeration */
568 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum");
569 used_ptr[index] = 1;
570 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
571 used_ptr[++index] = 1;
573 index++; /* skip aux words */
574 break;
576 case bt_Typedef: /* defined via a typedef, isymRef points */
577 strcpy (p1, "typedef");
578 break;
580 case bt_Range: /* subrange of int */
581 strcpy (p1, "subrange");
582 break;
584 case bt_Set: /* pascal sets */
585 strcpy (p1, "set");
586 break;
588 case bt_Complex: /* fortran complex */
589 strcpy (p1, "complex");
590 break;
592 case bt_DComplex: /* fortran double complex */
593 strcpy (p1, "double complex");
594 break;
596 case bt_Indirect: /* forward or unnamed typedef */
597 strcpy (p1, "forward/unamed typedef");
598 break;
600 case bt_FixedDec: /* Fixed Decimal */
601 strcpy (p1, "fixed decimal");
602 break;
604 case bt_FloatDec: /* Float Decimal */
605 strcpy (p1, "float decimal");
606 break;
608 case bt_String: /* Varying Length Character String */
609 strcpy (p1, "string");
610 break;
612 case bt_Bit: /* Aligned Bit String */
613 strcpy (p1, "bit");
614 break;
616 case bt_Picture: /* Picture */
617 strcpy (p1, "picture");
618 break;
620 case bt_Void: /* Void */
621 strcpy (p1, "void");
622 break;
624 default:
625 sprintf (p1, "Unknown basic type %d", (int) basic_type);
626 break;
629 p1 += strlen (buffer1);
632 * If this is a bitfield, get the bitsize.
634 if (u.ti.fBitfield)
636 int bitsize;
638 used_ptr[index] = 1;
639 bitsize = aux_ptr[index++].width;
640 sprintf (p1, " : %d", bitsize);
641 p1 += strlen (buffer1);
646 * Deal with any qualifiers.
648 if (qualifiers[0].type != tq_Nil)
651 * Snarf up any array bounds in the correct order. Arrays
652 * store 5 successive words in the aux. table:
653 * word 0 RNDXR to type of the bounds (ie, int)
654 * word 1 Current file descriptor index
655 * word 2 low bound
656 * word 3 high bound (or -1 if [])
657 * word 4 stride size in bits
659 for (i = 0; i < 7; i++)
661 if (qualifiers[i].type == tq_Array)
663 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
664 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
665 qualifiers[i].stride = aux_ptr[index+4].width;
666 used_ptr[index] = 1;
667 used_ptr[index+1] = 1;
668 used_ptr[index+2] = 1;
669 used_ptr[index+3] = 1;
670 used_ptr[index+4] = 1;
671 index += 5;
676 * Now print out the qualifiers.
678 for (i = 0; i < 6; i++)
680 switch (qualifiers[i].type)
682 case tq_Nil:
683 case tq_Max:
684 break;
686 case tq_Ptr:
687 strcpy (p2, "ptr to ");
688 p2 += sizeof ("ptr to ")-1;
689 break;
691 case tq_Vol:
692 strcpy (p2, "volatile ");
693 p2 += sizeof ("volatile ")-1;
694 break;
696 case tq_Far:
697 strcpy (p2, "far ");
698 p2 += sizeof ("far ")-1;
699 break;
701 case tq_Proc:
702 strcpy (p2, "func. ret. ");
703 p2 += sizeof ("func. ret. ");
704 break;
706 case tq_Array:
708 int first_array = i;
709 int j;
711 /* Print array bounds reversed (ie, in the order the C
712 programmer writes them). C is such a fun language.... */
714 while (i < 5 && qualifiers[i+1].type == tq_Array)
715 i++;
717 for (j = i; j >= first_array; j--)
719 strcpy (p2, "array [");
720 p2 += sizeof ("array [")-1;
721 if (qualifiers[j].low_bound != 0)
722 sprintf (p2,
723 "%ld:%ld {%ld bits}",
724 (long) qualifiers[j].low_bound,
725 (long) qualifiers[j].high_bound,
726 (long) qualifiers[j].stride);
728 else if (qualifiers[j].high_bound != -1)
729 sprintf (p2,
730 "%ld {%ld bits}",
731 (long) (qualifiers[j].high_bound + 1),
732 (long) (qualifiers[j].stride));
734 else
735 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
737 p2 += strlen (p2);
738 strcpy (p2, "] of ");
739 p2 += sizeof ("] of ")-1;
742 break;
747 strcpy (p2, buffer1);
748 return buffer2;
752 /* Print out the global file header for object files. */
754 void
755 print_global_hdr (ptr)
756 struct filehdr *ptr;
758 char *time = ctime ((time_t *)&ptr->f_timdat);
759 ushort flags = ptr->f_flags;
761 printf("Global file header:\n");
762 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
763 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
764 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
765 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
766 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
767 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
768 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
770 if ((flags & F_RELFLG) != 0)
771 printf (", F_RELFLG");
773 if ((flags & F_EXEC) != 0)
774 printf (", F_EXEC");
776 if ((flags & F_LNNO) != 0)
777 printf (", F_LNNO");
779 if ((flags & F_LSYMS) != 0)
780 printf (", F_LSYMS");
782 if ((flags & F_MINMAL) != 0)
783 printf (", F_MINMAL");
785 if ((flags & F_UPDATE) != 0)
786 printf (", F_UPDATE");
788 if ((flags & F_SWABD) != 0)
789 printf (", F_SWABD");
791 if ((flags & F_AR16WR) != 0)
792 printf (", F_AR16WR");
794 if ((flags & F_AR32WR) != 0)
795 printf (", F_AR32WR");
797 if ((flags & F_AR32W) != 0)
798 printf (", F_AR32W");
800 if ((flags & F_PATCH) != 0)
801 printf (", F_PATCH/F_NODF");
803 printf ("\n\n");
807 /* Print out the symbolic header. */
809 void
810 print_sym_hdr (sym_ptr)
811 HDRR *sym_ptr;
813 int width = 20;
815 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
816 sym_ptr->magic & 0xffff,
817 (sym_ptr->vstamp & 0xffff) >> 8,
818 sym_ptr->vstamp & 0xff);
820 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
821 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
823 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
824 (long)sym_ptr->cbLineOffset,
825 (long)sym_ptr->cbLine,
826 (long)sym_ptr->cbLine,
827 (int)sym_ptr->ilineMax);
829 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
830 (long)sym_ptr->cbDnOffset,
831 (long)sym_ptr->idnMax,
832 (long)(sym_ptr->idnMax * sizeof (DNR)));
834 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
835 (long)sym_ptr->cbPdOffset,
836 (long)sym_ptr->ipdMax,
837 (long)(sym_ptr->ipdMax * sizeof (PDR)));
839 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
840 (long)sym_ptr->cbSymOffset,
841 (long)sym_ptr->isymMax,
842 (long)(sym_ptr->isymMax * sizeof (SYMR)));
844 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
845 (long)sym_ptr->cbOptOffset,
846 (long)sym_ptr->ioptMax,
847 (long)(sym_ptr->ioptMax * sizeof (OPTR)));
849 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
850 (long)sym_ptr->cbAuxOffset,
851 (long)sym_ptr->iauxMax,
852 (long)(sym_ptr->iauxMax * sizeof (AUXU)));
854 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
855 (long)sym_ptr->cbSsOffset,
856 (long)sym_ptr->issMax,
857 (long)sym_ptr->issMax);
859 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
860 (long)sym_ptr->cbSsExtOffset,
861 (long)sym_ptr->issExtMax,
862 (long)sym_ptr->issExtMax);
864 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
865 (long)sym_ptr->cbFdOffset,
866 (long)sym_ptr->ifdMax,
867 (long)(sym_ptr->ifdMax * sizeof (FDR)));
869 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
870 (long)sym_ptr->cbRfdOffset,
871 (long)sym_ptr->crfd,
872 (long)(sym_ptr->crfd * sizeof (ulong)));
874 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
875 (long)sym_ptr->cbExtOffset,
876 (long)sym_ptr->iextMax,
877 (long)(sym_ptr->iextMax * sizeof (EXTR)));
881 /* Print out a symbol. */
883 void
884 print_symbol (sym_ptr, number, strbase, aux_base, ifd)
885 SYMR *sym_ptr;
886 int number;
887 char *strbase;
888 AUXU *aux_base;
889 int ifd;
891 sc_t storage_class = (sc_t) sym_ptr->sc;
892 st_t symbol_type = (st_t) sym_ptr->st;
893 ulong index = sym_ptr->index;
894 char *used_ptr = aux_used + (aux_base - aux_symbols);
895 scope_t *scope_ptr;
897 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
899 if (aux_base != (AUXU *)0 && index != indexNil)
900 switch (symbol_type)
902 case st_Nil:
903 case st_Label:
904 break;
906 case st_File:
907 case st_Block:
908 printf (" End+1 symbol: %ld\n", index);
909 if (want_scope)
911 if (free_scope == (scope_t *)0)
912 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
913 else
915 scope_ptr = free_scope;
916 free_scope = scope_ptr->prev;
918 scope_ptr->open_sym = number;
919 scope_ptr->st = symbol_type;
920 scope_ptr->sc = storage_class;
921 scope_ptr->prev = cur_scope;
922 cur_scope = scope_ptr;
924 break;
926 case st_End:
927 if (storage_class == sc_Text || storage_class == sc_Info)
928 printf (" First symbol: %ld\n", index);
929 else
931 used_ptr[index] = 1;
932 printf (" First symbol: %ld\n", aux_base[index].isym);
935 if (want_scope)
937 if (cur_scope == (scope_t *)0)
938 printf (" Can't pop end scope\n");
939 else
941 scope_ptr = cur_scope;
942 cur_scope = scope_ptr->prev;
943 scope_ptr->prev = free_scope;
944 free_scope = scope_ptr;
947 break;
949 case st_Proc:
950 case st_StaticProc:
951 if (MIPS_IS_STAB(sym_ptr))
953 else if (ifd == -1) /* local symbol */
955 used_ptr[index] = used_ptr[index+1] = 1;
956 printf (" End+1 symbol: %-7ld Type: %s\n",
957 aux_base[index].isym, type_to_string (aux_base, index+1));
959 else /* global symbol */
960 printf (" Local symbol: %ld\n", index);
962 if (want_scope)
964 if (free_scope == (scope_t *)0)
965 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
966 else
968 scope_ptr = free_scope;
969 free_scope = scope_ptr->prev;
971 scope_ptr->open_sym = number;
972 scope_ptr->st = symbol_type;
973 scope_ptr->sc = storage_class;
974 scope_ptr->prev = cur_scope;
975 cur_scope = scope_ptr;
977 break;
979 default:
980 if (!MIPS_IS_STAB (sym_ptr))
982 used_ptr[index] = 1;
983 printf (" Type: %s\n",
984 type_to_string (aux_base, index));
986 break;
989 if (want_scope)
991 printf (" Scopes: ");
992 if (cur_scope == (scope_t *)0)
993 printf (" none\n");
994 else
996 for (scope_ptr = cur_scope;
997 scope_ptr != (scope_t *)0;
998 scope_ptr = scope_ptr->prev)
1000 char *class;
1001 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1002 class = "func.";
1003 else if (scope_ptr->st == st_File)
1004 class = "file";
1005 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1006 class = "block";
1007 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1008 class = "type";
1009 else
1010 class = "???";
1012 printf (" %ld [%s]", scope_ptr->open_sym, class);
1014 printf ("\n");
1018 printf (" Value: %-13ld ",
1019 (long)sym_ptr->value);
1020 if (ifd == -1)
1021 printf ("String index: %ld\n", (long)sym_ptr->iss);
1022 else
1023 printf ("String index: %-11ld Ifd: %d\n",
1024 (long)sym_ptr->iss, ifd);
1026 printf (" Symbol type: %-11sStorage class: %-11s",
1027 st_to_string (symbol_type), sc_to_string (storage_class));
1029 if (MIPS_IS_STAB(sym_ptr))
1031 register int i = sizeof(stab_names) / sizeof(stab_names[0]);
1032 char *stab_name = "stab";
1033 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1034 while (--i >= 0)
1035 if (stab_names[i].code == code)
1037 stab_name = stab_names[i].string;
1038 break;
1040 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1042 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1043 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1044 else
1045 printf ("Index: %ld\n", (long)sym_ptr->index);
1050 /* Print out a word from the aux. table in various formats. */
1052 void
1053 print_aux (u, auxi, used)
1054 AUXU u;
1055 int auxi;
1056 int used;
1058 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1059 (used) ? " " : "* ",
1060 auxi,
1061 (long) u.isym,
1062 (long) u.rndx.rfd,
1063 (long) u.rndx.index,
1064 u.ti.bt,
1065 u.ti.fBitfield,
1066 u.ti.continued,
1067 u.ti.tq0,
1068 u.ti.tq1,
1069 u.ti.tq2,
1070 u.ti.tq3,
1071 u.ti.tq4,
1072 u.ti.tq5);
1076 /* Write aggregate information to a string. */
1078 void
1079 emit_aggregate (string, u, u2, which)
1080 char *string;
1081 AUXU u;
1082 AUXU u2;
1083 const char *which;
1085 int ifd = u.rndx.rfd;
1086 int index = u.rndx.index;
1087 int sym_base, ss_base;
1088 int name;
1090 if (ifd == ST_RFDESCAPE)
1091 ifd = u2.isym;
1093 sym_base = file_desc[ifd].isymBase;
1094 ss_base = file_desc[ifd].issBase;
1096 name = (index == indexNil) ? 0 : l_symbols[index + sym_base].iss;
1097 sprintf (string,
1098 "%s %s { ifd = %d, index = %d }",
1099 which,
1100 (name == 0) ? "/* no name */" : &l_strings[ ss_base + name ],
1101 ifd,
1102 index);
1106 /* Print out information about a file descriptor, and the symbols,
1107 procedures, and line numbers within it. */
1109 void
1110 print_file_desc (fdp, number)
1111 FDR *fdp;
1112 int number;
1114 char *str_base;
1115 AUXU *aux_base;
1116 int symi, pdi;
1117 int width = 20;
1118 char *used_base;
1120 str_base = l_strings + fdp->issBase;
1121 aux_base = aux_symbols + fdp->iauxBase;
1122 used_base = aux_used + (aux_base - aux_symbols);
1124 printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss);
1126 printf (" Name index = %-10ld Readin = %s\n",
1127 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1129 printf (" Merge = %-10s Endian = %s\n",
1130 (fdp->fMerge) ? "Yes" : "No",
1131 (fdp->fBigendian) ? "BIG" : "LITTLE");
1133 printf (" Debug level = %-10s Language = %s\n",
1134 glevel_to_string (fdp->glevel),
1135 lang_to_string((lang_t) fdp->lang));
1137 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1139 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1140 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1142 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1143 width, "Local strings",
1144 (ulong) fdp->issBase,
1145 (ulong) fdp->cbSs,
1146 (ulong) fdp->cbSs,
1147 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1149 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1150 width, "Local symbols",
1151 (ulong) fdp->isymBase,
1152 (ulong) fdp->csym,
1153 (ulong) (fdp->csym * sizeof (SYMR)),
1154 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1156 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1157 width, "Line numbers",
1158 (ulong) fdp->cbLineOffset,
1159 (ulong) fdp->cline,
1160 (ulong) fdp->cbLine,
1161 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1163 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1164 width, "Optimization symbols",
1165 (ulong) fdp->ioptBase,
1166 (ulong) fdp->copt,
1167 (ulong) (fdp->copt * sizeof (OPTR)),
1168 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1170 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1171 width, "Procedures",
1172 (ulong) fdp->ipdFirst,
1173 (ulong) fdp->cpd,
1174 (ulong) (fdp->cpd * sizeof (PDR)),
1175 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1177 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1178 width, "Auxiliary symbols",
1179 (ulong) fdp->iauxBase,
1180 (ulong) fdp->caux,
1181 (ulong) (fdp->caux * sizeof (AUXU)),
1182 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1184 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1185 width, "Relative Files",
1186 (ulong) fdp->rfdBase,
1187 (ulong) fdp->crfd,
1188 (ulong) (fdp->crfd * sizeof (ulong)),
1189 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1192 if (want_scope && cur_scope != (scope_t *)0)
1193 printf ("\n Warning scope does not start at 0!\n");
1196 * print the info about the symbol table.
1198 printf ("\n There are %lu local symbols, starting at %lu\n",
1199 (ulong) fdp->csym,
1200 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1202 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1203 print_symbol (&l_symbols[symi],
1204 symi - fdp->isymBase,
1205 str_base,
1206 aux_base,
1207 -1);
1209 if (want_scope && cur_scope != (scope_t *)0)
1210 printf ("\n Warning scope does not end at 0!\n");
1213 * print the aux. table if desired.
1216 if (want_aux && fdp->caux != 0)
1218 int auxi;
1220 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1221 (ulong) fdp->caux,
1222 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1224 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1225 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1229 * print the relative file descriptors.
1231 if (want_rfd && fdp->crfd != 0)
1233 ulong *rfd_ptr, i;
1235 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1236 (ulong) fdp->crfd,
1237 (ulong) fdp->rfdBase);
1239 rfd_ptr = rfile_desc + fdp->rfdBase;
1240 for (i = 0; i < fdp->crfd; i++)
1242 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1243 rfd_ptr++;
1248 * do the procedure descriptors.
1250 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1251 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1253 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1255 PDR *proc_ptr = &proc_desc[pdi];
1256 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1258 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1259 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1260 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1262 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1263 (long) proc_ptr->regmask,
1264 (long) proc_ptr->regoffset,
1265 (long) proc_ptr->fregmask,
1266 (long) proc_ptr->fregoffset);
1268 printf ("\t .frame $%d,%ld,$%d\n",
1269 (int) proc_ptr->framereg,
1270 (long) proc_ptr->frameoffset,
1271 (int) proc_ptr->pcreg);
1273 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1274 (long) proc_ptr->iopt,
1275 (long) proc_ptr->isym);
1277 printf ("\t First line # = %-11ld Last line # = %ld\n",
1278 (long) proc_ptr->lnLow,
1279 (long) proc_ptr->lnHigh);
1281 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1282 (long) proc_ptr->cbLineOffset,
1283 (long) proc_ptr->adr);
1286 * print the line number entries.
1289 if (want_line && fdp->cline != 0)
1291 int delta, count;
1292 long cur_line = proc_ptr->lnLow;
1293 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1294 + fdp->cbLineOffset);
1295 uchar *line_end;
1297 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1298 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1299 else /* not last proc. */
1300 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1301 + fdp->cbLineOffset);
1303 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1304 (ulong) (line_end - line_ptr),
1305 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1307 while (line_ptr < line_end)
1308 { /* sign extend nibble */
1309 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1310 count = (*line_ptr & 0xf) + 1;
1311 if (delta != -8)
1312 line_ptr++;
1313 else
1315 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1316 delta = (delta ^ 0x8000) - 0x8000;
1317 line_ptr += 3;
1320 cur_line += delta;
1321 printf ("\t Line %11ld, delta %5d, count %2d\n",
1322 cur_line,
1323 delta,
1324 count);
1331 /* Read in the portions of the .T file that we will print out. */
1333 void
1334 read_tfile __proto((void))
1336 short magic;
1337 off_t sym_hdr_offset = 0;
1339 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t)0, "Magic number");
1340 if (!tfile)
1342 /* Print out the global header, since this is not a T-file. */
1344 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t)0,
1345 "Global file header");
1347 print_global_hdr (&global_hdr);
1349 if (global_hdr.f_symptr == 0)
1351 printf ("No symbolic header, Goodbye!\n");
1352 exit (1);
1355 sym_hdr_offset = global_hdr.f_symptr;
1358 (void) read_seek ((PTR_T) &sym_hdr,
1359 sizeof (sym_hdr),
1360 sym_hdr_offset,
1361 "Symbolic header");
1363 print_sym_hdr (&sym_hdr);
1365 lines = (LINER *) read_seek ((PTR_T)0,
1366 sym_hdr.cbLine,
1367 sym_hdr.cbLineOffset,
1368 "Line numbers");
1370 dense_nums = (DNR *) read_seek ((PTR_T)0,
1371 sym_hdr.idnMax * sizeof (DNR),
1372 sym_hdr.cbDnOffset,
1373 "Dense numbers");
1375 proc_desc = (PDR *) read_seek ((PTR_T)0,
1376 sym_hdr.ipdMax * sizeof (PDR),
1377 sym_hdr.cbPdOffset,
1378 "Procedure tables");
1380 l_symbols = (SYMR *) read_seek ((PTR_T)0,
1381 sym_hdr.isymMax * sizeof (SYMR),
1382 sym_hdr.cbSymOffset,
1383 "Local symbols");
1385 opt_symbols = (OPTR *) read_seek ((PTR_T)0,
1386 sym_hdr.ioptMax * sizeof (OPTR),
1387 sym_hdr.cbOptOffset,
1388 "Optimization symbols");
1390 aux_symbols = (AUXU *) read_seek ((PTR_T)0,
1391 sym_hdr.iauxMax * sizeof (AUXU),
1392 sym_hdr.cbAuxOffset,
1393 "Auxiliary symbols");
1395 if (sym_hdr.iauxMax > 0)
1397 aux_used = calloc (sym_hdr.iauxMax, 1);
1398 if (aux_used == (char *)0)
1400 perror ("calloc");
1401 exit (1);
1405 l_strings = (char *) read_seek ((PTR_T)0,
1406 sym_hdr.issMax,
1407 sym_hdr.cbSsOffset,
1408 "Local string table");
1410 e_strings = (char *) read_seek ((PTR_T)0,
1411 sym_hdr.issExtMax,
1412 sym_hdr.cbSsExtOffset,
1413 "External string table");
1415 file_desc = (FDR *) read_seek ((PTR_T)0,
1416 sym_hdr.ifdMax * sizeof (FDR),
1417 sym_hdr.cbFdOffset,
1418 "File tables");
1420 rfile_desc = (ulong *) read_seek ((PTR_T)0,
1421 sym_hdr.crfd * sizeof (ulong),
1422 sym_hdr.cbRfdOffset,
1423 "Relative file tables");
1425 e_symbols = (EXTR *) read_seek ((PTR_T)0,
1426 sym_hdr.iextMax * sizeof (EXTR),
1427 sym_hdr.cbExtOffset,
1428 "External symbols");
1434 main (argc, argv)
1435 int argc;
1436 char **argv;
1438 int i, opt;
1441 * Process arguments
1443 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1444 switch (opt)
1446 default: errors++; break;
1447 case 'a': want_aux++; break; /* print aux table */
1448 case 'l': want_line++; break; /* print line numbers */
1449 case 'r': want_rfd++; break; /* print relative fd's */
1450 case 's': want_scope++; break; /* print scope info */
1451 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1454 if (errors || optind != argc - 1)
1456 fprintf (stderr, "Calling Sequence:\n");
1457 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1458 fprintf (stderr, "\n");
1459 fprintf (stderr, "switches:\n");
1460 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1461 fprintf (stderr, "\t-l Print out line numbers.\n");
1462 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1463 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1464 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1465 return 1;
1469 * Open and process the input file.
1471 tfile_fd = open (argv[optind], O_RDONLY);
1472 if (tfile_fd < 0)
1474 perror (argv[optind]);
1475 return 1;
1478 read_tfile ();
1481 * Print any global aux words if any.
1483 if (want_aux)
1485 long last_aux_in_use;
1487 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1489 printf ("\nGlobal auxiliary entries before first file:\n");
1490 for (i = 0; i < file_desc[0].iauxBase; i++)
1491 print_aux (aux_symbols[i], 0, aux_used[i]);
1494 if (sym_hdr.ifdMax == 0)
1495 last_aux_in_use = 0;
1496 else
1497 last_aux_in_use =
1498 file_desc[sym_hdr.ifdMax-1].iauxBase +
1499 file_desc[sym_hdr.ifdMax-1].caux - 1;
1501 if (last_aux_in_use < sym_hdr.iauxMax-1)
1503 printf ("\nGlobal auxiliary entries after last file:\n");
1504 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1505 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1510 * Print the information for each file.
1512 for (i = 0; i < sym_hdr.ifdMax; i++)
1513 print_file_desc (&file_desc[i], i);
1516 * Print the external symbols.
1518 want_scope = 0; /* scope info is meaning for extern symbols */
1519 printf ("\nThere are %lu external symbols, starting at %lu\n",
1520 (ulong) sym_hdr.iextMax,
1521 (ulong) sym_hdr.cbExtOffset);
1523 for(i = 0; i < sym_hdr.iextMax; i++)
1524 print_symbol (&e_symbols[i].asym, i, e_strings,
1525 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1526 e_symbols[i].ifd);
1529 * Print unused aux symbols now.
1532 if (want_aux)
1534 int first_time = 1;
1536 for (i = 0; i < sym_hdr.iauxMax; i++)
1538 if (! aux_used[i])
1540 if (first_time)
1542 printf ("\nThe following auxiliary table entries were unused:\n\n");
1543 first_time = 0;
1546 printf (" #%-5d %11ld 0x%08lx %s\n",
1548 (long) aux_symbols[i].isym,
1549 (long) aux_symbols[i].isym,
1550 type_to_string (aux_symbols, i));
1555 return 0;
1559 void
1560 fancy_abort ()
1562 fprintf (stderr, "mips-tdump internal error");
1563 exit (1);
1566 void
1567 fatal(s)
1568 char *s;
1570 fprintf(stderr, "%s\n", s);
1571 exit(1);
1574 /* Same as `malloc' but report error if no memory available. */
1576 PTR_T
1577 xmalloc (size)
1578 unsigned size;
1580 register PTR_T value = malloc (size);
1581 if (value == 0)
1582 fatal ("Virtual memory exhausted.");
1583 return value;