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