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