]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/readelf.c
* readelf.c (get_machine_flags): Check for EF_CPU32.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@cygnus.com>
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23 \f
24
25 #include <assert.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <time.h>
29
30 #include "bfd.h"
31
32 #include "elf/common.h"
33 #include "elf/external.h"
34 #include "elf/internal.h"
35 #include "elf/dwarf2.h"
36
37 /* The following headers use the elf/reloc-macros.h file to
38 automatically generate relocation recognition functions
39 such as elf_mips_reloc_type() */
40
41 #define RELOC_MACROS_GEN_FUNC
42
43 #include "elf/i386.h"
44 #include "elf/v850.h"
45 #include "elf/ppc.h"
46 #include "elf/mips.h"
47 #include "elf/alpha.h"
48 #include "elf/arm.h"
49 #include "elf/m68k.h"
50 #include "elf/sparc.h"
51 #include "elf/m32r.h"
52 #include "elf/d10v.h"
53 #include "elf/d30v.h"
54 #include "elf/sh.h"
55 #include "elf/mn10200.h"
56 #include "elf/mn10300.h"
57 #include "elf/hppa.h"
58 #include "elf/arc.h"
59 #include "elf/fr30.h"
60 #include "elf/mcore.h"
61
62 #include "bucomm.h"
63 #include "getopt.h"
64
65 #ifdef ANSI_PROTOTYPES
66 #include <stdarg.h>
67 #else
68 #include <varargs.h>
69 #endif
70
71 char * program_name = "readelf";
72 unsigned int dynamic_addr;
73 unsigned int dynamic_size;
74 unsigned int rela_addr;
75 unsigned int rela_size;
76 char * dynamic_strings;
77 char * string_table;
78 Elf_Internal_Sym * dynamic_symbols;
79 Elf_Internal_Syminfo * dynamic_syminfo;
80 unsigned long dynamic_syminfo_offset;
81 unsigned int dynamic_syminfo_nent;
82 char program_interpreter [64];
83 int dynamic_info[DT_JMPREL + 1];
84 int version_info[16];
85 int loadaddr = 0;
86 Elf_Internal_Ehdr elf_header;
87 Elf_Internal_Shdr * section_headers;
88 Elf_Internal_Dyn * dynamic_segment;
89 int show_name;
90 int do_dynamic;
91 int do_syms;
92 int do_reloc;
93 int do_sections;
94 int do_segments;
95 int do_using_dynamic;
96 int do_header;
97 int do_dump;
98 int do_version;
99 int do_histogram;
100 int do_debugging;
101 int do_debug_info;
102 int do_debug_abbrevs;
103 int do_debug_lines;
104 int do_debug_pubnames;
105 int do_debug_aranges;
106 int binary_class;
107
108 /* A dynamic array of flags indicating which sections require dumping. */
109 char * dump_sects = NULL;
110 unsigned int num_dump_sects = 0;
111
112 #define HEX_DUMP (1 << 0)
113 #define DISASS_DUMP (1 << 1)
114 #define DEBUG_DUMP (1 << 2)
115
116 /* Forward declarations for dumb compilers. */
117 static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
118 static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
119 static const char * get_dynamic_type PARAMS ((unsigned long type));
120 static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *));
121 static char * get_file_type PARAMS ((unsigned e_type));
122 static char * get_machine_name PARAMS ((unsigned e_machine));
123 static char * get_machine_data PARAMS ((unsigned e_data));
124 static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
125 static const char * get_mips_segment_type PARAMS ((unsigned long type));
126 static const char * get_segment_type PARAMS ((unsigned long p_type));
127 static const char * get_mips_section_type_name PARAMS ((unsigned int sh_type));
128 static const char * get_section_type_name PARAMS ((unsigned int sh_type));
129 static char * get_symbol_binding PARAMS ((unsigned int binding));
130 static char * get_symbol_type PARAMS ((unsigned int type));
131 static void usage PARAMS ((void));
132 static void parse_args PARAMS ((int argc, char ** argv));
133 static int process_file_header PARAMS ((void));
134 static int process_program_headers PARAMS ((FILE *));
135 static int process_section_headers PARAMS ((FILE *));
136 static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *entry));
137 static int process_dynamic_segment PARAMS ((FILE *));
138 static int process_symbol_table PARAMS ((FILE *));
139 static int process_section_contents PARAMS ((FILE *));
140 static void process_file PARAMS ((char * file_name));
141 static int process_relocs PARAMS ((FILE *));
142 static int process_version_sections PARAMS ((FILE *));
143 static char * get_ver_flags PARAMS ((unsigned int flags));
144 static char * get_symbol_index_type PARAMS ((unsigned int type));
145 static int get_section_headers PARAMS ((FILE * file));
146 static int get_file_header PARAMS ((FILE * file));
147 static Elf_Internal_Sym * get_elf_symbols PARAMS ((FILE * file, unsigned long offset, unsigned long number));
148 static int * get_dynamic_data PARAMS ((FILE * file, unsigned int number));
149 #ifdef SUPPORT_DISASSEMBLY
150 static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
151 #endif
152 static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
153 static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
154 static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
155 static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
156 static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
157 static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
158 static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
159 static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
160 static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
161 static int process_extended_line_op PARAMS ((unsigned char *, int));
162 static void reset_state_machine PARAMS ((int));
163 static char * get_TAG_name PARAMS ((unsigned long));
164 static char * get_AT_name PARAMS ((unsigned long));
165 static char * get_FORM_name PARAMS ((unsigned long));
166 static void free_abbrevs PARAMS ((void));
167 static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
168 static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
169 static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
170 static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
171 static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
172 static void request_dump PARAMS ((unsigned int, char));
173 static const char * get_elf_class PARAMS ((unsigned char));
174 static const char * get_data_encoding PARAMS ((unsigned char));
175 static const char * get_osabi_name PARAMS ((unsigned char));
176
177 typedef int Elf32_Word;
178
179 #define SECTION_NAME(X) (string_table + (X)->sh_name)
180
181 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
182
183 #define BYTE_GET(field) byte_get (field, sizeof (field))
184
185 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
186
187 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
188 if (fseek (file, offset, SEEK_SET)) \
189 { \
190 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
191 return 0; \
192 } \
193 \
194 var = (type) malloc (size); \
195 \
196 if (var == NULL) \
197 { \
198 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
199 return 0; \
200 } \
201 \
202 if (fread (var, size, 1, file) != 1) \
203 { \
204 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
205 free (var); \
206 var = NULL; \
207 return 0; \
208 }
209
210
211 #define GET_DATA(offset, var, reason) \
212 if (fseek (file, offset, SEEK_SET)) \
213 { \
214 error (_("Unable to seek to %x for %s\n"), offset, reason); \
215 return 0; \
216 } \
217 else if (fread (& var, sizeof (var), 1, file) != 1) \
218 { \
219 error (_("Unable to read data at %x for %s\n"), offset, reason); \
220 return 0; \
221 }
222
223 #ifdef ANSI_PROTOTYPES
224 static void
225 error (const char * message, ...)
226 {
227 va_list args;
228
229 fprintf (stderr, _("%s: Error: "), program_name);
230 va_start (args, message);
231 vfprintf (stderr, message, args);
232 va_end (args);
233 return;
234 }
235
236 static void
237 warn (const char * message, ...)
238 {
239 va_list args;
240
241 fprintf (stderr, _("%s: Warning: "), program_name);
242 va_start (args, message);
243 vfprintf (stderr, message, args);
244 va_end (args);
245 return;
246 }
247 #else
248 static void
249 error (va_alist)
250 va_dcl
251 {
252 char * message;
253 va_list args;
254
255 fprintf (stderr, _("%s: Error: "), program_name);
256 va_start (args);
257 message = va_arg (args, char *);
258 vfprintf (stderr, message, args);
259 va_end (args);
260 return;
261 }
262
263 static void
264 warn (va_alist)
265 va_dcl
266 {
267 char * message;
268 va_list args;
269
270 fprintf (stderr, _("%s: Warning: "), program_name);
271 va_start (args);
272 message = va_arg (args, char *);
273 vfprintf (stderr, message, args);
274 va_end (args);
275 return;
276 }
277 #endif
278
279 static unsigned long int
280 byte_get_little_endian (field, size)
281 unsigned char * field;
282 int size;
283 {
284 switch (size)
285 {
286 case 1:
287 return * field;
288
289 case 2:
290 return ((unsigned int) (field [0]))
291 | (((unsigned int) (field [1])) << 8);
292
293 case 4:
294 return ((unsigned long) (field [0]))
295 | (((unsigned long) (field [1])) << 8)
296 | (((unsigned long) (field [2])) << 16)
297 | (((unsigned long) (field [3])) << 24);
298
299 default:
300 error (_("Unhandled data length: %d\n"), size);
301 abort();
302 }
303 }
304
305 static unsigned long int
306 byte_get_big_endian (field, size)
307 unsigned char * field;
308 int size;
309 {
310 switch (size)
311 {
312 case 1:
313 return * field;
314
315 case 2:
316 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
317
318 case 4:
319 return ((unsigned long) (field [3]))
320 | (((unsigned long) (field [2])) << 8)
321 | (((unsigned long) (field [1])) << 16)
322 | (((unsigned long) (field [0])) << 24);
323
324 default:
325 error (_("Unhandled data length: %d\n"), size);
326 abort();
327 }
328 }
329
330
331 /* Display the contents of the relocation data
332 found at the specified offset. */
333 static int
334 dump_relocations (file, rel_offset, rel_size, symtab, strtab)
335 FILE * file;
336 unsigned long rel_offset;
337 unsigned long rel_size;
338 Elf_Internal_Sym * symtab;
339 char * strtab;
340 {
341 unsigned int i;
342 int is_rela;
343 Elf_Internal_Rel * rels;
344 Elf_Internal_Rela * relas;
345
346
347 /* Compute number of relocations and read them in. */
348 switch (elf_header.e_machine)
349 {
350 /* Targets that use REL relocations. */
351 case EM_ARM:
352 case EM_386:
353 case EM_486:
354 case EM_CYGNUS_M32R:
355 case EM_CYGNUS_D10V:
356 case EM_MIPS:
357 case EM_MIPS_RS4_BE:
358 {
359 Elf32_External_Rel * erels;
360
361 GET_DATA_ALLOC (rel_offset, rel_size, erels,
362 Elf32_External_Rel *, "relocs");
363
364 rel_size = rel_size / sizeof (Elf32_External_Rel);
365
366 rels = (Elf_Internal_Rel *) malloc (rel_size *
367 sizeof (Elf_Internal_Rel));
368
369 for (i = 0; i < rel_size; i++)
370 {
371 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
372 rels[i].r_info = BYTE_GET (erels[i].r_info);
373 }
374
375 free (erels);
376
377 is_rela = 0;
378 relas = (Elf_Internal_Rela *) rels;
379 }
380 break;
381
382 /* Targets that use RELA relocations. */
383 case EM_68K:
384 case EM_SPARC:
385 case EM_PPC:
386 case EM_CYGNUS_V850:
387 case EM_CYGNUS_D30V:
388 case EM_CYGNUS_MN10200:
389 case EM_CYGNUS_MN10300:
390 case EM_CYGNUS_FR30:
391 case EM_SH:
392 case EM_ALPHA:
393 case EM_MCORE:
394 {
395 Elf32_External_Rela * erelas;
396
397 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
398 Elf32_External_Rela *, "relocs");
399
400 rel_size = rel_size / sizeof (Elf32_External_Rela);
401
402 relas = (Elf_Internal_Rela *) malloc (rel_size *
403 sizeof (Elf_Internal_Rela));
404
405 for (i = 0; i < rel_size; i++)
406 {
407 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
408 relas[i].r_info = BYTE_GET (erelas[i].r_info);
409 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
410 }
411
412 free (erelas);
413
414 is_rela = 1;
415 rels = (Elf_Internal_Rel *) relas;
416 }
417 break;
418
419 default:
420 warn (_("Don't know about relocations on this machine architecture\n"));
421 return 0;
422 }
423
424 if (is_rela)
425 printf
426 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
427 else
428 printf
429 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
430
431 for (i = 0; i < rel_size; i++)
432 {
433 const char * rtype;
434 unsigned long offset;
435 unsigned long info;
436 int symtab_index;
437
438 if (is_rela)
439 {
440 offset = relas [i].r_offset;
441 info = relas [i].r_info;
442 }
443 else
444 {
445 offset = rels [i].r_offset;
446 info = rels [i].r_info;
447 }
448
449 printf (" %8.8lx %5.5lx ", offset, info);
450
451 switch (elf_header.e_machine)
452 {
453 default:
454 rtype = NULL;
455 break;
456
457 case EM_CYGNUS_M32R:
458 rtype = elf_m32r_reloc_type (ELF32_R_TYPE (info));
459 break;
460
461 case EM_386:
462 case EM_486:
463 rtype = elf_i386_reloc_type (ELF32_R_TYPE (info));
464 break;
465
466 case EM_68K:
467 rtype = elf_m68k_reloc_type (ELF32_R_TYPE (info));
468 break;
469
470 case EM_SPARC:
471 rtype = elf_sparc_reloc_type (ELF32_R_TYPE (info));
472 break;
473
474 case EM_CYGNUS_V850:
475 rtype = v850_reloc_type (ELF32_R_TYPE (info));
476 break;
477
478 case EM_CYGNUS_D10V:
479 rtype = elf_d10v_reloc_type (ELF32_R_TYPE (info));
480 break;
481
482 case EM_CYGNUS_D30V:
483 rtype = elf_d30v_reloc_type (ELF32_R_TYPE (info));
484 break;
485
486 case EM_SH:
487 rtype = elf_sh_reloc_type (ELF32_R_TYPE (info));
488 break;
489
490 case EM_CYGNUS_MN10300:
491 rtype = elf_mn10300_reloc_type (ELF32_R_TYPE (info));
492 break;
493
494 case EM_CYGNUS_MN10200:
495 rtype = elf_mn10200_reloc_type (ELF32_R_TYPE (info));
496 break;
497
498 case EM_CYGNUS_FR30:
499 rtype = elf_fr30_reloc_type (ELF32_R_TYPE (info));
500 break;
501
502 case EM_MCORE:
503 rtype = elf_mcore_reloc_type (ELF32_R_TYPE (info));
504 break;
505
506 case EM_PPC:
507 rtype = elf_ppc_reloc_type (ELF32_R_TYPE (info));
508 break;
509
510 case EM_MIPS:
511 case EM_MIPS_RS4_BE:
512 rtype = elf_mips_reloc_type (ELF32_R_TYPE (info));
513 break;
514
515 case EM_ALPHA:
516 rtype = elf_alpha_reloc_type (ELF32_R_TYPE (info));
517 break;
518
519 case EM_ARM:
520 rtype = elf_arm_reloc_type (ELF32_R_TYPE (info));
521 break;
522
523 case EM_CYGNUS_ARC:
524 rtype = elf_arc_reloc_type (ELF32_R_TYPE (info));
525 break;
526
527 case EM_PARISC:
528 rtype = elf32_hppa_reloc_type (ELF32_R_TYPE (info));
529 break;
530 }
531
532 if (rtype == NULL)
533 printf (_("unrecognised: %-7lx"), ELF32_R_TYPE (info));
534 else
535 printf ("%-21.21s", rtype);
536
537 symtab_index = ELF32_R_SYM (info);
538
539 if (symtab_index && symtab != NULL)
540 {
541 Elf_Internal_Sym * psym;
542
543 psym = symtab + symtab_index;
544
545 printf (" %08lx ", (unsigned long) psym->st_value);
546
547 if (psym->st_name == 0)
548 printf ("%-25.25s",
549 SECTION_NAME (section_headers + psym->st_shndx));
550 else if (strtab == NULL)
551 printf (_("<string table index %3ld>"), psym->st_name);
552 else
553 printf ("%-25.25s", strtab + psym->st_name);
554
555 if (is_rela)
556 printf (" + %lx", (unsigned long) relas [i].r_addend);
557 }
558
559 putchar ('\n');
560 }
561
562 free (relas);
563
564 return 1;
565 }
566
567 static const char *
568 get_mips_dynamic_type (type)
569 unsigned long type;
570 {
571 switch (type)
572 {
573 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
574 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
575 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
576 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
577 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
578 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
579 case DT_MIPS_MSYM: return "MIPS_MSYM";
580 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
581 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
582 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
583 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
584 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
585 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
586 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
587 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
588 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
589 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
590 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
591 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
592 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
593 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
594 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
595 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
596 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
597 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
598 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
599 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
600 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
601 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
602 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
603 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
604 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
605 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
606 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
607 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
608 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
609 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
610 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
611 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
612 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
613 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
614 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
615 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
616 default:
617 return NULL;
618 }
619 }
620
621 static const char *
622 get_dynamic_type (type)
623 unsigned long type;
624 {
625 static char buff [32];
626
627 switch (type)
628 {
629 case DT_NULL: return "NULL";
630 case DT_NEEDED: return "NEEDED";
631 case DT_PLTRELSZ: return "PLTRELSZ";
632 case DT_PLTGOT: return "PLTGOT";
633 case DT_HASH: return "HASH";
634 case DT_STRTAB: return "STRTAB";
635 case DT_SYMTAB: return "SYMTAB";
636 case DT_RELA: return "RELA";
637 case DT_RELASZ: return "RELASZ";
638 case DT_RELAENT: return "RELAENT";
639 case DT_STRSZ: return "STRSZ";
640 case DT_SYMENT: return "SYMENT";
641 case DT_INIT: return "INIT";
642 case DT_FINI: return "FINI";
643 case DT_SONAME: return "SONAME";
644 case DT_RPATH: return "RPATH";
645 case DT_SYMBOLIC: return "SYMBOLIC";
646 case DT_REL: return "REL";
647 case DT_RELSZ: return "RELSZ";
648 case DT_RELENT: return "RELENT";
649 case DT_PLTREL: return "PLTREL";
650 case DT_DEBUG: return "DEBUG";
651 case DT_TEXTREL: return "TEXTREL";
652 case DT_JMPREL: return "JMPREL";
653 case DT_BIND_NOW: return "BIND_NOW";
654 case DT_INIT_ARRAY: return "INIT_ARRAY";
655 case DT_FINI_ARRAY: return "FINI_ARRAY";
656 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
657 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
658
659 case DT_PLTPADSZ: return "PLTPADSZ";
660 case DT_MOVEENT: return "MOVEENT";
661 case DT_MOVESZ: return "MOVESZ";
662 case DT_FEATURE_1: return "FEATURE_1";
663 case DT_POSFLAG_1: return "POSFLAG_1";
664 case DT_SYMINSZ: return "SYMINSZ";
665 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
666
667 case DT_ADDRRNGLO: return "ADDRRNGLO";
668 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
669
670 case DT_VERSYM: return "VERSYM";
671
672 case DT_RELACOUNT: return "RELACOUNT";
673 case DT_RELCOUNT: return "RELCOUNT";
674 case DT_FLAGS_1: return "FLAGS_1";
675 case DT_VERDEF: return "VERDEF";
676 case DT_VERDEFNUM: return "VERDEFNUM";
677 case DT_VERNEED: return "VERNEED";
678 case DT_VERNEEDNUM: return "VERNEEDNUM";
679
680 case DT_AUXILIARY: return "AUXILARY";
681 case DT_USED: return "USED";
682 case DT_FILTER: return "FILTER";
683
684 default:
685 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
686 {
687 const char * result;
688
689 switch (elf_header.e_machine)
690 {
691 case EM_MIPS:
692 case EM_MIPS_RS4_BE:
693 result = get_mips_dynamic_type (type);
694 break;
695 default:
696 result = NULL;
697 break;
698 }
699
700 if (result != NULL)
701 return result;
702
703 sprintf (buff, _("Processor Specific: %lx"), type);
704 }
705 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
706 sprintf (buff, _("Operating System specific: %lx"), type);
707 else
708 sprintf (buff, _("<unknown>: %lx"), type);
709
710 return buff;
711 }
712 }
713
714 static char *
715 get_file_type (e_type)
716 unsigned e_type;
717 {
718 static char buff [32];
719
720 switch (e_type)
721 {
722 case ET_NONE: return _("NONE (None)");
723 case ET_REL: return _("REL (Relocatable file)");
724 case ET_EXEC: return _("EXEC (Executable file)");
725 case ET_DYN: return _("DYN (Shared object file)");
726 case ET_CORE: return _("CORE (Core file)");
727
728 default:
729 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
730 sprintf (buff, _("Processor Specific: (%x)"), e_type);
731 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
732 sprintf (buff, _("OS Specific: (%x)"), e_type);
733 else
734 sprintf (buff, _("<unknown>: %x"), e_type);
735 return buff;
736 }
737 }
738
739 static char *
740 get_machine_name (e_machine)
741 unsigned e_machine;
742 {
743 static char buff [32];
744
745 switch (e_machine)
746 {
747 case EM_NONE: return _("None");
748 case EM_M32: return "WE32100";
749 case EM_SPARC: return "Sparc";
750 case EM_386: return "Intel 80386";
751 case EM_68K: return "MC68000";
752 case EM_88K: return "MC88000";
753 case EM_486: return "Intel 80486";
754 case EM_860: return "Intel 80860";
755 case EM_MIPS: return "MIPS R3000 big-endian";
756 case EM_S370: return "Amdahl";
757 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
758 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
759 case EM_PARISC: return "HPPA";
760 case EM_PPC_OLD: return "Power PC (old)";
761 case EM_SPARC32PLUS: return "Sparc v8+" ;
762 case EM_960: return "Intel 90860";
763 case EM_PPC: return "PowerPC";
764 case EM_V800: return "NEC V800";
765 case EM_FR20: return "Fujitsu FR20";
766 case EM_RH32: return "TRW RH32";
767 case EM_MCORE: return "MCORE";
768 case EM_ARM: return "ARM";
769 case EM_OLD_ALPHA: return "Digital Alpha (old)";
770 case EM_SH: return "Hitachi SH";
771 case EM_SPARCV9: return "Sparc v9";
772 case EM_TRICORE: return "Siemens Tricore";
773 case EM_ARC: return "Argonaut RISC Core";
774 case EM_H8_300: return "Hitachi H8/300";
775 case EM_H8_300H: return "Hitachi H8/300H";
776 case EM_H8S: return "Hitachi H8S";
777 case EM_H8_500: return "Hitachi H8/500";
778 case EM_IA_64: return "Intel Merced";
779 case EM_MIPS_X: return "Stanford MIPS-X";
780 case EM_COLDFIRE: return "Motorola Coldfire";
781 case EM_68HC12: return "Motorola M68HC12";
782 case EM_ALPHA: return "Alpha";
783 case EM_CYGNUS_D10V: return "d10v";
784 case EM_CYGNUS_D30V: return "d30v";
785 case EM_CYGNUS_ARC: return "Arc";
786 case EM_CYGNUS_M32R: return "Mitsubishi M32r";
787 case EM_CYGNUS_V850: return "NEC v850";
788 case EM_CYGNUS_MN10300: return "mn10300";
789 case EM_CYGNUS_MN10200: return "mn10200";
790 case EM_CYGNUS_FR30: return "Fujitsu FR30";
791
792 default:
793 sprintf (buff, _("<unknown>: %x"), e_machine);
794 return buff;
795 }
796 }
797
798 static char *
799 get_machine_flags (e_flags, e_machine)
800 unsigned e_flags;
801 unsigned e_machine;
802 {
803 static char buf [1024];
804
805 buf[0] = '\0';
806 if (e_flags)
807 {
808 switch (e_machine)
809 {
810 default:
811 break;
812
813 case EM_68K:
814 if (e_flags & EF_CPU32)
815 strcat (buf, ", cpu32");
816 break;
817
818 case EM_PPC:
819 if (e_flags & EF_PPC_EMB)
820 strcat (buf, ", emb");
821
822 if (e_flags & EF_PPC_RELOCATABLE)
823 strcat (buf, ", relocatable");
824
825 if (e_flags & EF_PPC_RELOCATABLE_LIB)
826 strcat (buf, ", relocatable-lib");
827 break;
828
829 case EM_CYGNUS_V850:
830 switch (e_flags & EF_V850_ARCH)
831 {
832 case E_V850E_ARCH:
833 strcat (buf, ", v850e");
834 break;
835 case E_V850EA_ARCH:
836 strcat (buf, ", v850ea");
837 break;
838 case E_V850_ARCH:
839 strcat (buf, ", v850");
840 break;
841 default:
842 strcat (buf, ", unknown v850 architecture variant");
843 break;
844 }
845 break;
846
847 case EM_CYGNUS_M32R:
848 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
849 strcat (buf, ", m32r");
850
851 break;
852
853 case EM_MIPS:
854 case EM_MIPS_RS4_BE:
855 if (e_flags & EF_MIPS_NOREORDER)
856 strcat (buf, ", noreorder");
857
858 if (e_flags & EF_MIPS_PIC)
859 strcat (buf, ", pic");
860
861 if (e_flags & EF_MIPS_CPIC)
862 strcat (buf, ", cpic");
863
864 if (e_flags & EF_MIPS_ABI2)
865 strcat (buf, ", abi2");
866
867 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
868 strcat (buf, ", mips1");
869
870 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
871 strcat (buf, ", mips2");
872
873 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
874 strcat (buf, ", mips3");
875
876 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
877 strcat (buf, ", mips4");
878 break;
879 }
880 }
881
882 return buf;
883 }
884
885 static char *
886 get_machine_data (e_data)
887 unsigned e_data;
888 {
889 static char buff [32];
890
891 switch (e_data)
892 {
893 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
894 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
895 default:
896 sprintf (buff, _("<unknown>: %x"), e_data);
897 return buff;
898 }
899 }
900
901 static const char *
902 get_mips_segment_type (type)
903 unsigned long type;
904 {
905 switch (type)
906 {
907 case PT_MIPS_REGINFO:
908 return "REGINFO";
909 case PT_MIPS_RTPROC:
910 return "RTPROC";
911 case PT_MIPS_OPTIONS:
912 return "OPTIONS";
913 default:
914 break;
915 }
916
917 return NULL;
918 }
919
920 static const char *
921 get_segment_type (p_type)
922 unsigned long p_type;
923 {
924 static char buff [32];
925
926 switch (p_type)
927 {
928 case PT_NULL: return "NULL";
929 case PT_LOAD: return "LOAD";
930 case PT_DYNAMIC: return "DYNAMIC";
931 case PT_INTERP: return "INTERP";
932 case PT_NOTE: return "NOTE";
933 case PT_SHLIB: return "SHLIB";
934 case PT_PHDR: return "PHDR";
935
936 default:
937 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
938 {
939 const char * result;
940
941 switch (elf_header.e_machine)
942 {
943 case EM_MIPS:
944 case EM_MIPS_RS4_BE:
945 result = get_mips_segment_type (p_type);
946 break;
947 default:
948 result = NULL;
949 break;
950 }
951
952 if (result != NULL)
953 return result;
954
955 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
956 }
957 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
958 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
959 else
960 sprintf (buff, _("<unknown>: %lx"), p_type);
961
962 return buff;
963 }
964 }
965
966 static const char *
967 get_mips_section_type_name (sh_type)
968 unsigned int sh_type;
969 {
970 switch (sh_type)
971 {
972 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
973 case SHT_MIPS_MSYM: return "MIPS_MSYM";
974 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
975 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
976 case SHT_MIPS_UCODE: return "MIPS_UCODE";
977 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
978 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
979 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
980 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
981 case SHT_MIPS_RELD: return "MIPS_RELD";
982 case SHT_MIPS_IFACE: return "MIPS_IFACE";
983 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
984 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
985 case SHT_MIPS_SHDR: return "MIPS_SHDR";
986 case SHT_MIPS_FDESC: return "MIPS_FDESC";
987 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
988 case SHT_MIPS_DENSE: return "MIPS_DENSE";
989 case SHT_MIPS_PDESC: return "MIPS_PDESC";
990 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
991 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
992 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
993 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
994 case SHT_MIPS_LINE: return "MIPS_LINE";
995 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
996 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
997 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
998 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
999 case SHT_MIPS_DWARF: return "MIPS_DWARF";
1000 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
1001 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1002 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
1003 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
1004 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1005 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1006 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1007 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1008 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1009 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1010 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1011 default:
1012 break;
1013 }
1014 return NULL;
1015 }
1016
1017 static const char *
1018 get_section_type_name (sh_type)
1019 unsigned int sh_type;
1020 {
1021 static char buff [32];
1022
1023 switch (sh_type)
1024 {
1025 case SHT_NULL: return "NULL";
1026 case SHT_PROGBITS: return "PROGBITS";
1027 case SHT_SYMTAB: return "SYMTAB";
1028 case SHT_STRTAB: return "STRTAB";
1029 case SHT_RELA: return "RELA";
1030 case SHT_HASH: return "HASH";
1031 case SHT_DYNAMIC: return "DYNAMIC";
1032 case SHT_NOTE: return "NOTE";
1033 case SHT_NOBITS: return "NOBITS";
1034 case SHT_REL: return "REL";
1035 case SHT_SHLIB: return "SHLIB";
1036 case SHT_DYNSYM: return "DYNSYM";
1037 case SHT_GNU_verdef: return "VERDEF";
1038 case SHT_GNU_verneed: return "VERNEED";
1039 case SHT_GNU_versym: return "VERSYM";
1040 case 0x6ffffff0: return "VERSYM";
1041 case 0x6ffffffc: return "VERDEF";
1042 case 0x7ffffffd: return "AUXILIARY";
1043 case 0x7fffffff: return "FILTER";
1044
1045 default:
1046 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1047 {
1048 const char * result;
1049
1050 switch (elf_header.e_machine)
1051 {
1052 case EM_MIPS:
1053 case EM_MIPS_RS4_BE:
1054 result = get_mips_section_type_name (sh_type);
1055 break;
1056 default:
1057 result = NULL;
1058 break;
1059 }
1060
1061 if (result != NULL)
1062 return result;
1063
1064 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1065 }
1066 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1067 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1068 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1069 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1070 else
1071 sprintf (buff, _("<unknown>: %x"), sh_type);
1072
1073 return buff;
1074 }
1075 }
1076
1077 struct option options [] =
1078 {
1079 {"all", no_argument, 0, 'a'},
1080 {"file-header", no_argument, 0, 'h'},
1081 {"program-headers", no_argument, 0, 'l'},
1082 {"headers", no_argument, 0, 'e'},
1083 {"histogram", no_argument, & do_histogram, 1},
1084 {"segments", no_argument, 0, 'l'},
1085 {"sections", no_argument, 0, 'S'},
1086 {"section-headers", no_argument, 0, 'S'},
1087 {"symbols", no_argument, 0, 's'},
1088 {"syms", no_argument, 0, 's'},
1089 {"relocs", no_argument, 0, 'r'},
1090 {"dynamic", no_argument, 0, 'd'},
1091 {"version-info", no_argument, 0, 'V'},
1092 {"use-dynamic", no_argument, 0, 'D'},
1093 {"hex-dump", required_argument, 0, 'x'},
1094 {"debug-dump", optional_argument, 0, 'w'},
1095 #ifdef SUPPORT_DISASSEMBLY
1096 {"instruction-dump", required_argument, 0, 'i'},
1097 #endif
1098
1099 {"version", no_argument, 0, 'v'},
1100 {"help", no_argument, 0, 'H'},
1101 {0, no_argument, 0, 0}
1102 };
1103
1104 static void
1105 usage ()
1106 {
1107 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1108 fprintf (stdout, _(" Options are:\n"));
1109 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1110 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1111 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1112 fprintf (stdout, _(" Display the program headers\n"));
1113 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1114 fprintf (stdout, _(" Display the sections' header\n"));
1115 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1116 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1117 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1118 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1119 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1120 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1121 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1122 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1123 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1124 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1125 #ifdef SUPPORT_DISASSEMBLY
1126 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1127 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1128 #endif
1129 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1130 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1131 fprintf (stdout, _(" -H or --help Display this information\n"));
1132 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1133
1134 exit (0);
1135 }
1136
1137 static void
1138 request_dump (section, type)
1139 unsigned int section;
1140 char type;
1141 {
1142 if (section >= num_dump_sects)
1143 {
1144 char * new_dump_sects;
1145
1146 new_dump_sects = (char *) calloc (section + 1, 1);
1147
1148 if (new_dump_sects == NULL)
1149 error (_("Out of memory allocating dump request table."));
1150 else
1151 {
1152 /* Copy current flag settings. */
1153 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1154
1155 free (dump_sects);
1156
1157 dump_sects = new_dump_sects;
1158 num_dump_sects = section + 1;
1159 }
1160 }
1161
1162 if (dump_sects)
1163 dump_sects [section] |= type;
1164
1165 return;
1166 }
1167
1168 static void
1169 parse_args (argc, argv)
1170 int argc;
1171 char ** argv;
1172 {
1173 int c;
1174
1175 if (argc < 2)
1176 usage ();
1177
1178 while ((c = getopt_long
1179 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1180 {
1181 char * cp;
1182 int section;
1183
1184 switch (c)
1185 {
1186 case 0:
1187 /* Long options. */
1188 break;
1189 case 'H':
1190 usage ();
1191 break;
1192
1193 case 'a':
1194 do_syms ++;
1195 do_reloc ++;
1196 do_dynamic ++;
1197 do_header ++;
1198 do_sections ++;
1199 do_segments ++;
1200 do_version ++;
1201 do_histogram ++;
1202 break;
1203 case 'e':
1204 do_header ++;
1205 do_sections ++;
1206 do_segments ++;
1207 break;
1208 case 'D':
1209 do_using_dynamic ++;
1210 break;
1211 case 'r':
1212 do_reloc ++;
1213 break;
1214 case 'h':
1215 do_header ++;
1216 break;
1217 case 'l':
1218 do_segments ++;
1219 break;
1220 case 's':
1221 do_syms ++;
1222 break;
1223 case 'S':
1224 do_sections ++;
1225 break;
1226 case 'd':
1227 do_dynamic ++;
1228 break;
1229 case 'x':
1230 do_dump ++;
1231 section = strtoul (optarg, & cp, 0);
1232 if (! * cp && section >= 0)
1233 {
1234 request_dump (section, HEX_DUMP);
1235 break;
1236 }
1237 goto oops;
1238 case 'w':
1239 do_dump ++;
1240 if (optarg == 0)
1241 do_debugging = 1;
1242 else
1243 {
1244 do_debugging = 0;
1245 switch (optarg[0])
1246 {
1247 case 'i':
1248 case 'I':
1249 do_debug_info = 1;
1250 break;
1251
1252 case 'a':
1253 case 'A':
1254 do_debug_abbrevs = 1;
1255 break;
1256
1257 case 'l':
1258 case 'L':
1259 do_debug_lines = 1;
1260 break;
1261
1262 case 'p':
1263 case 'P':
1264 do_debug_pubnames = 1;
1265 break;
1266
1267 case 'r':
1268 case 'R':
1269 do_debug_aranges = 1;
1270 break;
1271
1272 default:
1273 warn (_("Unrecognised debug option '%s'\n"), optarg);
1274 break;
1275 }
1276 }
1277 break;
1278 #ifdef SUPPORT_DISASSEMBLY
1279 case 'i':
1280 do_dump ++;
1281 section = strtoul (optarg, & cp, 0);
1282 if (! * cp && section >= 0)
1283 {
1284 request_dump (section, DISASS_DUMP);
1285 break;
1286 }
1287 goto oops;
1288 #endif
1289 case 'v':
1290 print_version (program_name);
1291 break;
1292 case 'V':
1293 do_version ++;
1294 break;
1295 default:
1296 oops:
1297 /* xgettext:c-format */
1298 error (_("Invalid option '-%c'\n"), c);
1299 /* Drop through. */
1300 case '?':
1301 usage ();
1302 }
1303 }
1304
1305 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1306 && !do_segments && !do_header && !do_dump && !do_version
1307 && !do_histogram && !do_debugging)
1308 usage ();
1309 else if (argc < 3)
1310 {
1311 warn (_("Nothing to do.\n"));
1312 usage();
1313 }
1314 }
1315
1316 static const char *
1317 get_elf_class (elf_class)
1318 unsigned char elf_class;
1319 {
1320 switch (elf_class)
1321 {
1322 case ELFCLASSNONE: return _("none");
1323 case ELFCLASS32: return _("ELF32");
1324 case ELFCLASS64: return _("ELF64");
1325 default: return _("<unknown>");
1326 }
1327 }
1328
1329 static const char *
1330 get_data_encoding (encoding)
1331 unsigned char encoding;
1332 {
1333 switch (encoding)
1334 {
1335 case ELFDATANONE: return _("none");
1336 case ELFDATA2LSB: return _("2's complement, little endian");
1337 case ELFDATA2MSB: return _("2's complement, big endian");
1338 default: return _("<unknown>");
1339 }
1340 }
1341
1342 static const char *
1343 get_osabi_name (osabi)
1344 unsigned char osabi;
1345 {
1346 switch (osabi)
1347 {
1348 case ELFOSABI_SYSV: return _("UNIX - System V");
1349 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1350 case ELFOSABI_STANDALONE: return _("Standalone App");
1351 default: return _("<unknown>");
1352 }
1353 }
1354
1355 /* Decode the data held in 'elf_header'. */
1356 static int
1357 process_file_header ()
1358 {
1359 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1360 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1361 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1362 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1363 {
1364 error
1365 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1366 return 0;
1367 }
1368
1369 if (do_header)
1370 {
1371 int i;
1372
1373 printf (_("ELF Header:\n"));
1374 printf (_(" Magic: "));
1375 for (i = 0; i < EI_NIDENT; i ++)
1376 printf ("%2.2x ", elf_header.e_ident [i]);
1377 printf ("\n");
1378 printf (_(" Class: %s\n"),
1379 get_elf_class (elf_header.e_ident [EI_CLASS]));
1380 printf (_(" Data: %s\n"),
1381 get_data_encoding (elf_header.e_ident [EI_DATA]));
1382 printf (_(" Version: %d %s\n"),
1383 elf_header.e_ident [EI_VERSION],
1384 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
1385 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown>" : "");
1386 printf (_(" OS/ABI: %s\n"),
1387 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1388 printf (_(" ABI Version: %d\n"),
1389 elf_header.e_ident [EI_ABIVERSION]);
1390 printf (_(" Type: %s\n"),
1391 get_file_type (elf_header.e_type));
1392 printf (_(" Machine: %s\n"),
1393 get_machine_name (elf_header.e_machine));
1394 printf (_(" Version: 0x%lx\n"),
1395 (unsigned long) elf_header.e_version);
1396 printf (_(" Data: %s\n"),
1397 get_machine_data (elf_header.e_ident [EI_DATA]));
1398 printf (_(" Entry point address: 0x%lx\n"),
1399 (unsigned long) elf_header.e_entry);
1400 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1401 (long) elf_header.e_phoff);
1402 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1403 (long) elf_header.e_shoff);
1404 printf (_(" Flags: 0x%lx%s\n"),
1405 (unsigned long) elf_header.e_flags,
1406 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1407 printf (_(" Size of this header: %ld (bytes)\n"),
1408 (long) elf_header.e_ehsize);
1409 printf (_(" Size of program headers: %ld (bytes)\n"),
1410 (long) elf_header.e_phentsize);
1411 printf (_(" Number of program headers: %ld\n"),
1412 (long) elf_header.e_phnum);
1413 printf (_(" Size of section headers: %ld (bytes)\n"),
1414 (long) elf_header.e_shentsize);
1415 printf (_(" Number of section headers: %ld\n"),
1416 (long) elf_header.e_shnum);
1417 printf (_(" Section header string table index: %ld\n"),
1418 (long) elf_header.e_shstrndx);
1419 }
1420
1421 /* Test class after dumping header so that at least the header can be
1422 display on 64 bit binaries. */
1423
1424 binary_class = elf_header.e_ident [EI_CLASS];
1425 if (binary_class != ELFCLASS32)
1426 {
1427 error (_("Not a 32 bit ELF file\n"));
1428 return 0;
1429 }
1430
1431 return 1;
1432 }
1433
1434
1435 static int
1436 process_program_headers (file)
1437 FILE * file;
1438 {
1439 Elf32_External_Phdr * phdrs;
1440 Elf32_Internal_Phdr * program_headers;
1441 Elf32_Internal_Phdr * segment;
1442 unsigned int i;
1443
1444 if (elf_header.e_phnum == 0)
1445 {
1446 if (do_segments)
1447 printf (_("\nThere are no program headers in this file.\n"));
1448 return 1;
1449 }
1450
1451 if (do_segments && !do_header)
1452 {
1453 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1454 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1455 printf (_("There are %d program headers, starting at offset %lx:\n"),
1456 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1457 }
1458
1459 GET_DATA_ALLOC (elf_header.e_phoff,
1460 elf_header.e_phentsize * elf_header.e_phnum,
1461 phdrs, Elf32_External_Phdr *, "program headers");
1462
1463 program_headers = (Elf32_Internal_Phdr *) malloc
1464 (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
1465
1466 if (program_headers == NULL)
1467 {
1468 error (_("Out of memory\n"));
1469 return 0;
1470 }
1471
1472 for (i = 0, segment = program_headers;
1473 i < elf_header.e_phnum;
1474 i ++, segment ++)
1475 {
1476 segment->p_type = BYTE_GET (phdrs[i].p_type);
1477 segment->p_offset = BYTE_GET (phdrs[i].p_offset);
1478 segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
1479 segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
1480 segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
1481 segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
1482 segment->p_flags = BYTE_GET (phdrs[i].p_flags);
1483 segment->p_align = BYTE_GET (phdrs[i].p_align);
1484 }
1485
1486 free (phdrs);
1487
1488 if (do_segments)
1489 {
1490 printf
1491 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1492 printf
1493 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1494 }
1495
1496 loadaddr = -1;
1497 dynamic_addr = 0;
1498
1499 for (i = 0, segment = program_headers;
1500 i < elf_header.e_phnum;
1501 i ++, segment ++)
1502 {
1503 if (do_segments)
1504 {
1505 printf (" %-11.11s ", get_segment_type (segment->p_type));
1506 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1507 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1508 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1509 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1510 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1511 printf ("%c%c%c ",
1512 (segment->p_flags & PF_R ? 'R' : ' '),
1513 (segment->p_flags & PF_W ? 'W' : ' '),
1514 (segment->p_flags & PF_X ? 'E' : ' '));
1515 printf ("%#lx", (unsigned long) segment->p_align);
1516 }
1517
1518 switch (segment->p_type)
1519 {
1520 case PT_LOAD:
1521 if (loadaddr == -1)
1522 loadaddr = (segment->p_vaddr & 0xfffff000)
1523 - (segment->p_offset & 0xfffff000);
1524 break;
1525
1526 case PT_DYNAMIC:
1527 if (dynamic_addr)
1528 error (_("more than one dynamic segment\n"));
1529
1530 dynamic_addr = segment->p_offset;
1531 dynamic_size = segment->p_filesz;
1532 break;
1533
1534 case PT_INTERP:
1535 if (fseek (file, segment->p_offset, SEEK_SET))
1536 error (_("Unable to find program interpreter name\n"));
1537 else
1538 {
1539 program_interpreter[0] = 0;
1540 fscanf (file, "%63s", program_interpreter);
1541
1542 if (do_segments)
1543 printf (_("\n [Requesting program interpreter: %s]"),
1544 program_interpreter);
1545 }
1546 break;
1547 }
1548
1549 if (do_segments)
1550 putc ('\n', stdout);
1551 }
1552
1553 if (loadaddr == -1)
1554 {
1555 /* Very strange. */
1556 loadaddr = 0;
1557 }
1558
1559 if (do_segments && section_headers != NULL)
1560 {
1561 printf (_("\n Section to Segment mapping:\n"));
1562 printf (_(" Segment Sections...\n"));
1563
1564 assert (string_table != NULL);
1565
1566 for (i = 0; i < elf_header.e_phnum; i++)
1567 {
1568 int j;
1569 Elf32_Internal_Shdr * section;
1570
1571 segment = program_headers + i;
1572 section = section_headers;
1573
1574 printf (" %2.2d ", i);
1575
1576 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1577 {
1578 if (section->sh_size > 0
1579 /* Compare allocated sections by VMA, unallocated
1580 sections by file offset. */
1581 && (section->sh_flags & SHF_ALLOC
1582 ? (section->sh_addr >= segment->p_vaddr
1583 && section->sh_addr + section->sh_size
1584 <= segment->p_vaddr + segment->p_memsz)
1585 : (section->sh_offset >= segment->p_offset
1586 && (section->sh_offset + section->sh_size
1587 <= segment->p_offset + segment->p_filesz))))
1588 printf ("%s ", SECTION_NAME (section));
1589 }
1590
1591 putc ('\n',stdout);
1592 }
1593 }
1594
1595 free (program_headers);
1596
1597 return 1;
1598 }
1599
1600
1601 static int
1602 get_section_headers (file)
1603 FILE * file;
1604 {
1605 Elf32_External_Shdr * shdrs;
1606 Elf32_Internal_Shdr * internal;
1607 unsigned int i;
1608
1609 GET_DATA_ALLOC (elf_header.e_shoff,
1610 elf_header.e_shentsize * elf_header.e_shnum,
1611 shdrs, Elf32_External_Shdr *, "section headers");
1612
1613 section_headers = (Elf32_Internal_Shdr *) malloc
1614 (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
1615
1616 if (section_headers == NULL)
1617 {
1618 error (_("Out of memory\n"));
1619 return 0;
1620 }
1621
1622 for (i = 0, internal = section_headers;
1623 i < elf_header.e_shnum;
1624 i ++, internal ++)
1625 {
1626 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1627 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1628 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1629 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1630 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1631 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1632 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1633 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1634 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1635 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1636 }
1637
1638 free (shdrs);
1639
1640 return 1;
1641 }
1642
1643 static Elf_Internal_Sym *
1644 get_elf_symbols (file, offset, number)
1645 FILE * file;
1646 unsigned long offset;
1647 unsigned long number;
1648 {
1649 Elf32_External_Sym * esyms;
1650 Elf_Internal_Sym * isyms;
1651 Elf_Internal_Sym * psym;
1652 unsigned int j;
1653
1654 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1655 esyms, Elf32_External_Sym *, "symbols");
1656
1657 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1658
1659 if (isyms == NULL)
1660 {
1661 error (_("Out of memory\n"));
1662 free (esyms);
1663
1664 return NULL;
1665 }
1666
1667 for (j = 0, psym = isyms;
1668 j < number;
1669 j ++, psym ++)
1670 {
1671 psym->st_name = BYTE_GET (esyms[j].st_name);
1672 psym->st_value = BYTE_GET (esyms[j].st_value);
1673 psym->st_size = BYTE_GET (esyms[j].st_size);
1674 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1675 psym->st_info = BYTE_GET (esyms[j].st_info);
1676 psym->st_other = BYTE_GET (esyms[j].st_other);
1677 }
1678
1679 free (esyms);
1680
1681 return isyms;
1682 }
1683
1684 static int
1685 process_section_headers (file)
1686 FILE * file;
1687 {
1688 Elf32_Internal_Shdr * section;
1689 int i;
1690
1691 section_headers = NULL;
1692
1693 if (elf_header.e_shnum == 0)
1694 {
1695 if (do_sections)
1696 printf (_("\nThere are no sections in this file.\n"));
1697
1698 return 1;
1699 }
1700
1701 if (do_sections && !do_header)
1702 printf (_("There are %d section headers, starting at offset %lx:\n"),
1703 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
1704
1705 if (! get_section_headers (file))
1706 return 0;
1707
1708 /* Read in the string table, so that we have names to display. */
1709 section = section_headers + elf_header.e_shstrndx;
1710
1711 if (section->sh_size != 0)
1712 {
1713 unsigned long string_table_offset;
1714
1715 string_table_offset = section->sh_offset;
1716
1717 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1718 string_table, char *, "string table");
1719 }
1720
1721 /* Scan the sections for the dynamic symbol table
1722 and dynamic string table and debug sections. */
1723 dynamic_symbols = NULL;
1724 dynamic_strings = NULL;
1725 dynamic_syminfo = NULL;
1726 for (i = 0, section = section_headers;
1727 i < elf_header.e_shnum;
1728 i ++, section ++)
1729 {
1730 char * name = SECTION_NAME (section);
1731
1732 if (section->sh_type == SHT_DYNSYM)
1733 {
1734 if (dynamic_symbols != NULL)
1735 {
1736 error (_("File contains multiple dynamic symbol tables\n"));
1737 continue;
1738 }
1739
1740 dynamic_symbols = get_elf_symbols
1741 (file, section->sh_offset,
1742 section->sh_size / section->sh_entsize);
1743 }
1744 else if (section->sh_type == SHT_STRTAB
1745 && strcmp (name, ".dynstr") == 0)
1746 {
1747 if (dynamic_strings != NULL)
1748 {
1749 error (_("File contains multiple dynamic string tables\n"));
1750 continue;
1751 }
1752
1753 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1754 dynamic_strings, char *, "dynamic strings");
1755 }
1756 else if ((do_debugging || do_debug_info || do_debug_abbrevs
1757 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
1758 && strncmp (name, ".debug_", 7) == 0)
1759 {
1760 name += 7;
1761
1762 if (do_debugging
1763 || (do_debug_info && (strcmp (name, "info") == 0))
1764 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
1765 || (do_debug_lines && (strcmp (name, "line") == 0))
1766 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
1767 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
1768 )
1769 request_dump (i, DEBUG_DUMP);
1770 }
1771 }
1772
1773 if (! do_sections)
1774 return 1;
1775
1776 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1777 printf
1778 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1779
1780 for (i = 0, section = section_headers;
1781 i < elf_header.e_shnum;
1782 i ++, section ++)
1783 {
1784 printf (" [%2d] %-17.17s %-15.15s ",
1785 i,
1786 SECTION_NAME (section),
1787 get_section_type_name (section->sh_type));
1788
1789 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1790 (unsigned long) section->sh_addr,
1791 (unsigned long) section->sh_offset,
1792 (unsigned long) section->sh_size,
1793 (unsigned long) section->sh_entsize);
1794
1795 printf (" %c%c%c %2ld %3lx %ld\n",
1796 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1797 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1798 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1799 (unsigned long) section->sh_link,
1800 (unsigned long) section->sh_info,
1801 (unsigned long) section->sh_addralign);
1802 }
1803
1804 return 1;
1805 }
1806
1807 /* Process the reloc section. */
1808 static int
1809 process_relocs (file)
1810 FILE * file;
1811 {
1812 unsigned long rel_size;
1813 unsigned long rel_offset;
1814
1815
1816 if (!do_reloc)
1817 return 1;
1818
1819 if (do_using_dynamic)
1820 {
1821 rel_size = 0;
1822 rel_offset = 0;
1823
1824 if (dynamic_info[DT_REL])
1825 {
1826 rel_offset = dynamic_info[DT_REL];
1827 rel_size = dynamic_info[DT_RELSZ];
1828 }
1829 else if (dynamic_info [DT_RELA])
1830 {
1831 rel_offset = dynamic_info[DT_RELA];
1832 rel_size = dynamic_info[DT_RELASZ];
1833 }
1834 else if (dynamic_info[DT_JMPREL])
1835 {
1836 rel_offset = dynamic_info[DT_JMPREL];
1837 rel_size = dynamic_info[DT_PLTRELSZ];
1838 }
1839
1840 if (rel_size)
1841 {
1842 printf
1843 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
1844 rel_offset, rel_size);
1845
1846 dump_relocations (file, rel_offset - loadaddr, rel_size,
1847 dynamic_symbols, dynamic_strings);
1848 }
1849 else
1850 printf (_("\nThere are no dynamic relocations in this file.\n"));
1851 }
1852 else
1853 {
1854 Elf32_Internal_Shdr * section;
1855 unsigned long i;
1856 int found = 0;
1857
1858 for (i = 0, section = section_headers;
1859 i < elf_header.e_shnum;
1860 i++, section ++)
1861 {
1862 if ( section->sh_type != SHT_RELA
1863 && section->sh_type != SHT_REL)
1864 continue;
1865
1866 rel_offset = section->sh_offset;
1867 rel_size = section->sh_size;
1868
1869 if (rel_size)
1870 {
1871 Elf32_Internal_Shdr * strsec;
1872 Elf32_Internal_Shdr * symsec;
1873 Elf_Internal_Sym * symtab;
1874 char * strtab;
1875
1876 printf (_("\nRelocation section "));
1877
1878 if (string_table == NULL)
1879 printf ("%d", section->sh_name);
1880 else
1881 printf ("'%s'", SECTION_NAME (section));
1882
1883 printf (_(" at offset 0x%lx contains %lu entries:\n"),
1884 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
1885
1886 symsec = section_headers + section->sh_link;
1887
1888 symtab = get_elf_symbols (file, symsec->sh_offset,
1889 symsec->sh_size / symsec->sh_entsize);
1890
1891 if (symtab == NULL)
1892 continue;
1893
1894 strsec = section_headers + symsec->sh_link;
1895
1896 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1897 char *, "string table");
1898
1899 dump_relocations (file, rel_offset, rel_size, symtab, strtab);
1900
1901 free (strtab);
1902 free (symtab);
1903
1904 found = 1;
1905 }
1906 }
1907
1908 if (! found)
1909 printf (_("\nThere are no relocations in this file.\n"));
1910 }
1911
1912 return 1;
1913 }
1914
1915
1916 static void
1917 dynamic_segment_mips_val (entry)
1918 Elf_Internal_Dyn * entry;
1919 {
1920 switch (entry->d_tag)
1921 {
1922 case DT_MIPS_FLAGS:
1923 if (entry->d_un.d_val == 0)
1924 printf ("NONE\n");
1925 else
1926 {
1927 static const char * opts[] =
1928 {
1929 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
1930 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
1931 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
1932 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
1933 "RLD_ORDER_SAFE"
1934 };
1935 unsigned int cnt;
1936 int first = 1;
1937 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
1938 if (entry->d_un.d_val & (1 << cnt))
1939 {
1940 printf ("%s%s", first ? "" : " ", opts[cnt]);
1941 first = 0;
1942 }
1943 puts ("");
1944 }
1945 break;
1946
1947 case DT_MIPS_IVERSION:
1948 if (dynamic_strings != NULL)
1949 printf ("Interface Version: %s\n",
1950 dynamic_strings + entry->d_un.d_val);
1951 else
1952 printf ("%ld\n", (long) entry->d_un.d_ptr);
1953 break;
1954
1955 case DT_MIPS_TIME_STAMP:
1956 {
1957 char timebuf[20];
1958 time_t time = entry->d_un.d_val;
1959 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
1960 printf ("Time Stamp: %s\n", timebuf);
1961 }
1962 break;
1963
1964 case DT_MIPS_RLD_VERSION:
1965 case DT_MIPS_LOCAL_GOTNO:
1966 case DT_MIPS_CONFLICTNO:
1967 case DT_MIPS_LIBLISTNO:
1968 case DT_MIPS_SYMTABNO:
1969 case DT_MIPS_UNREFEXTNO:
1970 case DT_MIPS_HIPAGENO:
1971 case DT_MIPS_DELTA_CLASS_NO:
1972 case DT_MIPS_DELTA_INSTANCE_NO:
1973 case DT_MIPS_DELTA_RELOC_NO:
1974 case DT_MIPS_DELTA_SYM_NO:
1975 case DT_MIPS_DELTA_CLASSSYM_NO:
1976 case DT_MIPS_COMPACT_SIZE:
1977 printf ("%ld\n", (long) entry->d_un.d_ptr);
1978 break;
1979
1980 default:
1981 printf ("%#lx\n", (long) entry->d_un.d_ptr);
1982 }
1983 }
1984
1985 /* Parse the dynamic segment */
1986 static int
1987 process_dynamic_segment (file)
1988 FILE * file;
1989 {
1990 Elf_Internal_Dyn * entry;
1991 Elf32_External_Dyn * edyn;
1992 unsigned int i;
1993
1994 if (dynamic_size == 0)
1995 {
1996 if (do_dynamic)
1997 printf (_("\nThere is no dynamic segment in this file.\n"));
1998
1999 return 1;
2000 }
2001
2002 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2003 edyn, Elf32_External_Dyn *, "dynamic segment");
2004
2005 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2006 how large .dynamic is now. We can do this even before the byte
2007 swapping since the DT_NULL tag is recognizable. */
2008 dynamic_size = 0;
2009 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
2010 ;
2011
2012 dynamic_segment = (Elf_Internal_Dyn *)
2013 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2014
2015 if (dynamic_segment == NULL)
2016 {
2017 error (_("Out of memory\n"));
2018 free (edyn);
2019 return 0;
2020 }
2021
2022 for (i = 0, entry = dynamic_segment;
2023 i < dynamic_size;
2024 i ++, entry ++)
2025 {
2026 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2027 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2028 }
2029
2030 free (edyn);
2031
2032 /* Find the appropriate symbol table. */
2033 if (dynamic_symbols == NULL)
2034 {
2035 for (i = 0, entry = dynamic_segment;
2036 i < dynamic_size;
2037 ++i, ++ entry)
2038 {
2039 unsigned long offset;
2040 long num_syms;
2041
2042 if (entry->d_tag != DT_SYMTAB)
2043 continue;
2044
2045 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2046
2047 /* Since we do not know how big the symbol table is,
2048 we default to reading in the entire file (!) and
2049 processing that. This is overkill, I know, but it
2050 should work. */
2051
2052 offset = entry->d_un.d_val - loadaddr;
2053
2054 if (fseek (file, 0, SEEK_END))
2055 error (_("Unable to seek to end of file!"));
2056
2057 num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2058
2059 if (num_syms < 1)
2060 {
2061 error (_("Unable to determine the number of symbols to load\n"));
2062 continue;
2063 }
2064
2065 dynamic_symbols = get_elf_symbols (file, offset, num_syms);
2066 }
2067 }
2068
2069 /* Similarly find a string table. */
2070 if (dynamic_strings == NULL)
2071 {
2072 for (i = 0, entry = dynamic_segment;
2073 i < dynamic_size;
2074 ++i, ++ entry)
2075 {
2076 unsigned long offset;
2077 long str_tab_len;
2078
2079 if (entry->d_tag != DT_STRTAB)
2080 continue;
2081
2082 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2083
2084 /* Since we do not know how big the string table is,
2085 we default to reading in the entire file (!) and
2086 processing that. This is overkill, I know, but it
2087 should work. */
2088
2089 offset = entry->d_un.d_val - loadaddr;
2090 if (fseek (file, 0, SEEK_END))
2091 error (_("Unable to seek to end of file\n"));
2092 str_tab_len = ftell (file) - offset;
2093
2094 if (str_tab_len < 1)
2095 {
2096 error
2097 (_("Unable to determine the length of the dynamic string table\n"));
2098 continue;
2099 }
2100
2101 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2102 "dynamic string table");
2103
2104 break;
2105 }
2106 }
2107
2108 /* And find the syminfo section if available. */
2109 if (dynamic_syminfo == NULL)
2110 {
2111 unsigned int syminsz = 0;
2112
2113 for (i = 0, entry = dynamic_segment;
2114 i < dynamic_size;
2115 ++i, ++ entry)
2116 {
2117 if (entry->d_tag == DT_SYMINENT)
2118 {
2119 /* Note: these braces are necessary to avoid a syntax
2120 error from the SunOS4 C compiler. */
2121 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2122 }
2123 else if (entry->d_tag == DT_SYMINSZ)
2124 syminsz = entry->d_un.d_val;
2125 else if (entry->d_tag == DT_SYMINFO)
2126 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2127 }
2128
2129 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2130 {
2131 Elf_External_Syminfo *extsyminfo;
2132 Elf_Internal_Syminfo *syminfo;
2133
2134 /* There is a syminfo section. Read the data. */
2135 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2136 Elf_External_Syminfo *, "symbol information");
2137
2138 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2139 if (dynamic_syminfo == NULL)
2140 {
2141 error (_("Out of memory\n"));
2142 return 0;
2143 }
2144
2145 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2146 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2147 ++i, ++syminfo)
2148 {
2149 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2150 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2151 }
2152
2153 free (extsyminfo);
2154 }
2155 }
2156
2157 if (do_dynamic && dynamic_addr)
2158 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2159 dynamic_addr, dynamic_size);
2160 if (do_dynamic)
2161 printf (_(" Tag Type Name/Value\n"));
2162
2163 for (i = 0, entry = dynamic_segment;
2164 i < dynamic_size;
2165 i++, entry ++)
2166 {
2167 if (do_dynamic)
2168 printf (_(" 0x%-8.8lx (%s)%*s"),
2169 (unsigned long) entry->d_tag,
2170 get_dynamic_type (entry->d_tag),
2171 27 - strlen (get_dynamic_type (entry->d_tag)),
2172 " ");
2173
2174 switch (entry->d_tag)
2175 {
2176 case DT_AUXILIARY:
2177 case DT_FILTER:
2178 if (do_dynamic)
2179 {
2180 if (entry->d_tag == DT_AUXILIARY)
2181 printf (_("Auxiliary library"));
2182 else
2183 printf (_("Filter library"));
2184
2185 if (dynamic_strings)
2186 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2187 else
2188 printf (": %#lx\n", (long) entry->d_un.d_val);
2189 }
2190 break;
2191
2192 case DT_FEATURE_1:
2193 if (do_dynamic)
2194 {
2195 printf (_("Flags:"));
2196 if (entry->d_un.d_val == 0)
2197 printf (_(" None\n"));
2198 else
2199 {
2200 unsigned long int val = entry->d_un.d_val;
2201 if (val & DTF_1_PARINIT)
2202 {
2203 printf (" PARINIT");
2204 val ^= DTF_1_PARINIT;
2205 }
2206 if (val != 0)
2207 printf (" %lx", val);
2208 puts ("");
2209 }
2210 }
2211 break;
2212
2213 case DT_POSFLAG_1:
2214 if (do_dynamic)
2215 {
2216 printf (_("Flags:"));
2217 if (entry->d_un.d_val == 0)
2218 printf (_(" None\n"));
2219 else
2220 {
2221 unsigned long int val = entry->d_un.d_val;
2222 if (val & DF_P1_LAZYLOAD)
2223 {
2224 printf (" LAZYLOAD");
2225 val ^= DF_P1_LAZYLOAD;
2226 }
2227 if (val & DF_P1_GROUPPERM)
2228 {
2229 printf (" GROUPPERM");
2230 val ^= DF_P1_GROUPPERM;
2231 }
2232 if (val != 0)
2233 printf (" %lx", val);
2234 puts ("");
2235 }
2236 }
2237 break;
2238
2239 case DT_FLAGS_1:
2240 if (do_dynamic)
2241 {
2242 printf (_("Flags:"));
2243 if (entry->d_un.d_val == 0)
2244 printf (_(" None\n"));
2245 else
2246 {
2247 unsigned long int val = entry->d_un.d_val;
2248 if (val & DF_1_NOW)
2249 {
2250 printf (" NOW");
2251 val ^= DF_1_NOW;
2252 }
2253 if (val & DF_1_GLOBAL)
2254 {
2255 printf (" GLOBAL");
2256 val ^= DF_1_GLOBAL;
2257 }
2258 if (val & DF_1_GROUP)
2259 {
2260 printf (" GROUP");
2261 val ^= DF_1_GROUP;
2262 }
2263 if (val & DF_1_NODELETE)
2264 {
2265 printf (" NODELETE");
2266 val ^= DF_1_NODELETE;
2267 }
2268 if (val & DF_1_LOADFLTR)
2269 {
2270 printf (" LOADFLTR");
2271 val ^= DF_1_LOADFLTR;
2272 }
2273 if (val & DF_1_INITFIRST)
2274 {
2275 printf (" INITFIRST");
2276 val ^= DF_1_INITFIRST;
2277 }
2278 if (val & DF_1_NOOPEN)
2279 {
2280 printf (" NOOPEN");
2281 val ^= DF_1_NOOPEN;
2282 }
2283 if (val & DF_1_ORIGIN)
2284 {
2285 printf (" ORIGIN");
2286 val ^= DF_1_ORIGIN;
2287 }
2288 if (val & DF_1_DIRECT)
2289 {
2290 printf (" DIRECT");
2291 val ^= DF_1_DIRECT;
2292 }
2293 if (val & DF_1_TRANS)
2294 {
2295 printf (" TRANS");
2296 val ^= DF_1_TRANS;
2297 }
2298 if (val & DF_1_INTERPOSE)
2299 {
2300 printf (" INTERPOSE");
2301 val ^= DF_1_INTERPOSE;
2302 }
2303 if (val != 0)
2304 printf (" %lx", val);
2305 puts ("");
2306 }
2307 }
2308 break;
2309
2310 case DT_PLTREL:
2311 if (do_dynamic)
2312 puts (get_dynamic_type (entry->d_un.d_val));
2313 break;
2314
2315 case DT_NULL :
2316 case DT_NEEDED :
2317 case DT_PLTGOT :
2318 case DT_HASH :
2319 case DT_STRTAB :
2320 case DT_SYMTAB :
2321 case DT_RELA :
2322 case DT_INIT :
2323 case DT_FINI :
2324 case DT_SONAME :
2325 case DT_RPATH :
2326 case DT_SYMBOLIC:
2327 case DT_REL :
2328 case DT_DEBUG :
2329 case DT_TEXTREL :
2330 case DT_JMPREL :
2331 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2332
2333 if (do_dynamic)
2334 {
2335 char * name;
2336
2337 if (dynamic_strings == NULL)
2338 name = NULL;
2339 else
2340 name = dynamic_strings + entry->d_un.d_val;
2341
2342 if (name)
2343 {
2344 switch (entry->d_tag)
2345 {
2346 case DT_NEEDED:
2347 printf (_("Shared library: [%s]"), name);
2348
2349 if (strcmp (name, program_interpreter))
2350 printf ("\n");
2351 else
2352 printf (_(" program interpreter\n"));
2353 break;
2354
2355 case DT_SONAME:
2356 printf (_("Library soname: [%s]\n"), name);
2357 break;
2358
2359 case DT_RPATH:
2360 printf (_("Library rpath: [%s]\n"), name);
2361 break;
2362
2363 default:
2364 printf ("%#lx\n", (long) entry->d_un.d_val);
2365 }
2366 }
2367 else
2368 printf ("%#lx\n", (long) entry->d_un.d_val);
2369 }
2370 break;
2371
2372 case DT_PLTRELSZ:
2373 case DT_RELASZ :
2374 case DT_STRSZ :
2375 case DT_RELSZ :
2376 case DT_RELAENT :
2377 case DT_SYMENT :
2378 case DT_RELENT :
2379 case DT_PLTPADSZ:
2380 case DT_MOVEENT :
2381 case DT_MOVESZ :
2382 case DT_INIT_ARRAYSZ:
2383 case DT_FINI_ARRAYSZ:
2384 if (do_dynamic)
2385 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2386 break;
2387
2388 case DT_VERDEFNUM:
2389 case DT_VERNEEDNUM:
2390 case DT_RELACOUNT:
2391 case DT_RELCOUNT:
2392 if (do_dynamic)
2393 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2394 break;
2395
2396 case DT_SYMINSZ:
2397 case DT_SYMINENT:
2398 case DT_SYMINFO:
2399 case DT_USED:
2400 case DT_INIT_ARRAY:
2401 case DT_FINI_ARRAY:
2402 if (do_dynamic)
2403 {
2404 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2405 {
2406 char * name;
2407
2408 name = dynamic_strings + entry->d_un.d_val;
2409
2410 if (* name)
2411 {
2412 printf (_("Not needed object: [%s]\n"), name);
2413 break;
2414 }
2415 }
2416
2417 printf ("%#lx\n", (long) entry->d_un.d_val);
2418 }
2419 break;
2420
2421 case DT_BIND_NOW:
2422 /* The value of this entry is ignored. */
2423 break;
2424
2425 default:
2426 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2427 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2428 entry->d_un.d_val;
2429
2430 if (do_dynamic)
2431 {
2432 switch (elf_header.e_machine)
2433 {
2434 case EM_MIPS:
2435 case EM_MIPS_RS4_BE:
2436 dynamic_segment_mips_val (entry);
2437 break;
2438 default:
2439 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2440 }
2441 }
2442 break;
2443 }
2444 }
2445
2446 return 1;
2447 }
2448
2449 static char *
2450 get_ver_flags (flags)
2451 unsigned int flags;
2452 {
2453 static char buff [32];
2454
2455 buff[0] = 0;
2456
2457 if (flags == 0)
2458 return _("none");
2459
2460 if (flags & VER_FLG_BASE)
2461 strcat (buff, "BASE ");
2462
2463 if (flags & VER_FLG_WEAK)
2464 {
2465 if (flags & VER_FLG_BASE)
2466 strcat (buff, "| ");
2467
2468 strcat (buff, "WEAK ");
2469 }
2470
2471 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2472 strcat (buff, "| <unknown>");
2473
2474 return buff;
2475 }
2476
2477 /* Display the contents of the version sections. */
2478 static int
2479 process_version_sections (file)
2480 FILE * file;
2481 {
2482 Elf32_Internal_Shdr * section;
2483 unsigned i;
2484 int found = 0;
2485
2486 if (! do_version)
2487 return 1;
2488
2489 for (i = 0, section = section_headers;
2490 i < elf_header.e_shnum;
2491 i++, section ++)
2492 {
2493 switch (section->sh_type)
2494 {
2495 case SHT_GNU_verdef:
2496 {
2497 Elf_External_Verdef * edefs;
2498 unsigned int idx;
2499 unsigned int cnt;
2500
2501 found = 1;
2502
2503 printf
2504 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2505 SECTION_NAME (section), section->sh_info);
2506
2507 printf (_(" Addr: 0x"));
2508 printf_vma (section->sh_addr);
2509 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2510 section->sh_offset, section->sh_link,
2511 SECTION_NAME (section_headers + section->sh_link));
2512
2513 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2514 edefs, Elf_External_Verdef *,
2515 "version definition section");
2516
2517 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2518 {
2519 char * vstart;
2520 Elf_External_Verdef * edef;
2521 Elf_Internal_Verdef ent;
2522 Elf_External_Verdaux * eaux;
2523 Elf_Internal_Verdaux aux;
2524 int j;
2525 int isum;
2526
2527 vstart = ((char *) edefs) + idx;
2528
2529 edef = (Elf_External_Verdef *) vstart;
2530
2531 ent.vd_version = BYTE_GET (edef->vd_version);
2532 ent.vd_flags = BYTE_GET (edef->vd_flags);
2533 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2534 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2535 ent.vd_hash = BYTE_GET (edef->vd_hash);
2536 ent.vd_aux = BYTE_GET (edef->vd_aux);
2537 ent.vd_next = BYTE_GET (edef->vd_next);
2538
2539 printf (_(" %#06x: Rev: %d Flags: %s"),
2540 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2541
2542 printf (_(" Index: %d Cnt: %d "),
2543 ent.vd_ndx, ent.vd_cnt);
2544
2545 vstart += ent.vd_aux;
2546
2547 eaux = (Elf_External_Verdaux *) vstart;
2548
2549 aux.vda_name = BYTE_GET (eaux->vda_name);
2550 aux.vda_next = BYTE_GET (eaux->vda_next);
2551
2552 if (dynamic_strings)
2553 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2554 else
2555 printf (_("Name index: %ld\n"), aux.vda_name);
2556
2557 isum = idx + ent.vd_aux;
2558
2559 for (j = 1; j < ent.vd_cnt; j ++)
2560 {
2561 isum += aux.vda_next;
2562 vstart += aux.vda_next;
2563
2564 eaux = (Elf_External_Verdaux *) vstart;
2565
2566 aux.vda_name = BYTE_GET (eaux->vda_name);
2567 aux.vda_next = BYTE_GET (eaux->vda_next);
2568
2569 if (dynamic_strings)
2570 printf (_(" %#06x: Parent %d: %s\n"),
2571 isum, j, dynamic_strings + aux.vda_name);
2572 else
2573 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2574 isum, j, aux.vda_name);
2575 }
2576
2577 idx += ent.vd_next;
2578 }
2579
2580 free (edefs);
2581 }
2582 break;
2583
2584 case SHT_GNU_verneed:
2585 {
2586 Elf_External_Verneed * eneed;
2587 unsigned int idx;
2588 unsigned int cnt;
2589
2590 found = 1;
2591
2592 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2593 SECTION_NAME (section), section->sh_info);
2594
2595 printf (_(" Addr: 0x"));
2596 printf_vma (section->sh_addr);
2597 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
2598 section->sh_offset, section->sh_link,
2599 SECTION_NAME (section_headers + section->sh_link));
2600
2601 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2602 eneed, Elf_External_Verneed *,
2603 "version need section");
2604
2605 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2606 {
2607 Elf_External_Verneed * entry;
2608 Elf_Internal_Verneed ent;
2609 int j;
2610 int isum;
2611 char * vstart;
2612
2613 vstart = ((char *) eneed) + idx;
2614
2615 entry = (Elf_External_Verneed *) vstart;
2616
2617 ent.vn_version = BYTE_GET (entry->vn_version);
2618 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
2619 ent.vn_file = BYTE_GET (entry->vn_file);
2620 ent.vn_aux = BYTE_GET (entry->vn_aux);
2621 ent.vn_next = BYTE_GET (entry->vn_next);
2622
2623 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
2624
2625 if (dynamic_strings)
2626 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
2627 else
2628 printf (_(" File: %lx"), ent.vn_file);
2629
2630 printf (_(" Cnt: %d\n"), ent.vn_cnt);
2631
2632 vstart += ent.vn_aux;
2633
2634 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
2635 {
2636 Elf_External_Vernaux * eaux;
2637 Elf_Internal_Vernaux aux;
2638
2639 eaux = (Elf_External_Vernaux *) vstart;
2640
2641 aux.vna_hash = BYTE_GET (eaux->vna_hash);
2642 aux.vna_flags = BYTE_GET (eaux->vna_flags);
2643 aux.vna_other = BYTE_GET (eaux->vna_other);
2644 aux.vna_name = BYTE_GET (eaux->vna_name);
2645 aux.vna_next = BYTE_GET (eaux->vna_next);
2646
2647 if (dynamic_strings)
2648 printf (_(" %#06x: Name: %s"),
2649 isum, dynamic_strings + aux.vna_name);
2650 else
2651 printf (_(" %#06x: Name index: %lx"),
2652 isum, aux.vna_name);
2653
2654 printf (_(" Flags: %s Version: %d\n"),
2655 get_ver_flags (aux.vna_flags), aux.vna_other);
2656
2657 isum += aux.vna_next;
2658 vstart += aux.vna_next;
2659 }
2660
2661 idx += ent.vn_next;
2662 }
2663
2664 free (eneed);
2665 }
2666 break;
2667
2668 case SHT_GNU_versym:
2669 {
2670 Elf32_Internal_Shdr * link_section;
2671 int total;
2672 int cnt;
2673 unsigned char * edata;
2674 unsigned short * data;
2675 char * strtab;
2676 Elf_Internal_Sym * symbols;
2677 Elf32_Internal_Shdr * string_sec;
2678
2679 link_section = section_headers + section->sh_link;
2680 total = section->sh_size / section->sh_entsize;
2681
2682 found = 1;
2683
2684 symbols = get_elf_symbols
2685 (file, link_section->sh_offset,
2686 link_section->sh_size / link_section->sh_entsize);
2687
2688 string_sec = section_headers + link_section->sh_link;
2689
2690 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2691 strtab, char *, "version string table");
2692
2693 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2694 SECTION_NAME (section), total);
2695
2696 printf (_(" Addr: "));
2697 printf_vma (section->sh_addr);
2698 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2699 section->sh_offset, section->sh_link,
2700 SECTION_NAME (link_section));
2701
2702 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2703 - loadaddr,
2704 total * sizeof (short), edata,
2705 unsigned char *, "version symbol data");
2706
2707 data = (unsigned short *) malloc (total * sizeof (short));
2708
2709 for (cnt = total; cnt --;)
2710 data [cnt] = byte_get (edata + cnt * sizeof (short),
2711 sizeof (short));
2712
2713 free (edata);
2714
2715 for (cnt = 0; cnt < total; cnt += 4)
2716 {
2717 int j, nn;
2718
2719 printf (" %03x:", cnt);
2720
2721 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2722 switch (data [cnt + j])
2723 {
2724 case 0:
2725 fputs (_(" 0 (*local*) "), stdout);
2726 break;
2727
2728 case 1:
2729 fputs (_(" 1 (*global*) "), stdout);
2730 break;
2731
2732 default:
2733 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
2734 data [cnt + j] & 0x8000 ? 'h' : ' ');
2735
2736 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2737 && section_headers[symbols [cnt + j].st_shndx].sh_type
2738 == SHT_NOBITS)
2739 {
2740 /* We must test both. */
2741 Elf_Internal_Verneed ivn;
2742 unsigned long offset;
2743
2744 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2745 - loadaddr;
2746
2747 do
2748 {
2749 Elf_External_Verneed evn;
2750 Elf_External_Vernaux evna;
2751 Elf_Internal_Vernaux ivna;
2752 unsigned long vna_off;
2753
2754 GET_DATA (offset, evn, "version need");
2755
2756 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2757 ivn.vn_next = BYTE_GET (evn.vn_next);
2758
2759 vna_off = offset + ivn.vn_aux;
2760
2761 do
2762 {
2763 GET_DATA (vna_off, evna,
2764 "version need aux (1)");
2765
2766 ivna.vna_next = BYTE_GET (evna.vna_next);
2767 ivna.vna_other = BYTE_GET (evna.vna_other);
2768
2769 vna_off += ivna.vna_next;
2770 }
2771 while (ivna.vna_other != data [cnt + j]
2772 && ivna.vna_next != 0);
2773
2774 if (ivna.vna_other == data [cnt + j])
2775 {
2776 ivna.vna_name = BYTE_GET (evna.vna_name);
2777
2778 nn += printf ("(%s%-*s",
2779 strtab + ivna.vna_name,
2780 12 - strlen (strtab
2781 + ivna.vna_name),
2782 ")");
2783 break;
2784 }
2785 else if (ivn.vn_next == 0)
2786 {
2787 if (data [cnt + j] != 0x8001)
2788 {
2789 Elf_Internal_Verdef ivd;
2790 Elf_External_Verdef evd;
2791
2792 offset = version_info
2793 [DT_VERSIONTAGIDX (DT_VERDEF)]
2794 - loadaddr;
2795
2796 do
2797 {
2798 GET_DATA (offset, evd,
2799 "version definition");
2800
2801 ivd.vd_next = BYTE_GET (evd.vd_next);
2802 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2803
2804 offset += ivd.vd_next;
2805 }
2806 while (ivd.vd_ndx
2807 != (data [cnt + j] & 0x7fff)
2808 && ivd.vd_next != 0);
2809
2810 if (ivd.vd_ndx
2811 == (data [cnt + j] & 0x7fff))
2812 {
2813 Elf_External_Verdaux evda;
2814 Elf_Internal_Verdaux ivda;
2815
2816 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2817
2818 GET_DATA (offset + ivd.vd_aux, evda,
2819 "version definition aux");
2820
2821 ivda.vda_name =
2822 BYTE_GET (evda.vda_name);
2823
2824 nn +=
2825 printf ("(%s%-*s",
2826 strtab + ivda.vda_name,
2827 12
2828 - strlen (strtab
2829 + ivda.vda_name),
2830 ")");
2831 }
2832 }
2833
2834 break;
2835 }
2836 else
2837 offset += ivn.vn_next;
2838 }
2839 while (ivn.vn_next);
2840 }
2841 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2842 {
2843 Elf_Internal_Verneed ivn;
2844 unsigned long offset;
2845
2846 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2847 - loadaddr;
2848
2849 do
2850 {
2851 Elf_Internal_Vernaux ivna;
2852 Elf_External_Verneed evn;
2853 Elf_External_Vernaux evna;
2854 unsigned long a_off;
2855
2856 GET_DATA (offset, evn, "version need");
2857
2858 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2859 ivn.vn_next = BYTE_GET (evn.vn_next);
2860
2861 a_off = offset + ivn.vn_aux;
2862
2863 do
2864 {
2865 GET_DATA (a_off, evna,
2866 "version need aux (2)");
2867
2868 ivna.vna_next = BYTE_GET (evna.vna_next);
2869 ivna.vna_other = BYTE_GET (evna.vna_other);
2870
2871 a_off += ivna.vna_next;
2872 }
2873 while (ivna.vna_other != data [cnt + j]
2874 && ivna.vna_next != 0);
2875
2876 if (ivna.vna_other == data [cnt + j])
2877 {
2878 ivna.vna_name = BYTE_GET (evna.vna_name);
2879
2880 nn += printf ("(%s%-*s",
2881 strtab + ivna.vna_name,
2882 12 - strlen (strtab
2883 + ivna.vna_name),
2884 ")");
2885 break;
2886 }
2887
2888 offset += ivn.vn_next;
2889 }
2890 while (ivn.vn_next);
2891 }
2892 else if (data [cnt + j] != 0x8001)
2893 {
2894 Elf_Internal_Verdef ivd;
2895 Elf_External_Verdef evd;
2896 unsigned long offset;
2897
2898 offset = version_info
2899 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2900
2901 do
2902 {
2903 GET_DATA (offset, evd, "version def");
2904
2905 ivd.vd_next = BYTE_GET (evd.vd_next);
2906 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2907
2908 offset += ivd.vd_next;
2909 }
2910 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
2911 && ivd.vd_next != 0);
2912
2913 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
2914 {
2915 Elf_External_Verdaux evda;
2916 Elf_Internal_Verdaux ivda;
2917
2918 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2919
2920 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
2921 evda, "version def aux");
2922
2923 ivda.vda_name = BYTE_GET (evda.vda_name);
2924
2925 nn += printf ("(%s%-*s",
2926 strtab + ivda.vda_name,
2927 12 - strlen (strtab
2928 + ivda.vda_name),
2929 ")");
2930 }
2931 }
2932
2933 if (nn < 18)
2934 printf ("%*c", 18 - nn, ' ');
2935 }
2936
2937 putchar ('\n');
2938 }
2939
2940 free (data);
2941 free (strtab);
2942 free (symbols);
2943 }
2944 break;
2945
2946 default:
2947 break;
2948 }
2949 }
2950
2951 if (! found)
2952 printf (_("\nNo version information found in this file.\n"));
2953
2954 return 1;
2955 }
2956
2957 static char *
2958 get_symbol_binding (binding)
2959 unsigned int binding;
2960 {
2961 static char buff [32];
2962
2963 switch (binding)
2964 {
2965 case STB_LOCAL: return _("LOCAL");
2966 case STB_GLOBAL: return _("GLOBAL");
2967 case STB_WEAK: return _("WEAK");
2968 default:
2969 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
2970 sprintf (buff, _("<processor specific>: %d"), binding);
2971 else if (binding >= STB_LOOS && binding <= STB_HIOS)
2972 sprintf (buff, _("<OS specific>: %d"), binding);
2973 else
2974 sprintf (buff, _("<unknown>: %d"), binding);
2975 return buff;
2976 }
2977 }
2978
2979 static char *
2980 get_symbol_type (type)
2981 unsigned int type;
2982 {
2983 static char buff [32];
2984
2985 switch (type)
2986 {
2987 case STT_NOTYPE: return _("NOTYPE");
2988 case STT_OBJECT: return _("OBJECT");
2989 case STT_FUNC: return _("FUNC");
2990 case STT_SECTION: return _("SECTION");
2991 case STT_FILE: return _("FILE");
2992 default:
2993 if (type >= STT_LOPROC && type <= STT_HIPROC)
2994 sprintf (buff, _("<processor specific>: %d"), type);
2995 else if (type >= STT_LOOS && type <= STT_HIOS)
2996 sprintf (buff, _("<OS specific>: %d"), type);
2997 else
2998 sprintf (buff, _("<unknown>: %d"), type);
2999 return buff;
3000 }
3001 }
3002
3003 static char *
3004 get_symbol_index_type (type)
3005 unsigned int type;
3006 {
3007 switch (type)
3008 {
3009 case SHN_UNDEF: return "UND";
3010 case SHN_ABS: return "ABS";
3011 case SHN_COMMON: return "COM";
3012 default:
3013 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3014 return "PRC";
3015 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3016 return "RSV";
3017 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3018 return "OS ";
3019 else
3020 {
3021 static char buff [32];
3022
3023 sprintf (buff, "%3d", type);
3024 return buff;
3025 }
3026 }
3027 }
3028
3029
3030 static int *
3031 get_dynamic_data (file, number)
3032 FILE * file;
3033 unsigned int number;
3034 {
3035 char * e_data;
3036 int * i_data;
3037
3038 e_data = (char *) malloc (number * 4);
3039
3040 if (e_data == NULL)
3041 {
3042 error (_("Out of memory\n"));
3043 return NULL;
3044 }
3045
3046 if (fread (e_data, 4, number, file) != number)
3047 {
3048 error (_("Unable to read in dynamic data\n"));
3049 return NULL;
3050 }
3051
3052 i_data = (int *) malloc (number * sizeof (* i_data));
3053
3054 if (i_data == NULL)
3055 {
3056 error (_("Out of memory\n"));
3057 free (e_data);
3058 return NULL;
3059 }
3060
3061 while (number--)
3062 i_data [number] = byte_get (e_data + number * 4, 4);
3063
3064 free (e_data);
3065
3066 return i_data;
3067 }
3068
3069 /* Dump the symbol table */
3070 static int
3071 process_symbol_table (file)
3072 FILE * file;
3073 {
3074 Elf32_Internal_Shdr * section;
3075 char nb [4];
3076 char nc [4];
3077 int nbuckets;
3078 int nchains;
3079 int * buckets = NULL;
3080 int * chains = NULL;
3081
3082 if (! do_syms && !do_histogram)
3083 return 1;
3084
3085 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3086 || do_histogram))
3087 {
3088 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3089 {
3090 error (_("Unable to seek to start of dynamic information"));
3091 return 0;
3092 }
3093
3094 if (fread (nb, sizeof (nb), 1, file) != 1)
3095 {
3096 error (_("Failed to read in number of buckets\n"));
3097 return 0;
3098 }
3099
3100 if (fread (nc, sizeof (nc), 1, file) != 1)
3101 {
3102 error (_("Failed to read in number of chains\n"));
3103 return 0;
3104 }
3105
3106 nbuckets = byte_get (nb, 4);
3107 nchains = byte_get (nc, 4);
3108
3109 buckets = get_dynamic_data (file, nbuckets);
3110 chains = get_dynamic_data (file, nchains);
3111
3112 if (buckets == NULL || chains == NULL)
3113 return 0;
3114 }
3115
3116 if (do_syms
3117 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3118 {
3119 int hn;
3120 int si;
3121
3122 printf (_("\nSymbol table for image:\n"));
3123 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3124
3125 for (hn = 0; hn < nbuckets; hn++)
3126 {
3127 if (! buckets [hn])
3128 continue;
3129
3130 for (si = buckets [hn]; si; si = chains [si])
3131 {
3132 Elf_Internal_Sym * psym;
3133
3134 psym = dynamic_symbols + si;
3135
3136 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3137 si, hn,
3138 (unsigned long) psym->st_value,
3139 (unsigned long) psym->st_size,
3140 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3141 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3142 psym->st_other);
3143
3144 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3145
3146 printf (" %s\n", dynamic_strings + psym->st_name);
3147 }
3148 }
3149 }
3150 else if (do_syms && !do_using_dynamic)
3151 {
3152 unsigned int i;
3153
3154 for (i = 0, section = section_headers;
3155 i < elf_header.e_shnum;
3156 i++, section++)
3157 {
3158 unsigned int si;
3159 char * strtab;
3160 Elf_Internal_Sym * symtab;
3161 Elf_Internal_Sym * psym;
3162
3163
3164 if ( section->sh_type != SHT_SYMTAB
3165 && section->sh_type != SHT_DYNSYM)
3166 continue;
3167
3168 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3169 SECTION_NAME (section),
3170 (unsigned long) (section->sh_size / section->sh_entsize));
3171 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3172 stdout);
3173
3174 symtab = get_elf_symbols (file, section->sh_offset,
3175 section->sh_size / section->sh_entsize);
3176 if (symtab == NULL)
3177 continue;
3178
3179 if (section->sh_link == elf_header.e_shstrndx)
3180 strtab = string_table;
3181 else
3182 {
3183 Elf32_Internal_Shdr * string_sec;
3184
3185 string_sec = section_headers + section->sh_link;
3186
3187 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3188 strtab, char *, "string table");
3189 }
3190
3191 for (si = 0, psym = symtab;
3192 si < section->sh_size / section->sh_entsize;
3193 si ++, psym ++)
3194 {
3195 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3196 si,
3197 (unsigned long) psym->st_value,
3198 (unsigned long) psym->st_size,
3199 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3200 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3201 psym->st_other);
3202
3203 if (psym->st_shndx == 0)
3204 fputs (" UND", stdout);
3205 else if ((psym->st_shndx & 0xffff) == 0xfff1)
3206 fputs (" ABS", stdout);
3207 else if ((psym->st_shndx & 0xffff) == 0xfff2)
3208 fputs (" COM", stdout);
3209 else
3210 printf ("%4x", psym->st_shndx);
3211
3212 printf (" %s", strtab + psym->st_name);
3213
3214 if (section->sh_type == SHT_DYNSYM &&
3215 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3216 {
3217 unsigned char data[2];
3218 unsigned short vers_data;
3219 unsigned long offset;
3220 int is_nobits;
3221 int check_def;
3222
3223 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3224 - loadaddr;
3225
3226 GET_DATA (offset + si * sizeof (vers_data), data,
3227 "version data");
3228
3229 vers_data = byte_get (data, 2);
3230
3231 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3232 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3233 : 0;
3234
3235 check_def = (psym->st_shndx != SHN_UNDEF);
3236
3237 if ((vers_data & 0x8000) || vers_data > 1)
3238 {
3239 if (is_nobits || ! check_def)
3240 {
3241 Elf_External_Verneed evn;
3242 Elf_Internal_Verneed ivn;
3243 Elf_Internal_Vernaux ivna;
3244
3245 /* We must test both. */
3246 offset = version_info
3247 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3248
3249 GET_DATA (offset, evn, "version need");
3250
3251 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3252 ivn.vn_next = BYTE_GET (evn.vn_next);
3253
3254 do
3255 {
3256 unsigned long vna_off;
3257
3258 vna_off = offset + ivn.vn_aux;
3259
3260 do
3261 {
3262 Elf_External_Vernaux evna;
3263
3264 GET_DATA (vna_off, evna,
3265 "version need aux (3)");
3266
3267 ivna.vna_other = BYTE_GET (evna.vna_other);
3268 ivna.vna_next = BYTE_GET (evna.vna_next);
3269 ivna.vna_name = BYTE_GET (evna.vna_name);
3270
3271 vna_off += ivna.vna_next;
3272 }
3273 while (ivna.vna_other != vers_data
3274 && ivna.vna_next != 0);
3275
3276 if (ivna.vna_other == vers_data)
3277 break;
3278
3279 offset += ivn.vn_next;
3280 }
3281 while (ivn.vn_next != 0);
3282
3283 if (ivna.vna_other == vers_data)
3284 {
3285 printf ("@%s (%d)",
3286 strtab + ivna.vna_name, ivna.vna_other);
3287 check_def = 0;
3288 }
3289 else if (! is_nobits)
3290 error (_("bad dynamic symbol"));
3291 else
3292 check_def = 1;
3293 }
3294
3295 if (check_def)
3296 {
3297 if (vers_data != 0x8001)
3298 {
3299 Elf_Internal_Verdef ivd;
3300 Elf_Internal_Verdaux ivda;
3301 Elf_External_Verdaux evda;
3302 unsigned long offset;
3303
3304 offset =
3305 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3306 - loadaddr;
3307
3308 do
3309 {
3310 Elf_External_Verdef evd;
3311
3312 GET_DATA (offset, evd, "version def");
3313
3314 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3315 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3316 ivd.vd_next = BYTE_GET (evd.vd_next);
3317
3318 offset += ivd.vd_next;
3319 }
3320 while (ivd.vd_ndx != (vers_data & 0x7fff)
3321 && ivd.vd_next != 0);
3322
3323 offset -= ivd.vd_next;
3324 offset += ivd.vd_aux;
3325
3326 GET_DATA (offset, evda, "version def aux");
3327
3328 ivda.vda_name = BYTE_GET (evda.vda_name);
3329
3330 if (psym->st_name != ivda.vda_name)
3331 printf ((vers_data & 0x8000)
3332 ? "@%s" : "@@%s",
3333 strtab + ivda.vda_name);
3334 }
3335 }
3336 }
3337 }
3338
3339 putchar ('\n');
3340 }
3341
3342 free (symtab);
3343 if (strtab != string_table)
3344 free (strtab);
3345 }
3346 }
3347 else if (do_syms)
3348 printf
3349 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3350
3351 if (do_histogram && buckets != NULL)
3352 {
3353 int *lengths;
3354 int *counts;
3355 int hn;
3356 int si;
3357 int maxlength = 0;
3358 int nzero_counts = 0;
3359 int nsyms = 0;
3360
3361 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3362 nbuckets);
3363 printf (_(" Length Number %% of total Coverage\n"));
3364
3365 lengths = (int *) calloc (nbuckets, sizeof (int));
3366 if (lengths == NULL)
3367 {
3368 error (_("Out of memory"));
3369 return 0;
3370 }
3371 for (hn = 0; hn < nbuckets; ++hn)
3372 {
3373 if (! buckets [hn])
3374 continue;
3375
3376 for (si = buckets[hn]; si; si = chains[si])
3377 {
3378 ++nsyms;
3379 if (maxlength < ++lengths[hn])
3380 ++maxlength;
3381 }
3382 }
3383
3384 counts = (int *) calloc (maxlength + 1, sizeof (int));
3385 if (counts == NULL)
3386 {
3387 error (_("Out of memory"));
3388 return 0;
3389 }
3390
3391 for (hn = 0; hn < nbuckets; ++hn)
3392 ++ counts [lengths [hn]];
3393
3394 printf (" 0 %-10d (%5.1f%%)\n",
3395 counts[0], (counts[0] * 100.0) / nbuckets);
3396 for (si = 1; si <= maxlength; ++si)
3397 {
3398 nzero_counts += counts[si] * si;
3399 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3400 si, counts[si], (counts[si] * 100.0) / nbuckets,
3401 (nzero_counts * 100.0) / nsyms);
3402 }
3403
3404 free (counts);
3405 free (lengths);
3406 }
3407
3408 if (buckets != NULL)
3409 {
3410 free (buckets);
3411 free (chains);
3412 }
3413
3414 return 1;
3415 }
3416
3417 static int
3418 process_syminfo (file)
3419 FILE * file;
3420 {
3421 int i;
3422
3423 if (dynamic_syminfo == NULL
3424 || !do_dynamic)
3425 /* No syminfo, this is ok. */
3426 return 1;
3427
3428 /* There better should be a dynamic symbol section. */
3429 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3430 return 0;
3431
3432 if (dynamic_addr)
3433 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3434 dynamic_syminfo_offset, dynamic_syminfo_nent);
3435
3436 printf (_(" Num: Name BoundTo Flags\n"));
3437 for (i = 0; i < dynamic_syminfo_nent; ++i)
3438 {
3439 unsigned short int flags = dynamic_syminfo[i].si_flags;
3440
3441 printf ("%4d: %-30s ", i,
3442 dynamic_strings + dynamic_symbols[i].st_name);
3443
3444 switch (dynamic_syminfo[i].si_boundto)
3445 {
3446 case SYMINFO_BT_SELF:
3447 fputs ("SELF ", stdout);
3448 break;
3449 case SYMINFO_BT_PARENT:
3450 fputs ("PARENT ", stdout);
3451 break;
3452 default:
3453 if (dynamic_syminfo[i].si_boundto > 0
3454 && dynamic_syminfo[i].si_boundto < dynamic_size)
3455 printf ("%-10s ",
3456 dynamic_strings
3457 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3458 else
3459 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3460 break;
3461 }
3462
3463 if (flags & SYMINFO_FLG_DIRECT)
3464 printf (" DIRECT");
3465 if (flags & SYMINFO_FLG_PASSTHRU)
3466 printf (" PASSTHRU");
3467 if (flags & SYMINFO_FLG_COPY)
3468 printf (" COPY");
3469 if (flags & SYMINFO_FLG_LAZYLOAD)
3470 printf (" LAZYLOAD");
3471
3472 puts ("");
3473 }
3474
3475 return 1;
3476 }
3477
3478 #ifdef SUPPORT_DISASSEMBLY
3479 static void
3480 disassemble_section (section, file)
3481 Elf32_Internal_Shdr * section;
3482 FILE * file;
3483 {
3484 printf (_("\nAssembly dump of section %s\n"),
3485 SECTION_NAME (section));
3486
3487 /* XXX -- to be done --- XXX */
3488
3489 return 1;
3490 }
3491 #endif
3492
3493 static int
3494 dump_section (section, file)
3495 Elf32_Internal_Shdr * section;
3496 FILE * file;
3497 {
3498 int bytes;
3499 int addr;
3500 unsigned char * data;
3501 unsigned char * start;
3502
3503 bytes = section->sh_size;
3504
3505 if (bytes == 0)
3506 {
3507 printf (_("\nSection '%s' has no data to dump.\n"),
3508 SECTION_NAME (section));
3509 return 0;
3510 }
3511 else
3512 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3513
3514 addr = section->sh_addr;
3515
3516 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3517 "section data");
3518
3519 data = start;
3520
3521 while (bytes)
3522 {
3523 int j;
3524 int k;
3525 int lbytes;
3526
3527 lbytes = (bytes > 16 ? 16 : bytes);
3528
3529 printf (" 0x%8.8x ", addr);
3530
3531 switch (elf_header.e_ident [EI_DATA])
3532 {
3533 case ELFDATA2LSB:
3534 for (j = 15; j >= 0; j --)
3535 {
3536 if (j < lbytes)
3537 printf ("%2.2x", data [j]);
3538 else
3539 printf (" ");
3540
3541 if (!(j & 0x3))
3542 printf (" ");
3543 }
3544 break;
3545
3546 case ELFDATA2MSB:
3547 for (j = 0; j < 16; j++)
3548 {
3549 if (j < lbytes)
3550 printf ("%2.2x", data [j]);
3551 else
3552 printf (" ");
3553
3554 if ((j & 3) == 3)
3555 printf (" ");
3556 }
3557 break;
3558 }
3559
3560 for (j = 0; j < lbytes; j++)
3561 {
3562 k = data [j];
3563 if (k >= ' ' && k < 0x80)
3564 printf ("%c", k);
3565 else
3566 printf (".");
3567 }
3568
3569 putchar ('\n');
3570
3571 data += lbytes;
3572 addr += lbytes;
3573 bytes -= lbytes;
3574 }
3575
3576 free (start);
3577
3578 return 1;
3579 }
3580
3581
3582 static unsigned long int
3583 read_leb128 (data, length_return, sign)
3584 unsigned char * data;
3585 int * length_return;
3586 int sign;
3587 {
3588 unsigned long int result = 0;
3589 unsigned int num_read = 0;
3590 int shift = 0;
3591 unsigned char byte;
3592
3593 do
3594 {
3595 byte = * data ++;
3596 num_read ++;
3597
3598 result |= (byte & 0x7f) << shift;
3599
3600 shift += 7;
3601
3602 }
3603 while (byte & 0x80);
3604
3605 if (length_return != NULL)
3606 * length_return = num_read;
3607
3608 if (sign && (shift < 32) && (byte & 0x40))
3609 result |= -1 << shift;
3610
3611 return result;
3612 }
3613
3614 typedef struct State_Machine_Registers
3615 {
3616 unsigned long address;
3617 unsigned int file;
3618 unsigned int line;
3619 unsigned int column;
3620 int is_stmt;
3621 int basic_block;
3622 int end_sequence;
3623 /* This variable hold the number of the last entry seen
3624 in the File Table. */
3625 unsigned int last_file_entry;
3626 } SMR;
3627
3628 static SMR state_machine_regs;
3629
3630 static void
3631 reset_state_machine (is_stmt)
3632 int is_stmt;
3633 {
3634 state_machine_regs.address = 0;
3635 state_machine_regs.file = 1;
3636 state_machine_regs.line = 1;
3637 state_machine_regs.column = 0;
3638 state_machine_regs.is_stmt = is_stmt;
3639 state_machine_regs.basic_block = 0;
3640 state_machine_regs.end_sequence = 0;
3641 state_machine_regs.last_file_entry = 0;
3642 }
3643
3644 /* Handled an extend line op. Returns true if this is the end
3645 of sequence. */
3646 static int
3647 process_extended_line_op (data, is_stmt)
3648 unsigned char * data;
3649 int is_stmt;
3650 {
3651 unsigned char op_code;
3652 int bytes_read;
3653 unsigned int len;
3654 unsigned char * name;
3655 unsigned long adr;
3656
3657 len = read_leb128 (data, & bytes_read, 0);
3658 data += bytes_read;
3659
3660 if (len == 0)
3661 {
3662 warn (_("badly formed extended line op encountered!"));
3663 return bytes_read;
3664 }
3665
3666 len += bytes_read;
3667 op_code = * data ++;
3668
3669 printf (_(" Extended opcode %d: "), op_code);
3670
3671 switch (op_code)
3672 {
3673 case DW_LNE_end_sequence:
3674 printf (_("End of Sequence\n\n"));
3675 reset_state_machine (is_stmt);
3676 break;
3677
3678 case DW_LNE_set_address:
3679 /* XXX - assumption here that address size is 4! */
3680 adr = byte_get (data, 4);
3681 printf (_("set Address to 0x%lx\n"), adr);
3682 state_machine_regs.address = adr;
3683 break;
3684
3685 case DW_LNE_define_file:
3686 printf (_(" define new File Table entry\n"));
3687 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3688
3689 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3690 name = data;
3691 data += strlen (data) + 1;
3692 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3693 data += bytes_read;
3694 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3695 data += bytes_read;
3696 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3697 printf (_("%s\n\n"), name);
3698 break;
3699
3700 default:
3701 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
3702 break;
3703 }
3704
3705 return len;
3706 }
3707
3708
3709 static int
3710 display_debug_lines (section, start, file)
3711 Elf32_Internal_Shdr * section;
3712 unsigned char * start;
3713 FILE * file;
3714 {
3715 DWARF2_External_LineInfo * external;
3716 DWARF2_Internal_LineInfo info;
3717 unsigned char * standard_opcodes;
3718 unsigned char * data = start;
3719 unsigned char * end = start + section->sh_size;
3720 unsigned char * end_of_sequence;
3721 int i;
3722
3723 printf (_("\nDump of debug contents of section %s:\n\n"),
3724 SECTION_NAME (section));
3725
3726 while (data < end)
3727 {
3728 external = (DWARF2_External_LineInfo *) data;
3729
3730 /* Check the length of the block. */
3731 info.li_length = BYTE_GET (external->li_length);
3732 if (info.li_length > section->sh_size)
3733 {
3734 warn
3735 (_("The line info appears to be corrupt - the section is too small\n"));
3736 return 0;
3737 }
3738
3739 /* Check its version number. */
3740 info.li_version = BYTE_GET (external->li_version);
3741 if (info.li_version != 2)
3742 {
3743 warn (_("Only DWARF version 2 line info is currently supported.\n"));
3744 return 0;
3745 }
3746
3747 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
3748 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
3749 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
3750 info.li_line_base = BYTE_GET (external->li_line_base);
3751 info.li_line_range = BYTE_GET (external->li_line_range);
3752 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
3753
3754 /* Sign extend the line base field. */
3755 info.li_line_base <<= 24;
3756 info.li_line_base >>= 24;
3757
3758 printf (_(" Length: %ld\n"), info.li_length);
3759 printf (_(" DWARF Version: %d\n"), info.li_version);
3760 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
3761 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
3762 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
3763 printf (_(" Line Base: %d\n"), info.li_line_base);
3764 printf (_(" Line Range: %d\n"), info.li_line_range);
3765 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
3766
3767 end_of_sequence = data + info.li_length + sizeof (info.li_length);
3768
3769 reset_state_machine (info.li_default_is_stmt);
3770
3771 /* Display the contents of the Opcodes table. */
3772 standard_opcodes = data + sizeof (* external);
3773
3774 printf (_("\n Opcodes:\n"));
3775
3776 for (i = 1; i < info.li_opcode_base; i++)
3777 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
3778
3779 /* Display the contents of the Directory table. */
3780 data = standard_opcodes + info.li_opcode_base - 1;
3781
3782 if (* data == 0)
3783 printf (_("\n The Directory Table is empty.\n"));
3784 else
3785 {
3786 printf (_("\n The Directory Table:\n"));
3787
3788 while (* data != 0)
3789 {
3790 printf (_(" %s\n"), data);
3791
3792 data += strlen (data) + 1;
3793 }
3794 }
3795
3796 /* Skip the NUL at the end of the table. */
3797 data ++;
3798
3799 /* Display the contents of the File Name table. */
3800 if (* data == 0)
3801 printf (_("\n The File Name Table is empty.\n"));
3802 else
3803 {
3804 printf (_("\n The File Name Table:\n"));
3805 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3806
3807 while (* data != 0)
3808 {
3809 char * name;
3810 int bytes_read;
3811
3812 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3813 name = data;
3814
3815 data += strlen (data) + 1;
3816
3817 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3818 data += bytes_read;
3819 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3820 data += bytes_read;
3821 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3822 data += bytes_read;
3823 printf (_("%s\n"), name);
3824 }
3825 }
3826
3827 /* Skip the NUL at the end of the table. */
3828 data ++;
3829
3830 /* Now display the statements. */
3831 printf (_("\n Line Number Statements:\n"));
3832
3833
3834 while (data < end_of_sequence)
3835 {
3836 unsigned char op_code;
3837 int adv;
3838 int bytes_read;
3839
3840 op_code = * data ++;
3841
3842 switch (op_code)
3843 {
3844 case DW_LNS_extended_op:
3845 data += process_extended_line_op (data, info.li_default_is_stmt);
3846 break;
3847
3848 case DW_LNS_copy:
3849 printf (_(" Copy\n"));
3850 break;
3851
3852 case DW_LNS_advance_pc:
3853 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
3854 data += bytes_read;
3855 state_machine_regs.address += adv;
3856 printf (_(" Advance PC by %d to %lx\n"), adv,
3857 state_machine_regs.address);
3858 break;
3859
3860 case DW_LNS_advance_line:
3861 adv = read_leb128 (data, & bytes_read, 1);
3862 data += bytes_read;
3863 state_machine_regs.line += adv;
3864 printf (_(" Advance Line by %d to %d\n"), adv,
3865 state_machine_regs.line);
3866 break;
3867
3868 case DW_LNS_set_file:
3869 adv = read_leb128 (data, & bytes_read, 0);
3870 data += bytes_read;
3871 printf (_(" Set File Name to entry %d in the File Name Table\n"),
3872 adv);
3873 state_machine_regs.file = adv;
3874 break;
3875
3876 case DW_LNS_set_column:
3877 adv = read_leb128 (data, & bytes_read, 0);
3878 data += bytes_read;
3879 printf (_(" Set column to %d\n"), adv);
3880 state_machine_regs.column = adv;
3881 break;
3882
3883 case DW_LNS_negate_stmt:
3884 adv = state_machine_regs.is_stmt;
3885 adv = ! adv;
3886 printf (_(" Set is_stmt to %d\n"), adv);
3887 state_machine_regs.is_stmt = adv;
3888 break;
3889
3890 case DW_LNS_set_basic_block:
3891 printf (_(" Set basic block\n"));
3892 state_machine_regs.basic_block = 1;
3893 break;
3894
3895 case DW_LNS_const_add_pc:
3896 adv = (255 - info.li_opcode_base) / info.li_line_range;
3897 state_machine_regs.address += adv;
3898 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
3899 state_machine_regs.address);
3900 break;
3901
3902 case DW_LNS_fixed_advance_pc:
3903 adv = byte_get (data, 2);
3904 data += 2;
3905 state_machine_regs.address += adv;
3906 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
3907 adv, state_machine_regs.address);
3908 break;
3909
3910 default:
3911 op_code -= info.li_opcode_base;
3912 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
3913 state_machine_regs.address += adv;
3914 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
3915 op_code, adv, state_machine_regs.address);
3916 adv += (op_code % info.li_line_range) + info.li_line_base;
3917 state_machine_regs.line += adv;
3918 printf (_(" and Line by %d to %d\n"),
3919 adv, state_machine_regs.line);
3920 break;
3921 }
3922 }
3923 printf ("\n");
3924 }
3925
3926 return 1;
3927 }
3928
3929 static int
3930 display_debug_pubnames (section, start, file)
3931 Elf32_Internal_Shdr * section;
3932 unsigned char * start;
3933 FILE * file;
3934 {
3935 DWARF2_External_PubNames * external;
3936 DWARF2_Internal_PubNames pubnames;
3937 unsigned char * end;
3938
3939 end = start + section->sh_size;
3940
3941 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
3942
3943 while (start < end)
3944 {
3945 unsigned char * data;
3946 unsigned long offset;
3947
3948 external = (DWARF2_External_PubNames *) start;
3949
3950 pubnames.pn_length = BYTE_GET (external->pn_length);
3951 pubnames.pn_version = BYTE_GET (external->pn_version);
3952 pubnames.pn_offset = BYTE_GET (external->pn_offset);
3953 pubnames.pn_size = BYTE_GET (external->pn_size);
3954
3955 data = start + sizeof (* external);
3956 start += pubnames.pn_length + sizeof (external->pn_length);
3957
3958 if (pubnames.pn_version != 2)
3959 {
3960 warn (_("Only DWARF 2 pubnames are currently supported"));
3961 continue;
3962 }
3963
3964 printf (_(" Length: %ld\n"),
3965 pubnames.pn_length);
3966 printf (_(" Version: %d\n"),
3967 pubnames.pn_version);
3968 printf (_(" Offset into .debug_info section: %ld\n"),
3969 pubnames.pn_offset);
3970 printf (_(" Size of area in .debug_info section: %ld\n"),
3971 pubnames.pn_size);
3972
3973 printf (_("\n Offset\tName\n"));
3974
3975 do
3976 {
3977 offset = byte_get (data, 4);
3978
3979 if (offset != 0)
3980 {
3981 data += 4;
3982 printf (" %ld\t\t%s\n", offset, data);
3983 data += strlen (data) + 1;
3984 }
3985 }
3986 while (offset != 0);
3987 }
3988
3989 printf ("\n");
3990 return 1;
3991 }
3992
3993 static char *
3994 get_TAG_name (tag)
3995 unsigned long tag;
3996 {
3997 switch (tag)
3998 {
3999 case DW_TAG_padding: return "DW_TAG_padding";
4000 case DW_TAG_array_type: return "DW_TAG_array_type";
4001 case DW_TAG_class_type: return "DW_TAG_class_type";
4002 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4003 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4004 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4005 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4006 case DW_TAG_label: return "DW_TAG_label";
4007 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4008 case DW_TAG_member: return "DW_TAG_member";
4009 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4010 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4011 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4012 case DW_TAG_string_type: return "DW_TAG_string_type";
4013 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4014 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4015 case DW_TAG_typedef: return "DW_TAG_typedef";
4016 case DW_TAG_union_type: return "DW_TAG_union_type";
4017 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4018 case DW_TAG_variant: return "DW_TAG_variant";
4019 case DW_TAG_common_block: return "DW_TAG_common_block";
4020 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4021 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4022 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4023 case DW_TAG_module: return "DW_TAG_module";
4024 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4025 case DW_TAG_set_type: return "DW_TAG_set_type";
4026 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4027 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4028 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4029 case DW_TAG_base_type: return "DW_TAG_base_type";
4030 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4031 case DW_TAG_const_type: return "DW_TAG_const_type";
4032 case DW_TAG_constant: return "DW_TAG_constant";
4033 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4034 case DW_TAG_file_type: return "DW_TAG_file_type";
4035 case DW_TAG_friend: return "DW_TAG_friend";
4036 case DW_TAG_namelist: return "DW_TAG_namelist";
4037 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4038 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4039 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4040 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4041 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4042 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4043 case DW_TAG_try_block: return "DW_TAG_try_block";
4044 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4045 case DW_TAG_variable: return "DW_TAG_variable";
4046 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4047 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4048 case DW_TAG_format_label: return "DW_TAG_format_label";
4049 case DW_TAG_function_template: return "DW_TAG_function_template";
4050 case DW_TAG_class_template: return "DW_TAG_class_template";
4051 default:
4052 {
4053 static char buffer [100];
4054
4055 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4056 return buffer;
4057 }
4058 }
4059 }
4060
4061 static char *
4062 get_AT_name (attribute)
4063 unsigned long attribute;
4064 {
4065 switch (attribute)
4066 {
4067 case DW_AT_sibling: return "DW_AT_sibling";
4068 case DW_AT_location: return "DW_AT_location";
4069 case DW_AT_name: return "DW_AT_name";
4070 case DW_AT_ordering: return "DW_AT_ordering";
4071 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4072 case DW_AT_byte_size: return "DW_AT_byte_size";
4073 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4074 case DW_AT_bit_size: return "DW_AT_bit_size";
4075 case DW_AT_element_list: return "DW_AT_element_list";
4076 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4077 case DW_AT_low_pc: return "DW_AT_low_pc";
4078 case DW_AT_high_pc: return "DW_AT_high_pc";
4079 case DW_AT_language: return "DW_AT_language";
4080 case DW_AT_member: return "DW_AT_member";
4081 case DW_AT_discr: return "DW_AT_discr";
4082 case DW_AT_discr_value: return "DW_AT_discr_value";
4083 case DW_AT_visibility: return "DW_AT_visibility";
4084 case DW_AT_import: return "DW_AT_import";
4085 case DW_AT_string_length: return "DW_AT_string_length";
4086 case DW_AT_common_reference: return "DW_AT_common_reference";
4087 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4088 case DW_AT_const_value: return "DW_AT_const_value";
4089 case DW_AT_containing_type: return "DW_AT_containing_type";
4090 case DW_AT_default_value: return "DW_AT_default_value";
4091 case DW_AT_inline: return "DW_AT_inline";
4092 case DW_AT_is_optional: return "DW_AT_is_optional";
4093 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4094 case DW_AT_producer: return "DW_AT_producer";
4095 case DW_AT_prototyped: return "DW_AT_prototyped";
4096 case DW_AT_return_addr: return "DW_AT_return_addr";
4097 case DW_AT_start_scope: return "DW_AT_start_scope";
4098 case DW_AT_stride_size: return "DW_AT_stride_size";
4099 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4100 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4101 case DW_AT_accessibility: return "DW_AT_accessibility";
4102 case DW_AT_address_class: return "DW_AT_address_class";
4103 case DW_AT_artificial: return "DW_AT_artificial";
4104 case DW_AT_base_types: return "DW_AT_base_types";
4105 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4106 case DW_AT_count: return "DW_AT_count";
4107 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4108 case DW_AT_decl_column: return "DW_AT_decl_column";
4109 case DW_AT_decl_file: return "DW_AT_decl_file";
4110 case DW_AT_decl_line: return "DW_AT_decl_line";
4111 case DW_AT_declaration: return "DW_AT_declaration";
4112 case DW_AT_discr_list: return "DW_AT_discr_list";
4113 case DW_AT_encoding: return "DW_AT_encoding";
4114 case DW_AT_external: return "DW_AT_external";
4115 case DW_AT_frame_base: return "DW_AT_frame_base";
4116 case DW_AT_friend: return "DW_AT_friend";
4117 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4118 case DW_AT_macro_info: return "DW_AT_macro_info";
4119 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4120 case DW_AT_priority: return "DW_AT_priority";
4121 case DW_AT_segment: return "DW_AT_segment";
4122 case DW_AT_specification: return "DW_AT_specification";
4123 case DW_AT_static_link: return "DW_AT_static_link";
4124 case DW_AT_type: return "DW_AT_type";
4125 case DW_AT_use_location: return "DW_AT_use_location";
4126 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4127 case DW_AT_virtuality: return "DW_AT_virtuality";
4128 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4129 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4130 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4131 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4132 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4133 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4134 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4135 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4136 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4137 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4138 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4139 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4140 case DW_AT_sf_names: return "DW_AT_sf_names";
4141 case DW_AT_src_info: return "DW_AT_src_info";
4142 case DW_AT_mac_info: return "DW_AT_mac_info";
4143 case DW_AT_src_coords: return "DW_AT_src_coords";
4144 case DW_AT_body_begin: return "DW_AT_body_begin";
4145 case DW_AT_body_end: return "DW_AT_body_end";
4146 default:
4147 {
4148 static char buffer [100];
4149
4150 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4151 return buffer;
4152 }
4153 }
4154 }
4155
4156 static char *
4157 get_FORM_name (form)
4158 unsigned long form;
4159 {
4160 switch (form)
4161 {
4162 case DW_FORM_addr: return "DW_FORM_addr";
4163 case DW_FORM_block2: return "DW_FORM_block2";
4164 case DW_FORM_block4: return "DW_FORM_block4";
4165 case DW_FORM_data2: return "DW_FORM_data2";
4166 case DW_FORM_data4: return "DW_FORM_data4";
4167 case DW_FORM_data8: return "DW_FORM_data8";
4168 case DW_FORM_string: return "DW_FORM_string";
4169 case DW_FORM_block: return "DW_FORM_block";
4170 case DW_FORM_block1: return "DW_FORM_block1";
4171 case DW_FORM_data1: return "DW_FORM_data1";
4172 case DW_FORM_flag: return "DW_FORM_flag";
4173 case DW_FORM_sdata: return "DW_FORM_sdata";
4174 case DW_FORM_strp: return "DW_FORM_strp";
4175 case DW_FORM_udata: return "DW_FORM_udata";
4176 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4177 case DW_FORM_ref1: return "DW_FORM_ref1";
4178 case DW_FORM_ref2: return "DW_FORM_ref2";
4179 case DW_FORM_ref4: return "DW_FORM_ref4";
4180 case DW_FORM_ref8: return "DW_FORM_ref8";
4181 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4182 case DW_FORM_indirect: return "DW_FORM_indirect";
4183 default:
4184 {
4185 static char buffer [100];
4186
4187 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4188 return buffer;
4189 }
4190 }
4191 }
4192
4193 /* FIXME: There are better and more effiecint ways to handle
4194 these structures. For now though, I just want something that
4195 is simple to implement. */
4196 typedef struct abbrev_attr
4197 {
4198 unsigned long attribute;
4199 unsigned long form;
4200 struct abbrev_attr * next;
4201 }
4202 abbrev_attr;
4203
4204 typedef struct abbrev_entry
4205 {
4206 unsigned long entry;
4207 unsigned long tag;
4208 int children;
4209 struct abbrev_attr * first_attr;
4210 struct abbrev_attr * last_attr;
4211 struct abbrev_entry * next;
4212 }
4213 abbrev_entry;
4214
4215 static abbrev_entry * first_abbrev = NULL;
4216 static abbrev_entry * last_abbrev = NULL;
4217
4218 static void
4219 free_abbrevs PARAMS ((void))
4220 {
4221 abbrev_entry * abbrev;
4222
4223 for (abbrev = first_abbrev; abbrev;)
4224 {
4225 abbrev_entry * next = abbrev->next;
4226 abbrev_attr * attr;
4227
4228 for (attr = abbrev->first_attr; attr;)
4229 {
4230 abbrev_attr * next = attr->next;
4231
4232 free (attr);
4233 attr = next;
4234 }
4235
4236 free (abbrev);
4237 abbrev = next;
4238 }
4239
4240 last_abbrev = first_abbrev = NULL;
4241 }
4242
4243 static void
4244 add_abbrev (number, tag, children)
4245 unsigned long number;
4246 unsigned long tag;
4247 int children;
4248 {
4249 abbrev_entry * entry;
4250
4251 entry = (abbrev_entry *) malloc (sizeof (* entry));
4252
4253 if (entry == NULL)
4254 /* ugg */
4255 return;
4256
4257 entry->entry = number;
4258 entry->tag = tag;
4259 entry->children = children;
4260 entry->first_attr = NULL;
4261 entry->last_attr = NULL;
4262 entry->next = NULL;
4263
4264 if (first_abbrev == NULL)
4265 first_abbrev = entry;
4266 else
4267 last_abbrev->next = entry;
4268
4269 last_abbrev = entry;
4270 }
4271
4272 static void
4273 add_abbrev_attr (attribute, form)
4274 unsigned long attribute;
4275 unsigned long form;
4276 {
4277 abbrev_attr * attr;
4278
4279 attr = (abbrev_attr *) malloc (sizeof (* attr));
4280
4281 if (attr == NULL)
4282 /* ugg */
4283 return;
4284
4285 attr->attribute = attribute;
4286 attr->form = form;
4287 attr->next = NULL;
4288
4289 if (last_abbrev->first_attr == NULL)
4290 last_abbrev->first_attr = attr;
4291 else
4292 last_abbrev->last_attr->next = attr;
4293
4294 last_abbrev->last_attr = attr;
4295 }
4296
4297 /* Processes the (partial) contents of a .debug_abbrev section.
4298 Returns NULL if the end of the section was encountered.
4299 Returns the address after the last byte read if the end of
4300 an abbreviation set was found. */
4301
4302 static unsigned char *
4303 process_abbrev_section (start, end)
4304 unsigned char * start;
4305 unsigned char * end;
4306 {
4307 if (first_abbrev != NULL)
4308 return NULL;
4309
4310 while (start < end)
4311 {
4312 int bytes_read;
4313 unsigned long entry;
4314 unsigned long tag;
4315 unsigned long attribute;
4316 int children;
4317
4318 entry = read_leb128 (start, & bytes_read, 0);
4319 start += bytes_read;
4320
4321 if (entry == 0)
4322 return start;
4323
4324 tag = read_leb128 (start, & bytes_read, 0);
4325 start += bytes_read;
4326
4327 children = * start ++;
4328
4329 add_abbrev (entry, tag, children);
4330
4331 do
4332 {
4333 unsigned long form;
4334
4335 attribute = read_leb128 (start, & bytes_read, 0);
4336 start += bytes_read;
4337
4338 form = read_leb128 (start, & bytes_read, 0);
4339 start += bytes_read;
4340
4341 if (attribute != 0)
4342 add_abbrev_attr (attribute, form);
4343 }
4344 while (attribute != 0);
4345 }
4346
4347 return NULL;
4348 }
4349
4350
4351 static int
4352 display_debug_abbrev (section, start, file)
4353 Elf32_Internal_Shdr * section;
4354 unsigned char * start;
4355 FILE * file;
4356 {
4357 abbrev_entry * entry;
4358 unsigned char * end = start + section->sh_size;
4359
4360 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4361
4362 do
4363 {
4364 start = process_abbrev_section (start, end);
4365
4366 printf (_(" Number TAG\n"));
4367
4368 for (entry = first_abbrev; entry; entry = entry->next)
4369 {
4370 abbrev_attr * attr;
4371
4372 printf (_(" %ld %s [%s]\n"),
4373 entry->entry,
4374 get_TAG_name (entry->tag),
4375 entry->children ? _("has children") : _("no children"));
4376
4377 for (attr = entry->first_attr; attr; attr = attr->next)
4378 {
4379 printf (_(" %-18s %s\n"),
4380 get_AT_name (attr->attribute),
4381 get_FORM_name (attr->form));
4382 }
4383 }
4384 }
4385 while (start);
4386
4387 printf ("\n");
4388
4389 return 1;
4390 }
4391
4392
4393 static unsigned char *
4394 display_block (data, length)
4395 unsigned char * data;
4396 unsigned long length;
4397 {
4398 printf (_(" %lu byte block: "), length);
4399
4400 while (length --)
4401 printf ("%lx ", byte_get (data ++, 1));
4402
4403 return data;
4404 }
4405
4406 static void
4407 decode_location_expression (data, pointer_size)
4408 unsigned char * data;
4409 unsigned int pointer_size;
4410 {
4411 unsigned char op;
4412 int bytes_read;
4413
4414 op = * data ++;
4415
4416 switch (op)
4417 {
4418 case DW_OP_addr: printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
4419 case DW_OP_deref: printf ("DW_OP_deref"); break;
4420 case DW_OP_const1u: printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
4421 case DW_OP_const1s: printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
4422 case DW_OP_const2u: printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
4423 case DW_OP_const2s: printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
4424 case DW_OP_const4u: printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
4425 case DW_OP_const4s: printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
4426 case DW_OP_const8u: printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
4427 case DW_OP_const8s: printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
4428 case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
4429 case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
4430 case DW_OP_dup: printf ("DW_OP_dup"); break;
4431 case DW_OP_drop: printf ("DW_OP_drop"); break;
4432 case DW_OP_over: printf ("DW_OP_over"); break;
4433 case DW_OP_pick: printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
4434 case DW_OP_swap: printf ("DW_OP_swap"); break;
4435 case DW_OP_rot: printf ("DW_OP_rot"); break;
4436 case DW_OP_xderef: printf ("DW_OP_xderef"); break;
4437 case DW_OP_abs: printf ("DW_OP_abs"); break;
4438 case DW_OP_and: printf ("DW_OP_and"); break;
4439 case DW_OP_div: printf ("DW_OP_div"); break;
4440 case DW_OP_minus: printf ("DW_OP_minus"); break;
4441 case DW_OP_mod: printf ("DW_OP_mod"); break;
4442 case DW_OP_mul: printf ("DW_OP_mul"); break;
4443 case DW_OP_neg: printf ("DW_OP_neg"); break;
4444 case DW_OP_not: printf ("DW_OP_not"); break;
4445 case DW_OP_or: printf ("DW_OP_or"); break;
4446 case DW_OP_plus: printf ("DW_OP_plus"); break;
4447 case DW_OP_plus_uconst: printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
4448 case DW_OP_shl: printf ("DW_OP_shl"); break;
4449 case DW_OP_shr: printf ("DW_OP_shr"); break;
4450 case DW_OP_shra: printf ("DW_OP_shra"); break;
4451 case DW_OP_xor: printf ("DW_OP_xor"); break;
4452 case DW_OP_bra: printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
4453 case DW_OP_eq: printf ("DW_OP_eq"); break;
4454 case DW_OP_ge: printf ("DW_OP_ge"); break;
4455 case DW_OP_gt: printf ("DW_OP_gt"); break;
4456 case DW_OP_le: printf ("DW_OP_le"); break;
4457 case DW_OP_lt: printf ("DW_OP_lt"); break;
4458 case DW_OP_ne: printf ("DW_OP_ne"); break;
4459 case DW_OP_skip: printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
4460 case DW_OP_lit0: printf ("DW_OP_lit0"); break;
4461 case DW_OP_lit1: printf ("DW_OP_lit1"); break;
4462 case DW_OP_lit2: printf ("DW_OP_lit2"); break;
4463 case DW_OP_lit3: printf ("DW_OP_lit3"); break;
4464 case DW_OP_lit4: printf ("DW_OP_lit4"); break;
4465 case DW_OP_lit5: printf ("DW_OP_lit5"); break;
4466 case DW_OP_lit6: printf ("DW_OP_lit6"); break;
4467 case DW_OP_lit7: printf ("DW_OP_lit7"); break;
4468 case DW_OP_lit8: printf ("DW_OP_lit8"); break;
4469 case DW_OP_lit9: printf ("DW_OP_lit9"); break;
4470 case DW_OP_lit10: printf ("DW_OP_lit10"); break;
4471 case DW_OP_lit11: printf ("DW_OP_lit11"); break;
4472 case DW_OP_lit12: printf ("DW_OP_lit12"); break;
4473 case DW_OP_lit13: printf ("DW_OP_lit13"); break;
4474 case DW_OP_lit14: printf ("DW_OP_lit14"); break;
4475 case DW_OP_lit15: printf ("DW_OP_lit15"); break;
4476 case DW_OP_lit16: printf ("DW_OP_lit16"); break;
4477 case DW_OP_lit17: printf ("DW_OP_lit17"); break;
4478 case DW_OP_lit18: printf ("DW_OP_lit18"); break;
4479 case DW_OP_lit19: printf ("DW_OP_lit19"); break;
4480 case DW_OP_lit20: printf ("DW_OP_lit20"); break;
4481 case DW_OP_lit21: printf ("DW_OP_lit21"); break;
4482 case DW_OP_lit22: printf ("DW_OP_lit22"); break;
4483 case DW_OP_lit23: printf ("DW_OP_lit23"); break;
4484 case DW_OP_lit24: printf ("DW_OP_lit24"); break;
4485 case DW_OP_lit25: printf ("DW_OP_lit25"); break;
4486 case DW_OP_lit26: printf ("DW_OP_lit26"); break;
4487 case DW_OP_lit27: printf ("DW_OP_lit27"); break;
4488 case DW_OP_lit28: printf ("DW_OP_lit28"); break;
4489 case DW_OP_lit29: printf ("DW_OP_lit29"); break;
4490 case DW_OP_lit30: printf ("DW_OP_lit30"); break;
4491 case DW_OP_lit31: printf ("DW_OP_lit31"); break;
4492 case DW_OP_reg0: printf ("DW_OP_reg0"); break;
4493 case DW_OP_reg1: printf ("DW_OP_reg1"); break;
4494 case DW_OP_reg2: printf ("DW_OP_reg2"); break;
4495 case DW_OP_reg3: printf ("DW_OP_reg3"); break;
4496 case DW_OP_reg4: printf ("DW_OP_reg4"); break;
4497 case DW_OP_reg5: printf ("DW_OP_reg5"); break;
4498 case DW_OP_reg6: printf ("DW_OP_reg6"); break;
4499 case DW_OP_reg7: printf ("DW_OP_reg7"); break;
4500 case DW_OP_reg8: printf ("DW_OP_reg8"); break;
4501 case DW_OP_reg9: printf ("DW_OP_reg9"); break;
4502 case DW_OP_reg10: printf ("DW_OP_reg10"); break;
4503 case DW_OP_reg11: printf ("DW_OP_reg11"); break;
4504 case DW_OP_reg12: printf ("DW_OP_reg12"); break;
4505 case DW_OP_reg13: printf ("DW_OP_reg13"); break;
4506 case DW_OP_reg14: printf ("DW_OP_reg14"); break;
4507 case DW_OP_reg15: printf ("DW_OP_reg15"); break;
4508 case DW_OP_reg16: printf ("DW_OP_reg16"); break;
4509 case DW_OP_reg17: printf ("DW_OP_reg17"); break;
4510 case DW_OP_reg18: printf ("DW_OP_reg18"); break;
4511 case DW_OP_reg19: printf ("DW_OP_reg19"); break;
4512 case DW_OP_reg20: printf ("DW_OP_reg20"); break;
4513 case DW_OP_reg21: printf ("DW_OP_reg21"); break;
4514 case DW_OP_reg22: printf ("DW_OP_reg22"); break;
4515 case DW_OP_reg23: printf ("DW_OP_reg23"); break;
4516 case DW_OP_reg24: printf ("DW_OP_reg24"); break;
4517 case DW_OP_reg25: printf ("DW_OP_reg25"); break;
4518 case DW_OP_reg26: printf ("DW_OP_reg26"); break;
4519 case DW_OP_reg27: printf ("DW_OP_reg27"); break;
4520 case DW_OP_reg28: printf ("DW_OP_reg28"); break;
4521 case DW_OP_reg29: printf ("DW_OP_reg29"); break;
4522 case DW_OP_reg30: printf ("DW_OP_reg30"); break;
4523 case DW_OP_reg31: printf ("DW_OP_reg31"); break;
4524 case DW_OP_breg0: printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
4525 case DW_OP_breg1: printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
4526 case DW_OP_breg2: printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
4527 case DW_OP_breg3: printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
4528 case DW_OP_breg4: printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
4529 case DW_OP_breg5: printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
4530 case DW_OP_breg6: printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
4531 case DW_OP_breg7: printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
4532 case DW_OP_breg8: printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
4533 case DW_OP_breg9: printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
4534 case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
4535 case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
4536 case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
4537 case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
4538 case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
4539 case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
4540 case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
4541 case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
4542 case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
4543 case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
4544 case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
4545 case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
4546 case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
4547 case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
4548 case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
4549 case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
4550 case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
4551 case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
4552 case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
4553 case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
4554 case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
4555 case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
4556 case DW_OP_regx: printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
4557 case DW_OP_fbreg: printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
4558 case DW_OP_bregx: printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
4559 case DW_OP_piece: printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
4560 case DW_OP_deref_size: printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
4561 case DW_OP_xderef_size: printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
4562 case DW_OP_nop: printf ("DW_OP_nop"); break;
4563
4564 default:
4565 if (op >= DW_OP_lo_user
4566 && op <= DW_OP_hi_user)
4567 printf (_("(User defined location op)"));
4568 else
4569 printf (_("(Unknown location op)"));
4570 break;
4571 }
4572 }
4573
4574
4575 static unsigned char *
4576 read_and_display_attr (attribute, form, data, pointer_size)
4577 unsigned long attribute;
4578 unsigned long form;
4579 unsigned char * data;
4580 unsigned long pointer_size;
4581 {
4582 unsigned long uvalue;
4583 unsigned char * block_start;
4584 int bytes_read;
4585 int is_ref = 0;
4586
4587 printf (" %-18s:", get_AT_name (attribute));
4588
4589 switch (form)
4590 {
4591 case DW_FORM_ref_addr:
4592 case DW_FORM_ref1:
4593 case DW_FORM_ref2:
4594 case DW_FORM_ref4:
4595 case DW_FORM_ref8:
4596 case DW_FORM_ref_udata:
4597 is_ref = 1;
4598 }
4599
4600 switch (form)
4601 {
4602 case DW_FORM_ref_addr:
4603 case DW_FORM_addr:
4604 uvalue = byte_get (data, pointer_size);
4605 printf (is_ref ? " <%x>" : " %#x", uvalue);
4606 data += pointer_size;
4607 break;
4608
4609 case DW_FORM_ref1:
4610 case DW_FORM_flag:
4611 case DW_FORM_data1:
4612 uvalue = byte_get (data ++, 1);
4613 printf (is_ref ? " <%x>" : " %d", uvalue);
4614 break;
4615
4616 case DW_FORM_ref2:
4617 case DW_FORM_data2:
4618 uvalue = byte_get (data, 2);
4619 data += 2;
4620 printf (is_ref ? " <%x>" : " %d", uvalue);
4621 break;
4622
4623 case DW_FORM_ref4:
4624 case DW_FORM_data4:
4625 uvalue = byte_get (data, 4);
4626 data += 4;
4627 printf (is_ref ? " <%x>" : " %d", uvalue);
4628 break;
4629
4630 case DW_FORM_ref8:
4631 case DW_FORM_data8:
4632 uvalue = byte_get (data, 4);
4633 printf (" %lx", uvalue);
4634 printf (" %lx", byte_get (data + 4, 4));
4635 data += 8;
4636 break;
4637
4638 case DW_FORM_string:
4639 printf (" %s", data);
4640 data += strlen (data) + 1;
4641 break;
4642
4643 case DW_FORM_sdata:
4644 uvalue = read_leb128 (data, & bytes_read, 1);
4645 data += bytes_read;
4646 printf (" %ld", (long) uvalue);
4647 break;
4648
4649 case DW_FORM_ref_udata:
4650 case DW_FORM_udata:
4651 uvalue = read_leb128 (data, & bytes_read, 0);
4652 data += bytes_read;
4653 printf (is_ref ? " <%lx>" : " %ld", uvalue);
4654 break;
4655
4656 case DW_FORM_block:
4657 uvalue = read_leb128 (data, & bytes_read, 0);
4658 block_start = data + bytes_read;
4659 data = display_block (block_start, uvalue);
4660 uvalue = * block_start;
4661 break;
4662
4663 case DW_FORM_block1:
4664 uvalue = byte_get (data, 1);
4665 block_start = data + 1;
4666 data = display_block (block_start, uvalue);
4667 uvalue = * block_start;
4668 break;
4669
4670 case DW_FORM_block2:
4671 uvalue = byte_get (data, 2);
4672 block_start = data + 2;
4673 data = display_block (block_start, uvalue);
4674 uvalue = * block_start;
4675 break;
4676
4677 case DW_FORM_block4:
4678 uvalue = byte_get (data, 4);
4679 block_start = data + 4;
4680 data = display_block (block_start, uvalue);
4681 uvalue = * block_start;
4682 break;
4683
4684 case DW_FORM_strp:
4685 case DW_FORM_indirect:
4686 warn (_("Unable to handle FORM: %d"), form);
4687 break;
4688
4689 default:
4690 warn (_("Unrecognised form: %d"), form);
4691 break;
4692 }
4693
4694 /* For some attributes we can display futher information. */
4695
4696 printf ("\t");
4697
4698 switch (attribute)
4699 {
4700 case DW_AT_inline:
4701 switch (uvalue)
4702 {
4703 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
4704 case DW_INL_inlined: printf (_("(inlined)")); break;
4705 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
4706 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
4707 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
4708 }
4709 break;
4710
4711 case DW_AT_frame_base:
4712 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
4713 printf ("(reg %ld)", uvalue - DW_OP_reg0);
4714 break;
4715
4716 case DW_AT_language:
4717 switch (uvalue)
4718 {
4719 case DW_LANG_C: printf ("(non-ANSI C)"); break;
4720 case DW_LANG_C89: printf ("(ANSI C)"); break;
4721 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
4722 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
4723 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
4724 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
4725 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
4726 case DW_LANG_Ada83: printf ("(Ada)"); break;
4727 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
4728 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
4729 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
4730 default: printf ("(Unknown: %lx)", uvalue); break;
4731 }
4732 break;
4733
4734 case DW_AT_encoding:
4735 switch (uvalue)
4736 {
4737 case DW_ATE_void: printf ("(void)"); break;
4738 case DW_ATE_address: printf ("(machine address)"); break;
4739 case DW_ATE_boolean: printf ("(boolean)"); break;
4740 case DW_ATE_complex_float: printf ("(complex float)"); break;
4741 case DW_ATE_float: printf ("(float)"); break;
4742 case DW_ATE_signed: printf ("(signed)"); break;
4743 case DW_ATE_signed_char: printf ("(signed char)"); break;
4744 case DW_ATE_unsigned: printf ("(unsigned)"); break;
4745 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
4746 default:
4747 if (uvalue >= DW_ATE_lo_user
4748 && uvalue <= DW_ATE_hi_user)
4749 printf ("(user defined type)");
4750 else
4751 printf ("(unknown type)");
4752 break;
4753 }
4754 break;
4755
4756 case DW_AT_accessibility:
4757 switch (uvalue)
4758 {
4759 case DW_ACCESS_public: printf ("(public)"); break;
4760 case DW_ACCESS_protected: printf ("(protected)"); break;
4761 case DW_ACCESS_private: printf ("(private)"); break;
4762 default: printf ("(unknown accessibility)"); break;
4763 }
4764 break;
4765
4766 case DW_AT_visibility:
4767 switch (uvalue)
4768 {
4769 case DW_VIS_local: printf ("(local)"); break;
4770 case DW_VIS_exported: printf ("(exported)"); break;
4771 case DW_VIS_qualified: printf ("(qualified)"); break;
4772 default: printf ("(unknown visibility)"); break;
4773 }
4774 break;
4775
4776 case DW_AT_virtuality:
4777 switch (uvalue)
4778 {
4779 case DW_VIRTUALITY_none: printf ("(none)"); break;
4780 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
4781 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
4782 default: printf ("(unknown virtuality)"); break;
4783 }
4784 break;
4785
4786 case DW_AT_identifier_case:
4787 switch (uvalue)
4788 {
4789 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
4790 case DW_ID_up_case: printf ("(up_case)"); break;
4791 case DW_ID_down_case: printf ("(down_case)"); break;
4792 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
4793 default: printf ("(unknown case)"); break;
4794 }
4795 break;
4796
4797 case DW_AT_calling_convention:
4798 switch (uvalue)
4799 {
4800 case DW_CC_normal: printf ("(normal)"); break;
4801 case DW_CC_program: printf ("(program)"); break;
4802 case DW_CC_nocall: printf ("(nocall)"); break;
4803 default:
4804 if (uvalue >= DW_CC_lo_user
4805 && uvalue <= DW_CC_hi_user)
4806 printf ("(user defined)");
4807 else
4808 printf ("(unknown convention)");
4809 }
4810 break;
4811
4812 case DW_AT_location:
4813 case DW_AT_data_member_location:
4814 case DW_AT_vtable_elem_location:
4815 printf ("(");
4816 decode_location_expression (block_start, pointer_size);
4817 printf (")");
4818 break;
4819
4820 default:
4821 break;
4822 }
4823
4824 printf ("\n");
4825 return data;
4826 }
4827
4828 static int
4829 display_debug_info (section, start, file)
4830 Elf32_Internal_Shdr * section;
4831 unsigned char * start;
4832 FILE * file;
4833 {
4834 unsigned char * end = start + section->sh_size;
4835 unsigned char * section_begin = start;
4836
4837 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4838
4839 while (start < end)
4840 {
4841 DWARF2_External_CompUnit * external;
4842 DWARF2_Internal_CompUnit compunit;
4843 unsigned char * tags;
4844 int i;
4845 int level;
4846
4847 external = (DWARF2_External_CompUnit *) start;
4848
4849 compunit.cu_length = BYTE_GET (external->cu_length);
4850 compunit.cu_version = BYTE_GET (external->cu_version);
4851 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
4852 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
4853
4854 tags = start + sizeof (* external);
4855 start += compunit.cu_length + sizeof (external->cu_length);
4856
4857 if (compunit.cu_version != 2)
4858 {
4859 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
4860 continue;
4861 }
4862
4863 printf (_(" Compilation Unit:\n"));
4864 printf (_(" Length: %ld\n"), compunit.cu_length);
4865 printf (_(" Version: %d\n"), compunit.cu_version);
4866 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
4867 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
4868
4869 if (first_abbrev != NULL)
4870 free_abbrevs ();
4871
4872 /* Read in the abbrevs used by this compilation unit. */
4873
4874 {
4875 Elf32_Internal_Shdr * sec;
4876 unsigned char * begin;
4877
4878 /* Locate the .debug_abbrev section and process it. */
4879 for (i = 0, sec = section_headers;
4880 i < elf_header.e_shnum;
4881 i ++, sec ++)
4882 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
4883 break;
4884
4885 if (i == -1 || sec->sh_size == 0)
4886 {
4887 warn (_("Unable to locate .debug_abbrev section!\n"));
4888 return 0;
4889 }
4890
4891 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
4892 "debug_abbrev section data");
4893
4894 process_abbrev_section (begin + compunit.cu_abbrev_offset,
4895 begin + sec->sh_size);
4896
4897 free (begin);
4898 }
4899
4900 level = 0;
4901 while (tags < start)
4902 {
4903 int bytes_read;
4904 int abbrev_number;
4905 abbrev_entry * entry;
4906 abbrev_attr * attr;
4907
4908 abbrev_number = read_leb128 (tags, & bytes_read, 0);
4909 tags += bytes_read;
4910
4911 /* A null DIE marks the end of a list of children. */
4912 if (abbrev_number == 0)
4913 {
4914 --level;
4915 continue;
4916 }
4917
4918 /* Scan through the abbreviation list until we reach the
4919 correct entry. */
4920 for (entry = first_abbrev;
4921 entry && entry->entry != abbrev_number;
4922 entry = entry->next)
4923 continue;
4924
4925 if (entry == NULL)
4926 {
4927 warn (_("Unable to locate entry %d in the abbreviation table\n"),
4928 abbrev_number);
4929 return 0;
4930 }
4931
4932 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
4933 level, tags - section_begin - bytes_read,
4934 abbrev_number,
4935 get_TAG_name (entry->tag));
4936
4937 for (attr = entry->first_attr; attr; attr = attr->next)
4938 tags = read_and_display_attr (attr->attribute,
4939 attr->form,
4940 tags,
4941 compunit.cu_pointer_size);
4942
4943 if (entry->children)
4944 ++level;
4945 }
4946 }
4947
4948 printf ("\n");
4949
4950 return 1;
4951 }
4952
4953 static int
4954 display_debug_aranges (section, start, file)
4955 Elf32_Internal_Shdr * section;
4956 unsigned char * start;
4957 FILE * file;
4958 {
4959 unsigned char * end = start + section->sh_size;
4960
4961 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4962
4963 while (start < end)
4964 {
4965 DWARF2_External_ARange * external;
4966 DWARF2_Internal_ARange arange;
4967 unsigned char * ranges;
4968 unsigned long length;
4969 unsigned long address;
4970
4971 external = (DWARF2_External_ARange *) start;
4972
4973 arange.ar_length = BYTE_GET (external->ar_length);
4974 arange.ar_version = BYTE_GET (external->ar_version);
4975 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
4976 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
4977 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
4978
4979 printf (_(" Length: %ld\n"), arange.ar_length);
4980 printf (_(" Version: %d\n"), arange.ar_version);
4981 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
4982 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
4983 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
4984
4985 printf (_("\n Address Length\n"));
4986
4987 ranges = start + sizeof (* external);
4988
4989 for (;;)
4990 {
4991 address = byte_get (ranges, arange.ar_pointer_size);
4992
4993 if (address == 0)
4994 break;
4995
4996 ranges += arange.ar_pointer_size;
4997
4998 length = byte_get (ranges, arange.ar_pointer_size);
4999
5000 ranges += arange.ar_pointer_size;
5001
5002 printf (" %8.8lx %lu\n", address, length);
5003 }
5004
5005 start += arange.ar_length + sizeof (external->ar_length);
5006 }
5007
5008 printf ("\n");
5009
5010 return 1;
5011 }
5012
5013
5014 static int
5015 display_debug_not_supported (section, start, file)
5016 Elf32_Internal_Shdr * section;
5017 unsigned char * start;
5018 FILE * file;
5019 {
5020 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5021 SECTION_NAME (section));
5022
5023 return 1;
5024 }
5025
5026 /* A structure containing the name of a debug section and a pointer
5027 to a function that can decode it. */
5028 struct
5029 {
5030 char * name;
5031 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5032 }
5033 debug_displays[] =
5034 {
5035 { ".debug_info", display_debug_info },
5036 { ".debug_abbrev", display_debug_abbrev },
5037 { ".debug_line", display_debug_lines },
5038 { ".debug_aranges", display_debug_aranges },
5039 { ".debug_pubnames", display_debug_pubnames },
5040 { ".debug_macinfo", display_debug_not_supported },
5041 { ".debug_frame", display_debug_not_supported },
5042 { ".debug_str", display_debug_not_supported },
5043 { ".debug_static_func", display_debug_not_supported },
5044 { ".debug_static_vars", display_debug_not_supported },
5045 { ".debug_types", display_debug_not_supported },
5046 { ".debug_weaknames", display_debug_not_supported }
5047 };
5048
5049 static int
5050 display_debug_section (section, file)
5051 Elf32_Internal_Shdr * section;
5052 FILE * file;
5053 {
5054 char * name = SECTION_NAME (section);
5055 bfd_size_type length;
5056 unsigned char * start;
5057 int i;
5058
5059 length = section->sh_size;
5060 if (length == 0)
5061 {
5062 printf (_("\nSection '%s' has no debugging data.\n"), name);
5063 return 0;
5064 }
5065
5066 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5067 "debug section data");
5068
5069 /* See if we know how to display the contents of this section. */
5070 for (i = NUM_ELEM (debug_displays); i--;)
5071 if (strcmp (debug_displays[i].name, name) == 0)
5072 {
5073 debug_displays[i].display (section, start, file);
5074 break;
5075 }
5076
5077 if (i == -1)
5078 printf (_("Unrecognised debug section: %s\n"), name);
5079
5080 free (start);
5081
5082 /* If we loaded in the abbrev section at some point,
5083 we must release it here. */
5084 if (first_abbrev != NULL)
5085 free_abbrevs ();
5086
5087 return 1;
5088 }
5089
5090 static int
5091 process_section_contents (file)
5092 FILE * file;
5093 {
5094 Elf32_Internal_Shdr * section;
5095 unsigned int i;
5096
5097 if (! do_dump)
5098 return 1;
5099
5100 for (i = 0, section = section_headers;
5101 i < elf_header.e_shnum
5102 && i < num_dump_sects;
5103 i ++, section ++)
5104 {
5105 #ifdef SUPPORT_DISASSEMBLY
5106 if (dump_sects[i] & DISASS_DUMP)
5107 disassemble_section (section, file);
5108 #endif
5109 if (dump_sects[i] & HEX_DUMP)
5110 dump_section (section, file);
5111
5112 if (dump_sects[i] & DEBUG_DUMP)
5113 display_debug_section (section, file);
5114 }
5115
5116 if (i < num_dump_sects)
5117 warn (_("Some sections were not dumped because they do not exist!\n"));
5118
5119 return 1;
5120 }
5121
5122 static void
5123 process_mips_fpe_exception (mask)
5124 int mask;
5125 {
5126 if (mask)
5127 {
5128 int first = 1;
5129 if (mask & OEX_FPU_INEX)
5130 fputs ("INEX", stdout), first = 0;
5131 if (mask & OEX_FPU_UFLO)
5132 printf ("%sUFLO", first ? "" : "|"), first = 0;
5133 if (mask & OEX_FPU_OFLO)
5134 printf ("%sOFLO", first ? "" : "|"), first = 0;
5135 if (mask & OEX_FPU_DIV0)
5136 printf ("%sDIV0", first ? "" : "|"), first = 0;
5137 if (mask & OEX_FPU_INVAL)
5138 printf ("%sINVAL", first ? "" : "|");
5139 }
5140 else
5141 fputs ("0", stdout);
5142 }
5143
5144 static int
5145 process_mips_specific (file)
5146 FILE *file;
5147 {
5148 Elf_Internal_Dyn *entry;
5149 size_t liblist_offset = 0;
5150 size_t liblistno = 0;
5151 size_t conflictsno = 0;
5152 size_t options_offset = 0;
5153 size_t conflicts_offset = 0;
5154
5155 /* We have a lot of special sections. Thanks SGI! */
5156 if (dynamic_segment == NULL)
5157 /* No information available. */
5158 return 0;
5159
5160 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5161 switch (entry->d_tag)
5162 {
5163 case DT_MIPS_LIBLIST:
5164 liblist_offset = entry->d_un.d_val - loadaddr;
5165 break;
5166 case DT_MIPS_LIBLISTNO:
5167 liblistno = entry->d_un.d_val;
5168 break;
5169 case DT_MIPS_OPTIONS:
5170 options_offset = entry->d_un.d_val - loadaddr;
5171 break;
5172 case DT_MIPS_CONFLICT:
5173 conflicts_offset = entry->d_un.d_val - loadaddr;
5174 break;
5175 case DT_MIPS_CONFLICTNO:
5176 conflictsno = entry->d_un.d_val;
5177 break;
5178 default:
5179 break;
5180 }
5181
5182 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5183 {
5184 Elf32_External_Lib *elib;
5185 size_t cnt;
5186
5187 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5188 elib, Elf32_External_Lib *, "liblist");
5189
5190 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5191 fputs (" Library Time Stamp Checksum Version Flags\n",
5192 stdout);
5193
5194 for (cnt = 0; cnt < liblistno; ++cnt)
5195 {
5196 Elf32_Lib liblist;
5197 time_t time;
5198 char timebuf[20];
5199
5200 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5201 time = BYTE_GET (elib[cnt].l_time_stamp);
5202 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5203 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5204 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5205
5206 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5207
5208 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5209 dynamic_strings + liblist.l_name, timebuf,
5210 liblist.l_checksum, liblist.l_version);
5211
5212 if (liblist.l_flags == 0)
5213 puts (" NONE");
5214 else
5215 {
5216 static const struct
5217 {
5218 const char *name;
5219 int bit;
5220 } l_flags_vals[] =
5221 {
5222 { " EXACT_MATCH", LL_EXACT_MATCH },
5223 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5224 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5225 { " EXPORTS", LL_EXPORTS },
5226 { " DELAY_LOAD", LL_DELAY_LOAD },
5227 { " DELTA", LL_DELTA }
5228 };
5229 int flags = liblist.l_flags;
5230 int fcnt;
5231
5232 for (fcnt = 0;
5233 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5234 ++fcnt)
5235 if ((flags & l_flags_vals[fcnt].bit) != 0)
5236 {
5237 fputs (l_flags_vals[fcnt].name, stdout);
5238 flags ^= l_flags_vals[fcnt].bit;
5239 }
5240 if (flags != 0)
5241 printf (" %#x", (unsigned int) flags);
5242
5243 puts ("");
5244 }
5245 }
5246
5247 free (elib);
5248 }
5249
5250 if (options_offset != 0)
5251 {
5252 Elf_External_Options *eopt;
5253 Elf_Internal_Shdr *sect = section_headers;
5254 Elf_Internal_Options *iopt;
5255 Elf_Internal_Options *option;
5256 size_t offset;
5257 int cnt;
5258
5259 /* Find the section header so that we get the size. */
5260 while (sect->sh_type != SHT_MIPS_OPTIONS)
5261 ++sect;
5262
5263 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5264 Elf_External_Options *, "options");
5265
5266 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5267 * sizeof (*iopt));
5268 if (iopt == NULL)
5269 {
5270 error (_("Out of memory"));
5271 return 0;
5272 }
5273
5274 offset = cnt = 0;
5275 option = iopt;
5276 while (offset < sect->sh_size)
5277 {
5278 Elf_External_Options *eoption;
5279
5280 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5281
5282 option->kind = BYTE_GET (eoption->kind);
5283 option->size = BYTE_GET (eoption->size);
5284 option->section = BYTE_GET (eoption->section);
5285 option->info = BYTE_GET (eoption->info);
5286
5287 offset += option->size;
5288 ++option;
5289 ++cnt;
5290 }
5291
5292 printf (_("\nSection '%s' contains %d entries:\n"),
5293 string_table + sect->sh_name, cnt);
5294
5295 option = iopt;
5296 while (cnt-- > 0)
5297 {
5298 size_t len;
5299
5300 switch (option->kind)
5301 {
5302 case ODK_NULL:
5303 /* This shouldn't happen. */
5304 printf (" NULL %d %lx", option->section, option->info);
5305 break;
5306 case ODK_REGINFO:
5307 printf (" REGINFO ");
5308 if (elf_header.e_machine == EM_MIPS)
5309 {
5310 /* 32bit form. */
5311 Elf32_External_RegInfo *ereg;
5312 Elf32_RegInfo reginfo;
5313
5314 ereg = (Elf32_External_RegInfo *) (option + 1);
5315 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5316 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5317 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5318 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5319 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5320 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5321
5322 printf ("GPR %08lx GP 0x%lx\n",
5323 reginfo.ri_gprmask,
5324 (unsigned long) reginfo.ri_gp_value);
5325 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5326 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5327 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5328 }
5329 else
5330 {
5331 /* 64 bit form. */
5332 Elf64_External_RegInfo *ereg;
5333 Elf64_Internal_RegInfo reginfo;
5334
5335 ereg = (Elf64_External_RegInfo *) (option + 1);
5336 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5337 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5338 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5339 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5340 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5341 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5342
5343 printf ("GPR %08lx GP 0x",
5344 reginfo.ri_gprmask);
5345 printf_vma (reginfo.ri_gp_value);
5346 printf ("\n");
5347
5348 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5349 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5350 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5351 }
5352 ++option;
5353 continue;
5354 case ODK_EXCEPTIONS:
5355 fputs (" EXCEPTIONS fpe_min(", stdout);
5356 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
5357 fputs (") fpe_max(", stdout);
5358 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
5359 fputs (")", stdout);
5360
5361 if (option->info & OEX_PAGE0)
5362 fputs (" PAGE0", stdout);
5363 if (option->info & OEX_SMM)
5364 fputs (" SMM", stdout);
5365 if (option->info & OEX_FPDBUG)
5366 fputs (" FPDBUG", stdout);
5367 if (option->info & OEX_DISMISS)
5368 fputs (" DISMISS", stdout);
5369 break;
5370 case ODK_PAD:
5371 fputs (" PAD ", stdout);
5372 if (option->info & OPAD_PREFIX)
5373 fputs (" PREFIX", stdout);
5374 if (option->info & OPAD_POSTFIX)
5375 fputs (" POSTFIX", stdout);
5376 if (option->info & OPAD_SYMBOL)
5377 fputs (" SYMBOL", stdout);
5378 break;
5379 case ODK_HWPATCH:
5380 fputs (" HWPATCH ", stdout);
5381 if (option->info & OHW_R4KEOP)
5382 fputs (" R4KEOP", stdout);
5383 if (option->info & OHW_R8KPFETCH)
5384 fputs (" R8KPFETCH", stdout);
5385 if (option->info & OHW_R5KEOP)
5386 fputs (" R5KEOP", stdout);
5387 if (option->info & OHW_R5KCVTL)
5388 fputs (" R5KCVTL", stdout);
5389 break;
5390 case ODK_FILL:
5391 fputs (" FILL ", stdout);
5392 /* XXX Print content of info word? */
5393 break;
5394 case ODK_TAGS:
5395 fputs (" TAGS ", stdout);
5396 /* XXX Print content of info word? */
5397 break;
5398 case ODK_HWAND:
5399 fputs (" HWAND ", stdout);
5400 if (option->info & OHWA0_R4KEOP_CHECKED)
5401 fputs (" R4KEOP_CHECKED", stdout);
5402 if (option->info & OHWA0_R4KEOP_CLEAN)
5403 fputs (" R4KEOP_CLEAN", stdout);
5404 break;
5405 case ODK_HWOR:
5406 fputs (" HWOR ", stdout);
5407 if (option->info & OHWA0_R4KEOP_CHECKED)
5408 fputs (" R4KEOP_CHECKED", stdout);
5409 if (option->info & OHWA0_R4KEOP_CLEAN)
5410 fputs (" R4KEOP_CLEAN", stdout);
5411 break;
5412 case ODK_GP_GROUP:
5413 printf (" GP_GROUP %#06lx self-contained %#06lx",
5414 option->info & OGP_GROUP,
5415 (option->info & OGP_SELF) >> 16);
5416 break;
5417 case ODK_IDENT:
5418 printf (" IDENT %#06lx self-contained %#06lx",
5419 option->info & OGP_GROUP,
5420 (option->info & OGP_SELF) >> 16);
5421 break;
5422 default:
5423 /* This shouldn't happen. */
5424 printf (" %3d ??? %d %lx",
5425 option->kind, option->section, option->info);
5426 break;
5427 }
5428
5429 len = sizeof (*eopt);
5430 while (len < option->size)
5431 if (((char *) option)[len] >= ' '
5432 && ((char *) option)[len] < 0x7f)
5433 printf ("%c", ((char *) option)[len++]);
5434 else
5435 printf ("\\%03o", ((char *) option)[len++]);
5436
5437 fputs ("\n", stdout);
5438 ++option;
5439 }
5440
5441 free (eopt);
5442 }
5443
5444 if (conflicts_offset != 0 && conflictsno != 0)
5445 {
5446 Elf32_External_Conflict *econf32;
5447 Elf64_External_Conflict *econf64;
5448 Elf32_Conflict *iconf;
5449 size_t cnt;
5450
5451 if (dynamic_symbols == NULL)
5452 {
5453 error (_("conflict list with without table"));
5454 return 0;
5455 }
5456
5457 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
5458 if (iconf == NULL)
5459 {
5460 error (_("Out of memory"));
5461 return 0;
5462 }
5463
5464 if (binary_class == ELFCLASS32)
5465 {
5466 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
5467 econf32, Elf32_External_Conflict *, "conflict");
5468
5469 for (cnt = 0; cnt < conflictsno; ++cnt)
5470 iconf[cnt] = BYTE_GET (econf32[cnt]);
5471 }
5472 else
5473 {
5474 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
5475 econf64, Elf64_External_Conflict *, "conflict");
5476
5477 for (cnt = 0; cnt < conflictsno; ++cnt)
5478 iconf[cnt] = BYTE_GET (econf64[cnt]);
5479 }
5480
5481 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
5482 puts (_(" Num: Index Value Name"));
5483
5484 for (cnt = 0; cnt < conflictsno; ++cnt)
5485 {
5486 Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
5487
5488 printf ("%5u: %8lu %#10lx %s\n",
5489 cnt, iconf[cnt], (unsigned long) psym->st_value,
5490 dynamic_strings + psym->st_name);
5491 }
5492
5493
5494 free (iconf);
5495 }
5496
5497 return 1;
5498 }
5499
5500 static int
5501 process_arch_specific (file)
5502 FILE *file;
5503 {
5504 switch (elf_header.e_machine)
5505 {
5506 case EM_MIPS:
5507 case EM_MIPS_RS4_BE:
5508 return process_mips_specific (file);
5509 break;
5510 default:
5511 break;
5512 }
5513 return 1;
5514 }
5515
5516 static int
5517 get_file_header (file)
5518 FILE * file;
5519 {
5520 Elf32_External_Ehdr ehdr;
5521
5522 if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
5523 return 0;
5524
5525 memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
5526
5527 if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
5528 byte_get = byte_get_little_endian;
5529 else
5530 byte_get = byte_get_big_endian;
5531
5532 elf_header.e_entry = BYTE_GET (ehdr.e_entry);
5533 elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
5534 elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
5535 elf_header.e_version = BYTE_GET (ehdr.e_version);
5536 elf_header.e_flags = BYTE_GET (ehdr.e_flags);
5537 elf_header.e_type = BYTE_GET (ehdr.e_type);
5538 elf_header.e_machine = BYTE_GET (ehdr.e_machine);
5539 elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
5540 elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
5541 elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
5542 elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
5543 elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
5544 elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
5545
5546 return 1;
5547 }
5548
5549 static void
5550 process_file (file_name)
5551 char * file_name;
5552 {
5553 FILE * file;
5554 struct stat statbuf;
5555 unsigned int i;
5556
5557 if (stat (file_name, & statbuf) < 0)
5558 {
5559 error (_("Cannot stat input file %s.\n"), file_name);
5560 return;
5561 }
5562
5563 file = fopen (file_name, "rb");
5564 if (file == NULL)
5565 {
5566 error (_("Input file %s not found.\n"), file_name);
5567 return;
5568 }
5569
5570 if (! get_file_header (file))
5571 {
5572 error (_("%s: Failed to read file header\n"), file_name);
5573 fclose (file);
5574 return;
5575 }
5576
5577 /* Initialise per file variables. */
5578 for (i = NUM_ELEM (version_info); i--;)
5579 version_info[i] = 0;
5580
5581 for (i = NUM_ELEM (dynamic_info); i--;)
5582 dynamic_info[i] = 0;
5583
5584 /* Process the file. */
5585 if (show_name)
5586 printf (_("\nFile: %s\n"), file_name);
5587
5588 if (! process_file_header ())
5589 {
5590 fclose (file);
5591 return;
5592 }
5593
5594 process_section_headers (file);
5595
5596 process_program_headers (file);
5597
5598 process_dynamic_segment (file);
5599
5600 process_relocs (file);
5601
5602 process_symbol_table (file);
5603
5604 process_syminfo (file);
5605
5606 process_version_sections (file);
5607
5608 process_section_contents (file);
5609
5610 process_arch_specific (file);
5611
5612 fclose (file);
5613
5614 if (section_headers)
5615 {
5616 free (section_headers);
5617 section_headers = NULL;
5618 }
5619
5620 if (string_table)
5621 {
5622 free (string_table);
5623 string_table = NULL;
5624 }
5625
5626 if (dynamic_strings)
5627 {
5628 free (dynamic_strings);
5629 dynamic_strings = NULL;
5630 }
5631
5632 if (dynamic_symbols)
5633 {
5634 free (dynamic_symbols);
5635 dynamic_symbols = NULL;
5636 }
5637
5638 if (dynamic_syminfo)
5639 {
5640 free (dynamic_syminfo);
5641 dynamic_syminfo = NULL;
5642 }
5643 }
5644
5645 #ifdef SUPPORT_DISASSEMBLY
5646 /* Needed by the i386 disassembler. For extra credit, someone could
5647 fix this so that we insert symbolic addresses here, esp for GOT/PLT
5648 symbols */
5649
5650 void
5651 print_address (unsigned int addr, FILE * outfile)
5652 {
5653 fprintf (outfile,"0x%8.8x", addr);
5654 }
5655
5656 /* Needed by the i386 disassembler. */
5657 void
5658 db_task_printsym (unsigned int addr)
5659 {
5660 print_address (addr, stderr);
5661 }
5662 #endif
5663
5664 int
5665 main (argc, argv)
5666 int argc;
5667 char ** argv;
5668 {
5669 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5670 setlocale (LC_MESSAGES, "");
5671 #endif
5672 bindtextdomain (PACKAGE, LOCALEDIR);
5673 textdomain (PACKAGE);
5674
5675 parse_args (argc, argv);
5676
5677 if (optind < (argc - 1))
5678 show_name = 1;
5679
5680 while (optind < argc)
5681 process_file (argv [optind ++]);
5682
5683 if (dump_sects != NULL)
5684 free (dump_sects);
5685
5686 return 0;
5687 }