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