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