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