* pa/pa.c (compute_movstrsi_length): Handle residuals correctly.
[official-gcc.git] / gcc / mips-tdump.c
blob6890fc73e22af97de61818b6b326d47bd8462751
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994, 1995 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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/file.h>
26 #include <time.h>
27 #include <fcntl.h>
28 #include <errno.h>
29 #include "config.h"
31 #ifdef index
32 #undef index
33 #undef rindex
34 #endif
35 #ifndef CROSS_COMPILE
36 #include <a.out.h>
37 #else
38 #include "mips/a.out.h"
39 #endif /* CROSS_COMPILE */
41 #ifndef MIPS_IS_STAB
42 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
43 and mips-tdump.c to print them out. This is used on the Alpha,
44 which does not include mips.h.
46 These must match the corresponding definitions in gdb/mipsread.c.
47 Unfortunately, gcc and gdb do not currently share any directories. */
49 #define CODE_MASK 0x8F300
50 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
51 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
52 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
53 #endif
55 #ifdef __STDC__
56 typedef void *PTR_T;
57 typedef const void *CPTR_T;
58 #define __proto(x) x
59 #else
61 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
62 typedef void *PTR_T;
63 typedef void *CPTR_T;
65 #else
66 typedef char *PTR_T; /* Ultrix 3.1 */
67 typedef char *CPTR_T;
68 #endif
70 #define __proto(x) ()
71 #define const
72 #endif
74 #define uchar unsigned char
75 #define ushort unsigned short
76 #define uint unsigned int
77 #define ulong unsigned long
80 /* Do to size_t being defined in sys/types.h and different
81 in stddef.h, we have to do this by hand..... Note, these
82 types are correct for MIPS based systems, and may not be
83 correct for other systems. */
85 #define size_t uint
86 #define ptrdiff_t int
89 /* Redefinition of of storage classes as an enumeration for better
90 debugging. */
92 #ifndef stStaParam
93 #define stStaParam 16 /* Fortran static parameters */
94 #endif
96 #ifndef btVoid
97 #define btVoid 26 /* void basic type */
98 #endif
100 typedef enum sc {
101 sc_Nil = scNil, /* no storage class */
102 sc_Text = scText, /* text symbol */
103 sc_Data = scData, /* initialized data symbol */
104 sc_Bss = scBss, /* un-initialized data symbol */
105 sc_Register = scRegister, /* value of symbol is register number */
106 sc_Abs = scAbs, /* value of symbol is absolute */
107 sc_Undefined = scUndefined, /* who knows? */
108 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
109 sc_Bits = scBits, /* this is a bit field */
110 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
111 sc_RegImage = scRegImage, /* register value saved on stack */
112 sc_Info = scInfo, /* symbol contains debugger information */
113 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
114 sc_SData = scSData, /* load time only small data */
115 sc_SBss = scSBss, /* load time only small common */
116 sc_RData = scRData, /* load time only read only data */
117 sc_Var = scVar, /* Var parameter (fortran,pascal) */
118 sc_Common = scCommon, /* common variable */
119 sc_SCommon = scSCommon, /* small common */
120 sc_VarRegister = scVarRegister, /* Var parameter in a register */
121 sc_Variant = scVariant, /* Variant record */
122 sc_SUndefined = scSUndefined, /* small undefined(external) data */
123 sc_Init = scInit, /* .init section symbol */
124 sc_Max = scMax /* Max storage class+1 */
125 } sc_t;
127 /* Redefinition of symbol type. */
129 typedef enum st {
130 st_Nil = stNil, /* Nuthin' special */
131 st_Global = stGlobal, /* external symbol */
132 st_Static = stStatic, /* static */
133 st_Param = stParam, /* procedure argument */
134 st_Local = stLocal, /* local variable */
135 st_Label = stLabel, /* label */
136 st_Proc = stProc, /* " " Procedure */
137 st_Block = stBlock, /* beginning of block */
138 st_End = stEnd, /* end (of anything) */
139 st_Member = stMember, /* member (of anything - struct/union/enum */
140 st_Typedef = stTypedef, /* type definition */
141 st_File = stFile, /* file name */
142 st_RegReloc = stRegReloc, /* register relocation */
143 st_Forward = stForward, /* forwarding address */
144 st_StaticProc = stStaticProc, /* load time only static procs */
145 st_StaParam = stStaParam, /* Fortran static parameters */
146 st_Constant = stConstant, /* const */
147 #ifdef stStruct
148 st_Struct = stStruct, /* struct */
149 st_Union = stUnion, /* union */
150 st_Enum = stEnum, /* enum */
151 #endif
152 st_Str = stStr, /* string */
153 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
154 st_Expr = stExpr, /* 2+2 vs. 4 */
155 st_Type = stType, /* post-coercion SER */
156 st_Max = stMax /* max type+1 */
157 } st_t;
159 /* Redefinition of type qualifiers. */
161 typedef enum tq {
162 tq_Nil = tqNil, /* bt is what you see */
163 tq_Ptr = tqPtr, /* pointer */
164 tq_Proc = tqProc, /* procedure */
165 tq_Array = tqArray, /* duh */
166 tq_Far = tqFar, /* longer addressing - 8086/8 land */
167 tq_Vol = tqVol, /* volatile */
168 tq_Max = tqMax /* Max type qualifier+1 */
169 } tq_t;
171 /* Redefinition of basic types. */
173 typedef enum bt {
174 bt_Nil = btNil, /* undefined */
175 bt_Adr = btAdr, /* address - integer same size as pointer */
176 bt_Char = btChar, /* character */
177 bt_UChar = btUChar, /* unsigned character */
178 bt_Short = btShort, /* short */
179 bt_UShort = btUShort, /* unsigned short */
180 bt_Int = btInt, /* int */
181 bt_UInt = btUInt, /* unsigned int */
182 bt_Long = btLong, /* long */
183 bt_ULong = btULong, /* unsigned long */
184 bt_Float = btFloat, /* float (real) */
185 bt_Double = btDouble, /* Double (real) */
186 bt_Struct = btStruct, /* Structure (Record) */
187 bt_Union = btUnion, /* Union (variant) */
188 bt_Enum = btEnum, /* Enumerated */
189 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
190 bt_Range = btRange, /* subrange of int */
191 bt_Set = btSet, /* pascal sets */
192 bt_Complex = btComplex, /* fortran complex */
193 bt_DComplex = btDComplex, /* fortran double complex */
194 bt_Indirect = btIndirect, /* forward or unnamed typedef */
195 bt_FixedDec = btFixedDec, /* Fixed Decimal */
196 bt_FloatDec = btFloatDec, /* Float Decimal */
197 bt_String = btString, /* Varying Length Character String */
198 bt_Bit = btBit, /* Aligned Bit String */
199 bt_Picture = btPicture, /* Picture */
200 bt_Void = btVoid, /* void */
201 bt_Max = btMax /* Max basic type+1 */
202 } bt_t;
204 /* Redefinition of the language codes. */
206 typedef enum lang {
207 lang_C = langC,
208 lang_Pascal = langPascal,
209 lang_Fortran = langFortran,
210 lang_Assembler = langAssembler,
211 lang_Machine = langMachine,
212 lang_Nil = langNil,
213 lang_Ada = langAda,
214 lang_Pl1 = langPl1,
215 lang_Cobol = langCobol
216 } lang_t;
218 /* Redefinition of the debug level codes. */
220 typedef enum glevel {
221 glevel_0 = GLEVEL_0,
222 glevel_1 = GLEVEL_1,
223 glevel_2 = GLEVEL_2,
224 glevel_3 = GLEVEL_3
225 } glevel_t;
228 /* Keep track of the active scopes. */
229 typedef struct scope {
230 struct scope *prev; /* previous scope */
231 ulong open_sym; /* symbol opening scope */
232 sc_t sc; /* storage class */
233 st_t st; /* symbol type */
234 } scope_t;
236 struct filehdr global_hdr; /* a.out header */
238 int errors = 0; /* # of errors */
239 int want_aux = 0; /* print aux table */
240 int want_line = 0; /* print line numbers */
241 int want_rfd = 0; /* print relative file desc's */
242 int want_scope = 0; /* print scopes for every symbol */
243 int tfile = 0; /* no global header file */
244 int tfile_fd; /* file descriptor of .T file */
245 off_t tfile_offset; /* current offset in .T file */
246 scope_t *cur_scope = 0; /* list of active scopes */
247 scope_t *free_scope = 0; /* list of freed scopes */
248 HDRR sym_hdr; /* symbolic header */
249 char *l_strings; /* local strings */
250 char *e_strings; /* external strings */
251 SYMR *l_symbols; /* local symbols */
252 EXTR *e_symbols; /* external symbols */
253 LINER *lines; /* line numbers */
254 DNR *dense_nums; /* dense numbers */
255 OPTR *opt_symbols; /* optimization symbols */
256 AUXU *aux_symbols; /* Auxiliary symbols */
257 char *aux_used; /* map of which aux syms are used */
258 FDR *file_desc; /* file tables */
259 ulong *rfile_desc; /* relative file tables */
260 PDR *proc_desc; /* procedure tables */
262 /* Forward reference for functions. */
263 PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));
264 void read_tfile __proto((void));
265 void print_global_hdr __proto((struct filehdr *));
266 void print_sym_hdr __proto((HDRR *));
267 void print_file_desc __proto((FDR *, int));
268 void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));
269 void print_aux __proto((AUXU, int, int));
270 void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));
271 char *st_to_string __proto((st_t));
272 char *sc_to_string __proto((sc_t));
273 char *glevel_to_string __proto((glevel_t));
274 char *lang_to_string __proto((lang_t));
275 char *type_to_string __proto((AUXU *, int, FDR *));
277 #ifndef __alpha
278 extern PTR_T malloc __proto((size_t));
279 extern PTR_T calloc __proto((size_t, size_t));
280 extern PTR_T realloc __proto((PTR_T, size_t));
281 extern void free __proto((PTR_T));
282 #endif
284 extern char *optarg;
285 extern int optind;
286 extern int opterr;
288 /* Create a table of debugging stab-codes and corresponding names. */
290 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
291 struct {short code; char string[10];} stab_names[] = {
292 #include "stab.def"
293 #undef __define_stab
297 /* Read some bytes at a specified location, and return a pointer. */
299 PTR_T
300 read_seek (ptr, size, offset, context)
301 PTR_T ptr; /* pointer to buffer or NULL */
302 size_t size; /* # bytes to read */
303 off_t offset; /* offset to read at */
304 const char *context; /* context for error message */
306 long read_size = 0;
308 if (size == 0) /* nothing to read */
309 return ptr;
311 if ((ptr == (PTR_T) 0 && (ptr = malloc (size)) == (PTR_T) 0)
312 || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
313 || (read_size = read (tfile_fd, ptr, size)) < 0)
315 perror (context);
316 exit (1);
319 if (read_size != size)
321 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
322 context, read_size, (long) size);
323 exit (1);
326 tfile_offset = offset + size;
327 return ptr;
331 /* Convert language code to string format. */
333 char *
334 lang_to_string (lang)
335 lang_t lang;
337 switch (lang)
339 case langC: return "C";
340 case langPascal: return "Pascal";
341 case langFortran: return "Fortran";
342 case langAssembler: return "Assembler";
343 case langMachine: return "Machine";
344 case langNil: return "Nil";
345 case langAda: return "Ada";
346 case langPl1: return "Pl1";
347 case langCobol: return "Cobol";
350 return "Unknown language";
354 /* Convert storage class to string. */
356 char *
357 sc_to_string(storage_class)
358 sc_t storage_class;
360 switch(storage_class)
362 case sc_Nil: return "Nil";
363 case sc_Text: return "Text";
364 case sc_Data: return "Data";
365 case sc_Bss: return "Bss";
366 case sc_Register: return "Register";
367 case sc_Abs: return "Abs";
368 case sc_Undefined: return "Undefined";
369 case sc_CdbLocal: return "CdbLocal";
370 case sc_Bits: return "Bits";
371 case sc_CdbSystem: return "CdbSystem";
372 case sc_RegImage: return "RegImage";
373 case sc_Info: return "Info";
374 case sc_UserStruct: return "UserStruct";
375 case sc_SData: return "SData";
376 case sc_SBss: return "SBss";
377 case sc_RData: return "RData";
378 case sc_Var: return "Var";
379 case sc_Common: return "Common";
380 case sc_SCommon: return "SCommon";
381 case sc_VarRegister: return "VarRegister";
382 case sc_Variant: return "Variant";
383 case sc_SUndefined: return "SUndefined";
384 case sc_Init: return "Init";
385 case sc_Max: return "Max";
388 return "???";
392 /* Convert symbol type to string. */
394 char *
395 st_to_string(symbol_type)
396 st_t symbol_type;
398 switch(symbol_type)
400 case st_Nil: return "Nil";
401 case st_Global: return "Global";
402 case st_Static: return "Static";
403 case st_Param: return "Param";
404 case st_Local: return "Local";
405 case st_Label: return "Label";
406 case st_Proc: return "Proc";
407 case st_Block: return "Block";
408 case st_End: return "End";
409 case st_Member: return "Member";
410 case st_Typedef: return "Typedef";
411 case st_File: return "File";
412 case st_RegReloc: return "RegReloc";
413 case st_Forward: return "Forward";
414 case st_StaticProc: return "StaticProc";
415 case st_Constant: return "Constant";
416 case st_StaParam: return "StaticParam";
417 #ifdef stStruct
418 case st_Struct: return "Struct";
419 case st_Union: return "Union";
420 case st_Enum: return "Enum";
421 #endif
422 case st_Str: return "String";
423 case st_Number: return "Number";
424 case st_Expr: return "Expr";
425 case st_Type: return "Type";
426 case st_Max: return "Max";
429 return "???";
433 /* Convert debug level to string. */
435 char *
436 glevel_to_string (g_level)
437 glevel_t g_level;
439 switch(g_level)
441 case GLEVEL_0: return "G0";
442 case GLEVEL_1: return "G1";
443 case GLEVEL_2: return "G2";
444 case GLEVEL_3: return "G3";
447 return "??";
451 /* Convert the type information to string format. */
453 char *
454 type_to_string (aux_ptr, index, fdp)
455 AUXU *aux_ptr;
456 int index;
457 FDR *fdp;
459 AUXU u;
460 struct qual {
461 tq_t type;
462 int low_bound;
463 int high_bound;
464 int stride;
465 } qualifiers[7];
467 bt_t basic_type;
468 int i;
469 static char buffer1[1024];
470 static char buffer2[1024];
471 char *p1 = buffer1;
472 char *p2 = buffer2;
473 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
475 for (i = 0; i < 7; i++)
477 qualifiers[i].low_bound = 0;
478 qualifiers[i].high_bound = 0;
479 qualifiers[i].stride = 0;
482 used_ptr[index] = 1;
483 u = aux_ptr[index++];
484 if (u.isym == -1)
485 return "-1 (no type)";
487 basic_type = (bt_t) u.ti.bt;
488 qualifiers[0].type = (tq_t) u.ti.tq0;
489 qualifiers[1].type = (tq_t) u.ti.tq1;
490 qualifiers[2].type = (tq_t) u.ti.tq2;
491 qualifiers[3].type = (tq_t) u.ti.tq3;
492 qualifiers[4].type = (tq_t) u.ti.tq4;
493 qualifiers[5].type = (tq_t) u.ti.tq5;
494 qualifiers[6].type = tq_Nil;
497 * Go get the basic type.
499 switch (basic_type)
501 case bt_Nil: /* undefined */
502 strcpy (p1, "nil");
503 break;
505 case bt_Adr: /* address - integer same size as pointer */
506 strcpy (p1, "address");
507 break;
509 case bt_Char: /* character */
510 strcpy (p1, "char");
511 break;
513 case bt_UChar: /* unsigned character */
514 strcpy (p1, "unsigned char");
515 break;
517 case bt_Short: /* short */
518 strcpy (p1, "short");
519 break;
521 case bt_UShort: /* unsigned short */
522 strcpy (p1, "unsigned short");
523 break;
525 case bt_Int: /* int */
526 strcpy (p1, "int");
527 break;
529 case bt_UInt: /* unsigned int */
530 strcpy (p1, "unsigned int");
531 break;
533 case bt_Long: /* long */
534 strcpy (p1, "long");
535 break;
537 case bt_ULong: /* unsigned long */
538 strcpy (p1, "unsigned long");
539 break;
541 case bt_Float: /* float (real) */
542 strcpy (p1, "float");
543 break;
545 case bt_Double: /* Double (real) */
546 strcpy (p1, "double");
547 break;
549 /* Structures add 1-2 aux words:
550 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
551 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
553 case bt_Struct: /* Structure (Record) */
554 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
555 used_ptr[index] = 1;
556 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
557 used_ptr[++index] = 1;
559 index++; /* skip aux words */
560 break;
562 /* Unions add 1-2 aux words:
563 1st word is [ST_RFDESCAPE, offset] pointer to union def;
564 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
566 case bt_Union: /* Union */
567 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
568 used_ptr[index] = 1;
569 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
570 used_ptr[++index] = 1;
572 index++; /* skip aux words */
573 break;
575 /* Enumerations add 1-2 aux words:
576 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
577 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
579 case bt_Enum: /* Enumeration */
580 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
581 used_ptr[index] = 1;
582 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
583 used_ptr[++index] = 1;
585 index++; /* skip aux words */
586 break;
588 case bt_Typedef: /* defined via a typedef, isymRef points */
589 strcpy (p1, "typedef");
590 break;
592 case bt_Range: /* subrange of int */
593 strcpy (p1, "subrange");
594 break;
596 case bt_Set: /* pascal sets */
597 strcpy (p1, "set");
598 break;
600 case bt_Complex: /* fortran complex */
601 strcpy (p1, "complex");
602 break;
604 case bt_DComplex: /* fortran double complex */
605 strcpy (p1, "double complex");
606 break;
608 case bt_Indirect: /* forward or unnamed typedef */
609 strcpy (p1, "forward/unnamed typedef");
610 break;
612 case bt_FixedDec: /* Fixed Decimal */
613 strcpy (p1, "fixed decimal");
614 break;
616 case bt_FloatDec: /* Float Decimal */
617 strcpy (p1, "float decimal");
618 break;
620 case bt_String: /* Varying Length Character String */
621 strcpy (p1, "string");
622 break;
624 case bt_Bit: /* Aligned Bit String */
625 strcpy (p1, "bit");
626 break;
628 case bt_Picture: /* Picture */
629 strcpy (p1, "picture");
630 break;
632 case bt_Void: /* Void */
633 strcpy (p1, "void");
634 break;
636 default:
637 sprintf (p1, "Unknown basic type %d", (int) basic_type);
638 break;
641 p1 += strlen (buffer1);
644 * If this is a bitfield, get the bitsize.
646 if (u.ti.fBitfield)
648 int bitsize;
650 used_ptr[index] = 1;
651 bitsize = aux_ptr[index++].width;
652 sprintf (p1, " : %d", bitsize);
653 p1 += strlen (buffer1);
658 * Deal with any qualifiers.
660 if (qualifiers[0].type != tq_Nil)
663 * Snarf up any array bounds in the correct order. Arrays
664 * store 5 successive words in the aux. table:
665 * word 0 RNDXR to type of the bounds (ie, int)
666 * word 1 Current file descriptor index
667 * word 2 low bound
668 * word 3 high bound (or -1 if [])
669 * word 4 stride size in bits
671 for (i = 0; i < 7; i++)
673 if (qualifiers[i].type == tq_Array)
675 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
676 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
677 qualifiers[i].stride = aux_ptr[index+4].width;
678 used_ptr[index] = 1;
679 used_ptr[index+1] = 1;
680 used_ptr[index+2] = 1;
681 used_ptr[index+3] = 1;
682 used_ptr[index+4] = 1;
683 index += 5;
688 * Now print out the qualifiers.
690 for (i = 0; i < 6; i++)
692 switch (qualifiers[i].type)
694 case tq_Nil:
695 case tq_Max:
696 break;
698 case tq_Ptr:
699 strcpy (p2, "ptr to ");
700 p2 += sizeof ("ptr to ")-1;
701 break;
703 case tq_Vol:
704 strcpy (p2, "volatile ");
705 p2 += sizeof ("volatile ")-1;
706 break;
708 case tq_Far:
709 strcpy (p2, "far ");
710 p2 += sizeof ("far ")-1;
711 break;
713 case tq_Proc:
714 strcpy (p2, "func. ret. ");
715 p2 += sizeof ("func. ret. ");
716 break;
718 case tq_Array:
720 int first_array = i;
721 int j;
723 /* Print array bounds reversed (ie, in the order the C
724 programmer writes them). C is such a fun language.... */
726 while (i < 5 && qualifiers[i+1].type == tq_Array)
727 i++;
729 for (j = i; j >= first_array; j--)
731 strcpy (p2, "array [");
732 p2 += sizeof ("array [")-1;
733 if (qualifiers[j].low_bound != 0)
734 sprintf (p2,
735 "%ld:%ld {%ld bits}",
736 (long) qualifiers[j].low_bound,
737 (long) qualifiers[j].high_bound,
738 (long) qualifiers[j].stride);
740 else if (qualifiers[j].high_bound != -1)
741 sprintf (p2,
742 "%ld {%ld bits}",
743 (long) (qualifiers[j].high_bound + 1),
744 (long) (qualifiers[j].stride));
746 else
747 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
749 p2 += strlen (p2);
750 strcpy (p2, "] of ");
751 p2 += sizeof ("] of ")-1;
754 break;
759 strcpy (p2, buffer1);
760 return buffer2;
764 /* Print out the global file header for object files. */
766 void
767 print_global_hdr (ptr)
768 struct filehdr *ptr;
770 char *time = ctime ((time_t *)&ptr->f_timdat);
771 ushort flags = ptr->f_flags;
773 printf("Global file header:\n");
774 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
775 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
776 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
777 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
778 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
779 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
780 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
782 if ((flags & F_RELFLG) != 0)
783 printf (", F_RELFLG");
785 if ((flags & F_EXEC) != 0)
786 printf (", F_EXEC");
788 if ((flags & F_LNNO) != 0)
789 printf (", F_LNNO");
791 if ((flags & F_LSYMS) != 0)
792 printf (", F_LSYMS");
794 if ((flags & F_MINMAL) != 0)
795 printf (", F_MINMAL");
797 if ((flags & F_UPDATE) != 0)
798 printf (", F_UPDATE");
800 if ((flags & F_SWABD) != 0)
801 printf (", F_SWABD");
803 if ((flags & F_AR16WR) != 0)
804 printf (", F_AR16WR");
806 if ((flags & F_AR32WR) != 0)
807 printf (", F_AR32WR");
809 if ((flags & F_AR32W) != 0)
810 printf (", F_AR32W");
812 if ((flags & F_PATCH) != 0)
813 printf (", F_PATCH/F_NODF");
815 printf ("\n\n");
819 /* Print out the symbolic header. */
821 void
822 print_sym_hdr (sym_ptr)
823 HDRR *sym_ptr;
825 int width = 20;
827 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
828 sym_ptr->magic & 0xffff,
829 (sym_ptr->vstamp & 0xffff) >> 8,
830 sym_ptr->vstamp & 0xff);
832 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
833 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
835 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
836 (long) sym_ptr->cbLineOffset,
837 (long) sym_ptr->cbLine,
838 (long) sym_ptr->cbLine,
839 (int) sym_ptr->ilineMax);
841 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
842 (long) sym_ptr->cbDnOffset,
843 (long) sym_ptr->idnMax,
844 (long) (sym_ptr->idnMax * sizeof (DNR)));
846 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
847 (long) sym_ptr->cbPdOffset,
848 (long) sym_ptr->ipdMax,
849 (long) (sym_ptr->ipdMax * sizeof (PDR)));
851 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
852 (long) sym_ptr->cbSymOffset,
853 (long) sym_ptr->isymMax,
854 (long) (sym_ptr->isymMax * sizeof (SYMR)));
856 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
857 (long) sym_ptr->cbOptOffset,
858 (long) sym_ptr->ioptMax,
859 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
861 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
862 (long) sym_ptr->cbAuxOffset,
863 (long) sym_ptr->iauxMax,
864 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
866 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
867 (long) sym_ptr->cbSsOffset,
868 (long) sym_ptr->issMax,
869 (long) sym_ptr->issMax);
871 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
872 (long) sym_ptr->cbSsExtOffset,
873 (long) sym_ptr->issExtMax,
874 (long) sym_ptr->issExtMax);
876 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
877 (long) sym_ptr->cbFdOffset,
878 (long) sym_ptr->ifdMax,
879 (long) (sym_ptr->ifdMax * sizeof (FDR)));
881 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
882 (long) sym_ptr->cbRfdOffset,
883 (long) sym_ptr->crfd,
884 (long) (sym_ptr->crfd * sizeof (ulong)));
886 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
887 (long) sym_ptr->cbExtOffset,
888 (long) sym_ptr->iextMax,
889 (long) (sym_ptr->iextMax * sizeof (EXTR)));
893 /* Print out a symbol. */
895 void
896 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
897 SYMR *sym_ptr;
898 int number;
899 char *strbase;
900 AUXU *aux_base;
901 int ifd;
902 FDR *fdp;
904 sc_t storage_class = (sc_t) sym_ptr->sc;
905 st_t symbol_type = (st_t) sym_ptr->st;
906 ulong index = sym_ptr->index;
907 char *used_ptr = aux_used + (aux_base - aux_symbols);
908 scope_t *scope_ptr;
910 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
912 if (aux_base != (AUXU *) 0 && index != indexNil)
913 switch (symbol_type)
915 case st_Nil:
916 case st_Label:
917 break;
919 case st_File:
920 case st_Block:
921 printf (" End+1 symbol: %ld\n", index);
922 if (want_scope)
924 if (free_scope == (scope_t *) 0)
925 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
926 else
928 scope_ptr = free_scope;
929 free_scope = scope_ptr->prev;
931 scope_ptr->open_sym = number;
932 scope_ptr->st = symbol_type;
933 scope_ptr->sc = storage_class;
934 scope_ptr->prev = cur_scope;
935 cur_scope = scope_ptr;
937 break;
939 case st_End:
940 if (storage_class == sc_Text || storage_class == sc_Info)
941 printf (" First symbol: %ld\n", index);
942 else
944 used_ptr[index] = 1;
945 printf (" First symbol: %ld\n", aux_base[index].isym);
948 if (want_scope)
950 if (cur_scope == (scope_t *) 0)
951 printf (" Can't pop end scope\n");
952 else
954 scope_ptr = cur_scope;
955 cur_scope = scope_ptr->prev;
956 scope_ptr->prev = free_scope;
957 free_scope = scope_ptr;
960 break;
962 case st_Proc:
963 case st_StaticProc:
964 if (MIPS_IS_STAB(sym_ptr))
966 else if (ifd == -1) /* local symbol */
968 used_ptr[index] = used_ptr[index+1] = 1;
969 printf (" End+1 symbol: %-7ld Type: %s\n",
970 aux_base[index].isym,
971 type_to_string (aux_base, index+1, fdp));
973 else /* global symbol */
974 printf (" Local symbol: %ld\n", index);
976 if (want_scope)
978 if (free_scope == (scope_t *) 0)
979 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
980 else
982 scope_ptr = free_scope;
983 free_scope = scope_ptr->prev;
985 scope_ptr->open_sym = number;
986 scope_ptr->st = symbol_type;
987 scope_ptr->sc = storage_class;
988 scope_ptr->prev = cur_scope;
989 cur_scope = scope_ptr;
991 break;
993 #ifdef stStruct
994 case st_Struct:
995 case st_Union:
996 case st_Enum:
997 printf (" End+1 symbol: %lu\n", index);
998 break;
999 #endif
1001 default:
1002 if (!MIPS_IS_STAB (sym_ptr))
1004 used_ptr[index] = 1;
1005 printf (" Type: %s\n",
1006 type_to_string (aux_base, index, fdp));
1008 break;
1011 if (want_scope)
1013 printf (" Scopes: ");
1014 if (cur_scope == (scope_t *) 0)
1015 printf (" none\n");
1016 else
1018 for (scope_ptr = cur_scope;
1019 scope_ptr != (scope_t *) 0;
1020 scope_ptr = scope_ptr->prev)
1022 char *class;
1023 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1024 class = "func.";
1025 else if (scope_ptr->st == st_File)
1026 class = "file";
1027 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1028 class = "block";
1029 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1030 class = "type";
1031 else
1032 class = "???";
1034 printf (" %ld [%s]", scope_ptr->open_sym, class);
1036 printf ("\n");
1040 printf (" Value: %-13ld ",
1041 (long)sym_ptr->value);
1042 if (ifd == -1)
1043 printf ("String index: %ld\n", (long)sym_ptr->iss);
1044 else
1045 printf ("String index: %-11ld Ifd: %d\n",
1046 (long)sym_ptr->iss, ifd);
1048 printf (" Symbol type: %-11sStorage class: %-11s",
1049 st_to_string (symbol_type), sc_to_string (storage_class));
1051 if (MIPS_IS_STAB(sym_ptr))
1053 register int i = sizeof(stab_names) / sizeof(stab_names[0]);
1054 char *stab_name = "stab";
1055 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1056 while (--i >= 0)
1057 if (stab_names[i].code == code)
1059 stab_name = stab_names[i].string;
1060 break;
1062 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1064 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1065 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1066 else
1067 printf ("Index: %ld\n", (long)sym_ptr->index);
1072 /* Print out a word from the aux. table in various formats. */
1074 void
1075 print_aux (u, auxi, used)
1076 AUXU u;
1077 int auxi;
1078 int used;
1080 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1081 (used) ? " " : "* ",
1082 auxi,
1083 (long) u.isym,
1084 (long) u.rndx.rfd,
1085 (long) u.rndx.index,
1086 u.ti.bt,
1087 u.ti.fBitfield,
1088 u.ti.continued,
1089 u.ti.tq0,
1090 u.ti.tq1,
1091 u.ti.tq2,
1092 u.ti.tq3,
1093 u.ti.tq4,
1094 u.ti.tq5);
1098 /* Write aggregate information to a string. */
1100 void
1101 emit_aggregate (string, u, u2, which, fdp)
1102 char *string;
1103 AUXU u;
1104 AUXU u2;
1105 const char *which;
1106 FDR *fdp;
1108 unsigned int ifd = u.rndx.rfd;
1109 unsigned int index = u.rndx.index;
1110 const char *name;
1112 if (ifd == ST_RFDESCAPE)
1113 ifd = u2.isym;
1115 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1116 struct return type of a procedure compiled without -g. */
1117 if (ifd == 0xffffffff
1118 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
1119 name = "<undefined>";
1120 else if (index == indexNil)
1121 name = "<no name>";
1122 else
1124 if (fdp == 0 || sym_hdr.crfd == 0)
1125 fdp = &file_desc[ifd];
1126 else
1127 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1128 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1131 sprintf (string,
1132 "%s %s { ifd = %u, index = %u }",
1133 which, name, ifd, index);
1137 /* Print out information about a file descriptor, and the symbols,
1138 procedures, and line numbers within it. */
1140 void
1141 print_file_desc (fdp, number)
1142 FDR *fdp;
1143 int number;
1145 char *str_base;
1146 AUXU *aux_base;
1147 int symi, pdi;
1148 int width = 20;
1149 char *used_base;
1151 str_base = l_strings + fdp->issBase;
1152 aux_base = aux_symbols + fdp->iauxBase;
1153 used_base = aux_used + (aux_base - aux_symbols);
1155 printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss);
1157 printf (" Name index = %-10ld Readin = %s\n",
1158 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1160 printf (" Merge = %-10s Endian = %s\n",
1161 (fdp->fMerge) ? "Yes" : "No",
1162 (fdp->fBigendian) ? "BIG" : "LITTLE");
1164 printf (" Debug level = %-10s Language = %s\n",
1165 glevel_to_string (fdp->glevel),
1166 lang_to_string((lang_t) fdp->lang));
1168 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1170 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1171 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1173 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1174 width, "Local strings",
1175 (ulong) fdp->issBase,
1176 (ulong) fdp->cbSs,
1177 (ulong) fdp->cbSs,
1178 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1180 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1181 width, "Local symbols",
1182 (ulong) fdp->isymBase,
1183 (ulong) fdp->csym,
1184 (ulong) (fdp->csym * sizeof (SYMR)),
1185 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1187 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1188 width, "Line numbers",
1189 (ulong) fdp->cbLineOffset,
1190 (ulong) fdp->cline,
1191 (ulong) fdp->cbLine,
1192 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1194 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1195 width, "Optimization symbols",
1196 (ulong) fdp->ioptBase,
1197 (ulong) fdp->copt,
1198 (ulong) (fdp->copt * sizeof (OPTR)),
1199 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1201 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1202 width, "Procedures",
1203 (ulong) fdp->ipdFirst,
1204 (ulong) fdp->cpd,
1205 (ulong) (fdp->cpd * sizeof (PDR)),
1206 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1208 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1209 width, "Auxiliary symbols",
1210 (ulong) fdp->iauxBase,
1211 (ulong) fdp->caux,
1212 (ulong) (fdp->caux * sizeof (AUXU)),
1213 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1215 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1216 width, "Relative Files",
1217 (ulong) fdp->rfdBase,
1218 (ulong) fdp->crfd,
1219 (ulong) (fdp->crfd * sizeof (ulong)),
1220 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1223 if (want_scope && cur_scope != (scope_t *) 0)
1224 printf ("\n Warning scope does not start at 0!\n");
1227 * print the info about the symbol table.
1229 printf ("\n There are %lu local symbols, starting at %lu\n",
1230 (ulong) fdp->csym,
1231 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1233 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1234 print_symbol (&l_symbols[symi],
1235 symi - fdp->isymBase,
1236 str_base,
1237 aux_base,
1239 fdp);
1241 if (want_scope && cur_scope != (scope_t *) 0)
1242 printf ("\n Warning scope does not end at 0!\n");
1245 * print the aux. table if desired.
1248 if (want_aux && fdp->caux != 0)
1250 int auxi;
1252 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1253 (ulong) fdp->caux,
1254 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1256 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1257 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1261 * print the relative file descriptors.
1263 if (want_rfd && fdp->crfd != 0)
1265 ulong *rfd_ptr, i;
1267 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1268 (ulong) fdp->crfd,
1269 (ulong) fdp->rfdBase);
1271 rfd_ptr = rfile_desc + fdp->rfdBase;
1272 for (i = 0; i < fdp->crfd; i++)
1274 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1275 rfd_ptr++;
1280 * do the procedure descriptors.
1282 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1283 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1285 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1287 PDR *proc_ptr = &proc_desc[pdi];
1288 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1290 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1291 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1292 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1294 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1295 (long) proc_ptr->regmask,
1296 (long) proc_ptr->regoffset,
1297 (long) proc_ptr->fregmask,
1298 (long) proc_ptr->fregoffset);
1300 printf ("\t .frame $%d,%ld,$%d\n",
1301 (int) proc_ptr->framereg,
1302 (long) proc_ptr->frameoffset,
1303 (int) proc_ptr->pcreg);
1305 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1306 (long) proc_ptr->iopt,
1307 (long) proc_ptr->isym);
1309 printf ("\t First line # = %-11ld Last line # = %ld\n",
1310 (long) proc_ptr->lnLow,
1311 (long) proc_ptr->lnHigh);
1313 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1314 (long) proc_ptr->cbLineOffset,
1315 (long) proc_ptr->adr);
1318 * print the line number entries.
1321 if (want_line && fdp->cline != 0)
1323 int delta, count;
1324 long cur_line = proc_ptr->lnLow;
1325 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1326 + fdp->cbLineOffset);
1327 uchar *line_end;
1329 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1330 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1331 else /* not last proc. */
1332 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1333 + fdp->cbLineOffset);
1335 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1336 (ulong) (line_end - line_ptr),
1337 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1339 while (line_ptr < line_end)
1340 { /* sign extend nibble */
1341 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1342 count = (*line_ptr & 0xf) + 1;
1343 if (delta != -8)
1344 line_ptr++;
1345 else
1347 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1348 delta = (delta ^ 0x8000) - 0x8000;
1349 line_ptr += 3;
1352 cur_line += delta;
1353 printf ("\t Line %11ld, delta %5d, count %2d\n",
1354 cur_line,
1355 delta,
1356 count);
1363 /* Read in the portions of the .T file that we will print out. */
1365 void
1366 read_tfile __proto((void))
1368 short magic;
1369 off_t sym_hdr_offset = 0;
1371 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number");
1372 if (!tfile)
1374 /* Print out the global header, since this is not a T-file. */
1376 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0,
1377 "Global file header");
1379 print_global_hdr (&global_hdr);
1381 if (global_hdr.f_symptr == 0)
1383 printf ("No symbolic header, Goodbye!\n");
1384 exit (1);
1387 sym_hdr_offset = global_hdr.f_symptr;
1390 (void) read_seek ((PTR_T) &sym_hdr,
1391 sizeof (sym_hdr),
1392 sym_hdr_offset,
1393 "Symbolic header");
1395 print_sym_hdr (&sym_hdr);
1397 lines = (LINER *) read_seek ((PTR_T) 0,
1398 sym_hdr.cbLine,
1399 sym_hdr.cbLineOffset,
1400 "Line numbers");
1402 dense_nums = (DNR *) read_seek ((PTR_T) 0,
1403 sym_hdr.idnMax * sizeof (DNR),
1404 sym_hdr.cbDnOffset,
1405 "Dense numbers");
1407 proc_desc = (PDR *) read_seek ((PTR_T) 0,
1408 sym_hdr.ipdMax * sizeof (PDR),
1409 sym_hdr.cbPdOffset,
1410 "Procedure tables");
1412 l_symbols = (SYMR *) read_seek ((PTR_T) 0,
1413 sym_hdr.isymMax * sizeof (SYMR),
1414 sym_hdr.cbSymOffset,
1415 "Local symbols");
1417 opt_symbols = (OPTR *) read_seek ((PTR_T) 0,
1418 sym_hdr.ioptMax * sizeof (OPTR),
1419 sym_hdr.cbOptOffset,
1420 "Optimization symbols");
1422 aux_symbols = (AUXU *) read_seek ((PTR_T) 0,
1423 sym_hdr.iauxMax * sizeof (AUXU),
1424 sym_hdr.cbAuxOffset,
1425 "Auxiliary symbols");
1427 if (sym_hdr.iauxMax > 0)
1429 aux_used = calloc (sym_hdr.iauxMax, 1);
1430 if (aux_used == (char *) 0)
1432 perror ("calloc");
1433 exit (1);
1437 l_strings = (char *) read_seek ((PTR_T) 0,
1438 sym_hdr.issMax,
1439 sym_hdr.cbSsOffset,
1440 "Local string table");
1442 e_strings = (char *) read_seek ((PTR_T) 0,
1443 sym_hdr.issExtMax,
1444 sym_hdr.cbSsExtOffset,
1445 "External string table");
1447 file_desc = (FDR *) read_seek ((PTR_T) 0,
1448 sym_hdr.ifdMax * sizeof (FDR),
1449 sym_hdr.cbFdOffset,
1450 "File tables");
1452 rfile_desc = (ulong *) read_seek ((PTR_T) 0,
1453 sym_hdr.crfd * sizeof (ulong),
1454 sym_hdr.cbRfdOffset,
1455 "Relative file tables");
1457 e_symbols = (EXTR *) read_seek ((PTR_T) 0,
1458 sym_hdr.iextMax * sizeof (EXTR),
1459 sym_hdr.cbExtOffset,
1460 "External symbols");
1466 main (argc, argv)
1467 int argc;
1468 char **argv;
1470 int i, opt;
1473 * Process arguments
1475 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1476 switch (opt)
1478 default: errors++; break;
1479 case 'a': want_aux++; break; /* print aux table */
1480 case 'l': want_line++; break; /* print line numbers */
1481 case 'r': want_rfd++; break; /* print relative fd's */
1482 case 's': want_scope++; break; /* print scope info */
1483 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1486 if (errors || optind != argc - 1)
1488 fprintf (stderr, "Calling Sequence:\n");
1489 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1490 fprintf (stderr, "\n");
1491 fprintf (stderr, "switches:\n");
1492 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1493 fprintf (stderr, "\t-l Print out line numbers.\n");
1494 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1495 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1496 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1497 return 1;
1501 * Open and process the input file.
1503 tfile_fd = open (argv[optind], O_RDONLY);
1504 if (tfile_fd < 0)
1506 perror (argv[optind]);
1507 return 1;
1510 read_tfile ();
1513 * Print any global aux words if any.
1515 if (want_aux)
1517 long last_aux_in_use;
1519 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1521 printf ("\nGlobal auxiliary entries before first file:\n");
1522 for (i = 0; i < file_desc[0].iauxBase; i++)
1523 print_aux (aux_symbols[i], 0, aux_used[i]);
1526 if (sym_hdr.ifdMax == 0)
1527 last_aux_in_use = 0;
1528 else
1529 last_aux_in_use =
1530 file_desc[sym_hdr.ifdMax-1].iauxBase +
1531 file_desc[sym_hdr.ifdMax-1].caux - 1;
1533 if (last_aux_in_use < sym_hdr.iauxMax-1)
1535 printf ("\nGlobal auxiliary entries after last file:\n");
1536 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1537 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1542 * Print the information for each file.
1544 for (i = 0; i < sym_hdr.ifdMax; i++)
1545 print_file_desc (&file_desc[i], i);
1548 * Print the external symbols.
1550 want_scope = 0; /* scope info is meaning for extern symbols */
1551 printf ("\nThere are %lu external symbols, starting at %lu\n",
1552 (ulong) sym_hdr.iextMax,
1553 (ulong) sym_hdr.cbExtOffset);
1555 for(i = 0; i < sym_hdr.iextMax; i++)
1556 print_symbol (&e_symbols[i].asym, i, e_strings,
1557 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1558 e_symbols[i].ifd,
1559 &file_desc[e_symbols[i].ifd]);
1562 * Print unused aux symbols now.
1565 if (want_aux)
1567 int first_time = 1;
1569 for (i = 0; i < sym_hdr.iauxMax; i++)
1571 if (! aux_used[i])
1573 if (first_time)
1575 printf ("\nThe following auxiliary table entries were unused:\n\n");
1576 first_time = 0;
1579 printf (" #%-5d %11ld 0x%08lx %s\n",
1581 (long) aux_symbols[i].isym,
1582 (long) aux_symbols[i].isym,
1583 type_to_string (aux_symbols, i, (FDR *) 0));
1588 return 0;
1592 void
1593 fancy_abort ()
1595 fprintf (stderr, "mips-tdump internal error");
1596 exit (1);
1599 void
1600 fatal(s)
1601 char *s;
1603 fprintf(stderr, "%s\n", s);
1604 exit(1);
1607 /* Same as `malloc' but report error if no memory available. */
1609 PTR_T
1610 xmalloc (size)
1611 unsigned size;
1613 register PTR_T value = malloc (size);
1614 if (value == 0)
1615 fatal ("Virtual memory exhausted.");
1616 return value;