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