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