]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/mips-tdump.c
1 /* Read and manage MIPS symbol tables from object modules.
2 Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999
3 Free Software Foundation, Inc.
4 Contributed by hartzell@boulder.colorado.edu,
5 Rewritten by meissner@osf.org.
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
33 #include "mips/a.out.h"
34 #endif /* CROSS_COMPILE */
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)
50 #define __proto(x) PARAMS(x)
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
64 fprintf(stderr
, "%s\n", s
);
65 exit(FATAL_EXIT_CODE
);
68 /* Due to size_t being defined in sys/types.h and different
69 in stddef.h, we have to do this by hand..... Note, these
70 types are correct for MIPS based systems, and may not be
71 correct for other systems. */
77 /* Redefinition of storage classes as an enumeration for better
81 #define stStaParam 16 /* Fortran static parameters */
85 #define btVoid 26 /* void basic type */
89 sc_Nil
= scNil
, /* no storage class */
90 sc_Text
= scText
, /* text symbol */
91 sc_Data
= scData
, /* initialized data symbol */
92 sc_Bss
= scBss
, /* un-initialized data symbol */
93 sc_Register
= scRegister
, /* value of symbol is register number */
94 sc_Abs
= scAbs
, /* value of symbol is absolute */
95 sc_Undefined
= scUndefined
, /* who knows? */
96 sc_CdbLocal
= scCdbLocal
, /* variable's value is IN se->va.?? */
97 sc_Bits
= scBits
, /* this is a bit field */
98 sc_CdbSystem
= scCdbSystem
, /* var's value is IN CDB's address space */
99 sc_RegImage
= scRegImage
, /* register value saved on stack */
100 sc_Info
= scInfo
, /* symbol contains debugger information */
101 sc_UserStruct
= scUserStruct
, /* addr in struct user for current process */
102 sc_SData
= scSData
, /* load time only small data */
103 sc_SBss
= scSBss
, /* load time only small common */
104 sc_RData
= scRData
, /* load time only read only data */
105 sc_Var
= scVar
, /* Var parameter (fortran,pascal) */
106 sc_Common
= scCommon
, /* common variable */
107 sc_SCommon
= scSCommon
, /* small common */
108 sc_VarRegister
= scVarRegister
, /* Var parameter in a register */
109 sc_Variant
= scVariant
, /* Variant record */
110 sc_SUndefined
= scSUndefined
, /* small undefined(external) data */
111 sc_Init
= scInit
, /* .init section symbol */
112 sc_Max
= scMax
/* Max storage class+1 */
115 /* Redefinition of symbol type. */
118 st_Nil
= stNil
, /* Nuthin' special */
119 st_Global
= stGlobal
, /* external symbol */
120 st_Static
= stStatic
, /* static */
121 st_Param
= stParam
, /* procedure argument */
122 st_Local
= stLocal
, /* local variable */
123 st_Label
= stLabel
, /* label */
124 st_Proc
= stProc
, /* " " Procedure */
125 st_Block
= stBlock
, /* beginning of block */
126 st_End
= stEnd
, /* end (of anything) */
127 st_Member
= stMember
, /* member (of anything - struct/union/enum */
128 st_Typedef
= stTypedef
, /* type definition */
129 st_File
= stFile
, /* file name */
130 st_RegReloc
= stRegReloc
, /* register relocation */
131 st_Forward
= stForward
, /* forwarding address */
132 st_StaticProc
= stStaticProc
, /* load time only static procs */
133 st_StaParam
= stStaParam
, /* Fortran static parameters */
134 st_Constant
= stConstant
, /* const */
136 st_Struct
= stStruct
, /* struct */
137 st_Union
= stUnion
, /* union */
138 st_Enum
= stEnum
, /* enum */
140 st_Str
= stStr
, /* string */
141 st_Number
= stNumber
, /* pure number (ie. 4 NOR 2+2) */
142 st_Expr
= stExpr
, /* 2+2 vs. 4 */
143 st_Type
= stType
, /* post-coercion SER */
144 st_Max
= stMax
/* max type+1 */
147 /* Redefinition of type qualifiers. */
150 tq_Nil
= tqNil
, /* bt is what you see */
151 tq_Ptr
= tqPtr
, /* pointer */
152 tq_Proc
= tqProc
, /* procedure */
153 tq_Array
= tqArray
, /* duh */
154 tq_Far
= tqFar
, /* longer addressing - 8086/8 land */
155 tq_Vol
= tqVol
, /* volatile */
156 tq_Max
= tqMax
/* Max type qualifier+1 */
159 /* Redefinition of basic types. */
162 bt_Nil
= btNil
, /* undefined */
163 bt_Adr
= btAdr
, /* address - integer same size as pointer */
164 bt_Char
= btChar
, /* character */
165 bt_UChar
= btUChar
, /* unsigned character */
166 bt_Short
= btShort
, /* short */
167 bt_UShort
= btUShort
, /* unsigned short */
168 bt_Int
= btInt
, /* int */
169 bt_UInt
= btUInt
, /* unsigned int */
170 bt_Long
= btLong
, /* long */
171 bt_ULong
= btULong
, /* unsigned long */
172 bt_Float
= btFloat
, /* float (real) */
173 bt_Double
= btDouble
, /* Double (real) */
174 bt_Struct
= btStruct
, /* Structure (Record) */
175 bt_Union
= btUnion
, /* Union (variant) */
176 bt_Enum
= btEnum
, /* Enumerated */
177 bt_Typedef
= btTypedef
, /* defined via a typedef, isymRef points */
178 bt_Range
= btRange
, /* subrange of int */
179 bt_Set
= btSet
, /* pascal sets */
180 bt_Complex
= btComplex
, /* fortran complex */
181 bt_DComplex
= btDComplex
, /* fortran double complex */
182 bt_Indirect
= btIndirect
, /* forward or unnamed typedef */
183 bt_FixedDec
= btFixedDec
, /* Fixed Decimal */
184 bt_FloatDec
= btFloatDec
, /* Float Decimal */
185 bt_String
= btString
, /* Varying Length Character String */
186 bt_Bit
= btBit
, /* Aligned Bit String */
187 bt_Picture
= btPicture
, /* Picture */
188 bt_Void
= btVoid
, /* void */
189 bt_Max
= btMax
/* Max basic type+1 */
192 /* Redefinition of the language codes. */
196 lang_Pascal
= langPascal
,
197 lang_Fortran
= langFortran
,
198 lang_Assembler
= langAssembler
,
199 lang_Machine
= langMachine
,
203 lang_Cobol
= langCobol
206 /* Redefinition of the debug level codes. */
208 typedef enum glevel
{
216 /* Keep track of the active scopes. */
217 typedef struct scope
{
218 struct scope
*prev
; /* previous scope */
219 ulong open_sym
; /* symbol opening scope */
220 sc_t sc
; /* storage class */
221 st_t st
; /* symbol type */
224 struct filehdr global_hdr
; /* a.out header */
226 int errors
= 0; /* # of errors */
227 int want_aux
= 0; /* print aux table */
228 int want_line
= 0; /* print line numbers */
229 int want_rfd
= 0; /* print relative file desc's */
230 int want_scope
= 0; /* print scopes for every symbol */
231 int tfile
= 0; /* no global header file */
232 int tfile_fd
; /* file descriptor of .T file */
233 off_t tfile_offset
; /* current offset in .T file */
234 scope_t
*cur_scope
= 0; /* list of active scopes */
235 scope_t
*free_scope
= 0; /* list of freed scopes */
236 HDRR sym_hdr
; /* symbolic header */
237 char *l_strings
; /* local strings */
238 char *e_strings
; /* external strings */
239 SYMR
*l_symbols
; /* local symbols */
240 EXTR
*e_symbols
; /* external symbols */
241 LINER
*lines
; /* line numbers */
242 DNR
*dense_nums
; /* dense numbers */
243 OPTR
*opt_symbols
; /* optimization symbols */
244 AUXU
*aux_symbols
; /* Auxiliary symbols */
245 char *aux_used
; /* map of which aux syms are used */
246 FDR
*file_desc
; /* file tables */
247 ulong
*rfile_desc
; /* relative file tables */
248 PDR
*proc_desc
; /* procedure tables */
250 /* Forward reference for functions. */
251 PTR_T read_seek
__proto((PTR_T
, size_t, off_t
, const char *));
252 void read_tfile
__proto((void));
253 void print_global_hdr
__proto((struct filehdr
*));
254 void print_sym_hdr
__proto((HDRR
*));
255 void print_file_desc
__proto((FDR
*, int));
256 void print_symbol
__proto((SYMR
*, int, char *, AUXU
*, int, FDR
*));
257 void print_aux
__proto((AUXU
, int, int));
258 void emit_aggregate
__proto((char *, AUXU
, AUXU
, const char *, FDR
*));
259 const char *st_to_string
__proto((st_t
));
260 const char *sc_to_string
__proto((sc_t
));
261 const char *glevel_to_string
__proto((glevel_t
));
262 const char *lang_to_string
__proto((lang_t
));
263 const char *type_to_string
__proto((AUXU
*, int, FDR
*));
266 # ifdef NEED_DECLARATION_MALLOC
267 extern PTR_T malloc
__proto((size_t));
269 # ifdef NEED_DECLARATION_CALLOC
270 extern PTR_T calloc
__proto((size_t, size_t));
272 # ifdef NEED_DECLARATION_REALLOC
273 extern PTR_T realloc
__proto((PTR_T
, size_t));
281 /* Create a table of debugging stab-codes and corresponding names. */
283 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
284 struct {short code
; char string
[10];} stab_names
[] = {
290 /* Read some bytes at a specified location, and return a pointer. */
293 read_seek (ptr
, size
, offset
, context
)
294 PTR_T ptr
; /* pointer to buffer or NULL */
295 size_t size
; /* # bytes to read */
296 off_t offset
; /* offset to read at */
297 const char *context
; /* context for error message */
301 if (size
== 0) /* nothing to read */
304 if ((ptr
== (PTR_T
) 0 && (ptr
= malloc (size
)) == (PTR_T
) 0)
305 || (tfile_offset
!= offset
&& lseek (tfile_fd
, offset
, 0) == -1)
306 || (read_size
= read (tfile_fd
, ptr
, size
)) < 0)
312 if (read_size
!= size
)
314 fprintf (stderr
, "%s: read %ld bytes, expected %ld bytes\n",
315 context
, read_size
, (long) size
);
319 tfile_offset
= offset
+ size
;
324 /* Convert language code to string format. */
327 lang_to_string (lang
)
332 case langC
: return "C";
333 case langPascal
: return "Pascal";
334 case langFortran
: return "Fortran";
335 case langAssembler
: return "Assembler";
336 case langMachine
: return "Machine";
337 case langNil
: return "Nil";
338 case langAda
: return "Ada";
339 case langPl1
: return "Pl1";
340 case langCobol
: return "Cobol";
343 return "Unknown language";
347 /* Convert storage class to string. */
350 sc_to_string(storage_class
)
353 switch(storage_class
)
355 case sc_Nil
: return "Nil";
356 case sc_Text
: return "Text";
357 case sc_Data
: return "Data";
358 case sc_Bss
: return "Bss";
359 case sc_Register
: return "Register";
360 case sc_Abs
: return "Abs";
361 case sc_Undefined
: return "Undefined";
362 case sc_CdbLocal
: return "CdbLocal";
363 case sc_Bits
: return "Bits";
364 case sc_CdbSystem
: return "CdbSystem";
365 case sc_RegImage
: return "RegImage";
366 case sc_Info
: return "Info";
367 case sc_UserStruct
: return "UserStruct";
368 case sc_SData
: return "SData";
369 case sc_SBss
: return "SBss";
370 case sc_RData
: return "RData";
371 case sc_Var
: return "Var";
372 case sc_Common
: return "Common";
373 case sc_SCommon
: return "SCommon";
374 case sc_VarRegister
: return "VarRegister";
375 case sc_Variant
: return "Variant";
376 case sc_SUndefined
: return "SUndefined";
377 case sc_Init
: return "Init";
378 case sc_Max
: return "Max";
385 /* Convert symbol type to string. */
388 st_to_string(symbol_type
)
393 case st_Nil
: return "Nil";
394 case st_Global
: return "Global";
395 case st_Static
: return "Static";
396 case st_Param
: return "Param";
397 case st_Local
: return "Local";
398 case st_Label
: return "Label";
399 case st_Proc
: return "Proc";
400 case st_Block
: return "Block";
401 case st_End
: return "End";
402 case st_Member
: return "Member";
403 case st_Typedef
: return "Typedef";
404 case st_File
: return "File";
405 case st_RegReloc
: return "RegReloc";
406 case st_Forward
: return "Forward";
407 case st_StaticProc
: return "StaticProc";
408 case st_Constant
: return "Constant";
409 case st_StaParam
: return "StaticParam";
411 case st_Struct
: return "Struct";
412 case st_Union
: return "Union";
413 case st_Enum
: return "Enum";
415 case st_Str
: return "String";
416 case st_Number
: return "Number";
417 case st_Expr
: return "Expr";
418 case st_Type
: return "Type";
419 case st_Max
: return "Max";
426 /* Convert debug level to string. */
429 glevel_to_string (g_level
)
434 case GLEVEL_0
: return "G0";
435 case GLEVEL_1
: return "G1";
436 case GLEVEL_2
: return "G2";
437 case GLEVEL_3
: return "G3";
444 /* Convert the type information to string format. */
447 type_to_string (aux_ptr
, index
, fdp
)
462 static char buffer1
[1024];
463 static char buffer2
[1024];
466 char *used_ptr
= aux_used
+ (aux_ptr
- aux_symbols
);
468 for (i
= 0; i
< 7; i
++)
470 qualifiers
[i
].low_bound
= 0;
471 qualifiers
[i
].high_bound
= 0;
472 qualifiers
[i
].stride
= 0;
476 u
= aux_ptr
[index
++];
478 return "-1 (no type)";
480 basic_type
= (bt_t
) u
.ti
.bt
;
481 qualifiers
[0].type
= (tq_t
) u
.ti
.tq0
;
482 qualifiers
[1].type
= (tq_t
) u
.ti
.tq1
;
483 qualifiers
[2].type
= (tq_t
) u
.ti
.tq2
;
484 qualifiers
[3].type
= (tq_t
) u
.ti
.tq3
;
485 qualifiers
[4].type
= (tq_t
) u
.ti
.tq4
;
486 qualifiers
[5].type
= (tq_t
) u
.ti
.tq5
;
487 qualifiers
[6].type
= tq_Nil
;
490 * Go get the basic type.
494 case bt_Nil
: /* undefined */
498 case bt_Adr
: /* address - integer same size as pointer */
499 strcpy (p1
, "address");
502 case bt_Char
: /* character */
506 case bt_UChar
: /* unsigned character */
507 strcpy (p1
, "unsigned char");
510 case bt_Short
: /* short */
511 strcpy (p1
, "short");
514 case bt_UShort
: /* unsigned short */
515 strcpy (p1
, "unsigned short");
518 case bt_Int
: /* int */
522 case bt_UInt
: /* unsigned int */
523 strcpy (p1
, "unsigned int");
526 case bt_Long
: /* long */
530 case bt_ULong
: /* unsigned long */
531 strcpy (p1
, "unsigned long");
534 case bt_Float
: /* float (real) */
535 strcpy (p1
, "float");
538 case bt_Double
: /* Double (real) */
539 strcpy (p1
, "double");
542 /* Structures add 1-2 aux words:
543 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
544 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
546 case bt_Struct
: /* Structure (Record) */
547 emit_aggregate (p1
, aux_ptr
[index
], aux_ptr
[index
+1], "struct", fdp
);
549 if (aux_ptr
[index
].rndx
.rfd
== ST_RFDESCAPE
)
550 used_ptr
[++index
] = 1;
552 index
++; /* skip aux words */
555 /* Unions add 1-2 aux words:
556 1st word is [ST_RFDESCAPE, offset] pointer to union def;
557 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
559 case bt_Union
: /* Union */
560 emit_aggregate (p1
, aux_ptr
[index
], aux_ptr
[index
+1], "union", fdp
);
562 if (aux_ptr
[index
].rndx
.rfd
== ST_RFDESCAPE
)
563 used_ptr
[++index
] = 1;
565 index
++; /* skip aux words */
568 /* Enumerations add 1-2 aux words:
569 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
570 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
572 case bt_Enum
: /* Enumeration */
573 emit_aggregate (p1
, aux_ptr
[index
], aux_ptr
[index
+1], "enum", fdp
);
575 if (aux_ptr
[index
].rndx
.rfd
== ST_RFDESCAPE
)
576 used_ptr
[++index
] = 1;
578 index
++; /* skip aux words */
581 case bt_Typedef
: /* defined via a typedef, isymRef points */
582 strcpy (p1
, "typedef");
585 case bt_Range
: /* subrange of int */
586 strcpy (p1
, "subrange");
589 case bt_Set
: /* pascal sets */
593 case bt_Complex
: /* fortran complex */
594 strcpy (p1
, "complex");
597 case bt_DComplex
: /* fortran double complex */
598 strcpy (p1
, "double complex");
601 case bt_Indirect
: /* forward or unnamed typedef */
602 strcpy (p1
, "forward/unnamed typedef");
605 case bt_FixedDec
: /* Fixed Decimal */
606 strcpy (p1
, "fixed decimal");
609 case bt_FloatDec
: /* Float Decimal */
610 strcpy (p1
, "float decimal");
613 case bt_String
: /* Varying Length Character String */
614 strcpy (p1
, "string");
617 case bt_Bit
: /* Aligned Bit String */
621 case bt_Picture
: /* Picture */
622 strcpy (p1
, "picture");
625 case bt_Void
: /* Void */
630 sprintf (p1
, "Unknown basic type %d", (int) basic_type
);
634 p1
+= strlen (buffer1
);
637 * If this is a bitfield, get the bitsize.
644 bitsize
= aux_ptr
[index
++].width
;
645 sprintf (p1
, " : %d", bitsize
);
646 p1
+= strlen (buffer1
);
651 * Deal with any qualifiers.
653 if (qualifiers
[0].type
!= tq_Nil
)
656 * Snarf up any array bounds in the correct order. Arrays
657 * store 5 successive words in the aux. table:
658 * word 0 RNDXR to type of the bounds (ie, int)
659 * word 1 Current file descriptor index
661 * word 3 high bound (or -1 if [])
662 * word 4 stride size in bits
664 for (i
= 0; i
< 7; i
++)
666 if (qualifiers
[i
].type
== tq_Array
)
668 qualifiers
[i
].low_bound
= aux_ptr
[index
+2].dnLow
;
669 qualifiers
[i
].high_bound
= aux_ptr
[index
+3].dnHigh
;
670 qualifiers
[i
].stride
= aux_ptr
[index
+4].width
;
672 used_ptr
[index
+1] = 1;
673 used_ptr
[index
+2] = 1;
674 used_ptr
[index
+3] = 1;
675 used_ptr
[index
+4] = 1;
681 * Now print out the qualifiers.
683 for (i
= 0; i
< 6; i
++)
685 switch (qualifiers
[i
].type
)
692 strcpy (p2
, "ptr to ");
693 p2
+= sizeof ("ptr to ")-1;
697 strcpy (p2
, "volatile ");
698 p2
+= sizeof ("volatile ")-1;
703 p2
+= sizeof ("far ")-1;
707 strcpy (p2
, "func. ret. ");
708 p2
+= sizeof ("func. ret. ");
716 /* Print array bounds reversed (ie, in the order the C
717 programmer writes them). C is such a fun language.... */
719 while (i
< 5 && qualifiers
[i
+1].type
== tq_Array
)
722 for (j
= i
; j
>= first_array
; j
--)
724 strcpy (p2
, "array [");
725 p2
+= sizeof ("array [")-1;
726 if (qualifiers
[j
].low_bound
!= 0)
728 "%ld:%ld {%ld bits}",
729 (long) qualifiers
[j
].low_bound
,
730 (long) qualifiers
[j
].high_bound
,
731 (long) qualifiers
[j
].stride
);
733 else if (qualifiers
[j
].high_bound
!= -1)
736 (long) (qualifiers
[j
].high_bound
+ 1),
737 (long) (qualifiers
[j
].stride
));
740 sprintf (p2
, " {%ld bits}", (long) (qualifiers
[j
].stride
));
743 strcpy (p2
, "] of ");
744 p2
+= sizeof ("] of ")-1;
752 strcpy (p2
, buffer1
);
757 /* Print out the global file header for object files. */
760 print_global_hdr (ptr
)
763 char *time
= ctime ((time_t *)&ptr
->f_timdat
);
764 ushort flags
= ptr
->f_flags
;
766 printf("Global file header:\n");
767 printf(" %-*s 0x%x\n", 24, "magic number", (ushort
) ptr
->f_magic
);
768 printf(" %-*s %d\n", 24, "# sections", (int) ptr
->f_nscns
);
769 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr
->f_timdat
, time
);
770 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr
->f_symptr
);
771 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr
->f_nsyms
);
772 printf(" %-*s %ld\n", 24, "optional header", (long) ptr
->f_opthdr
);
773 printf(" %-*s 0x%x", 24, "flags", (ushort
) flags
);
775 if ((flags
& F_RELFLG
) != 0)
776 printf (", F_RELFLG");
778 if ((flags
& F_EXEC
) != 0)
781 if ((flags
& F_LNNO
) != 0)
784 if ((flags
& F_LSYMS
) != 0)
785 printf (", F_LSYMS");
787 if ((flags
& F_MINMAL
) != 0)
788 printf (", F_MINMAL");
790 if ((flags
& F_UPDATE
) != 0)
791 printf (", F_UPDATE");
793 if ((flags
& F_SWABD
) != 0)
794 printf (", F_SWABD");
796 if ((flags
& F_AR16WR
) != 0)
797 printf (", F_AR16WR");
799 if ((flags
& F_AR32WR
) != 0)
800 printf (", F_AR32WR");
802 if ((flags
& F_AR32W
) != 0)
803 printf (", F_AR32W");
805 if ((flags
& F_PATCH
) != 0)
806 printf (", F_PATCH/F_NODF");
812 /* Print out the symbolic header. */
815 print_sym_hdr (sym_ptr
)
820 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
821 sym_ptr
->magic
& 0xffff,
822 (sym_ptr
->vstamp
& 0xffff) >> 8,
823 sym_ptr
->vstamp
& 0xff);
825 printf(" %-*s %11s %11s %11s\n", width
, "Info", "Offset", "Number", "Bytes");
826 printf(" %-*s %11s %11s %11s\n", width
, "====", "======", "======", "=====\n");
828 printf(" %-*s %11ld %11ld %11ld [%d]\n", width
, "Line numbers",
829 (long) sym_ptr
->cbLineOffset
,
830 (long) sym_ptr
->cbLine
,
831 (long) sym_ptr
->cbLine
,
832 (int) sym_ptr
->ilineMax
);
834 printf(" %-*s %11ld %11ld %11ld\n", width
, "Dense numbers",
835 (long) sym_ptr
->cbDnOffset
,
836 (long) sym_ptr
->idnMax
,
837 (long) (sym_ptr
->idnMax
* sizeof (DNR
)));
839 printf(" %-*s %11ld %11ld %11ld\n", width
, "Procedures Tables",
840 (long) sym_ptr
->cbPdOffset
,
841 (long) sym_ptr
->ipdMax
,
842 (long) (sym_ptr
->ipdMax
* sizeof (PDR
)));
844 printf(" %-*s %11ld %11ld %11ld\n", width
, "Local Symbols",
845 (long) sym_ptr
->cbSymOffset
,
846 (long) sym_ptr
->isymMax
,
847 (long) (sym_ptr
->isymMax
* sizeof (SYMR
)));
849 printf(" %-*s %11ld %11ld %11ld\n", width
, "Optimization Symbols",
850 (long) sym_ptr
->cbOptOffset
,
851 (long) sym_ptr
->ioptMax
,
852 (long) (sym_ptr
->ioptMax
* sizeof (OPTR
)));
854 printf(" %-*s %11ld %11ld %11ld\n", width
, "Auxiliary Symbols",
855 (long) sym_ptr
->cbAuxOffset
,
856 (long) sym_ptr
->iauxMax
,
857 (long) (sym_ptr
->iauxMax
* sizeof (AUXU
)));
859 printf(" %-*s %11ld %11ld %11ld\n", width
, "Local Strings",
860 (long) sym_ptr
->cbSsOffset
,
861 (long) sym_ptr
->issMax
,
862 (long) sym_ptr
->issMax
);
864 printf(" %-*s %11ld %11ld %11ld\n", width
, "External Strings",
865 (long) sym_ptr
->cbSsExtOffset
,
866 (long) sym_ptr
->issExtMax
,
867 (long) sym_ptr
->issExtMax
);
869 printf(" %-*s %11ld %11ld %11ld\n", width
, "File Tables",
870 (long) sym_ptr
->cbFdOffset
,
871 (long) sym_ptr
->ifdMax
,
872 (long) (sym_ptr
->ifdMax
* sizeof (FDR
)));
874 printf(" %-*s %11ld %11ld %11ld\n", width
, "Relative Files",
875 (long) sym_ptr
->cbRfdOffset
,
876 (long) sym_ptr
->crfd
,
877 (long) (sym_ptr
->crfd
* sizeof (ulong
)));
879 printf(" %-*s %11ld %11ld %11ld\n", width
, "External Symbols",
880 (long) sym_ptr
->cbExtOffset
,
881 (long) sym_ptr
->iextMax
,
882 (long) (sym_ptr
->iextMax
* sizeof (EXTR
)));
886 /* Print out a symbol. */
889 print_symbol (sym_ptr
, number
, strbase
, aux_base
, ifd
, fdp
)
897 sc_t storage_class
= (sc_t
) sym_ptr
->sc
;
898 st_t symbol_type
= (st_t
) sym_ptr
->st
;
899 ulong index
= sym_ptr
->index
;
900 char *used_ptr
= aux_used
+ (aux_base
- aux_symbols
);
903 printf ("\n Symbol# %d: \"%s\"\n", number
, sym_ptr
->iss
+ strbase
);
905 if (aux_base
!= (AUXU
*) 0 && index
!= indexNil
)
914 printf (" End+1 symbol: %ld\n", index
);
917 if (free_scope
== (scope_t
*) 0)
918 scope_ptr
= (scope_t
*) xmalloc (sizeof (scope_t
));
921 scope_ptr
= free_scope
;
922 free_scope
= scope_ptr
->prev
;
924 scope_ptr
->open_sym
= number
;
925 scope_ptr
->st
= symbol_type
;
926 scope_ptr
->sc
= storage_class
;
927 scope_ptr
->prev
= cur_scope
;
928 cur_scope
= scope_ptr
;
933 if (storage_class
== sc_Text
|| storage_class
== sc_Info
)
934 printf (" First symbol: %ld\n", index
);
938 printf (" First symbol: %ld\n", (long) aux_base
[index
].isym
);
943 if (cur_scope
== (scope_t
*) 0)
944 printf (" Can't pop end scope\n");
947 scope_ptr
= cur_scope
;
948 cur_scope
= scope_ptr
->prev
;
949 scope_ptr
->prev
= free_scope
;
950 free_scope
= scope_ptr
;
957 if (MIPS_IS_STAB(sym_ptr
))
959 else if (ifd
== -1) /* local symbol */
961 used_ptr
[index
] = used_ptr
[index
+1] = 1;
962 printf (" End+1 symbol: %-7ld Type: %s\n",
963 (long) aux_base
[index
].isym
,
964 type_to_string (aux_base
, index
+1, fdp
));
966 else /* global symbol */
967 printf (" Local symbol: %ld\n", index
);
971 if (free_scope
== (scope_t
*) 0)
972 scope_ptr
= (scope_t
*) xmalloc (sizeof (scope_t
));
975 scope_ptr
= free_scope
;
976 free_scope
= scope_ptr
->prev
;
978 scope_ptr
->open_sym
= number
;
979 scope_ptr
->st
= symbol_type
;
980 scope_ptr
->sc
= storage_class
;
981 scope_ptr
->prev
= cur_scope
;
982 cur_scope
= scope_ptr
;
990 printf (" End+1 symbol: %lu\n", index
);
995 if (!MIPS_IS_STAB (sym_ptr
))
998 printf (" Type: %s\n",
999 type_to_string (aux_base
, index
, fdp
));
1006 printf (" Scopes: ");
1007 if (cur_scope
== (scope_t
*) 0)
1011 for (scope_ptr
= cur_scope
;
1012 scope_ptr
!= (scope_t
*) 0;
1013 scope_ptr
= scope_ptr
->prev
)
1016 if (scope_ptr
->st
== st_Proc
|| scope_ptr
->st
== st_StaticProc
)
1018 else if (scope_ptr
->st
== st_File
)
1020 else if (scope_ptr
->st
== st_Block
&& scope_ptr
->sc
== sc_Text
)
1022 else if (scope_ptr
->st
== st_Block
&& scope_ptr
->sc
== sc_Info
)
1027 printf (" %ld [%s]", scope_ptr
->open_sym
, class);
1033 printf (" Value: %-13ld ",
1034 (long)sym_ptr
->value
);
1036 printf ("String index: %ld\n", (long)sym_ptr
->iss
);
1038 printf ("String index: %-11ld Ifd: %d\n",
1039 (long)sym_ptr
->iss
, ifd
);
1041 printf (" Symbol type: %-11sStorage class: %-11s",
1042 st_to_string (symbol_type
), sc_to_string (storage_class
));
1044 if (MIPS_IS_STAB(sym_ptr
))
1046 register int i
= sizeof(stab_names
) / sizeof(stab_names
[0]);
1047 const char *stab_name
= "stab";
1048 short code
= MIPS_UNMARK_STAB(sym_ptr
->index
);
1050 if (stab_names
[i
].code
== code
)
1052 stab_name
= stab_names
[i
].string
;
1055 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr
->index
, stab_name
);
1057 else if (sym_ptr
->st
== stLabel
&& sym_ptr
->index
!= indexNil
)
1058 printf ("Index: %ld (line#)\n", (long)sym_ptr
->index
);
1060 printf ("Index: %ld\n", (long)sym_ptr
->index
);
1065 /* Print out a word from the aux. table in various formats. */
1068 print_aux (u
, auxi
, used
)
1073 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1074 (used
) ? " " : "* ",
1078 (long) u
.rndx
.index
,
1091 /* Write aggregate information to a string. */
1094 emit_aggregate (string
, u
, u2
, which
, fdp
)
1101 unsigned int ifd
= u
.rndx
.rfd
;
1102 unsigned int index
= u
.rndx
.index
;
1105 if (ifd
== ST_RFDESCAPE
)
1108 /* An ifd of -1 is an opaque type. An escaped index of 0 is a
1109 struct return type of a procedure compiled without -g. */
1110 if (ifd
== 0xffffffff
1111 || (u
.rndx
.rfd
== ST_RFDESCAPE
&& index
== 0))
1112 name
= "<undefined>";
1113 else if (index
== indexNil
)
1117 if (fdp
== 0 || sym_hdr
.crfd
== 0)
1118 fdp
= &file_desc
[ifd
];
1120 fdp
= &file_desc
[rfile_desc
[fdp
->rfdBase
+ ifd
]];
1121 name
= &l_strings
[fdp
->issBase
+ l_symbols
[index
+ fdp
->isymBase
].iss
];
1125 "%s %s { ifd = %u, index = %u }",
1126 which
, name
, ifd
, index
);
1130 /* Print out information about a file descriptor, and the symbols,
1131 procedures, and line numbers within it. */
1134 print_file_desc (fdp
, number
)
1144 str_base
= l_strings
+ fdp
->issBase
;
1145 aux_base
= aux_symbols
+ fdp
->iauxBase
;
1146 used_base
= aux_used
+ (aux_base
- aux_symbols
);
1148 printf ("\nFile #%d, \"%s\"\n\n",
1150 fdp
->rss
!= issNil
? str_base
+ fdp
->rss
: "<unknown>");
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
,
1173 (ulong
) (fdp
->issBase
+ sym_hdr
.cbSsOffset
));
1175 printf(" %-*s %11lu %11lu %11lu %11lu\n",
1176 width
, "Local symbols",
1177 (ulong
) fdp
->isymBase
,
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
,
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
,
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
,
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
,
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
,
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",
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
,
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)
1247 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
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)
1262 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1264 (ulong
) fdp
->rfdBase
);
1266 rfd_ptr
= rfile_desc
+ fdp
->rfdBase
;
1267 for (i
= 0; i
< (ulong
) fdp
->crfd
; i
++)
1269 printf ("\t#%-5ld %11ld, 0x%08lx\n", i
, *rfd_ptr
, *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
));
1286 printf ("\t Name index = %-11ld Name = \"%s\"\n",
1287 (long) l_symbols
[proc_ptr
->isym
+ fdp
->isymBase
].iss
,
1288 l_symbols
[proc_ptr
->isym
+ fdp
->isymBase
].iss
+ str_base
);
1290 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
1291 (long) proc_ptr
->regmask
,
1292 (long) proc_ptr
->regoffset
,
1293 (long) proc_ptr
->fregmask
,
1294 (long) proc_ptr
->fregoffset
);
1296 printf ("\t .frame $%d,%ld,$%d\n",
1297 (int) proc_ptr
->framereg
,
1298 (long) proc_ptr
->frameoffset
,
1299 (int) proc_ptr
->pcreg
);
1301 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1302 (long) proc_ptr
->iopt
,
1303 (long) proc_ptr
->isym
);
1305 printf ("\t First line # = %-11ld Last line # = %ld\n",
1306 (long) proc_ptr
->lnLow
,
1307 (long) proc_ptr
->lnHigh
);
1309 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1310 (long) proc_ptr
->cbLineOffset
,
1311 (long) proc_ptr
->adr
);
1314 * print the line number entries.
1317 if (want_line
&& fdp
->cline
!= 0)
1320 long cur_line
= proc_ptr
->lnLow
;
1321 uchar
*line_ptr
= (((uchar
*)lines
) + proc_ptr
->cbLineOffset
1322 + fdp
->cbLineOffset
);
1325 if (pdi
== fdp
->cpd
+ fdp
->ipdFirst
- 1) /* last procedure */
1326 line_end
= ((uchar
*)lines
) + fdp
->cbLine
+ fdp
->cbLineOffset
;
1327 else /* not last proc. */
1328 line_end
= (((uchar
*)lines
) + proc_desc
[pdi
+1].cbLineOffset
1329 + fdp
->cbLineOffset
);
1331 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
1332 (ulong
) (line_end
- line_ptr
),
1333 (ulong
) (fdp
->ilineBase
+ sym_hdr
.cbLineOffset
));
1335 while (line_ptr
< line_end
)
1336 { /* sign extend nibble */
1337 delta
= ((*line_ptr
>> 4) ^ 0x8) - 0x8;
1338 count
= (*line_ptr
& 0xf) + 1;
1343 delta
= (((line_ptr
[1]) & 0xff) << 8) + ((line_ptr
[2]) & 0xff);
1344 delta
= (delta
^ 0x8000) - 0x8000;
1349 printf ("\t Line %11ld, delta %5d, count %2d\n",
1359 /* Read in the portions of the .T file that we will print out. */
1362 read_tfile
__proto((void))
1365 off_t sym_hdr_offset
= 0;
1367 (void) read_seek ((PTR_T
) &magic
, sizeof (magic
), (off_t
) 0, "Magic number");
1370 /* Print out the global header, since this is not a T-file. */
1372 (void) read_seek ((PTR_T
) &global_hdr
, sizeof (global_hdr
), (off_t
) 0,
1373 "Global file header");
1375 print_global_hdr (&global_hdr
);
1377 if (global_hdr
.f_symptr
== 0)
1379 printf ("No symbolic header, Goodbye!\n");
1383 sym_hdr_offset
= global_hdr
.f_symptr
;
1386 (void) read_seek ((PTR_T
) &sym_hdr
,
1391 print_sym_hdr (&sym_hdr
);
1393 lines
= (LINER
*) read_seek ((PTR_T
) 0,
1395 sym_hdr
.cbLineOffset
,
1398 dense_nums
= (DNR
*) read_seek ((PTR_T
) 0,
1399 sym_hdr
.idnMax
* sizeof (DNR
),
1403 proc_desc
= (PDR
*) read_seek ((PTR_T
) 0,
1404 sym_hdr
.ipdMax
* sizeof (PDR
),
1406 "Procedure tables");
1408 l_symbols
= (SYMR
*) read_seek ((PTR_T
) 0,
1409 sym_hdr
.isymMax
* sizeof (SYMR
),
1410 sym_hdr
.cbSymOffset
,
1413 opt_symbols
= (OPTR
*) read_seek ((PTR_T
) 0,
1414 sym_hdr
.ioptMax
* sizeof (OPTR
),
1415 sym_hdr
.cbOptOffset
,
1416 "Optimization symbols");
1418 aux_symbols
= (AUXU
*) read_seek ((PTR_T
) 0,
1419 sym_hdr
.iauxMax
* sizeof (AUXU
),
1420 sym_hdr
.cbAuxOffset
,
1421 "Auxiliary symbols");
1423 if (sym_hdr
.iauxMax
> 0)
1424 aux_used
= xcalloc (sym_hdr
.iauxMax
, 1);
1426 l_strings
= (char *) read_seek ((PTR_T
) 0,
1429 "Local string table");
1431 e_strings
= (char *) read_seek ((PTR_T
) 0,
1433 sym_hdr
.cbSsExtOffset
,
1434 "External string table");
1436 file_desc
= (FDR
*) read_seek ((PTR_T
) 0,
1437 sym_hdr
.ifdMax
* sizeof (FDR
),
1441 rfile_desc
= (ulong
*) read_seek ((PTR_T
) 0,
1442 sym_hdr
.crfd
* sizeof (ulong
),
1443 sym_hdr
.cbRfdOffset
,
1444 "Relative file tables");
1446 e_symbols
= (EXTR
*) read_seek ((PTR_T
) 0,
1447 sym_hdr
.iextMax
* sizeof (EXTR
),
1448 sym_hdr
.cbExtOffset
,
1449 "External symbols");
1464 while ((opt
= getopt (argc
, argv
, "alrst")) != EOF
)
1467 default: errors
++; break;
1468 case 'a': want_aux
++; break; /* print aux table */
1469 case 'l': want_line
++; break; /* print line numbers */
1470 case 'r': want_rfd
++; break; /* print relative fd's */
1471 case 's': want_scope
++; break; /* print scope info */
1472 case 't': tfile
++; break; /* this is a tfile (without header), and not a .o */
1475 if (errors
|| optind
!= argc
- 1)
1477 fprintf (stderr
, "Calling Sequence:\n");
1478 fprintf (stderr
, "\t%s [-alrst] <object-or-T-file>\n", argv
[0]);
1479 fprintf (stderr
, "\n");
1480 fprintf (stderr
, "switches:\n");
1481 fprintf (stderr
, "\t-a Print out auxiliary table.\n");
1482 fprintf (stderr
, "\t-l Print out line numbers.\n");
1483 fprintf (stderr
, "\t-r Print out relative file descriptors.\n");
1484 fprintf (stderr
, "\t-s Print out the current scopes for an item.\n");
1485 fprintf (stderr
, "\t-t Assume there is no global header (ie, a T-file).\n");
1490 * Open and process the input file.
1492 tfile_fd
= open (argv
[optind
], O_RDONLY
);
1495 perror (argv
[optind
]);
1502 * Print any global aux words if any.
1506 long last_aux_in_use
;
1508 if (sym_hdr
.ifdMax
!= 0 && file_desc
[0].iauxBase
!= 0)
1510 printf ("\nGlobal auxiliary entries before first file:\n");
1511 for (i
= 0; i
< file_desc
[0].iauxBase
; i
++)
1512 print_aux (aux_symbols
[i
], 0, aux_used
[i
]);
1515 if (sym_hdr
.ifdMax
== 0)
1516 last_aux_in_use
= 0;
1519 = (file_desc
[sym_hdr
.ifdMax
-1].iauxBase
1520 + file_desc
[sym_hdr
.ifdMax
-1].caux
- 1);
1522 if (last_aux_in_use
< sym_hdr
.iauxMax
-1)
1524 printf ("\nGlobal auxiliary entries after last file:\n");
1525 for (i
= last_aux_in_use
; i
< sym_hdr
.iauxMax
; i
++)
1526 print_aux (aux_symbols
[i
], i
- last_aux_in_use
, aux_used
[i
]);
1531 * Print the information for each file.
1533 for (i
= 0; i
< sym_hdr
.ifdMax
; i
++)
1534 print_file_desc (&file_desc
[i
], i
);
1537 * Print the external symbols.
1539 want_scope
= 0; /* scope info is meaning for extern symbols */
1540 printf ("\nThere are %lu external symbols, starting at %lu\n",
1541 (ulong
) sym_hdr
.iextMax
,
1542 (ulong
) sym_hdr
.cbExtOffset
);
1544 for(i
= 0; i
< sym_hdr
.iextMax
; i
++)
1545 print_symbol (&e_symbols
[i
].asym
, i
, e_strings
,
1546 aux_symbols
+ file_desc
[e_symbols
[i
].ifd
].iauxBase
,
1548 &file_desc
[e_symbols
[i
].ifd
]);
1551 * Print unused aux symbols now.
1558 for (i
= 0; i
< sym_hdr
.iauxMax
; i
++)
1564 printf ("\nThe following auxiliary table entries were unused:\n\n");
1568 printf (" #%-5d %11ld 0x%08lx %s\n",
1570 (long) aux_symbols
[i
].isym
,
1571 (long) aux_symbols
[i
].isym
,
1572 type_to_string (aux_symbols
, i
, (FDR
*) 0));
1584 fprintf (stderr
, "mips-tdump internal error");