]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/mips-tdump.c
d51a2eef0ec5cafb7e2a43ce97ddedbcf351f177
[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 Free Software Foundation, Inc.
3 Contributed by hartzell@boulder.colorado.edu,
4 Rewritten by meissner@osf.org.
5
6 This file is part of GNU CC.
7
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.
12
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.
17
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. */
22
23 #include "config.h"
24 #include "system.h"
25
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
60 static void
61 fatal(s)
62 const char *s;
63 {
64 fprintf(stderr, "%s\n", s);
65 exit(FATAL_EXIT_CODE);
66 }
67
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. */
72
73 #define size_t uint
74 #define ptrdiff_t int
75
76 \f
77 /* Redefinition of storage classes as an enumeration for better
78 debugging. */
79
80 #ifndef stStaParam
81 #define stStaParam 16 /* Fortran static parameters */
82 #endif
83
84 #ifndef btVoid
85 #define btVoid 26 /* void basic type */
86 #endif
87
88 typedef enum sc {
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 */
113 } sc_t;
114
115 /* Redefinition of symbol type. */
116
117 typedef enum st {
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 */
135 #ifdef stStruct
136 st_Struct = stStruct, /* struct */
137 st_Union = stUnion, /* union */
138 st_Enum = stEnum, /* enum */
139 #endif
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 */
145 } st_t;
146
147 /* Redefinition of type qualifiers. */
148
149 typedef enum tq {
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 */
157 } tq_t;
158
159 /* Redefinition of basic types. */
160
161 typedef enum bt {
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 */
190 } bt_t;
191
192 /* Redefinition of the language codes. */
193
194 typedef enum lang {
195 lang_C = langC,
196 lang_Pascal = langPascal,
197 lang_Fortran = langFortran,
198 lang_Assembler = langAssembler,
199 lang_Machine = langMachine,
200 lang_Nil = langNil,
201 lang_Ada = langAda,
202 lang_Pl1 = langPl1,
203 lang_Cobol = langCobol
204 } lang_t;
205
206 /* Redefinition of the debug level codes. */
207
208 typedef enum glevel {
209 glevel_0 = GLEVEL_0,
210 glevel_1 = GLEVEL_1,
211 glevel_2 = GLEVEL_2,
212 glevel_3 = GLEVEL_3
213 } glevel_t;
214
215 \f
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 */
222 } scope_t;
223
224 struct filehdr global_hdr; /* a.out header */
225
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 */
249
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 *));
264
265 #ifndef __alpha
266 # ifdef NEED_DECLARATION_MALLOC
267 extern PTR_T malloc __proto((size_t));
268 # endif
269 # ifdef NEED_DECLARATION_CALLOC
270 extern PTR_T calloc __proto((size_t, size_t));
271 # endif
272 # ifdef NEED_DECLARATION_REALLOC
273 extern PTR_T realloc __proto((PTR_T, size_t));
274 # endif
275 #endif
276
277 extern char *optarg;
278 extern int optind;
279 extern int opterr;
280
281 /* Create a table of debugging stab-codes and corresponding names. */
282
283 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
284 struct {short code; char string[10];} stab_names[] = {
285 #include "stab.def"
286 #undef __define_stab
287 };
288
289 \f
290 /* Read some bytes at a specified location, and return a pointer. */
291
292 PTR_T
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 */
298 {
299 long read_size = 0;
300
301 if (size == 0) /* nothing to read */
302 return ptr;
303
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)
307 {
308 perror (context);
309 exit (1);
310 }
311
312 if (read_size != size)
313 {
314 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
315 context, read_size, (long) size);
316 exit (1);
317 }
318
319 tfile_offset = offset + size;
320 return ptr;
321 }
322
323 \f
324 /* Convert language code to string format. */
325
326 const char *
327 lang_to_string (lang)
328 lang_t lang;
329 {
330 switch (lang)
331 {
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";
341 }
342
343 return "Unknown language";
344 }
345
346 \f
347 /* Convert storage class to string. */
348
349 const char *
350 sc_to_string(storage_class)
351 sc_t storage_class;
352 {
353 switch(storage_class)
354 {
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";
379 }
380
381 return "???";
382 }
383
384 \f
385 /* Convert symbol type to string. */
386
387 const char *
388 st_to_string(symbol_type)
389 st_t symbol_type;
390 {
391 switch(symbol_type)
392 {
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";
410 #ifdef stStruct
411 case st_Struct: return "Struct";
412 case st_Union: return "Union";
413 case st_Enum: return "Enum";
414 #endif
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";
420 }
421
422 return "???";
423 }
424
425 \f
426 /* Convert debug level to string. */
427
428 const char *
429 glevel_to_string (g_level)
430 glevel_t g_level;
431 {
432 switch(g_level)
433 {
434 case GLEVEL_0: return "G0";
435 case GLEVEL_1: return "G1";
436 case GLEVEL_2: return "G2";
437 case GLEVEL_3: return "G3";
438 }
439
440 return "??";
441 }
442
443 \f
444 /* Convert the type information to string format. */
445
446 const char *
447 type_to_string (aux_ptr, index, fdp)
448 AUXU *aux_ptr;
449 int index;
450 FDR *fdp;
451 {
452 AUXU u;
453 struct qual {
454 tq_t type;
455 int low_bound;
456 int high_bound;
457 int stride;
458 } qualifiers[7];
459
460 bt_t basic_type;
461 int i;
462 static char buffer1[1024];
463 static char buffer2[1024];
464 char *p1 = buffer1;
465 char *p2 = buffer2;
466 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
467
468 for (i = 0; i < 7; i++)
469 {
470 qualifiers[i].low_bound = 0;
471 qualifiers[i].high_bound = 0;
472 qualifiers[i].stride = 0;
473 }
474
475 used_ptr[index] = 1;
476 u = aux_ptr[index++];
477 if (u.isym == -1)
478 return "-1 (no type)";
479
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;
488
489 /*
490 * Go get the basic type.
491 */
492 switch (basic_type)
493 {
494 case bt_Nil: /* undefined */
495 strcpy (p1, "nil");
496 break;
497
498 case bt_Adr: /* address - integer same size as pointer */
499 strcpy (p1, "address");
500 break;
501
502 case bt_Char: /* character */
503 strcpy (p1, "char");
504 break;
505
506 case bt_UChar: /* unsigned character */
507 strcpy (p1, "unsigned char");
508 break;
509
510 case bt_Short: /* short */
511 strcpy (p1, "short");
512 break;
513
514 case bt_UShort: /* unsigned short */
515 strcpy (p1, "unsigned short");
516 break;
517
518 case bt_Int: /* int */
519 strcpy (p1, "int");
520 break;
521
522 case bt_UInt: /* unsigned int */
523 strcpy (p1, "unsigned int");
524 break;
525
526 case bt_Long: /* long */
527 strcpy (p1, "long");
528 break;
529
530 case bt_ULong: /* unsigned long */
531 strcpy (p1, "unsigned long");
532 break;
533
534 case bt_Float: /* float (real) */
535 strcpy (p1, "float");
536 break;
537
538 case bt_Double: /* Double (real) */
539 strcpy (p1, "double");
540 break;
541
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. */
545
546 case bt_Struct: /* Structure (Record) */
547 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
548 used_ptr[index] = 1;
549 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
550 used_ptr[++index] = 1;
551
552 index++; /* skip aux words */
553 break;
554
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. */
558
559 case bt_Union: /* Union */
560 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
561 used_ptr[index] = 1;
562 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
563 used_ptr[++index] = 1;
564
565 index++; /* skip aux words */
566 break;
567
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. */
571
572 case bt_Enum: /* Enumeration */
573 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
574 used_ptr[index] = 1;
575 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
576 used_ptr[++index] = 1;
577
578 index++; /* skip aux words */
579 break;
580
581 case bt_Typedef: /* defined via a typedef, isymRef points */
582 strcpy (p1, "typedef");
583 break;
584
585 case bt_Range: /* subrange of int */
586 strcpy (p1, "subrange");
587 break;
588
589 case bt_Set: /* pascal sets */
590 strcpy (p1, "set");
591 break;
592
593 case bt_Complex: /* fortran complex */
594 strcpy (p1, "complex");
595 break;
596
597 case bt_DComplex: /* fortran double complex */
598 strcpy (p1, "double complex");
599 break;
600
601 case bt_Indirect: /* forward or unnamed typedef */
602 strcpy (p1, "forward/unnamed typedef");
603 break;
604
605 case bt_FixedDec: /* Fixed Decimal */
606 strcpy (p1, "fixed decimal");
607 break;
608
609 case bt_FloatDec: /* Float Decimal */
610 strcpy (p1, "float decimal");
611 break;
612
613 case bt_String: /* Varying Length Character String */
614 strcpy (p1, "string");
615 break;
616
617 case bt_Bit: /* Aligned Bit String */
618 strcpy (p1, "bit");
619 break;
620
621 case bt_Picture: /* Picture */
622 strcpy (p1, "picture");
623 break;
624
625 case bt_Void: /* Void */
626 strcpy (p1, "void");
627 break;
628
629 default:
630 sprintf (p1, "Unknown basic type %d", (int) basic_type);
631 break;
632 }
633
634 p1 += strlen (buffer1);
635
636 /*
637 * If this is a bitfield, get the bitsize.
638 */
639 if (u.ti.fBitfield)
640 {
641 int bitsize;
642
643 used_ptr[index] = 1;
644 bitsize = aux_ptr[index++].width;
645 sprintf (p1, " : %d", bitsize);
646 p1 += strlen (buffer1);
647 }
648
649
650 /*
651 * Deal with any qualifiers.
652 */
653 if (qualifiers[0].type != tq_Nil)
654 {
655 /*
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
660 * word 2 low bound
661 * word 3 high bound (or -1 if [])
662 * word 4 stride size in bits
663 */
664 for (i = 0; i < 7; i++)
665 {
666 if (qualifiers[i].type == tq_Array)
667 {
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;
671 used_ptr[index] = 1;
672 used_ptr[index+1] = 1;
673 used_ptr[index+2] = 1;
674 used_ptr[index+3] = 1;
675 used_ptr[index+4] = 1;
676 index += 5;
677 }
678 }
679
680 /*
681 * Now print out the qualifiers.
682 */
683 for (i = 0; i < 6; i++)
684 {
685 switch (qualifiers[i].type)
686 {
687 case tq_Nil:
688 case tq_Max:
689 break;
690
691 case tq_Ptr:
692 strcpy (p2, "ptr to ");
693 p2 += sizeof ("ptr to ")-1;
694 break;
695
696 case tq_Vol:
697 strcpy (p2, "volatile ");
698 p2 += sizeof ("volatile ")-1;
699 break;
700
701 case tq_Far:
702 strcpy (p2, "far ");
703 p2 += sizeof ("far ")-1;
704 break;
705
706 case tq_Proc:
707 strcpy (p2, "func. ret. ");
708 p2 += sizeof ("func. ret. ");
709 break;
710
711 case tq_Array:
712 {
713 int first_array = i;
714 int j;
715
716 /* Print array bounds reversed (ie, in the order the C
717 programmer writes them). C is such a fun language.... */
718
719 while (i < 5 && qualifiers[i+1].type == tq_Array)
720 i++;
721
722 for (j = i; j >= first_array; j--)
723 {
724 strcpy (p2, "array [");
725 p2 += sizeof ("array [")-1;
726 if (qualifiers[j].low_bound != 0)
727 sprintf (p2,
728 "%ld:%ld {%ld bits}",
729 (long) qualifiers[j].low_bound,
730 (long) qualifiers[j].high_bound,
731 (long) qualifiers[j].stride);
732
733 else if (qualifiers[j].high_bound != -1)
734 sprintf (p2,
735 "%ld {%ld bits}",
736 (long) (qualifiers[j].high_bound + 1),
737 (long) (qualifiers[j].stride));
738
739 else
740 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
741
742 p2 += strlen (p2);
743 strcpy (p2, "] of ");
744 p2 += sizeof ("] of ")-1;
745 }
746 }
747 break;
748 }
749 }
750 }
751
752 strcpy (p2, buffer1);
753 return buffer2;
754 }
755
756 \f
757 /* Print out the global file header for object files. */
758
759 void
760 print_global_hdr (ptr)
761 struct filehdr *ptr;
762 {
763 char *time = ctime ((time_t *)&ptr->f_timdat);
764 ushort flags = ptr->f_flags;
765
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);
774
775 if ((flags & F_RELFLG) != 0)
776 printf (", F_RELFLG");
777
778 if ((flags & F_EXEC) != 0)
779 printf (", F_EXEC");
780
781 if ((flags & F_LNNO) != 0)
782 printf (", F_LNNO");
783
784 if ((flags & F_LSYMS) != 0)
785 printf (", F_LSYMS");
786
787 if ((flags & F_MINMAL) != 0)
788 printf (", F_MINMAL");
789
790 if ((flags & F_UPDATE) != 0)
791 printf (", F_UPDATE");
792
793 if ((flags & F_SWABD) != 0)
794 printf (", F_SWABD");
795
796 if ((flags & F_AR16WR) != 0)
797 printf (", F_AR16WR");
798
799 if ((flags & F_AR32WR) != 0)
800 printf (", F_AR32WR");
801
802 if ((flags & F_AR32W) != 0)
803 printf (", F_AR32W");
804
805 if ((flags & F_PATCH) != 0)
806 printf (", F_PATCH/F_NODF");
807
808 printf ("\n\n");
809 }
810
811 \f
812 /* Print out the symbolic header. */
813
814 void
815 print_sym_hdr (sym_ptr)
816 HDRR *sym_ptr;
817 {
818 int width = 20;
819
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);
824
825 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
826 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
827
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);
833
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)));
838
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)));
843
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)));
848
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)));
853
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)));
858
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);
863
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);
868
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)));
873
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)));
878
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)));
883 }
884
885 \f
886 /* Print out a symbol. */
887
888 void
889 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
890 SYMR *sym_ptr;
891 int number;
892 char *strbase;
893 AUXU *aux_base;
894 int ifd;
895 FDR *fdp;
896 {
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);
901 scope_t *scope_ptr;
902
903 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
904
905 if (aux_base != (AUXU *) 0 && index != indexNil)
906 switch (symbol_type)
907 {
908 case st_Nil:
909 case st_Label:
910 break;
911
912 case st_File:
913 case st_Block:
914 printf (" End+1 symbol: %ld\n", index);
915 if (want_scope)
916 {
917 if (free_scope == (scope_t *) 0)
918 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
919 else
920 {
921 scope_ptr = free_scope;
922 free_scope = scope_ptr->prev;
923 }
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;
929 }
930 break;
931
932 case st_End:
933 if (storage_class == sc_Text || storage_class == sc_Info)
934 printf (" First symbol: %ld\n", index);
935 else
936 {
937 used_ptr[index] = 1;
938 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
939 }
940
941 if (want_scope)
942 {
943 if (cur_scope == (scope_t *) 0)
944 printf (" Can't pop end scope\n");
945 else
946 {
947 scope_ptr = cur_scope;
948 cur_scope = scope_ptr->prev;
949 scope_ptr->prev = free_scope;
950 free_scope = scope_ptr;
951 }
952 }
953 break;
954
955 case st_Proc:
956 case st_StaticProc:
957 if (MIPS_IS_STAB(sym_ptr))
958 ;
959 else if (ifd == -1) /* local symbol */
960 {
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));
965 }
966 else /* global symbol */
967 printf (" Local symbol: %ld\n", index);
968
969 if (want_scope)
970 {
971 if (free_scope == (scope_t *) 0)
972 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
973 else
974 {
975 scope_ptr = free_scope;
976 free_scope = scope_ptr->prev;
977 }
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;
983 }
984 break;
985
986 #ifdef stStruct
987 case st_Struct:
988 case st_Union:
989 case st_Enum:
990 printf (" End+1 symbol: %lu\n", index);
991 break;
992 #endif
993
994 default:
995 if (!MIPS_IS_STAB (sym_ptr))
996 {
997 used_ptr[index] = 1;
998 printf (" Type: %s\n",
999 type_to_string (aux_base, index, fdp));
1000 }
1001 break;
1002 }
1003
1004 if (want_scope)
1005 {
1006 printf (" Scopes: ");
1007 if (cur_scope == (scope_t *) 0)
1008 printf (" none\n");
1009 else
1010 {
1011 for (scope_ptr = cur_scope;
1012 scope_ptr != (scope_t *) 0;
1013 scope_ptr = scope_ptr->prev)
1014 {
1015 const char *class;
1016 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
1017 class = "func.";
1018 else if (scope_ptr->st == st_File)
1019 class = "file";
1020 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
1021 class = "block";
1022 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
1023 class = "type";
1024 else
1025 class = "???";
1026
1027 printf (" %ld [%s]", scope_ptr->open_sym, class);
1028 }
1029 printf ("\n");
1030 }
1031 }
1032
1033 printf (" Value: %-13ld ",
1034 (long)sym_ptr->value);
1035 if (ifd == -1)
1036 printf ("String index: %ld\n", (long)sym_ptr->iss);
1037 else
1038 printf ("String index: %-11ld Ifd: %d\n",
1039 (long)sym_ptr->iss, ifd);
1040
1041 printf (" Symbol type: %-11sStorage class: %-11s",
1042 st_to_string (symbol_type), sc_to_string (storage_class));
1043
1044 if (MIPS_IS_STAB(sym_ptr))
1045 {
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);
1049 while (--i >= 0)
1050 if (stab_names[i].code == code)
1051 {
1052 stab_name = stab_names[i].string;
1053 break;
1054 }
1055 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
1056 }
1057 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
1058 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
1059 else
1060 printf ("Index: %ld\n", (long)sym_ptr->index);
1061
1062 }
1063
1064 \f
1065 /* Print out a word from the aux. table in various formats. */
1066
1067 void
1068 print_aux (u, auxi, used)
1069 AUXU u;
1070 int auxi;
1071 int used;
1072 {
1073 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
1074 (used) ? " " : "* ",
1075 auxi,
1076 (long) u.isym,
1077 (long) u.rndx.rfd,
1078 (long) u.rndx.index,
1079 u.ti.bt,
1080 u.ti.fBitfield,
1081 u.ti.continued,
1082 u.ti.tq0,
1083 u.ti.tq1,
1084 u.ti.tq2,
1085 u.ti.tq3,
1086 u.ti.tq4,
1087 u.ti.tq5);
1088 }
1089
1090 \f
1091 /* Write aggregate information to a string. */
1092
1093 void
1094 emit_aggregate (string, u, u2, which, fdp)
1095 char *string;
1096 AUXU u;
1097 AUXU u2;
1098 const char *which;
1099 FDR *fdp;
1100 {
1101 unsigned int ifd = u.rndx.rfd;
1102 unsigned int index = u.rndx.index;
1103 const char *name;
1104
1105 if (ifd == ST_RFDESCAPE)
1106 ifd = u2.isym;
1107
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)
1114 name = "<no name>";
1115 else
1116 {
1117 if (fdp == 0 || sym_hdr.crfd == 0)
1118 fdp = &file_desc[ifd];
1119 else
1120 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
1121 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
1122 }
1123
1124 sprintf (string,
1125 "%s %s { ifd = %u, index = %u }",
1126 which, name, ifd, index);
1127 }
1128
1129 \f
1130 /* Print out information about a file descriptor, and the symbols,
1131 procedures, and line numbers within it. */
1132
1133 void
1134 print_file_desc (fdp, number)
1135 FDR *fdp;
1136 int number;
1137 {
1138 char *str_base;
1139 AUXU *aux_base;
1140 int symi, pdi;
1141 int width = 20;
1142 char *used_base;
1143
1144 str_base = l_strings + fdp->issBase;
1145 aux_base = aux_symbols + fdp->iauxBase;
1146 used_base = aux_used + (aux_base - aux_symbols);
1147
1148 printf ("\nFile #%d, \"%s\"\n\n",
1149 number,
1150 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
1151
1152 printf (" Name index = %-10ld Readin = %s\n",
1153 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
1154
1155 printf (" Merge = %-10s Endian = %s\n",
1156 (fdp->fMerge) ? "Yes" : "No",
1157 (fdp->fBigendian) ? "BIG" : "LITTLE");
1158
1159 printf (" Debug level = %-10s Language = %s\n",
1160 glevel_to_string (fdp->glevel),
1161 lang_to_string((lang_t) fdp->lang));
1162
1163 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
1164
1165 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
1166 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
1167
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));
1174
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));
1181
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));
1188
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));
1195
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));
1202
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));
1209
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));
1216
1217
1218 if (want_scope && cur_scope != (scope_t *) 0)
1219 printf ("\n Warning scope does not start at 0!\n");
1220
1221 /*
1222 * print the info about the symbol table.
1223 */
1224 printf ("\n There are %lu local symbols, starting at %lu\n",
1225 (ulong) fdp->csym,
1226 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
1227
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,
1233 -1,
1234 fdp);
1235
1236 if (want_scope && cur_scope != (scope_t *) 0)
1237 printf ("\n Warning scope does not end at 0!\n");
1238
1239 /*
1240 * print the aux. table if desired.
1241 */
1242
1243 if (want_aux && fdp->caux != 0)
1244 {
1245 int auxi;
1246
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));
1250
1251 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
1252 print_aux (aux_base[auxi], auxi, used_base[auxi]);
1253 }
1254
1255 /*
1256 * print the relative file descriptors.
1257 */
1258 if (want_rfd && fdp->crfd != 0)
1259 {
1260 ulong *rfd_ptr, i;
1261
1262 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
1263 (ulong) fdp->crfd,
1264 (ulong) fdp->rfdBase);
1265
1266 rfd_ptr = rfile_desc + fdp->rfdBase;
1267 for (i = 0; i < (ulong) fdp->crfd; i++)
1268 {
1269 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
1270 rfd_ptr++;
1271 }
1272 }
1273
1274 /*
1275 * do the procedure descriptors.
1276 */
1277 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
1278 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
1279
1280 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
1281 {
1282 PDR *proc_ptr = &proc_desc[pdi];
1283 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
1284
1285 if (l_symbols != 0)
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);
1289
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);
1295
1296 printf ("\t .frame $%d,%ld,$%d\n",
1297 (int) proc_ptr->framereg,
1298 (long) proc_ptr->frameoffset,
1299 (int) proc_ptr->pcreg);
1300
1301 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
1302 (long) proc_ptr->iopt,
1303 (long) proc_ptr->isym);
1304
1305 printf ("\t First line # = %-11ld Last line # = %ld\n",
1306 (long) proc_ptr->lnLow,
1307 (long) proc_ptr->lnHigh);
1308
1309 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
1310 (long) proc_ptr->cbLineOffset,
1311 (long) proc_ptr->adr);
1312
1313 /*
1314 * print the line number entries.
1315 */
1316
1317 if (want_line && fdp->cline != 0)
1318 {
1319 int delta, count;
1320 long cur_line = proc_ptr->lnLow;
1321 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
1322 + fdp->cbLineOffset);
1323 uchar *line_end;
1324
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);
1330
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));
1334
1335 while (line_ptr < line_end)
1336 { /* sign extend nibble */
1337 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
1338 count = (*line_ptr & 0xf) + 1;
1339 if (delta != -8)
1340 line_ptr++;
1341 else
1342 {
1343 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
1344 delta = (delta ^ 0x8000) - 0x8000;
1345 line_ptr += 3;
1346 }
1347
1348 cur_line += delta;
1349 printf ("\t Line %11ld, delta %5d, count %2d\n",
1350 cur_line,
1351 delta,
1352 count);
1353 }
1354 }
1355 }
1356 }
1357
1358 \f
1359 /* Read in the portions of the .T file that we will print out. */
1360
1361 void
1362 read_tfile __proto((void))
1363 {
1364 short magic;
1365 off_t sym_hdr_offset = 0;
1366
1367 (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number");
1368 if (!tfile)
1369 {
1370 /* Print out the global header, since this is not a T-file. */
1371
1372 (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0,
1373 "Global file header");
1374
1375 print_global_hdr (&global_hdr);
1376
1377 if (global_hdr.f_symptr == 0)
1378 {
1379 printf ("No symbolic header, Goodbye!\n");
1380 exit (1);
1381 }
1382
1383 sym_hdr_offset = global_hdr.f_symptr;
1384 }
1385
1386 (void) read_seek ((PTR_T) &sym_hdr,
1387 sizeof (sym_hdr),
1388 sym_hdr_offset,
1389 "Symbolic header");
1390
1391 print_sym_hdr (&sym_hdr);
1392
1393 lines = (LINER *) read_seek ((PTR_T) 0,
1394 sym_hdr.cbLine,
1395 sym_hdr.cbLineOffset,
1396 "Line numbers");
1397
1398 dense_nums = (DNR *) read_seek ((PTR_T) 0,
1399 sym_hdr.idnMax * sizeof (DNR),
1400 sym_hdr.cbDnOffset,
1401 "Dense numbers");
1402
1403 proc_desc = (PDR *) read_seek ((PTR_T) 0,
1404 sym_hdr.ipdMax * sizeof (PDR),
1405 sym_hdr.cbPdOffset,
1406 "Procedure tables");
1407
1408 l_symbols = (SYMR *) read_seek ((PTR_T) 0,
1409 sym_hdr.isymMax * sizeof (SYMR),
1410 sym_hdr.cbSymOffset,
1411 "Local symbols");
1412
1413 opt_symbols = (OPTR *) read_seek ((PTR_T) 0,
1414 sym_hdr.ioptMax * sizeof (OPTR),
1415 sym_hdr.cbOptOffset,
1416 "Optimization symbols");
1417
1418 aux_symbols = (AUXU *) read_seek ((PTR_T) 0,
1419 sym_hdr.iauxMax * sizeof (AUXU),
1420 sym_hdr.cbAuxOffset,
1421 "Auxiliary symbols");
1422
1423 if (sym_hdr.iauxMax > 0)
1424 aux_used = xcalloc (sym_hdr.iauxMax, 1);
1425
1426 l_strings = (char *) read_seek ((PTR_T) 0,
1427 sym_hdr.issMax,
1428 sym_hdr.cbSsOffset,
1429 "Local string table");
1430
1431 e_strings = (char *) read_seek ((PTR_T) 0,
1432 sym_hdr.issExtMax,
1433 sym_hdr.cbSsExtOffset,
1434 "External string table");
1435
1436 file_desc = (FDR *) read_seek ((PTR_T) 0,
1437 sym_hdr.ifdMax * sizeof (FDR),
1438 sym_hdr.cbFdOffset,
1439 "File tables");
1440
1441 rfile_desc = (ulong *) read_seek ((PTR_T) 0,
1442 sym_hdr.crfd * sizeof (ulong),
1443 sym_hdr.cbRfdOffset,
1444 "Relative file tables");
1445
1446 e_symbols = (EXTR *) read_seek ((PTR_T) 0,
1447 sym_hdr.iextMax * sizeof (EXTR),
1448 sym_hdr.cbExtOffset,
1449 "External symbols");
1450 }
1451
1452 \f
1453
1454 int
1455 main (argc, argv)
1456 int argc;
1457 char **argv;
1458 {
1459 int i, opt;
1460
1461 /*
1462 * Process arguments
1463 */
1464 while ((opt = getopt (argc, argv, "alrst")) != EOF)
1465 switch (opt)
1466 {
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 */
1473 }
1474
1475 if (errors || optind != argc - 1)
1476 {
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");
1486 return 1;
1487 }
1488
1489 /*
1490 * Open and process the input file.
1491 */
1492 tfile_fd = open (argv[optind], O_RDONLY);
1493 if (tfile_fd < 0)
1494 {
1495 perror (argv[optind]);
1496 return 1;
1497 }
1498
1499 read_tfile ();
1500
1501 /*
1502 * Print any global aux words if any.
1503 */
1504 if (want_aux)
1505 {
1506 long last_aux_in_use;
1507
1508 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
1509 {
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]);
1513 }
1514
1515 if (sym_hdr.ifdMax == 0)
1516 last_aux_in_use = 0;
1517 else
1518 last_aux_in_use
1519 = (file_desc[sym_hdr.ifdMax-1].iauxBase
1520 + file_desc[sym_hdr.ifdMax-1].caux - 1);
1521
1522 if (last_aux_in_use < sym_hdr.iauxMax-1)
1523 {
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]);
1527 }
1528 }
1529
1530 /*
1531 * Print the information for each file.
1532 */
1533 for (i = 0; i < sym_hdr.ifdMax; i++)
1534 print_file_desc (&file_desc[i], i);
1535
1536 /*
1537 * Print the external symbols.
1538 */
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);
1543
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,
1547 e_symbols[i].ifd,
1548 &file_desc[e_symbols[i].ifd]);
1549
1550 /*
1551 * Print unused aux symbols now.
1552 */
1553
1554 if (want_aux)
1555 {
1556 int first_time = 1;
1557
1558 for (i = 0; i < sym_hdr.iauxMax; i++)
1559 {
1560 if (! aux_used[i])
1561 {
1562 if (first_time)
1563 {
1564 printf ("\nThe following auxiliary table entries were unused:\n\n");
1565 first_time = 0;
1566 }
1567
1568 printf (" #%-5d %11ld 0x%08lx %s\n",
1569 i,
1570 (long) aux_symbols[i].isym,
1571 (long) aux_symbols[i].isym,
1572 type_to_string (aux_symbols, i, (FDR *) 0));
1573 }
1574 }
1575 }
1576
1577 return 0;
1578 }
1579
1580 \f
1581 void
1582 fancy_abort ()
1583 {
1584 fprintf (stderr, "mips-tdump internal error");
1585 exit (1);
1586 }