Fix for PR1654 - implement "movstrsi" pattern to copy simple blocks of memory.
[official-gcc.git] / gcc / mips-tdump.c
blob558e090a64d27c8937473cf7e72e90399ac7217b
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994, 1995, 1997 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 #ifdef __STDC__
51 typedef void *PTR_T;
52 typedef const void *CPTR_T;
53 #define __proto(x) x
54 #else
56 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
57 typedef void *PTR_T;
58 typedef void *CPTR_T;
60 #else
61 typedef char *PTR_T; /* Ultrix 3.1 */
62 typedef char *CPTR_T;
63 #endif
65 #define __proto(x) ()
66 #define const
67 #endif
69 #define uchar unsigned char
70 #define ushort unsigned short
71 #define uint unsigned int
72 #define ulong unsigned long
75 /* Do to size_t being defined in sys/types.h and different
76 in stddef.h, we have to do this by hand..... Note, these
77 types are correct for MIPS based systems, and may not be
78 correct for other systems. */
80 #define size_t uint
81 #define ptrdiff_t int
84 /* Redefinition of storage classes as an enumeration for better
85 debugging. */
87 #ifndef stStaParam
88 #define stStaParam 16 /* Fortran static parameters */
89 #endif
91 #ifndef btVoid
92 #define btVoid 26 /* void basic type */
93 #endif
95 typedef enum sc {
96 sc_Nil = scNil, /* no storage class */
97 sc_Text = scText, /* text symbol */
98 sc_Data = scData, /* initialized data symbol */
99 sc_Bss = scBss, /* un-initialized data symbol */
100 sc_Register = scRegister, /* value of symbol is register number */
101 sc_Abs = scAbs, /* value of symbol is absolute */
102 sc_Undefined = scUndefined, /* who knows? */
103 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
104 sc_Bits = scBits, /* this is a bit field */
105 sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */
106 sc_RegImage = scRegImage, /* register value saved on stack */
107 sc_Info = scInfo, /* symbol contains debugger information */
108 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
109 sc_SData = scSData, /* load time only small data */
110 sc_SBss = scSBss, /* load time only small common */
111 sc_RData = scRData, /* load time only read only data */
112 sc_Var = scVar, /* Var parameter (fortran,pascal) */
113 sc_Common = scCommon, /* common variable */
114 sc_SCommon = scSCommon, /* small common */
115 sc_VarRegister = scVarRegister, /* Var parameter in a register */
116 sc_Variant = scVariant, /* Variant record */
117 sc_SUndefined = scSUndefined, /* small undefined(external) data */
118 sc_Init = scInit, /* .init section symbol */
119 sc_Max = scMax /* Max storage class+1 */
120 } sc_t;
122 /* Redefinition of symbol type. */
124 typedef enum st {
125 st_Nil = stNil, /* Nuthin' special */
126 st_Global = stGlobal, /* external symbol */
127 st_Static = stStatic, /* static */
128 st_Param = stParam, /* procedure argument */
129 st_Local = stLocal, /* local variable */
130 st_Label = stLabel, /* label */
131 st_Proc = stProc, /* " " Procedure */
132 st_Block = stBlock, /* beginning of block */
133 st_End = stEnd, /* end (of anything) */
134 st_Member = stMember, /* member (of anything - struct/union/enum */
135 st_Typedef = stTypedef, /* type definition */
136 st_File = stFile, /* file name */
137 st_RegReloc = stRegReloc, /* register relocation */
138 st_Forward = stForward, /* forwarding address */
139 st_StaticProc = stStaticProc, /* load time only static procs */
140 st_StaParam = stStaParam, /* Fortran static parameters */
141 st_Constant = stConstant, /* const */
142 #ifdef stStruct
143 st_Struct = stStruct, /* struct */
144 st_Union = stUnion, /* union */
145 st_Enum = stEnum, /* enum */
146 #endif
147 st_Str = stStr, /* string */
148 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
149 st_Expr = stExpr, /* 2+2 vs. 4 */
150 st_Type = stType, /* post-coercion SER */
151 st_Max = stMax /* max type+1 */
152 } st_t;
154 /* Redefinition of type qualifiers. */
156 typedef enum tq {
157 tq_Nil = tqNil, /* bt is what you see */
158 tq_Ptr = tqPtr, /* pointer */
159 tq_Proc = tqProc, /* procedure */
160 tq_Array = tqArray, /* duh */
161 tq_Far = tqFar, /* longer addressing - 8086/8 land */
162 tq_Vol = tqVol, /* volatile */
163 tq_Max = tqMax /* Max type qualifier+1 */
164 } tq_t;
166 /* Redefinition of basic types. */
168 typedef enum bt {
169 bt_Nil = btNil, /* undefined */
170 bt_Adr = btAdr, /* address - integer same size as pointer */
171 bt_Char = btChar, /* character */
172 bt_UChar = btUChar, /* unsigned character */
173 bt_Short = btShort, /* short */
174 bt_UShort = btUShort, /* unsigned short */
175 bt_Int = btInt, /* int */
176 bt_UInt = btUInt, /* unsigned int */
177 bt_Long = btLong, /* long */
178 bt_ULong = btULong, /* unsigned long */
179 bt_Float = btFloat, /* float (real) */
180 bt_Double = btDouble, /* Double (real) */
181 bt_Struct = btStruct, /* Structure (Record) */
182 bt_Union = btUnion, /* Union (variant) */
183 bt_Enum = btEnum, /* Enumerated */
184 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
185 bt_Range = btRange, /* subrange of int */
186 bt_Set = btSet, /* pascal sets */
187 bt_Complex = btComplex, /* fortran complex */
188 bt_DComplex = btDComplex, /* fortran double complex */
189 bt_Indirect = btIndirect, /* forward or unnamed typedef */
190 bt_FixedDec = btFixedDec, /* Fixed Decimal */
191 bt_FloatDec = btFloatDec, /* Float Decimal */
192 bt_String = btString, /* Varying Length Character String */
193 bt_Bit = btBit, /* Aligned Bit String */
194 bt_Picture = btPicture, /* Picture */
195 bt_Void = btVoid, /* void */
196 bt_Max = btMax /* Max basic type+1 */
197 } bt_t;
199 /* Redefinition of the language codes. */
201 typedef enum lang {
202 lang_C = langC,
203 lang_Pascal = langPascal,
204 lang_Fortran = langFortran,
205 lang_Assembler = langAssembler,
206 lang_Machine = langMachine,
207 lang_Nil = langNil,
208 lang_Ada = langAda,
209 lang_Pl1 = langPl1,
210 lang_Cobol = langCobol
211 } lang_t;
213 /* Redefinition of the debug level codes. */
215 typedef enum glevel {
216 glevel_0 = GLEVEL_0,
217 glevel_1 = GLEVEL_1,
218 glevel_2 = GLEVEL_2,
219 glevel_3 = GLEVEL_3
220 } glevel_t;
223 /* Keep track of the active scopes. */
224 typedef struct scope {
225 struct scope *prev; /* previous scope */
226 ulong open_sym; /* symbol opening scope */
227 sc_t sc; /* storage class */
228 st_t st; /* symbol type */
229 } scope_t;
231 struct filehdr global_hdr; /* a.out header */
233 int errors = 0; /* # of errors */
234 int want_aux = 0; /* print aux table */
235 int want_line = 0; /* print line numbers */
236 int want_rfd = 0; /* print relative file desc's */
237 int want_scope = 0; /* print scopes for every symbol */
238 int tfile = 0; /* no global header file */
239 int tfile_fd; /* file descriptor of .T file */
240 off_t tfile_offset; /* current offset in .T file */
241 scope_t *cur_scope = 0; /* list of active scopes */
242 scope_t *free_scope = 0; /* list of freed scopes */
243 HDRR sym_hdr; /* symbolic header */
244 char *l_strings; /* local strings */
245 char *e_strings; /* external strings */
246 SYMR *l_symbols; /* local symbols */
247 EXTR *e_symbols; /* external symbols */
248 LINER *lines; /* line numbers */
249 DNR *dense_nums; /* dense numbers */
250 OPTR *opt_symbols; /* optimization symbols */
251 AUXU *aux_symbols; /* Auxiliary symbols */
252 char *aux_used; /* map of which aux syms are used */
253 FDR *file_desc; /* file tables */
254 ulong *rfile_desc; /* relative file tables */
255 PDR *proc_desc; /* procedure tables */
257 /* Forward reference for functions. */
258 PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *));
259 void read_tfile __proto((void));
260 void print_global_hdr __proto((struct filehdr *));
261 void print_sym_hdr __proto((HDRR *));
262 void print_file_desc __proto((FDR *, int));
263 void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *));
264 void print_aux __proto((AUXU, int, int));
265 void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *));
266 char *st_to_string __proto((st_t));
267 char *sc_to_string __proto((sc_t));
268 char *glevel_to_string __proto((glevel_t));
269 char *lang_to_string __proto((lang_t));
270 char *type_to_string __proto((AUXU *, int, FDR *));
272 #ifndef __alpha
273 extern PTR_T malloc __proto((size_t));
274 extern PTR_T calloc __proto((size_t, size_t));
275 extern PTR_T realloc __proto((PTR_T, size_t));
276 extern void free __proto((PTR_T));
277 #endif
279 extern char *optarg;
280 extern int optind;
281 extern int opterr;
283 /* Create a table of debugging stab-codes and corresponding names. */
285 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
286 struct {short code; char string[10];} stab_names[] = {
287 #include "stab.def"
288 #undef __define_stab
292 /* Read some bytes at a specified location, and return a pointer. */
294 PTR_T
295 read_seek (ptr, size, offset, context)
296 PTR_T ptr; /* pointer to buffer or NULL */
297 size_t size; /* # bytes to read */
298 off_t offset; /* offset to read at */
299 const char *context; /* context for error message */
301 long read_size = 0;
303 if (size == 0) /* nothing to read */
304 return ptr;
306 if ((ptr == (PTR_T) 0 && (ptr = malloc (size)) == (PTR_T) 0)
307 || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
308 || (read_size = read (tfile_fd, ptr, size)) < 0)
310 perror (context);
311 exit (1);
314 if (read_size != size)
316 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
317 context, read_size, (long) size);
318 exit (1);
321 tfile_offset = offset + size;
322 return ptr;
326 /* Convert language code to string format. */
328 char *
329 lang_to_string (lang)
330 lang_t lang;
332 switch (lang)
334 case langC: return "C";
335 case langPascal: return "Pascal";
336 case langFortran: return "Fortran";
337 case langAssembler: return "Assembler";
338 case langMachine: return "Machine";
339 case langNil: return "Nil";
340 case langAda: return "Ada";
341 case langPl1: return "Pl1";
342 case langCobol: return "Cobol";
345 return "Unknown language";
349 /* Convert storage class to string. */
351 char *
352 sc_to_string(storage_class)
353 sc_t storage_class;
355 switch(storage_class)
357 case sc_Nil: return "Nil";
358 case sc_Text: return "Text";
359 case sc_Data: return "Data";
360 case sc_Bss: return "Bss";
361 case sc_Register: return "Register";
362 case sc_Abs: return "Abs";
363 case sc_Undefined: return "Undefined";
364 case sc_CdbLocal: return "CdbLocal";
365 case sc_Bits: return "Bits";
366 case sc_CdbSystem: return "CdbSystem";
367 case sc_RegImage: return "RegImage";
368 case sc_Info: return "Info";
369 case sc_UserStruct: return "UserStruct";
370 case sc_SData: return "SData";
371 case sc_SBss: return "SBss";
372 case sc_RData: return "RData";
373 case sc_Var: return "Var";
374 case sc_Common: return "Common";
375 case sc_SCommon: return "SCommon";
376 case sc_VarRegister: return "VarRegister";
377 case sc_Variant: return "Variant";
378 case sc_SUndefined: return "SUndefined";
379 case sc_Init: return "Init";
380 case sc_Max: return "Max";
383 return "???";
387 /* Convert symbol type to string. */
389 char *
390 st_to_string(symbol_type)
391 st_t symbol_type;
393 switch(symbol_type)
395 case st_Nil: return "Nil";
396 case st_Global: return "Global";
397 case st_Static: return "Static";
398 case st_Param: return "Param";
399 case st_Local: return "Local";
400 case st_Label: return "Label";
401 case st_Proc: return "Proc";
402 case st_Block: return "Block";
403 case st_End: return "End";
404 case st_Member: return "Member";
405 case st_Typedef: return "Typedef";
406 case st_File: return "File";
407 case st_RegReloc: return "RegReloc";
408 case st_Forward: return "Forward";
409 case st_StaticProc: return "StaticProc";
410 case st_Constant: return "Constant";
411 case st_StaParam: return "StaticParam";
412 #ifdef stStruct
413 case st_Struct: return "Struct";
414 case st_Union: return "Union";
415 case st_Enum: return "Enum";
416 #endif
417 case st_Str: return "String";
418 case st_Number: return "Number";
419 case st_Expr: return "Expr";
420 case st_Type: return "Type";
421 case st_Max: return "Max";
424 return "???";
428 /* Convert debug level to string. */
430 char *
431 glevel_to_string (g_level)
432 glevel_t g_level;
434 switch(g_level)
436 case GLEVEL_0: return "G0";
437 case GLEVEL_1: return "G1";
438 case GLEVEL_2: return "G2";
439 case GLEVEL_3: return "G3";
442 return "??";
446 /* Convert the type information to string format. */
448 char *
449 type_to_string (aux_ptr, index, fdp)
450 AUXU *aux_ptr;
451 int index;
452 FDR *fdp;
454 AUXU u;
455 struct qual {
456 tq_t type;
457 int low_bound;
458 int high_bound;
459 int stride;
460 } qualifiers[7];
462 bt_t basic_type;
463 int i;
464 static char buffer1[1024];
465 static char buffer2[1024];
466 char *p1 = buffer1;
467 char *p2 = buffer2;
468 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
470 for (i = 0; i < 7; i++)
472 qualifiers[i].low_bound = 0;
473 qualifiers[i].high_bound = 0;
474 qualifiers[i].stride = 0;
477 used_ptr[index] = 1;
478 u = aux_ptr[index++];
479 if (u.isym == -1)
480 return "-1 (no type)";
482 basic_type = (bt_t) u.ti.bt;
483 qualifiers[0].type = (tq_t) u.ti.tq0;
484 qualifiers[1].type = (tq_t) u.ti.tq1;
485 qualifiers[2].type = (tq_t) u.ti.tq2;
486 qualifiers[3].type = (tq_t) u.ti.tq3;
487 qualifiers[4].type = (tq_t) u.ti.tq4;
488 qualifiers[5].type = (tq_t) u.ti.tq5;
489 qualifiers[6].type = tq_Nil;
492 * Go get the basic type.
494 switch (basic_type)
496 case bt_Nil: /* undefined */
497 strcpy (p1, "nil");
498 break;
500 case bt_Adr: /* address - integer same size as pointer */
501 strcpy (p1, "address");
502 break;
504 case bt_Char: /* character */
505 strcpy (p1, "char");
506 break;
508 case bt_UChar: /* unsigned character */
509 strcpy (p1, "unsigned char");
510 break;
512 case bt_Short: /* short */
513 strcpy (p1, "short");
514 break;
516 case bt_UShort: /* unsigned short */
517 strcpy (p1, "unsigned short");
518 break;
520 case bt_Int: /* int */
521 strcpy (p1, "int");
522 break;
524 case bt_UInt: /* unsigned int */
525 strcpy (p1, "unsigned int");
526 break;
528 case bt_Long: /* long */
529 strcpy (p1, "long");
530 break;
532 case bt_ULong: /* unsigned long */
533 strcpy (p1, "unsigned long");
534 break;
536 case bt_Float: /* float (real) */
537 strcpy (p1, "float");
538 break;
540 case bt_Double: /* Double (real) */
541 strcpy (p1, "double");
542 break;
544 /* Structures add 1-2 aux words:
545 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
546 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
548 case bt_Struct: /* Structure (Record) */
549 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
550 used_ptr[index] = 1;
551 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
552 used_ptr[++index] = 1;
554 index++; /* skip aux words */
555 break;
557 /* Unions add 1-2 aux words:
558 1st word is [ST_RFDESCAPE, offset] pointer to union def;
559 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
561 case bt_Union: /* Union */
562 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
563 used_ptr[index] = 1;
564 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
565 used_ptr[++index] = 1;
567 index++; /* skip aux words */
568 break;
570 /* Enumerations add 1-2 aux words:
571 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
572 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
574 case bt_Enum: /* Enumeration */
575 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
576 used_ptr[index] = 1;
577 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
578 used_ptr[++index] = 1;
580 index++; /* skip aux words */
581 break;
583 case bt_Typedef: /* defined via a typedef, isymRef points */
584 strcpy (p1, "typedef");
585 break;
587 case bt_Range: /* subrange of int */
588 strcpy (p1, "subrange");
589 break;
591 case bt_Set: /* pascal sets */
592 strcpy (p1, "set");
593 break;
595 case bt_Complex: /* fortran complex */
596 strcpy (p1, "complex");
597 break;
599 case bt_DComplex: /* fortran double complex */
600 strcpy (p1, "double complex");
601 break;
603 case bt_Indirect: /* forward or unnamed typedef */
604 strcpy (p1, "forward/unnamed typedef");
605 break;
607 case bt_FixedDec: /* Fixed Decimal */
608 strcpy (p1, "fixed decimal");
609 break;
611 case bt_FloatDec: /* Float Decimal */
612 strcpy (p1, "float decimal");
613 break;
615 case bt_String: /* Varying Length Character String */
616 strcpy (p1, "string");
617 break;
619 case bt_Bit: /* Aligned Bit String */
620 strcpy (p1, "bit");
621 break;
623 case bt_Picture: /* Picture */
624 strcpy (p1, "picture");
625 break;
627 case bt_Void: /* Void */
628 strcpy (p1, "void");
629 break;
631 default:
632 sprintf (p1, "Unknown basic type %d", (int) basic_type);
633 break;
636 p1 += strlen (buffer1);
639 * If this is a bitfield, get the bitsize.
641 if (u.ti.fBitfield)
643 int bitsize;
645 used_ptr[index] = 1;
646 bitsize = aux_ptr[index++].width;
647 sprintf (p1, " : %d", bitsize);
648 p1 += strlen (buffer1);
653 * Deal with any qualifiers.
655 if (qualifiers[0].type != tq_Nil)
658 * Snarf up any array bounds in the correct order. Arrays
659 * store 5 successive words in the aux. table:
660 * word 0 RNDXR to type of the bounds (ie, int)
661 * word 1 Current file descriptor index
662 * word 2 low bound
663 * word 3 high bound (or -1 if [])
664 * word 4 stride size in bits
666 for (i = 0; i < 7; i++)
668 if (qualifiers[i].type == tq_Array)
670 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
671 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
672 qualifiers[i].stride = aux_ptr[index+4].width;
673 used_ptr[index] = 1;
674 used_ptr[index+1] = 1;
675 used_ptr[index+2] = 1;
676 used_ptr[index+3] = 1;
677 used_ptr[index+4] = 1;
678 index += 5;
683 * Now print out the qualifiers.
685 for (i = 0; i < 6; i++)
687 switch (qualifiers[i].type)
689 case tq_Nil:
690 case tq_Max:
691 break;
693 case tq_Ptr:
694 strcpy (p2, "ptr to ");
695 p2 += sizeof ("ptr to ")-1;
696 break;
698 case tq_Vol:
699 strcpy (p2, "volatile ");
700 p2 += sizeof ("volatile ")-1;
701 break;
703 case tq_Far:
704 strcpy (p2, "far ");
705 p2 += sizeof ("far ")-1;
706 break;
708 case tq_Proc:
709 strcpy (p2, "func. ret. ");
710 p2 += sizeof ("func. ret. ");
711 break;
713 case tq_Array:
715 int first_array = i;
716 int j;
718 /* Print array bounds reversed (ie, in the order the C
719 programmer writes them). C is such a fun language.... */
721 while (i < 5 && qualifiers[i+1].type == tq_Array)
722 i++;
724 for (j = i; j >= first_array; j--)
726 strcpy (p2, "array [");
727 p2 += sizeof ("array [")-1;
728 if (qualifiers[j].low_bound != 0)
729 sprintf (p2,
730 "%ld:%ld {%ld bits}",
731 (long) qualifiers[j].low_bound,
732 (long) qualifiers[j].high_bound,
733 (long) qualifiers[j].stride);
735 else if (qualifiers[j].high_bound != -1)
736 sprintf (p2,
737 "%ld {%ld bits}",
738 (long) (qualifiers[j].high_bound + 1),
739 (long) (qualifiers[j].stride));
741 else
742 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
744 p2 += strlen (p2);
745 strcpy (p2, "] of ");
746 p2 += sizeof ("] of ")-1;
749 break;
754 strcpy (p2, buffer1);
755 return buffer2;
759 /* Print out the global file header for object files. */
761 void
762 print_global_hdr (ptr)
763 struct filehdr *ptr;
765 char *time = ctime ((time_t *)&ptr->f_timdat);
766 ushort flags = ptr->f_flags;
768 printf("Global file header:\n");
769 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
770 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
771 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
772 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
773 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
774 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
775 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
777 if ((flags & F_RELFLG) != 0)
778 printf (", F_RELFLG");
780 if ((flags & F_EXEC) != 0)
781 printf (", F_EXEC");
783 if ((flags & F_LNNO) != 0)
784 printf (", F_LNNO");
786 if ((flags & F_LSYMS) != 0)
787 printf (", F_LSYMS");
789 if ((flags & F_MINMAL) != 0)
790 printf (", F_MINMAL");
792 if ((flags & F_UPDATE) != 0)
793 printf (", F_UPDATE");
795 if ((flags & F_SWABD) != 0)
796 printf (", F_SWABD");
798 if ((flags & F_AR16WR) != 0)
799 printf (", F_AR16WR");
801 if ((flags & F_AR32WR) != 0)
802 printf (", F_AR32WR");
804 if ((flags & F_AR32W) != 0)
805 printf (", F_AR32W");
807 if ((flags & F_PATCH) != 0)
808 printf (", F_PATCH/F_NODF");
810 printf ("\n\n");
814 /* Print out the symbolic header. */
816 void
817 print_sym_hdr (sym_ptr)
818 HDRR *sym_ptr;
820 int width = 20;
822 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
823 sym_ptr->magic & 0xffff,
824 (sym_ptr->vstamp & 0xffff) >> 8,
825 sym_ptr->vstamp & 0xff);
827 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
828 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
830 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
831 (long) sym_ptr->cbLineOffset,
832 (long) sym_ptr->cbLine,
833 (long) sym_ptr->cbLine,
834 (int) sym_ptr->ilineMax);
836 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
837 (long) sym_ptr->cbDnOffset,
838 (long) sym_ptr->idnMax,
839 (long) (sym_ptr->idnMax * sizeof (DNR)));
841 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
842 (long) sym_ptr->cbPdOffset,
843 (long) sym_ptr->ipdMax,
844 (long) (sym_ptr->ipdMax * sizeof (PDR)));
846 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
847 (long) sym_ptr->cbSymOffset,
848 (long) sym_ptr->isymMax,
849 (long) (sym_ptr->isymMax * sizeof (SYMR)));
851 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
852 (long) sym_ptr->cbOptOffset,
853 (long) sym_ptr->ioptMax,
854 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
856 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
857 (long) sym_ptr->cbAuxOffset,
858 (long) sym_ptr->iauxMax,
859 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
861 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
862 (long) sym_ptr->cbSsOffset,
863 (long) sym_ptr->issMax,
864 (long) sym_ptr->issMax);
866 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
867 (long) sym_ptr->cbSsExtOffset,
868 (long) sym_ptr->issExtMax,
869 (long) sym_ptr->issExtMax);
871 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
872 (long) sym_ptr->cbFdOffset,
873 (long) sym_ptr->ifdMax,
874 (long) (sym_ptr->ifdMax * sizeof (FDR)));
876 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
877 (long) sym_ptr->cbRfdOffset,
878 (long) sym_ptr->crfd,
879 (long) (sym_ptr->crfd * sizeof (ulong)));
881 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
882 (long) sym_ptr->cbExtOffset,
883 (long) sym_ptr->iextMax,
884 (long) (sym_ptr->iextMax * sizeof (EXTR)));
888 /* Print out a symbol. */
890 void
891 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
892 SYMR *sym_ptr;
893 int number;
894 char *strbase;
895 AUXU *aux_base;
896 int ifd;
897 FDR *fdp;
899 sc_t storage_class = (sc_t) sym_ptr->sc;
900 st_t symbol_type = (st_t) sym_ptr->st;
901 ulong index = sym_ptr->index;
902 char *used_ptr = aux_used + (aux_base - aux_symbols);
903 scope_t *scope_ptr;
905 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
907 if (aux_base != (AUXU *) 0 && index != indexNil)
908 switch (symbol_type)
910 case st_Nil:
911 case st_Label:
912 break;
914 case st_File:
915 case st_Block:
916 printf (" End+1 symbol: %ld\n", index);
917 if (want_scope)
919 if (free_scope == (scope_t *) 0)
920 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
921 else
923 scope_ptr = free_scope;
924 free_scope = scope_ptr->prev;
926 scope_ptr->open_sym = number;
927 scope_ptr->st = symbol_type;
928 scope_ptr->sc = storage_class;
929 scope_ptr->prev = cur_scope;
930 cur_scope = scope_ptr;
932 break;
934 case st_End:
935 if (storage_class == sc_Text || storage_class == sc_Info)
936 printf (" First symbol: %ld\n", index);
937 else
939 used_ptr[index] = 1;
940 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
943 if (want_scope)
945 if (cur_scope == (scope_t *) 0)
946 printf (" Can't pop end scope\n");
947 else
949 scope_ptr = cur_scope;
950 cur_scope = scope_ptr->prev;
951 scope_ptr->prev = free_scope;
952 free_scope = scope_ptr;
955 break;
957 case st_Proc:
958 case st_StaticProc:
959 if (MIPS_IS_STAB(sym_ptr))
961 else if (ifd == -1) /* local symbol */
963 used_ptr[index] = used_ptr[index+1] = 1;
964 printf (" End+1 symbol: %-7ld Type: %s\n",
965 (long) aux_base[index].isym,
966 type_to_string (aux_base, index+1, fdp));
968 else /* global symbol */
969 printf (" Local symbol: %ld\n", index);
971 if (want_scope)
973 if (free_scope == (scope_t *) 0)
974 scope_ptr = (scope_t *) malloc (sizeof (scope_t));
975 else
977 scope_ptr = free_scope;
978 free_scope = scope_ptr->prev;
980 scope_ptr->open_sym = number;
981 scope_ptr->st = symbol_type;
982 scope_ptr->sc = storage_class;
983 scope_ptr->prev = cur_scope;
984 cur_scope = scope_ptr;
986 break;
988 #ifdef stStruct
989 case st_Struct:
990 case st_Union:
991 case st_Enum:
992 printf (" End+1 symbol: %lu\n", index);
993 break;
994 #endif
996 default:
997 if (!MIPS_IS_STAB (sym_ptr))
999 used_ptr[index] = 1;
1000 printf (" Type: %s\n",
1001 type_to_string (aux_base, index, fdp));
1003 break;
1006 if (want_scope)
1008 printf (" Scopes: ");
1009 if (cur_scope == (scope_t *) 0)
1010 printf (" none\n");
1011 else
1013 for (scope_ptr = cur_scope;
1014 scope_ptr != (scope_t *) 0;
1015 scope_ptr = scope_ptr->prev)
1017 char *class;
1018 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1019 class = "func.";
1020 else if (scope_ptr->st == st_File)
1021 class = "file";
1022 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1023 class = "block";
1024 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1025 class = "type";
1026 else
1027 class = "???";
1029 printf (" %ld [%s]", scope_ptr->open_sym, class);
1031 printf ("\n");
1035 printf (" Value: %-13ld ",
1036 (long)sym_ptr->value);
1037 if (ifd == -1)
1038 printf ("String index: %ld\n", (long)sym_ptr->iss);
1039 else
1040 printf ("String index: %-11ld Ifd: %d\n",
1041 (long)sym_ptr->iss, ifd);
1043 printf (" Symbol type: %-11sStorage class: %-11s",
1044 st_to_string (symbol_type), sc_to_string (storage_class));
1046 if (MIPS_IS_STAB(sym_ptr))
1048 register int i = sizeof(stab_names) / sizeof(stab_names[0]);
1049 char *stab_name = "stab";
1050 short code = MIPS_UNMARK_STAB(sym_ptr->index);
1051 while (--i >= 0)
1052 if (stab_names[i].code == code)
1054 stab_name = stab_names[i].string;
1055 break;
1057 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1059 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1060 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1061 else
1062 printf ("Index: %ld\n", (long)sym_ptr->index);
1067 /* Print out a word from the aux. table in various formats. */
1069 void
1070 print_aux (u, auxi, used)
1071 AUXU u;
1072 int auxi;
1073 int used;
1075 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1076 (used) ? " " : "* ",
1077 auxi,
1078 (long) u.isym,
1079 (long) u.rndx.rfd,
1080 (long) u.rndx.index,
1081 u.ti.bt,
1082 u.ti.fBitfield,
1083 u.ti.continued,
1084 u.ti.tq0,
1085 u.ti.tq1,
1086 u.ti.tq2,
1087 u.ti.tq3,
1088 u.ti.tq4,
1089 u.ti.tq5);
1093 /* Write aggregate information to a string. */
1095 void
1096 emit_aggregate (string, u, u2, which, fdp)
1097 char *string;
1098 AUXU u;
1099 AUXU u2;
1100 const char *which;
1101 FDR *fdp;
1103 unsigned int ifd = u.rndx.rfd;
1104 unsigned int index = u.rndx.index;
1105 const char *name;
1107 if (ifd == ST_RFDESCAPE)
1108 ifd = u2.isym;
1110 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1111 struct return type of a procedure compiled without -g. */
1112 if (ifd == 0xffffffff
1113 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
1114 name = "<undefined>";
1115 else if (index == indexNil)
1116 name = "<no name>";
1117 else
1119 if (fdp == 0 || sym_hdr.crfd == 0)
1120 fdp = &file_desc[ifd];
1121 else
1122 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1123 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1126 sprintf (string,
1127 "%s %s { ifd = %u, index = %u }",
1128 which, name, ifd, index);
1132 /* Print out information about a file descriptor, and the symbols,
1133 procedures, and line numbers within it. */
1135 void
1136 print_file_desc (fdp, number)
1137 FDR *fdp;
1138 int number;
1140 char *str_base;
1141 AUXU *aux_base;
1142 int symi, pdi;
1143 int width = 20;
1144 char *used_base;
1146 str_base = l_strings + fdp->issBase;
1147 aux_base = aux_symbols + fdp->iauxBase;
1148 used_base = aux_used + (aux_base - aux_symbols);
1150 printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss);
1152 printf (" Name index = %-10ld Readin = %s\n",
1153 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1155 printf (" Merge = %-10s Endian = %s\n",
1156 (fdp->fMerge) ? "Yes" : "No",
1157 (fdp->fBigendian) ? "BIG" : "LITTLE");
1159 printf (" Debug level = %-10s Language = %s\n",
1160 glevel_to_string (fdp->glevel),
1161 lang_to_string((lang_t) fdp->lang));
1163 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1165 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1166 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1168 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1169 width, "Local strings",
1170 (ulong) fdp->issBase,
1171 (ulong) fdp->cbSs,
1172 (ulong) fdp->cbSs,
1173 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
1175 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1176 width, "Local symbols",
1177 (ulong) fdp->isymBase,
1178 (ulong) fdp->csym,
1179 (ulong) (fdp->csym * sizeof (SYMR)),
1180 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
1182 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1183 width, "Line numbers",
1184 (ulong) fdp->cbLineOffset,
1185 (ulong) fdp->cline,
1186 (ulong) fdp->cbLine,
1187 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
1189 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1190 width, "Optimization symbols",
1191 (ulong) fdp->ioptBase,
1192 (ulong) fdp->copt,
1193 (ulong) (fdp->copt * sizeof (OPTR)),
1194 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
1196 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1197 width, "Procedures",
1198 (ulong) fdp->ipdFirst,
1199 (ulong) fdp->cpd,
1200 (ulong) (fdp->cpd * sizeof (PDR)),
1201 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
1203 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1204 width, "Auxiliary symbols",
1205 (ulong) fdp->iauxBase,
1206 (ulong) fdp->caux,
1207 (ulong) (fdp->caux * sizeof (AUXU)),
1208 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
1210 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1211 width, "Relative Files",
1212 (ulong) fdp->rfdBase,
1213 (ulong) fdp->crfd,
1214 (ulong) (fdp->crfd * sizeof (ulong)),
1215 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
1218 if (want_scope && cur_scope != (scope_t *) 0)
1219 printf ("\n Warning scope does not start at 0!\n");
1222 * print the info about the symbol table.
1224 printf ("\n There are %lu local symbols, starting at %lu\n",
1225 (ulong) fdp->csym,
1226 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1228 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
1229 print_symbol (&l_symbols[symi],
1230 symi - fdp->isymBase,
1231 str_base,
1232 aux_base,
1234 fdp);
1236 if (want_scope && cur_scope != (scope_t *) 0)
1237 printf ("\n Warning scope does not end at 0!\n");
1240 * print the aux. table if desired.
1243 if (want_aux && fdp->caux != 0)
1245 int auxi;
1247 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
1248 (ulong) fdp->caux,
1249 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
1251 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1252 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1256 * print the relative file descriptors.
1258 if (want_rfd && fdp->crfd != 0)
1260 ulong *rfd_ptr, i;
1262 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1263 (ulong) fdp->crfd,
1264 (ulong) fdp->rfdBase);
1266 rfd_ptr = rfile_desc + fdp->rfdBase;
1267 for (i = 0; i < fdp->crfd; i++)
1269 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1270 rfd_ptr++;
1275 * do the procedure descriptors.
1277 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1278 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1280 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1282 PDR *proc_ptr = &proc_desc[pdi];
1283 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1285 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1286 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
1287 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
1289 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1290 (long) proc_ptr->regmask,
1291 (long) proc_ptr->regoffset,
1292 (long) proc_ptr->fregmask,
1293 (long) proc_ptr->fregoffset);
1295 printf ("\t .frame $%d,%ld,$%d\n",
1296 (int) proc_ptr->framereg,
1297 (long) proc_ptr->frameoffset,
1298 (int) proc_ptr->pcreg);
1300 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1301 (long) proc_ptr->iopt,
1302 (long) proc_ptr->isym);
1304 printf ("\t First line # = %-11ld Last line # = %ld\n",
1305 (long) proc_ptr->lnLow,
1306 (long) proc_ptr->lnHigh);
1308 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1309 (long) proc_ptr->cbLineOffset,
1310 (long) proc_ptr->adr);
1313 * print the line number entries.
1316 if (want_line && fdp->cline != 0)
1318 int delta, count;
1319 long cur_line = proc_ptr->lnLow;
1320 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1321 + fdp->cbLineOffset);
1322 uchar *line_end;
1324 if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */
1325 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
1326 else /* not last proc. */
1327 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
1328 + fdp->cbLineOffset);
1330 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1331 (ulong) (line_end - line_ptr),
1332 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
1334 while (line_ptr < line_end)
1335 { /* sign extend nibble */
1336 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1337 count = (*line_ptr & 0xf) + 1;
1338 if (delta != -8)
1339 line_ptr++;
1340 else
1342 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1343 delta = (delta ^ 0x8000) - 0x8000;
1344 line_ptr += 3;
1347 cur_line += delta;
1348 printf ("\t Line %11ld, delta %5d, count %2d\n",
1349 cur_line,
1350 delta,
1351 count);
1358 /* Read in the portions of the .T file that we will print out. */
1360 void
1361 read_tfile __proto((void))
1363 short magic;
1364 off_t sym_hdr_offset = 0;
1366 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number");
1367 if (!tfile)
1369 /* Print out the global header, since this is not a T-file. */
1371 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0,
1372 "Global file header");
1374 print_global_hdr (&global_hdr);
1376 if (global_hdr.f_symptr == 0)
1378 printf ("No symbolic header, Goodbye!\n");
1379 exit (1);
1382 sym_hdr_offset = global_hdr.f_symptr;
1385 (void) read_seek ((PTR_T) &sym_hdr,
1386 sizeof (sym_hdr),
1387 sym_hdr_offset,
1388 "Symbolic header");
1390 print_sym_hdr (&sym_hdr);
1392 lines = (LINER *) read_seek ((PTR_T) 0,
1393 sym_hdr.cbLine,
1394 sym_hdr.cbLineOffset,
1395 "Line numbers");
1397 dense_nums = (DNR *) read_seek ((PTR_T) 0,
1398 sym_hdr.idnMax * sizeof (DNR),
1399 sym_hdr.cbDnOffset,
1400 "Dense numbers");
1402 proc_desc = (PDR *) read_seek ((PTR_T) 0,
1403 sym_hdr.ipdMax * sizeof (PDR),
1404 sym_hdr.cbPdOffset,
1405 "Procedure tables");
1407 l_symbols = (SYMR *) read_seek ((PTR_T) 0,
1408 sym_hdr.isymMax * sizeof (SYMR),
1409 sym_hdr.cbSymOffset,
1410 "Local symbols");
1412 opt_symbols = (OPTR *) read_seek ((PTR_T) 0,
1413 sym_hdr.ioptMax * sizeof (OPTR),
1414 sym_hdr.cbOptOffset,
1415 "Optimization symbols");
1417 aux_symbols = (AUXU *) read_seek ((PTR_T) 0,
1418 sym_hdr.iauxMax * sizeof (AUXU),
1419 sym_hdr.cbAuxOffset,
1420 "Auxiliary symbols");
1422 if (sym_hdr.iauxMax > 0)
1424 aux_used = calloc (sym_hdr.iauxMax, 1);
1425 if (aux_used == (char *) 0)
1427 perror ("calloc");
1428 exit (1);
1432 l_strings = (char *) read_seek ((PTR_T) 0,
1433 sym_hdr.issMax,
1434 sym_hdr.cbSsOffset,
1435 "Local string table");
1437 e_strings = (char *) read_seek ((PTR_T) 0,
1438 sym_hdr.issExtMax,
1439 sym_hdr.cbSsExtOffset,
1440 "External string table");
1442 file_desc = (FDR *) read_seek ((PTR_T) 0,
1443 sym_hdr.ifdMax * sizeof (FDR),
1444 sym_hdr.cbFdOffset,
1445 "File tables");
1447 rfile_desc = (ulong *) read_seek ((PTR_T) 0,
1448 sym_hdr.crfd * sizeof (ulong),
1449 sym_hdr.cbRfdOffset,
1450 "Relative file tables");
1452 e_symbols = (EXTR *) read_seek ((PTR_T) 0,
1453 sym_hdr.iextMax * sizeof (EXTR),
1454 sym_hdr.cbExtOffset,
1455 "External symbols");
1461 main (argc, argv)
1462 int argc;
1463 char **argv;
1465 int i, opt;
1468 * Process arguments
1470 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1471 switch (opt)
1473 default: errors++; break;
1474 case 'a': want_aux++; break; /* print aux table */
1475 case 'l': want_line++; break; /* print line numbers */
1476 case 'r': want_rfd++; break; /* print relative fd's */
1477 case 's': want_scope++; break; /* print scope info */
1478 case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
1481 if (errors || optind != argc - 1)
1483 fprintf (stderr, "Calling Sequence:\n");
1484 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
1485 fprintf (stderr, "\n");
1486 fprintf (stderr, "switches:\n");
1487 fprintf (stderr, "\t-a Print out auxiliary table.\n");
1488 fprintf (stderr, "\t-l Print out line numbers.\n");
1489 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
1490 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
1491 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
1492 return 1;
1496 * Open and process the input file.
1498 tfile_fd = open (argv[optind], O_RDONLY);
1499 if (tfile_fd < 0)
1501 perror (argv[optind]);
1502 return 1;
1505 read_tfile ();
1508 * Print any global aux words if any.
1510 if (want_aux)
1512 long last_aux_in_use;
1514 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1516 printf ("\nGlobal auxiliary entries before first file:\n");
1517 for (i = 0; i < file_desc[0].iauxBase; i++)
1518 print_aux (aux_symbols[i], 0, aux_used[i]);
1521 if (sym_hdr.ifdMax == 0)
1522 last_aux_in_use = 0;
1523 else
1524 last_aux_in_use
1525 = (file_desc[sym_hdr.ifdMax-1].iauxBase
1526 + file_desc[sym_hdr.ifdMax-1].caux - 1);
1528 if (last_aux_in_use < sym_hdr.iauxMax-1)
1530 printf ("\nGlobal auxiliary entries after last file:\n");
1531 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
1532 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
1537 * Print the information for each file.
1539 for (i = 0; i < sym_hdr.ifdMax; i++)
1540 print_file_desc (&file_desc[i], i);
1543 * Print the external symbols.
1545 want_scope = 0; /* scope info is meaning for extern symbols */
1546 printf ("\nThere are %lu external symbols, starting at %lu\n",
1547 (ulong) sym_hdr.iextMax,
1548 (ulong) sym_hdr.cbExtOffset);
1550 for(i = 0; i < sym_hdr.iextMax; i++)
1551 print_symbol (&e_symbols[i].asym, i, e_strings,
1552 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
1553 e_symbols[i].ifd,
1554 &file_desc[e_symbols[i].ifd]);
1557 * Print unused aux symbols now.
1560 if (want_aux)
1562 int first_time = 1;
1564 for (i = 0; i < sym_hdr.iauxMax; i++)
1566 if (! aux_used[i])
1568 if (first_time)
1570 printf ("\nThe following auxiliary table entries were unused:\n\n");
1571 first_time = 0;
1574 printf (" #%-5d %11ld 0x%08lx %s\n",
1576 (long) aux_symbols[i].isym,
1577 (long) aux_symbols[i].isym,
1578 type_to_string (aux_symbols, i, (FDR *) 0));
1583 return 0;
1587 void
1588 fancy_abort ()
1590 fprintf (stderr, "mips-tdump internal error");
1591 exit (1);
1594 void
1595 fatal(s)
1596 char *s;
1598 fprintf(stderr, "%s\n", s);
1599 exit(1);
1602 /* Same as `malloc' but report error if no memory available. */
1604 PTR_T
1605 xmalloc (size)
1606 unsigned size;
1608 register PTR_T value = malloc (size);
1609 if (value == 0)
1610 fatal ("Virtual memory exhausted.");
1611 return value;