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