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