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