]>
Commit | Line | Data |
---|---|---|
68e9eb95 | 1 | /* Read and manage MIPS symbol tables from object modules. |
a6d6c2c0 | 2 | Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2003, 2004, |
0e5997c0 | 3 | 2006, 2007, 2008 Free Software Foundation, Inc. |
7a824750 RK |
4 | Contributed by hartzell@boulder.colorado.edu, |
5 | Rewritten by meissner@osf.org. | |
68e9eb95 | 6 | |
1322177d | 7 | This file is part of GCC. |
68e9eb95 | 8 | |
1322177d LB |
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 | |
9dcd6f09 | 11 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 12 | version. |
68e9eb95 | 13 | |
1322177d LB |
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. | |
68e9eb95 RS |
18 | |
19 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
20 | along with GCC; see the file COPYING3. If not see |
21 | <http://www.gnu.org/licenses/>. */ | |
68e9eb95 | 22 | |
31031edd | 23 | #include "config.h" |
90fbb8c9 | 24 | #include "system.h" |
4977bab6 ZW |
25 | #include "coretypes.h" |
26 | #include "tm.h" | |
d90f9882 | 27 | #include "version.h" |
de5849f3 MM |
28 | #ifdef index |
29 | #undef index | |
de5849f3 | 30 | #endif |
2989d30c | 31 | #ifndef CROSS_DIRECTORY_STRUCTURE |
d07e072c MM |
32 | #include <a.out.h> |
33 | #else | |
04c3f19d | 34 | #include "mips/a.out.h" |
2989d30c | 35 | #endif /* CROSS_DIRECTORY_STRUCTURE */ |
d07e072c | 36 | |
d90f9882 RS |
37 | /* Include getopt.h for the sake of getopt_long. */ |
38 | #include "getopt.h" | |
39 | ||
3876db74 MM |
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. | |
0f41302f | 46 | Unfortunately, gcc and gdb do not currently share any directories. */ |
3876db74 MM |
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 | ||
68e9eb95 RS |
54 | #define uchar unsigned char |
55 | #define ushort unsigned short | |
56 | #define uint unsigned int | |
57 | #define ulong unsigned long | |
58 | ||
68e9eb95 | 59 | \f |
38e01259 | 60 | /* Redefinition of storage classes as an enumeration for better |
68e9eb95 RS |
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 */ | |
64fd9134 | 108 | st_Block = stBlock, /* beginning of block */ |
68e9eb95 RS |
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 */ | |
5346f1b9 RK |
118 | #ifdef stStruct |
119 | st_Struct = stStruct, /* struct */ | |
120 | st_Union = stUnion, /* union */ | |
121 | st_Enum = stEnum, /* enum */ | |
122 | #endif | |
68e9eb95 | 123 | st_Str = stStr, /* string */ |
89dbed81 | 124 | st_Number = stNumber, /* pure number (i.e. 4 NOR 2+2) */ |
68e9eb95 | 125 | st_Expr = stExpr, /* 2+2 vs. 4 */ |
64fd9134 | 126 | st_Type = stType, /* post-coercion SER */ |
68e9eb95 RS |
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 | \f | |
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 */ | |
3876db74 | 214 | int tfile = 0; /* no global header file */ |
d90f9882 RS |
215 | int version = 0; /* print version # */ |
216 | int verbose = 0; | |
68e9eb95 RS |
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 */ | |
64fd9134 | 229 | AUXU *aux_symbols; /* Auxiliary symbols */ |
68e9eb95 RS |
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. */ | |
cf633f5b AJ |
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 *); | |
68e9eb95 | 249 | |
68e9eb95 RS |
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}, | |
5e65297b | 257 | const struct {const short code; const char string[10];} stab_names[] = { |
68e9eb95 RS |
258 | #include "stab.def" |
259 | #undef __define_stab | |
260 | }; | |
261 | ||
d90f9882 RS |
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 | }; | |
68e9eb95 | 270 | \f |
cf633f5b AJ |
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. */ | |
68e9eb95 | 275 | |
fad205ff | 276 | static void * |
cf633f5b | 277 | read_seek (void *ptr, size_t size, off_t offset, const char *context) |
68e9eb95 RS |
278 | { |
279 | long read_size = 0; | |
280 | ||
281 | if (size == 0) /* nothing to read */ | |
282 | return ptr; | |
283 | ||
45a647be KG |
284 | if (!ptr) |
285 | ptr = xmalloc (size); | |
286 | ||
287 | if ((tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1) | |
68e9eb95 RS |
288 | || (read_size = read (tfile_fd, ptr, size)) < 0) |
289 | { | |
290 | perror (context); | |
291 | exit (1); | |
292 | } | |
293 | ||
45a647be | 294 | if (read_size != (long) size) |
68e9eb95 RS |
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 | \f | |
306 | /* Convert language code to string format. */ | |
307 | ||
45a647be | 308 | static const char * |
cf633f5b | 309 | lang_to_string (lang_t lang) |
68e9eb95 RS |
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 | \f | |
328 | /* Convert storage class to string. */ | |
329 | ||
45a647be | 330 | static const char * |
cf633f5b | 331 | sc_to_string (sc_t storage_class) |
68e9eb95 RS |
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 | \f | |
365 | /* Convert symbol type to string. */ | |
366 | ||
45a647be | 367 | static const char * |
cf633f5b | 368 | st_to_string (st_t symbol_type) |
68e9eb95 RS |
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"; | |
5346f1b9 RK |
389 | #ifdef stStruct |
390 | case st_Struct: return "Struct"; | |
391 | case st_Union: return "Union"; | |
392 | case st_Enum: return "Enum"; | |
393 | #endif | |
68e9eb95 RS |
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 | \f | |
405 | /* Convert debug level to string. */ | |
406 | ||
45a647be | 407 | static const char * |
cf633f5b | 408 | glevel_to_string (glevel_t g_level) |
68e9eb95 RS |
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 | } | |
cf633f5b | 420 | |
68e9eb95 RS |
421 | \f |
422 | /* Convert the type information to string format. */ | |
423 | ||
45a647be | 424 | static const char * |
cf633f5b | 425 | type_to_string (AUXU *aux_ptr, int index, FDR *fdp) |
68e9eb95 RS |
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) */ | |
5346f1b9 | 522 | emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp); |
68e9eb95 RS |
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 */ | |
5346f1b9 | 535 | emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp); |
68e9eb95 RS |
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 */ | |
5346f1b9 | 548 | emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp); |
68e9eb95 RS |
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 */ | |
debaccc2 | 577 | strcpy (p1, "forward/unnamed typedef"); |
68e9eb95 RS |
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 | |
64fd9134 | 632 | * store 5 successive words in the aux. table: |
454ff5cb | 633 | * word 0 RNDXR to type of the bounds (i.e., int) |
68e9eb95 RS |
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 | ||
454ff5cb | 691 | /* Print array bounds reversed (i.e., in the order the C |
0f41302f | 692 | programmer writes them). C is such a fun language.... */ |
68e9eb95 RS |
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 | \f | |
732 | /* Print out the global file header for object files. */ | |
733 | ||
45a647be | 734 | static void |
cf633f5b | 735 | print_global_hdr (struct filehdr *ptr) |
68e9eb95 | 736 | { |
46ab9205 | 737 | char *time = ctime ((time_t *)&ptr->f_timdat); |
68e9eb95 RS |
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); | |
6ba29526 | 747 | printf(" %-*s 0x%x", 24, "flags", (ushort) flags); |
68e9eb95 RS |
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 | \f | |
786 | /* Print out the symbolic header. */ | |
787 | ||
45a647be | 788 | static void |
cf633f5b | 789 | print_sym_hdr (HDRR *sym_ptr) |
68e9eb95 RS |
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 | ||
6ba29526 | 801 | printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers", |
0f41302f MS |
802 | (long) sym_ptr->cbLineOffset, |
803 | (long) sym_ptr->cbLine, | |
804 | (long) sym_ptr->cbLine, | |
805 | (int) sym_ptr->ilineMax); | |
68e9eb95 | 806 | |
6ba29526 | 807 | printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers", |
0f41302f MS |
808 | (long) sym_ptr->cbDnOffset, |
809 | (long) sym_ptr->idnMax, | |
810 | (long) (sym_ptr->idnMax * sizeof (DNR))); | |
68e9eb95 | 811 | |
6ba29526 | 812 | printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables", |
0f41302f MS |
813 | (long) sym_ptr->cbPdOffset, |
814 | (long) sym_ptr->ipdMax, | |
815 | (long) (sym_ptr->ipdMax * sizeof (PDR))); | |
68e9eb95 | 816 | |
6ba29526 | 817 | printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols", |
0f41302f MS |
818 | (long) sym_ptr->cbSymOffset, |
819 | (long) sym_ptr->isymMax, | |
820 | (long) (sym_ptr->isymMax * sizeof (SYMR))); | |
68e9eb95 | 821 | |
6ba29526 | 822 | printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols", |
0f41302f MS |
823 | (long) sym_ptr->cbOptOffset, |
824 | (long) sym_ptr->ioptMax, | |
825 | (long) (sym_ptr->ioptMax * sizeof (OPTR))); | |
68e9eb95 | 826 | |
6ba29526 | 827 | printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols", |
0f41302f MS |
828 | (long) sym_ptr->cbAuxOffset, |
829 | (long) sym_ptr->iauxMax, | |
830 | (long) (sym_ptr->iauxMax * sizeof (AUXU))); | |
68e9eb95 | 831 | |
6ba29526 | 832 | printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings", |
0f41302f MS |
833 | (long) sym_ptr->cbSsOffset, |
834 | (long) sym_ptr->issMax, | |
835 | (long) sym_ptr->issMax); | |
68e9eb95 | 836 | |
6ba29526 | 837 | printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings", |
0f41302f MS |
838 | (long) sym_ptr->cbSsExtOffset, |
839 | (long) sym_ptr->issExtMax, | |
840 | (long) sym_ptr->issExtMax); | |
68e9eb95 | 841 | |
6ba29526 | 842 | printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables", |
0f41302f MS |
843 | (long) sym_ptr->cbFdOffset, |
844 | (long) sym_ptr->ifdMax, | |
845 | (long) (sym_ptr->ifdMax * sizeof (FDR))); | |
68e9eb95 | 846 | |
6ba29526 | 847 | printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files", |
0f41302f MS |
848 | (long) sym_ptr->cbRfdOffset, |
849 | (long) sym_ptr->crfd, | |
850 | (long) (sym_ptr->crfd * sizeof (ulong))); | |
68e9eb95 | 851 | |
6ba29526 | 852 | printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols", |
0f41302f MS |
853 | (long) sym_ptr->cbExtOffset, |
854 | (long) sym_ptr->iextMax, | |
855 | (long) (sym_ptr->iextMax * sizeof (EXTR))); | |
68e9eb95 RS |
856 | } |
857 | ||
858 | \f | |
859 | /* Print out a symbol. */ | |
860 | ||
45a647be | 861 | static void |
cf633f5b AJ |
862 | print_symbol (SYMR *sym_ptr, int number, const char *strbase, AUXU *aux_base, |
863 | int ifd, FDR *fdp) | |
68e9eb95 RS |
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 | ||
0f41302f | 873 | if (aux_base != (AUXU *) 0 && index != indexNil) |
68e9eb95 RS |
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 | { | |
0f41302f | 885 | if (free_scope == (scope_t *) 0) |
1f57487c | 886 | scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); |
68e9eb95 RS |
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; | |
cd1661d6 | 906 | printf (" First symbol: %ld\n", (long) aux_base[index].isym); |
68e9eb95 RS |
907 | } |
908 | ||
909 | if (want_scope) | |
910 | { | |
0f41302f | 911 | if (cur_scope == (scope_t *) 0) |
68e9eb95 RS |
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", | |
cd1661d6 | 931 | (long) aux_base[index].isym, |
5346f1b9 | 932 | type_to_string (aux_base, index+1, fdp)); |
68e9eb95 RS |
933 | } |
934 | else /* global symbol */ | |
6ba29526 | 935 | printf (" Local symbol: %ld\n", index); |
68e9eb95 RS |
936 | |
937 | if (want_scope) | |
938 | { | |
0f41302f | 939 | if (free_scope == (scope_t *) 0) |
1f57487c | 940 | scope_ptr = (scope_t *) xmalloc (sizeof (scope_t)); |
68e9eb95 RS |
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 | ||
5346f1b9 RK |
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 | ||
68e9eb95 RS |
962 | default: |
963 | if (!MIPS_IS_STAB (sym_ptr)) | |
964 | { | |
965 | used_ptr[index] = 1; | |
966 | printf (" Type: %s\n", | |
5346f1b9 | 967 | type_to_string (aux_base, index, fdp)); |
68e9eb95 RS |
968 | } |
969 | break; | |
970 | } | |
971 | ||
972 | if (want_scope) | |
973 | { | |
974 | printf (" Scopes: "); | |
0f41302f | 975 | if (cur_scope == (scope_t *) 0) |
68e9eb95 RS |
976 | printf (" none\n"); |
977 | else | |
978 | { | |
979 | for (scope_ptr = cur_scope; | |
0f41302f | 980 | scope_ptr != (scope_t *) 0; |
68e9eb95 RS |
981 | scope_ptr = scope_ptr->prev) |
982 | { | |
1f57487c | 983 | const char *sclass; |
68e9eb95 | 984 | if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc) |
1f57487c | 985 | sclass = "func."; |
68e9eb95 | 986 | else if (scope_ptr->st == st_File) |
1f57487c | 987 | sclass = "file"; |
68e9eb95 | 988 | else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text) |
1f57487c | 989 | sclass = "block"; |
68e9eb95 | 990 | else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info) |
1f57487c | 991 | sclass = "type"; |
68e9eb95 | 992 | else |
1f57487c | 993 | sclass = "???"; |
68e9eb95 | 994 | |
1f57487c | 995 | printf (" %ld [%s]", scope_ptr->open_sym, sclass); |
68e9eb95 RS |
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 | { | |
b3694847 | 1014 | int i = ARRAY_SIZE (stab_names); |
47e6be47 | 1015 | const char *stab_name = "stab"; |
68e9eb95 | 1016 | short code = MIPS_UNMARK_STAB(sym_ptr->index); |
b3694847 | 1017 | |
68e9eb95 RS |
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 | \f | |
1034 | /* Print out a word from the aux. table in various formats. */ | |
1035 | ||
45a647be | 1036 | static void |
cf633f5b | 1037 | print_aux (AUXU u, int auxi, int used) |
68e9eb95 RS |
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 | \f | |
1057 | /* Write aggregate information to a string. */ | |
1058 | ||
45a647be | 1059 | static void |
cf633f5b | 1060 | emit_aggregate (char *string, AUXU u, AUXU u2, const char *which, FDR *fdp) |
68e9eb95 | 1061 | { |
5346f1b9 RK |
1062 | unsigned int ifd = u.rndx.rfd; |
1063 | unsigned int index = u.rndx.index; | |
1064 | const char *name; | |
cf633f5b | 1065 | |
68e9eb95 RS |
1066 | if (ifd == ST_RFDESCAPE) |
1067 | ifd = u2.isym; | |
cf633f5b | 1068 | |
5346f1b9 RK |
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 | } | |
cf633f5b | 1084 | |
68e9eb95 | 1085 | sprintf (string, |
5346f1b9 RK |
1086 | "%s %s { ifd = %u, index = %u }", |
1087 | which, name, ifd, index); | |
68e9eb95 RS |
1088 | } |
1089 | ||
1090 | \f | |
1091 | /* Print out information about a file descriptor, and the symbols, | |
1092 | procedures, and line numbers within it. */ | |
1093 | ||
45a647be | 1094 | static void |
cf633f5b | 1095 | print_file_desc (FDR *fdp, int number) |
68e9eb95 RS |
1096 | { |
1097 | char *str_base; | |
1098 | AUXU *aux_base; | |
1099 | int symi, pdi; | |
1100 | int width = 20; | |
1101 | char *used_base; | |
cf633f5b AJ |
1102 | |
1103 | str_base = l_strings + fdp->issBase; | |
68e9eb95 RS |
1104 | aux_base = aux_symbols + fdp->iauxBase; |
1105 | used_base = aux_used + (aux_base - aux_symbols); | |
1106 | ||
c4687d70 RO |
1107 | printf ("\nFile #%d, \"%s\"\n\n", |
1108 | number, | |
1109 | fdp->rss != issNil ? str_base + fdp->rss : "<unknown>"); | |
cf633f5b | 1110 | |
6ba29526 | 1111 | printf (" Name index = %-10ld Readin = %s\n", |
68e9eb95 RS |
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", | |
1119 | glevel_to_string (fdp->glevel), | |
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 | ||
6ba29526 | 1134 | printf(" %-*s %11lu %11lu %11lu %11lu\n", |
68e9eb95 RS |
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, | |
338f21be | 1145 | (ulong) fdp->cbLine, |
68e9eb95 RS |
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 | ||
b10d3744 | 1155 | printf(" %-*s %11lu %11lu %11lu %11lu\n", |
68e9eb95 RS |
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 | ||
0f41302f | 1177 | if (want_scope && cur_scope != (scope_t *) 0) |
68e9eb95 RS |
1178 | printf ("\n Warning scope does not start at 0!\n"); |
1179 | ||
cf633f5b | 1180 | /* |
68e9eb95 RS |
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, | |
5346f1b9 RK |
1192 | -1, |
1193 | fdp); | |
68e9eb95 | 1194 | |
0f41302f | 1195 | if (want_scope && cur_scope != (scope_t *) 0) |
68e9eb95 RS |
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 | ||
f11f1fb5 | 1225 | rfd_ptr = rfile_desc + fdp->rfdBase; |
47e6be47 | 1226 | for (i = 0; i < (ulong) fdp->crfd; i++) |
68e9eb95 RS |
1227 | { |
1228 | printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr); | |
1229 | rfd_ptr++; | |
1230 | } | |
1231 | } | |
1232 | ||
cf633f5b | 1233 | /* |
68e9eb95 RS |
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 | ||
c4687d70 RO |
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); | |
68e9eb95 RS |
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; | |
338f21be JW |
1280 | uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset |
1281 | + fdp->cbLineOffset); | |
68e9eb95 RS |
1282 | uchar *line_end; |
1283 | ||
1284 | if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ | |
338f21be | 1285 | line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset; |
0f41302f | 1286 | else /* not last proc. */ |
338f21be JW |
1287 | line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset |
1288 | + fdp->cbLineOffset); | |
68e9eb95 RS |
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 | \f | |
1318 | /* Read in the portions of the .T file that we will print out. */ | |
1319 | ||
45a647be | 1320 | static void |
cf633f5b | 1321 | read_tfile (void) |
68e9eb95 RS |
1322 | { |
1323 | short magic; | |
1324 | off_t sym_hdr_offset = 0; | |
1325 | ||
703ad42b | 1326 | read_seek (&magic, sizeof (magic), 0, "Magic number"); |
3876db74 | 1327 | if (!tfile) |
68e9eb95 | 1328 | { |
3876db74 MM |
1329 | /* Print out the global header, since this is not a T-file. */ |
1330 | ||
703ad42b | 1331 | read_seek (&global_hdr, sizeof (global_hdr), 0, "Global file header"); |
68e9eb95 RS |
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 | ||
703ad42b | 1344 | read_seek (&sym_hdr, sizeof (sym_hdr), sym_hdr_offset, "Symbolic header"); |
68e9eb95 RS |
1345 | |
1346 | print_sym_hdr (&sym_hdr); | |
1347 | ||
1f57487c RO |
1348 | lines = (LINER *) read_seek (NULL, sym_hdr.cbLine, sym_hdr.cbLineOffset, |
1349 | "Line numbers"); | |
68e9eb95 | 1350 | |
1f57487c RO |
1351 | dense_nums = (DNR *) read_seek (NULL, sym_hdr.idnMax * sizeof (DNR), |
1352 | sym_hdr.cbDnOffset, "Dense numbers"); | |
68e9eb95 | 1353 | |
1f57487c RO |
1354 | proc_desc = (PDR *) read_seek (NULL, sym_hdr.ipdMax * sizeof (PDR), |
1355 | sym_hdr.cbPdOffset, "Procedure tables"); | |
68e9eb95 | 1356 | |
1f57487c RO |
1357 | l_symbols = (SYMR *) read_seek (NULL, sym_hdr.isymMax * sizeof (SYMR), |
1358 | sym_hdr.cbSymOffset, "Local symbols"); | |
68e9eb95 | 1359 | |
1f57487c RO |
1360 | opt_symbols = (OPTR *) read_seek (NULL, sym_hdr.ioptMax * sizeof (OPTR), |
1361 | sym_hdr.cbOptOffset, | |
1362 | "Optimization symbols"); | |
68e9eb95 | 1363 | |
1f57487c RO |
1364 | aux_symbols = (AUXU *) read_seek (NULL, sym_hdr.iauxMax * sizeof (AUXU), |
1365 | sym_hdr.cbAuxOffset, "Auxiliary symbols"); | |
68e9eb95 RS |
1366 | |
1367 | if (sym_hdr.iauxMax > 0) | |
1f57487c | 1368 | aux_used = (char *) xcalloc (sym_hdr.iauxMax, 1); |
68e9eb95 | 1369 | |
1f57487c RO |
1370 | l_strings = (char *) read_seek (NULL, sym_hdr.issMax, |
1371 | sym_hdr.cbSsOffset, "Local string table"); | |
703ad42b | 1372 | |
1f57487c RO |
1373 | e_strings = (char *) read_seek (NULL, sym_hdr.issExtMax, |
1374 | sym_hdr.cbSsExtOffset, | |
1375 | "External string table"); | |
703ad42b | 1376 | |
1f57487c RO |
1377 | file_desc = (FDR *) read_seek (NULL, sym_hdr.ifdMax * sizeof (FDR), |
1378 | sym_hdr.cbFdOffset, "File tables"); | |
703ad42b | 1379 | |
1f57487c RO |
1380 | rfile_desc = (ulong *) read_seek (NULL, sym_hdr.crfd * sizeof (ulong), |
1381 | sym_hdr.cbRfdOffset, | |
1382 | "Relative file tables"); | |
703ad42b | 1383 | |
1f57487c RO |
1384 | e_symbols = (EXTR *) read_seek (NULL, sym_hdr.iextMax * sizeof (EXTR), |
1385 | sym_hdr.cbExtOffset, "External symbols"); | |
68e9eb95 RS |
1386 | } |
1387 | ||
1388 | \f | |
1389 | ||
cf633f5b | 1390 | extern int main (int, char **); |
341a243e | 1391 | |
68e9eb95 | 1392 | int |
cf633f5b | 1393 | main (int argc, char **argv) |
68e9eb95 RS |
1394 | { |
1395 | int i, opt; | |
1396 | ||
1397 | /* | |
1398 | * Process arguments | |
1399 | */ | |
d90f9882 | 1400 | while ((opt = getopt_long (argc, argv, "alrsvt", options, NULL)) != -1) |
68e9eb95 RS |
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 */ | |
d90f9882 RS |
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 */ | |
68e9eb95 RS |
1412 | } |
1413 | ||
d90f9882 RS |
1414 | if (version) |
1415 | { | |
2f41c1d6 | 1416 | printf ("mips-tdump %s%s\n", pkgversion_string, version_string); |
0e5997c0 | 1417 | fputs ("Copyright (C) 2008 Free Software Foundation, Inc.\n", stdout); |
d90f9882 RS |
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) | |
68e9eb95 RS |
1437 | { |
1438 | fprintf (stderr, "Calling Sequence:\n"); | |
b10d3744 | 1439 | fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]); |
68e9eb95 RS |
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"); | |
3876db74 | 1446 | fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); |
d90f9882 | 1447 | fprintf (stderr, "\t-v Print program version.\n"); |
68e9eb95 RS |
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 | |
db3cf6fb MS |
1480 | last_aux_in_use |
1481 | = (file_desc[sym_hdr.ifdMax-1].iauxBase | |
1482 | + file_desc[sym_hdr.ifdMax-1].caux - 1); | |
68e9eb95 RS |
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 | ||
cf633f5b | 1498 | /* |
68e9eb95 RS |
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, | |
5346f1b9 RK |
1509 | e_symbols[i].ifd, |
1510 | &file_desc[e_symbols[i].ifd]); | |
68e9eb95 RS |
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, | |
5346f1b9 | 1534 | type_to_string (aux_symbols, i, (FDR *) 0)); |
68e9eb95 RS |
1535 | } |
1536 | } | |
1537 | } | |
1538 | ||
1539 | return 0; | |
1540 | } |