Daily bump.
[official-gcc.git] / gcc / mips-tdump.c
blob9d3143d1028192fb610e4d9df6ef013e9f602321
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999 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 "config.h"
24 #include "system.h"
26 #ifdef index
27 #undef index
28 #undef rindex
29 #endif
30 #ifndef CROSS_COMPILE
31 #include <a.out.h>
32 #else
33 #include "mips/a.out.h"
34 #endif /* CROSS_COMPILE */
36 #ifndef MIPS_IS_STAB
37 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
38 and mips-tdump.c to print them out. This is used on the Alpha,
39 which does not include mips.h.
41 These must match the corresponding definitions in gdb/mipsread.c.
42 Unfortunately, gcc and gdb do not currently share any directories. */
44 #define CODE_MASK 0x8F300
45 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
46 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
47 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
48 #endif
50 #define __proto(x) PARAMS(x)
51 typedef PTR PTR_T;
52 typedef const PTR_T CPTR_T;
54 #define uchar unsigned char
55 #define ushort unsigned short
56 #define uint unsigned int
57 #define ulong unsigned long
60 static void
61 fatal(s)
62 const char *s;
64 fprintf(stderr, "%s\n", s);
65 exit(FATAL_EXIT_CODE);
68 /* Same as `malloc' but report error if no memory available. */
69 /* Do this before size_t is fiddled with so it matches the prototype
70 in libiberty.h . */
71 PTR
72 xmalloc (size)
73 size_t size;
75 register PTR value = (PTR) malloc (size);
76 if (value == 0)
77 fatal ("Virtual memory exhausted.");
78 return value;
81 /* Due to size_t being defined in sys/types.h and different
82 in stddef.h, we have to do this by hand..... Note, these
83 types are correct for MIPS based systems, and may not be
84 correct for other systems. */
86 #define size_t uint
87 #define ptrdiff_t int
90 /* Redefinition of storage classes as an enumeration for better
91 debugging. */
93 #ifndef stStaParam
94 #define stStaParam 16 /* Fortran static parameters */
95 #endif
97 #ifndef btVoid
98 #define btVoid 26 /* void basic type */
99 #endif
101 typedef enum sc {
102 sc_Nil = scNil, /* no storage class */
103 sc_Text = scText, /* text symbol */
104 sc_Data = scData, /* initialized data symbol */
105 sc_Bss = scBss, /* un-initialized data symbol */
106 sc_Register = scRegister, /* value of symbol is register number */
107 sc_Abs = scAbs, /* value of symbol is absolute */
108 sc_Undefined = scUndefined, /* who knows? */
109 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
110 sc_Bits = scBits, /* this is a bit field */
111 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
112 sc_RegImage = scRegImage, /* register value saved on stack */
113 sc_Info = scInfo, /* symbol contains debugger information */
114 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
115 sc_SData = scSData, /* load time only small data */
116 sc_SBss = scSBss, /* load time only small common */
117 sc_RData = scRData, /* load time only read only data */
118 sc_Var = scVar, /* Var parameter (fortran,pascal) */
119 sc_Common = scCommon, /* common variable */
120 sc_SCommon = scSCommon, /* small common */
121 sc_VarRegister = scVarRegister, /* Var parameter in a register */
122 sc_Variant = scVariant, /* Variant record */
123 sc_SUndefined = scSUndefined, /* small undefined(external) data */
124 sc_Init = scInit, /* .init section symbol */
125 sc_Max = scMax /* Max storage class+1 */
126 } sc_t;
128 /* Redefinition of symbol type. */
130 typedef enum st {
131 st_Nil = stNil, /* Nuthin' special */
132 st_Global = stGlobal, /* external symbol */
133 st_Static = stStatic, /* static */
134 st_Param = stParam, /* procedure argument */
135 st_Local = stLocal, /* local variable */
136 st_Label = stLabel, /* label */
137 st_Proc = stProc, /* " " Procedure */
138 st_Block = stBlock, /* beginning of block */
139 st_End = stEnd, /* end (of anything) */
140 st_Member = stMember, /* member (of anything - struct/union/enum */
141 st_Typedef = stTypedef, /* type definition */
142 st_File = stFile, /* file name */
143 st_RegReloc = stRegReloc, /* register relocation */
144 st_Forward = stForward, /* forwarding address */
145 st_StaticProc = stStaticProc, /* load time only static procs */
146 st_StaParam = stStaParam, /* Fortran static parameters */
147 st_Constant = stConstant, /* const */
148 #ifdef stStruct
149 st_Struct = stStruct, /* struct */
150 st_Union = stUnion, /* union */
151 st_Enum = stEnum, /* enum */
152 #endif
153 st_Str = stStr, /* string */
154 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
155 st_Expr = stExpr, /* 2+2 vs. 4 */
156 st_Type = stType, /* post-coercion SER */
157 st_Max = stMax /* max type+1 */
158 } st_t;
160 /* Redefinition of type qualifiers. */
162 typedef enum tq {
163 tq_Nil = tqNil, /* bt is what you see */
164 tq_Ptr = tqPtr, /* pointer */
165 tq_Proc = tqProc, /* procedure */
166 tq_Array = tqArray, /* duh */
167 tq_Far = tqFar, /* longer addressing - 8086/8 land */
168 tq_Vol = tqVol, /* volatile */
169 tq_Max = tqMax /* Max type qualifier+1 */
170 } tq_t;
172 /* Redefinition of basic types. */
174 typedef enum bt {
175 bt_Nil = btNil, /* undefined */
176 bt_Adr = btAdr, /* address - integer same size as pointer */
177 bt_Char = btChar, /* character */
178 bt_UChar = btUChar, /* unsigned character */
179 bt_Short = btShort, /* short */
180 bt_UShort = btUShort, /* unsigned short */
181 bt_Int = btInt, /* int */
182 bt_UInt = btUInt, /* unsigned int */
183 bt_Long = btLong, /* long */
184 bt_ULong = btULong, /* unsigned long */
185 bt_Float = btFloat, /* float (real) */
186 bt_Double = btDouble, /* Double (real) */
187 bt_Struct = btStruct, /* Structure (Record) */
188 bt_Union = btUnion, /* Union (variant) */
189 bt_Enum = btEnum, /* Enumerated */
190 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
191 bt_Range = btRange, /* subrange of int */
192 bt_Set = btSet, /* pascal sets */
193 bt_Complex = btComplex, /* fortran complex */
194 bt_DComplex = btDComplex, /* fortran double complex */
195 bt_Indirect = btIndirect, /* forward or unnamed typedef */
196 bt_FixedDec = btFixedDec, /* Fixed Decimal */
197 bt_FloatDec = btFloatDec, /* Float Decimal */
198 bt_String = btString, /* Varying Length Character String */
199 bt_Bit = btBit, /* Aligned Bit String */
200 bt_Picture = btPicture, /* Picture */
201 bt_Void = btVoid, /* void */
202 bt_Max = btMax /* Max basic type+1 */
203 } bt_t;
205 /* Redefinition of the language codes. */
207 typedef enum lang {
208 lang_C = langC,
209 lang_Pascal = langPascal,
210 lang_Fortran = langFortran,
211 lang_Assembler = langAssembler,
212 lang_Machine = langMachine,
213 lang_Nil = langNil,
214 lang_Ada = langAda,
215 lang_Pl1 = langPl1,
216 lang_Cobol = langCobol
217 } lang_t;
219 /* Redefinition of the debug level codes. */
221 typedef enum glevel {
222 glevel_0 = GLEVEL_0,
223 glevel_1 = GLEVEL_1,
224 glevel_2 = GLEVEL_2,
225 glevel_3 = GLEVEL_3
226 } glevel_t;
229 /* Keep track of the active scopes. */
230 typedef struct scope {
231 struct scope *prev; /* previous scope */
232 ulong open_sym; /* symbol opening scope */
233 sc_t sc; /* storage class */
234 st_t st; /* symbol type */
235 } scope_t;
237 struct filehdr global_hdr; /* a.out header */
239 int errors = 0; /* # of errors */
240 int want_aux = 0; /* print aux table */
241 int want_line = 0; /* print line numbers */
242 int want_rfd = 0; /* print relative file desc's */
243 int want_scope = 0; /* print scopes for every symbol */
244 int tfile = 0; /* no global header file */
245 int tfile_fd; /* file descriptor of .T file */
246 off_t tfile_offset; /* current offset in .T file */
247 scope_t *cur_scope = 0; /* list of active scopes */
248 scope_t *free_scope = 0; /* list of freed scopes */
249 HDRR sym_hdr; /* symbolic header */
250 char *l_strings; /* local strings */
251 char *e_strings; /* external strings */
252 SYMR *l_symbols; /* local symbols */
253 EXTR *e_symbols; /* external symbols */
254 LINER *lines; /* line numbers */
255 DNR *dense_nums; /* dense numbers */
256 OPTR *opt_symbols; /* optimization symbols */
257 AUXU *aux_symbols; /* Auxiliary symbols */
258 char *aux_used; /* map of which aux syms are used */
259 FDR *file_desc; /* file tables */
260 ulong *rfile_desc; /* relative file tables */
261 PDR *proc_desc; /* procedure tables */
263 /* Forward reference for functions. */
264 PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));
265 void read_tfile __proto((void));
266 void print_global_hdr __proto((struct filehdr *));
267 void print_sym_hdr __proto((HDRR *));
268 void print_file_desc __proto((FDR *, int));
269 void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));
270 void print_aux __proto((AUXU, int, int));
271 void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));
272 const char *st_to_string __proto((st_t));
273 const char *sc_to_string __proto((sc_t));
274 const char *glevel_to_string __proto((glevel_t));
275 const char *lang_to_string __proto((lang_t));
276 const char *type_to_string __proto((AUXU *, int, FDR *));
278 #ifndef __alpha
279 # ifdef NEED_DECLARATION_MALLOC
280 extern PTR_T malloc __proto((size_t));
281 # endif
282 # ifdef NEED_DECLARATION_CALLOC
283 extern PTR_T calloc __proto((size_t, size_t));
284 # endif
285 # ifdef NEED_DECLARATION_REALLOC
286 extern PTR_T realloc __proto((PTR_T, size_t));
287 # endif
288 #endif
290 extern char *optarg;
291 extern int optind;
292 extern int opterr;
294 /* Create a table of debugging stab-codes and corresponding names. */
296 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
297 struct {short code; char string[10];} stab_names[] = {
298 #include "stab.def"
299 #undef __define_stab
303 /* Read some bytes at a specified location, and return a pointer. */
305 PTR_T
306 read_seek (ptr, size, offset, context)
307 PTR_T ptr; /* pointer to buffer or NULL */
308 size_t size; /* # bytes to read */
309 off_t offset; /* offset to read at */
310 const char *context; /* context for error message */
312 long read_size = 0;
314 if (size == 0) /* nothing to read */
315 return ptr;
317 if ((ptr == (PTR_T) 0 && (ptr = malloc (size)) == (PTR_T) 0)
318 || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
319 || (read_size = read (tfile_fd, ptr, size)) < 0)
321 perror (context);
322 exit (1);
325 if (read_size != size)
327 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
328 context, read_size, (long) size);
329 exit (1);
332 tfile_offset = offset + size;
333 return ptr;
337 /* Convert language code to string format. */
339 const char *
340 lang_to_string (lang)
341 lang_t lang;
343 switch (lang)
345 case langC: return "C";
346 case langPascal: return "Pascal";
347 case langFortran: return "Fortran";
348 case langAssembler: return "Assembler";
349 case langMachine: return "Machine";
350 case langNil: return "Nil";
351 case langAda: return "Ada";
352 case langPl1: return "Pl1";
353 case langCobol: return "Cobol";
356 return "Unknown language";
360 /* Convert storage class to string. */
362 const char *
363 sc_to_string(storage_class)
364 sc_t storage_class;
366 switch(storage_class)
368 case sc_Nil: return "Nil";
369 case sc_Text: return "Text";
370 case sc_Data: return "Data";
371 case sc_Bss: return "Bss";
372 case sc_Register: return "Register";
373 case sc_Abs: return "Abs";
374 case sc_Undefined: return "Undefined";
375 case sc_CdbLocal: return "CdbLocal";
376 case sc_Bits: return "Bits";
377 case sc_CdbSystem: return "CdbSystem";
378 case sc_RegImage: return "RegImage";
379 case sc_Info: return "Info";
380 case sc_UserStruct: return "UserStruct";
381 case sc_SData: return "SData";
382 case sc_SBss: return "SBss";
383 case sc_RData: return "RData";
384 case sc_Var: return "Var";
385 case sc_Common: return "Common";
386 case sc_SCommon: return "SCommon";
387 case sc_VarRegister: return "VarRegister";
388 case sc_Variant: return "Variant";
389 case sc_SUndefined: return "SUndefined";
390 case sc_Init: return "Init";
391 case sc_Max: return "Max";
394 return "???";
398 /* Convert symbol type to string. */
400 const char *
401 st_to_string(symbol_type)
402 st_t symbol_type;
404 switch(symbol_type)
406 case st_Nil: return "Nil";
407 case st_Global: return "Global";
408 case st_Static: return "Static";
409 case st_Param: return "Param";
410 case st_Local: return "Local";
411 case st_Label: return "Label";
412 case st_Proc: return "Proc";
413 case st_Block: return "Block";
414 case st_End: return "End";
415 case st_Member: return "Member";
416 case st_Typedef: return "Typedef";
417 case st_File: return "File";
418 case st_RegReloc: return "RegReloc";
419 case st_Forward: return "Forward";
420 case st_StaticProc: return "StaticProc";
421 case st_Constant: return "Constant";
422 case st_StaParam: return "StaticParam";
423 #ifdef stStruct
424 case st_Struct: return "Struct";
425 case st_Union: return "Union";
426 case st_Enum: return "Enum";
427 #endif
428 case st_Str: return "String";
429 case st_Number: return "Number";
430 case st_Expr: return "Expr";
431 case st_Type: return "Type";
432 case st_Max: return "Max";
435 return "???";
439 /* Convert debug level to string. */
441 const char *
442 glevel_to_string (g_level)
443 glevel_t g_level;
445 switch(g_level)
447 case GLEVEL_0: return "G0";
448 case GLEVEL_1: return "G1";
449 case GLEVEL_2: return "G2";
450 case GLEVEL_3: return "G3";
453 return "??";
457 /* Convert the type information to string format. */
459 const char *
460 type_to_string (aux_ptr, index, fdp)
461 AUXU *aux_ptr;
462 int index;
463 FDR *fdp;
465 AUXU u;
466 struct qual {
467 tq_t type;
468 int low_bound;
469 int high_bound;
470 int stride;
471 } qualifiers[7];
473 bt_t basic_type;
474 int i;
475 static char buffer1[1024];
476 static char buffer2[1024];
477 char *p1 = buffer1;
478 char *p2 = buffer2;
479 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
481 for (i = 0; i < 7; i++)
483 qualifiers[i].low_bound = 0;
484 qualifiers[i].high_bound = 0;
485 qualifiers[i].stride = 0;
488 used_ptr[index] = 1;
489 u = aux_ptr[index++];
490 if (u.isym == -1)
491 return "-1 (no type)";
493 basic_type = (bt_t) u.ti.bt;
494 qualifiers[0].type = (tq_t) u.ti.tq0;
495 qualifiers[1].type = (tq_t) u.ti.tq1;
496 qualifiers[2].type = (tq_t) u.ti.tq2;
497 qualifiers[3].type = (tq_t) u.ti.tq3;
498 qualifiers[4].type = (tq_t) u.ti.tq4;
499 qualifiers[5].type = (tq_t) u.ti.tq5;
500 qualifiers[6].type = tq_Nil;
503 * Go get the basic type.
505 switch (basic_type)
507 case bt_Nil: /* undefined */
508 strcpy (p1, "nil");
509 break;
511 case bt_Adr: /* address - integer same size as pointer */
512 strcpy (p1, "address");
513 break;
515 case bt_Char: /* character */
516 strcpy (p1, "char");
517 break;
519 case bt_UChar: /* unsigned character */
520 strcpy (p1, "unsigned char");
521 break;
523 case bt_Short: /* short */
524 strcpy (p1, "short");
525 break;
527 case bt_UShort: /* unsigned short */
528 strcpy (p1, "unsigned short");
529 break;
531 case bt_Int: /* int */
532 strcpy (p1, "int");
533 break;
535 case bt_UInt: /* unsigned int */
536 strcpy (p1, "unsigned int");
537 break;
539 case bt_Long: /* long */
540 strcpy (p1, "long");
541 break;
543 case bt_ULong: /* unsigned long */
544 strcpy (p1, "unsigned long");
545 break;
547 case bt_Float: /* float (real) */
548 strcpy (p1, "float");
549 break;
551 case bt_Double: /* Double (real) */
552 strcpy (p1, "double");
553 break;
555 /* Structures add 1-2 aux words:
556 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
557 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
559 case bt_Struct: /* Structure (Record) */
560 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
561 used_ptr[index] = 1;
562 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
563 used_ptr[++index] = 1;
565 index++; /* skip aux words */
566 break;
568 /* Unions add 1-2 aux words:
569 1st word is [ST_RFDESCAPE, offset] pointer to union def;
570 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
572 case bt_Union: /* Union */
573 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
574 used_ptr[index] = 1;
575 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
576 used_ptr[++index] = 1;
578 index++; /* skip aux words */
579 break;
581 /* Enumerations add 1-2 aux words:
582 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
583 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
585 case bt_Enum: /* Enumeration */
586 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
587 used_ptr[index] = 1;
588 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
589 used_ptr[++index] = 1;
591 index++; /* skip aux words */
592 break;
594 case bt_Typedef: /* defined via a typedef, isymRef points */
595 strcpy (p1, "typedef");
596 break;
598 case bt_Range: /* subrange of int */
599 strcpy (p1, "subrange");
600 break;
602 case bt_Set: /* pascal sets */
603 strcpy (p1, "set");
604 break;
606 case bt_Complex: /* fortran complex */
607 strcpy (p1, "complex");
608 break;
610 case bt_DComplex: /* fortran double complex */
611 strcpy (p1, "double complex");
612 break;
614 case bt_Indirect: /* forward or unnamed typedef */
615 strcpy (p1, "forward/unnamed typedef");
616 break;
618 case bt_FixedDec: /* Fixed Decimal */
619 strcpy (p1, "fixed decimal");
620 break;
622 case bt_FloatDec: /* Float Decimal */
623 strcpy (p1, "float decimal");
624 break;
626 case bt_String: /* Varying Length Character String */
627 strcpy (p1, "string");
628 break;
630 case bt_Bit: /* Aligned Bit String */
631 strcpy (p1, "bit");
632 break;
634 case bt_Picture: /* Picture */
635 strcpy (p1, "picture");
636 break;
638 case bt_Void: /* Void */
639 strcpy (p1, "void");
640 break;
642 default:
643 sprintf (p1, "Unknown basic type %d", (int) basic_type);
644 break;
647 p1 += strlen (buffer1);
650 * If this is a bitfield, get the bitsize.
652 if (u.ti.fBitfield)
654 int bitsize;
656 used_ptr[index] = 1;
657 bitsize = aux_ptr[index++].width;
658 sprintf (p1, " : %d", bitsize);
659 p1 += strlen (buffer1);
664 * Deal with any qualifiers.
666 if (qualifiers[0].type != tq_Nil)
669 * Snarf up any array bounds in the correct order. Arrays
670 * store 5 successive words in the aux. table:
671 * word 0 RNDXR to type of the bounds (ie, int)
672 * word 1 Current file descriptor index
673 * word 2 low bound
674 * word 3 high bound (or -1 if [])
675 * word 4 stride size in bits
677 for (i = 0; i < 7; i++)
679 if (qualifiers[i].type == tq_Array)
681 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
682 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
683 qualifiers[i].stride = aux_ptr[index+4].width;
684 used_ptr[index] = 1;
685 used_ptr[index+1] = 1;
686 used_ptr[index+2] = 1;
687 used_ptr[index+3] = 1;
688 used_ptr[index+4] = 1;
689 index += 5;
694 * Now print out the qualifiers.
696 for (i = 0; i < 6; i++)
698 switch (qualifiers[i].type)
700 case tq_Nil:
701 case tq_Max:
702 break;
704 case tq_Ptr:
705 strcpy (p2, "ptr to ");
706 p2 += sizeof ("ptr to ")-1;
707 break;
709 case tq_Vol:
710 strcpy (p2, "volatile ");
711 p2 += sizeof ("volatile ")-1;
712 break;
714 case tq_Far:
715 strcpy (p2, "far ");
716 p2 += sizeof ("far ")-1;
717 break;
719 case tq_Proc:
720 strcpy (p2, "func. ret. ");
721 p2 += sizeof ("func. ret. ");
722 break;
724 case tq_Array:
726 int first_array = i;
727 int j;
729 /* Print array bounds reversed (ie, in the order the C
730 programmer writes them). C is such a fun language.... */
732 while (i < 5 && qualifiers[i+1].type == tq_Array)
733 i++;
735 for (j = i; j >= first_array; j--)
737 strcpy (p2, "array [");
738 p2 += sizeof ("array [")-1;
739 if (qualifiers[j].low_bound != 0)
740 sprintf (p2,
741 "%ld:%ld {%ld bits}",
742 (long) qualifiers[j].low_bound,
743 (long) qualifiers[j].high_bound,
744 (long) qualifiers[j].stride);
746 else if (qualifiers[j].high_bound != -1)
747 sprintf (p2,
748 "%ld {%ld bits}",
749 (long) (qualifiers[j].high_bound + 1),
750 (long) (qualifiers[j].stride));
752 else
753 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
755 p2 += strlen (p2);
756 strcpy (p2, "] of ");
757 p2 += sizeof ("] of ")-1;
760 break;
765 strcpy (p2, buffer1);
766 return buffer2;
770 /* Print out the global file header for object files. */
772 void
773 print_global_hdr (ptr)
774 struct filehdr *ptr;
776 char *time = ctime ((time_t *)&ptr->f_timdat);
777 ushort flags = ptr->f_flags;
779 printf("Global file header:\n");
780 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
781 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
782 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
783 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
784 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
785 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
786 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
788 if ((flags & F_RELFLG) != 0)
789 printf (", F_RELFLG");
791 if ((flags & F_EXEC) != 0)
792 printf (", F_EXEC");
794 if ((flags & F_LNNO) != 0)
795 printf (", F_LNNO");
797 if ((flags & F_LSYMS) != 0)
798 printf (", F_LSYMS");
800 if ((flags & F_MINMAL) != 0)
801 printf (", F_MINMAL");
803 if ((flags & F_UPDATE) != 0)
804 printf (", F_UPDATE");
806 if ((flags & F_SWABD) != 0)
807 printf (", F_SWABD");
809 if ((flags & F_AR16WR) != 0)
810 printf (", F_AR16WR");
812 if ((flags & F_AR32WR) != 0)
813 printf (", F_AR32WR");
815 if ((flags & F_AR32W) != 0)
816 printf (", F_AR32W");
818 if ((flags & F_PATCH) != 0)
819 printf (", F_PATCH/F_NODF");
821 printf ("\n\n");
825 /* Print out the symbolic header. */
827 void
828 print_sym_hdr (sym_ptr)
829 HDRR *sym_ptr;
831 int width = 20;
833 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
834 sym_ptr->magic & 0xffff,
835 (sym_ptr->vstamp & 0xffff) >> 8,
836 sym_ptr->vstamp & 0xff);
838 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
839 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
841 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
842 (long) sym_ptr->cbLineOffset,
843 (long) sym_ptr->cbLine,
844 (long) sym_ptr->cbLine,
845 (int) sym_ptr->ilineMax);
847 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
848 (long) sym_ptr->cbDnOffset,
849 (long) sym_ptr->idnMax,
850 (long) (sym_ptr->idnMax * sizeof (DNR)));
852 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
853 (long) sym_ptr->cbPdOffset,
854 (long) sym_ptr->ipdMax,
855 (long) (sym_ptr->ipdMax * sizeof (PDR)));
857 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
858 (long) sym_ptr->cbSymOffset,
859 (long) sym_ptr->isymMax,
860 (long) (sym_ptr->isymMax * sizeof (SYMR)));
862 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
863 (long) sym_ptr->cbOptOffset,
864 (long) sym_ptr->ioptMax,
865 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
867 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
868 (long) sym_ptr->cbAuxOffset,
869 (long) sym_ptr->iauxMax,
870 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
872 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
873 (long) sym_ptr->cbSsOffset,
874 (long) sym_ptr->issMax,
875 (long) sym_ptr->issMax);
877 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
878 (long) sym_ptr->cbSsExtOffset,
879 (long) sym_ptr->issExtMax,
880 (long) sym_ptr->issExtMax);
882 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
883 (long) sym_ptr->cbFdOffset,
884 (long) sym_ptr->ifdMax,
885 (long) (sym_ptr->ifdMax * sizeof (FDR)));
887 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
888 (long) sym_ptr->cbRfdOffset,
889 (long) sym_ptr->crfd,
890 (long) (sym_ptr->crfd * sizeof (ulong)));
892 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
893 (long) sym_ptr->cbExtOffset,
894 (long) sym_ptr->iextMax,
895 (long) (sym_ptr->iextMax * sizeof (EXTR)));
899 /* Print out a symbol. */
901 void
902 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
903 SYMR *sym_ptr;
904 int number;
905 char *strbase;
906 AUXU *aux_base;
907 int ifd;
908 FDR *fdp;
910 sc_t storage_class = (sc_t) sym_ptr->sc;
911 st_t symbol_type = (st_t) sym_ptr->st;
912 ulong index = sym_ptr->index;
913 char *used_ptr = aux_used + (aux_base - aux_symbols);
914 scope_t *scope_ptr;
916 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
918 if (aux_base != (AUXU *) 0 && index != indexNil)
919 switch (symbol_type)
921 case st_Nil:
922 case st_Label:
923 break;
925 case st_File:
926 case st_Block:
927 printf (" End+1 symbol: %ld\n", index);
928 if (want_scope)
930 if (free_scope == (scope_t *) 0)
931 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
932 else
934 scope_ptr = free_scope;
935 free_scope = scope_ptr->prev;
937 scope_ptr->open_sym = number;
938 scope_ptr->st = symbol_type;
939 scope_ptr->sc = storage_class;
940 scope_ptr->prev = cur_scope;
941 cur_scope = scope_ptr;
943 break;
945 case st_End:
946 if (storage_class == sc_Text || storage_class == sc_Info)
947 printf (" First symbol: %ld\n", index);
948 else
950 used_ptr[index] = 1;
951 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
954 if (want_scope)
956 if (cur_scope == (scope_t *) 0)
957 printf (" Can't pop end scope\n");
958 else
960 scope_ptr = cur_scope;
961 cur_scope = scope_ptr->prev;
962 scope_ptr->prev = free_scope;
963 free_scope = scope_ptr;
966 break;
968 case st_Proc:
969 case st_StaticProc:
970 if (MIPS_IS_STAB(sym_ptr))
972 else if (ifd == -1) /* local symbol */
974 used_ptr[index] = used_ptr[index+1] = 1;
975 printf (" End+1 symbol: %-7ld Type: %s\n",
976 (long) aux_base[index].isym,
977 type_to_string (aux_base, index+1, fdp));
979 else /* global symbol */
980 printf (" Local symbol: %ld\n", index);
982 if (want_scope)
984 if (free_scope == (scope_t *) 0)
985 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
986 else
988 scope_ptr = free_scope;
989 free_scope = scope_ptr->prev;
991 scope_ptr->open_sym = number;
992 scope_ptr->st = symbol_type;
993 scope_ptr->sc = storage_class;
994 scope_ptr->prev = cur_scope;
995 cur_scope = scope_ptr;
997 break;
999 #ifdef stStruct
1000 case st_Struct:
1001 case st_Union:
1002 case st_Enum:
1003 printf (" End+1 symbol: %lu\n", index);
1004 break;
1005 #endif
1007 default:
1008 if (!MIPS_IS_STAB (sym_ptr))
1010 used_ptr[index] = 1;
1011 printf (" Type: %s\n",
1012 type_to_string (aux_base, index, fdp));
1014 break;
1017 if (want_scope)
1019 printf (" Scopes: ");
1020 if (cur_scope == (scope_t *) 0)
1021 printf (" none\n");
1022 else
1024 for (scope_ptr = cur_scope;
1025 scope_ptr != (scope_t *) 0;
1026 scope_ptr = scope_ptr->prev)
1028 const char *class;
1029 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1030 class = "func.";
1031 else if (scope_ptr->st == st_File)
1032 class = "file";
1033 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1034 class = "block";
1035 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1036 class = "type";
1037 else
1038 class = "???";
1040 printf (" %ld [%s]", scope_ptr->open_sym, class);
1042 printf ("\n");
1046 printf (" Value: %-13ld ",
1047 (long)sym_ptr->value);
1048 if (ifd == -1)
1049 printf ("String index: %ld\n", (long)sym_ptr->iss);
1050 else
1051 printf ("String index: %-11ld Ifd: %d\n",
1052 (long)sym_ptr->iss, ifd);
1054 printf (" Symbol type: %-11sStorage class: %-11s",
1055 st_to_string (symbol_type), sc_to_string (storage_class));
1057 if (MIPS_IS_STAB(sym_ptr))
1059 register int i = sizeof(stab_names) / sizeof(stab_names[0]);
1060 const char *stab_name = "stab";
1061 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1062 while (--i >= 0)
1063 if (stab_names[i].code == code)
1065 stab_name = stab_names[i].string;
1066 break;
1068 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1070 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1071 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1072 else
1073 printf ("Index: %ld\n", (long)sym_ptr->index);
1078 /* Print out a word from the aux. table in various formats. */
1080 void
1081 print_aux (u, auxi, used)
1082 AUXU u;
1083 int auxi;
1084 int used;
1086 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1087 (used) ? " " : "* ",
1088 auxi,
1089 (long) u.isym,
1090 (long) u.rndx.rfd,
1091 (long) u.rndx.index,
1092 u.ti.bt,
1093 u.ti.fBitfield,
1094 u.ti.continued,
1095 u.ti.tq0,
1096 u.ti.tq1,
1097 u.ti.tq2,
1098 u.ti.tq3,
1099 u.ti.tq4,
1100 u.ti.tq5);
1104 /* Write aggregate information to a string. */
1106 void
1107 emit_aggregate (string, u, u2, which, fdp)
1108 char *string;
1109 AUXU u;
1110 AUXU u2;
1111 const char *which;
1112 FDR *fdp;
1114 unsigned int ifd = u.rndx.rfd;
1115 unsigned int index = u.rndx.index;
1116 const char *name;
1118 if (ifd == ST_RFDESCAPE)
1119 ifd = u2.isym;
1121 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1122 struct return type of a procedure compiled without -g. */
1123 if (ifd == 0xffffffff
1124 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
1125 name = "<undefined>";
1126 else if (index == indexNil)
1127 name = "<no name>";
1128 else
1130 if (fdp == 0 || sym_hdr.crfd == 0)
1131 fdp = &file_desc[ifd];
1132 else
1133 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1134 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1137 sprintf (string,
1138 "%s %s { ifd = %u, index = %u }",
1139 which, name, ifd, index);
1143 /* Print out information about a file descriptor, and the symbols,
1144 procedures, and line numbers within it. */
1146 void
1147 print_file_desc (fdp, number)
1148 FDR *fdp;
1149 int number;
1151 char *str_base;
1152 AUXU *aux_base;
1153 int symi, pdi;
1154 int width = 20;
1155 char *used_base;
1157 str_base = l_strings + fdp->issBase;
1158 aux_base = aux_symbols + fdp->iauxBase;
1159 used_base = aux_used + (aux_base - aux_symbols);
1161 printf ("\nFile #%d, \"%s\"\n\n",
1162 number,
1163 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
1165 printf (" Name index = %-10ld Readin = %s\n",
1166 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1168 printf (" Merge = %-10s Endian = %s\n",
1169 (fdp->fMerge) ? "Yes" : "No",
1170 (fdp->fBigendian) ? "BIG" : "LITTLE");
1172 printf (" Debug level = %-10s Language = %s\n",
1173 glevel_to_string (fdp->glevel),
1174 lang_to_string((lang_t) fdp->lang));
1176 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1178 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1179 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1181 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1182 width, "Local strings",
1183 (ulong) fdp->issBase,
1184 (ulong) fdp->cbSs,
1185 (ulong) fdp->cbSs,
1186 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1188 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1189 width, "Local symbols",
1190 (ulong) fdp->isymBase,
1191 (ulong) fdp->csym,
1192 (ulong) (fdp->csym * sizeof (SYMR)),
1193 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1195 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1196 width, "Line numbers",
1197 (ulong) fdp->cbLineOffset,
1198 (ulong) fdp->cline,
1199 (ulong) fdp->cbLine,
1200 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1202 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1203 width, "Optimization symbols",
1204 (ulong) fdp->ioptBase,
1205 (ulong) fdp->copt,
1206 (ulong) (fdp->copt * sizeof (OPTR)),
1207 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1209 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1210 width, "Procedures",
1211 (ulong) fdp->ipdFirst,
1212 (ulong) fdp->cpd,
1213 (ulong) (fdp->cpd * sizeof (PDR)),
1214 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1216 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1217 width, "Auxiliary symbols",
1218 (ulong) fdp->iauxBase,
1219 (ulong) fdp->caux,
1220 (ulong) (fdp->caux * sizeof (AUXU)),
1221 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1223 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1224 width, "Relative Files",
1225 (ulong) fdp->rfdBase,
1226 (ulong) fdp->crfd,
1227 (ulong) (fdp->crfd * sizeof (ulong)),
1228 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1231 if (want_scope && cur_scope != (scope_t *) 0)
1232 printf ("\n Warning scope does not start at 0!\n");
1235 * print the info about the symbol table.
1237 printf ("\n There are %lu local symbols, starting at %lu\n",
1238 (ulong) fdp->csym,
1239 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1241 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1242 print_symbol (&l_symbols[symi],
1243 symi - fdp->isymBase,
1244 str_base,
1245 aux_base,
1247 fdp);
1249 if (want_scope && cur_scope != (scope_t *) 0)
1250 printf ("\n Warning scope does not end at 0!\n");
1253 * print the aux. table if desired.
1256 if (want_aux && fdp->caux != 0)
1258 int auxi;
1260 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1261 (ulong) fdp->caux,
1262 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1264 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1265 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1269 * print the relative file descriptors.
1271 if (want_rfd && fdp->crfd != 0)
1273 ulong *rfd_ptr, i;
1275 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1276 (ulong) fdp->crfd,
1277 (ulong) fdp->rfdBase);
1279 rfd_ptr = rfile_desc + fdp->rfdBase;
1280 for (i = 0; i < (ulong) fdp->crfd; i++)
1282 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1283 rfd_ptr++;
1288 * do the procedure descriptors.
1290 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1291 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1293 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1295 PDR *proc_ptr = &proc_desc[pdi];
1296 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1298 if (l_symbols != 0)
1299 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1300 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1301 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1303 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1304 (long) proc_ptr->regmask,
1305 (long) proc_ptr->regoffset,
1306 (long) proc_ptr->fregmask,
1307 (long) proc_ptr->fregoffset);
1309 printf ("\t .frame $%d,%ld,$%d\n",
1310 (int) proc_ptr->framereg,
1311 (long) proc_ptr->frameoffset,
1312 (int) proc_ptr->pcreg);
1314 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1315 (long) proc_ptr->iopt,
1316 (long) proc_ptr->isym);
1318 printf ("\t First line # = %-11ld Last line # = %ld\n",
1319 (long) proc_ptr->lnLow,
1320 (long) proc_ptr->lnHigh);
1322 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1323 (long) proc_ptr->cbLineOffset,
1324 (long) proc_ptr->adr);
1327 * print the line number entries.
1330 if (want_line && fdp->cline != 0)
1332 int delta, count;
1333 long cur_line = proc_ptr->lnLow;
1334 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1335 + fdp->cbLineOffset);
1336 uchar *line_end;
1338 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1339 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1340 else /* not last proc. */
1341 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1342 + fdp->cbLineOffset);
1344 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1345 (ulong) (line_end - line_ptr),
1346 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1348 while (line_ptr < line_end)
1349 { /* sign extend nibble */
1350 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1351 count = (*line_ptr & 0xf) + 1;
1352 if (delta != -8)
1353 line_ptr++;
1354 else
1356 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1357 delta = (delta ^ 0x8000) - 0x8000;
1358 line_ptr += 3;
1361 cur_line += delta;
1362 printf ("\t Line %11ld, delta %5d, count %2d\n",
1363 cur_line,
1364 delta,
1365 count);
1372 /* Read in the portions of the .T file that we will print out. */
1374 void
1375 read_tfile __proto((void))
1377 short magic;
1378 off_t sym_hdr_offset = 0;
1380 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number");
1381 if (!tfile)
1383 /* Print out the global header, since this is not a T-file. */
1385 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0,
1386 "Global file header");
1388 print_global_hdr (&global_hdr);
1390 if (global_hdr.f_symptr == 0)
1392 printf ("No symbolic header, Goodbye!\n");
1393 exit (1);
1396 sym_hdr_offset = global_hdr.f_symptr;
1399 (void) read_seek ((PTR_T) &sym_hdr,
1400 sizeof (sym_hdr),
1401 sym_hdr_offset,
1402 "Symbolic header");
1404 print_sym_hdr (&sym_hdr);
1406 lines = (LINER *) read_seek ((PTR_T) 0,
1407 sym_hdr.cbLine,
1408 sym_hdr.cbLineOffset,
1409 "Line numbers");
1411 dense_nums = (DNR *) read_seek ((PTR_T) 0,
1412 sym_hdr.idnMax * sizeof (DNR),
1413 sym_hdr.cbDnOffset,
1414 "Dense numbers");
1416 proc_desc = (PDR *) read_seek ((PTR_T) 0,
1417 sym_hdr.ipdMax * sizeof (PDR),
1418 sym_hdr.cbPdOffset,
1419 "Procedure tables");
1421 l_symbols = (SYMR *) read_seek ((PTR_T) 0,
1422 sym_hdr.isymMax * sizeof (SYMR),
1423 sym_hdr.cbSymOffset,
1424 "Local symbols");
1426 opt_symbols = (OPTR *) read_seek ((PTR_T) 0,
1427 sym_hdr.ioptMax * sizeof (OPTR),
1428 sym_hdr.cbOptOffset,
1429 "Optimization symbols");
1431 aux_symbols = (AUXU *) read_seek ((PTR_T) 0,
1432 sym_hdr.iauxMax * sizeof (AUXU),
1433 sym_hdr.cbAuxOffset,
1434 "Auxiliary symbols");
1436 if (sym_hdr.iauxMax > 0)
1438 aux_used = calloc (sym_hdr.iauxMax, 1);
1439 if (aux_used == (char *) 0)
1441 perror ("calloc");
1442 exit (1);
1446 l_strings = (char *) read_seek ((PTR_T) 0,
1447 sym_hdr.issMax,
1448 sym_hdr.cbSsOffset,
1449 "Local string table");
1451 e_strings = (char *) read_seek ((PTR_T) 0,
1452 sym_hdr.issExtMax,
1453 sym_hdr.cbSsExtOffset,
1454 "External string table");
1456 file_desc = (FDR *) read_seek ((PTR_T) 0,
1457 sym_hdr.ifdMax * sizeof (FDR),
1458 sym_hdr.cbFdOffset,
1459 "File tables");
1461 rfile_desc = (ulong *) read_seek ((PTR_T) 0,
1462 sym_hdr.crfd * sizeof (ulong),
1463 sym_hdr.cbRfdOffset,
1464 "Relative file tables");
1466 e_symbols = (EXTR *) read_seek ((PTR_T) 0,
1467 sym_hdr.iextMax * sizeof (EXTR),
1468 sym_hdr.cbExtOffset,
1469 "External symbols");
1475 main (argc, argv)
1476 int argc;
1477 char **argv;
1479 int i, opt;
1482 * Process arguments
1484 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1485 switch (opt)
1487 default: errors++; break;
1488 case 'a': want_aux++; break; /* print aux table */
1489 case 'l': want_line++; break; /* print line numbers */
1490 case 'r': want_rfd++; break; /* print relative fd's */
1491 case 's': want_scope++; break; /* print scope info */
1492 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1495 if (errors || optind != argc - 1)
1497 fprintf (stderr, "Calling Sequence:\n");
1498 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1499 fprintf (stderr, "\n");
1500 fprintf (stderr, "switches:\n");
1501 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1502 fprintf (stderr, "\t-l Print out line numbers.\n");
1503 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1504 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1505 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1506 return 1;
1510 * Open and process the input file.
1512 tfile_fd = open (argv[optind], O_RDONLY);
1513 if (tfile_fd < 0)
1515 perror (argv[optind]);
1516 return 1;
1519 read_tfile ();
1522 * Print any global aux words if any.
1524 if (want_aux)
1526 long last_aux_in_use;
1528 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1530 printf ("\nGlobal auxiliary entries before first file:\n");
1531 for (i = 0; i < file_desc[0].iauxBase; i++)
1532 print_aux (aux_symbols[i], 0, aux_used[i]);
1535 if (sym_hdr.ifdMax == 0)
1536 last_aux_in_use = 0;
1537 else
1538 last_aux_in_use
1539 = (file_desc[sym_hdr.ifdMax-1].iauxBase
1540 + file_desc[sym_hdr.ifdMax-1].caux - 1);
1542 if (last_aux_in_use < sym_hdr.iauxMax-1)
1544 printf ("\nGlobal auxiliary entries after last file:\n");
1545 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1546 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1551 * Print the information for each file.
1553 for (i = 0; i < sym_hdr.ifdMax; i++)
1554 print_file_desc (&file_desc[i], i);
1557 * Print the external symbols.
1559 want_scope = 0; /* scope info is meaning for extern symbols */
1560 printf ("\nThere are %lu external symbols, starting at %lu\n",
1561 (ulong) sym_hdr.iextMax,
1562 (ulong) sym_hdr.cbExtOffset);
1564 for(i = 0; i < sym_hdr.iextMax; i++)
1565 print_symbol (&e_symbols[i].asym, i, e_strings,
1566 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1567 e_symbols[i].ifd,
1568 &file_desc[e_symbols[i].ifd]);
1571 * Print unused aux symbols now.
1574 if (want_aux)
1576 int first_time = 1;
1578 for (i = 0; i < sym_hdr.iauxMax; i++)
1580 if (! aux_used[i])
1582 if (first_time)
1584 printf ("\nThe following auxiliary table entries were unused:\n\n");
1585 first_time = 0;
1588 printf (" #%-5d %11ld 0x%08lx %s\n",
1590 (long) aux_symbols[i].isym,
1591 (long) aux_symbols[i].isym,
1592 type_to_string (aux_symbols, i, (FDR *) 0));
1597 return 0;
1601 void
1602 fancy_abort ()
1604 fprintf (stderr, "mips-tdump internal error");
1605 exit (1);