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