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