* gas/i386/amd.s: Add a symbol so a.out tests will work.
[binutils.git] / binutils / readelf.c
blob4edb22a3f73b6c27fc2455616cd26232cae65c96
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@cygnus.com>
7 This file is part of GNU Binutils.
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.
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.
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. */
25 #include <assert.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <time.h>
30 /* Define BFD64 here, even if our default architecture is 32 bit ELF
31 as this will allow us to read in and parse 64bit and 32bit ELF files. */
32 #define BFD64
33 #include "bfd.h"
35 #include "elf/common.h"
36 #include "elf/external.h"
37 #include "elf/internal.h"
38 #include "elf/dwarf2.h"
40 /* The following headers use the elf/reloc-macros.h file to
41 automatically generate relocation recognition functions
42 such as elf_mips_reloc_type() */
44 #define RELOC_MACROS_GEN_FUNC
46 #include "elf/i386.h"
47 #include "elf/v850.h"
48 #include "elf/ppc.h"
49 #include "elf/mips.h"
50 #include "elf/alpha.h"
51 #include "elf/arm.h"
52 #include "elf/m68k.h"
53 #include "elf/sparc.h"
54 #include "elf/m32r.h"
55 #include "elf/d10v.h"
56 #include "elf/d30v.h"
57 #include "elf/sh.h"
58 #include "elf/mn10200.h"
59 #include "elf/mn10300.h"
60 #include "elf/hppa.h"
61 #include "elf/arc.h"
62 #include "elf/fr30.h"
63 #include "elf/mcore.h"
64 #include "elf/i960.h"
66 #include "bucomm.h"
67 #include "getopt.h"
69 #ifdef ANSI_PROTOTYPES
70 #include <stdarg.h>
71 #else
72 #include <varargs.h>
73 #endif
75 char * program_name = "readelf";
76 unsigned int dynamic_addr;
77 bfd_size_type dynamic_size;
78 unsigned int rela_addr;
79 unsigned int rela_size;
80 char * dynamic_strings;
81 char * string_table;
82 unsigned long num_dynamic_syms;
83 Elf_Internal_Sym * dynamic_symbols;
84 Elf_Internal_Syminfo * dynamic_syminfo;
85 unsigned long dynamic_syminfo_offset;
86 unsigned int dynamic_syminfo_nent;
87 char program_interpreter [64];
88 int dynamic_info[DT_JMPREL + 1];
89 int version_info[16];
90 int loadaddr = 0;
91 Elf_Internal_Ehdr elf_header;
92 Elf_Internal_Shdr * section_headers;
93 Elf_Internal_Dyn * dynamic_segment;
94 int show_name;
95 int do_dynamic;
96 int do_syms;
97 int do_reloc;
98 int do_sections;
99 int do_segments;
100 int do_using_dynamic;
101 int do_header;
102 int do_dump;
103 int do_version;
104 int do_histogram;
105 int do_debugging;
106 int do_debug_info;
107 int do_debug_abbrevs;
108 int do_debug_lines;
109 int do_debug_pubnames;
110 int do_debug_aranges;
111 int is_32bit_elf;
113 /* A dynamic array of flags indicating which sections require dumping. */
114 char * dump_sects = NULL;
115 unsigned int num_dump_sects = 0;
117 #define HEX_DUMP (1 << 0)
118 #define DISASS_DUMP (1 << 1)
119 #define DEBUG_DUMP (1 << 2)
121 /* Forward declarations for dumb compilers. */
122 static bfd_vma (* byte_get) PARAMS ((unsigned char *, int));
123 static bfd_vma byte_get_little_endian PARAMS ((unsigned char *, int));
124 static bfd_vma byte_get_big_endian PARAMS ((unsigned char *, int));
125 static const char * get_mips_dynamic_type PARAMS ((unsigned long));
126 static const char * get_dynamic_type PARAMS ((unsigned long));
127 static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
128 static char * get_file_type PARAMS ((unsigned));
129 static char * get_machine_name PARAMS ((unsigned));
130 static char * get_machine_flags PARAMS ((unsigned, unsigned));
131 static const char * get_mips_segment_type PARAMS ((unsigned long));
132 static const char * get_segment_type PARAMS ((unsigned long));
133 static const char * get_mips_section_type_name PARAMS ((unsigned int));
134 static const char * get_section_type_name PARAMS ((unsigned int));
135 static char * get_symbol_binding PARAMS ((unsigned int));
136 static char * get_symbol_type PARAMS ((unsigned int));
137 static void usage PARAMS ((void));
138 static void parse_args PARAMS ((int, char **));
139 static int process_file_header PARAMS ((void));
140 static int process_program_headers PARAMS ((FILE *));
141 static int process_section_headers PARAMS ((FILE *));
142 static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *));
143 static int process_dynamic_segment PARAMS ((FILE *));
144 static int process_symbol_table PARAMS ((FILE *));
145 static int process_section_contents PARAMS ((FILE *));
146 static void process_file PARAMS ((char *));
147 static int process_relocs PARAMS ((FILE *));
148 static int process_version_sections PARAMS ((FILE *));
149 static char * get_ver_flags PARAMS ((unsigned int));
150 static char * get_symbol_index_type PARAMS ((unsigned int));
151 static int get_32bit_section_headers PARAMS ((FILE *));
152 static int get_64bit_section_headers PARAMS ((FILE *));
153 static int get_32bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
154 static int get_64bit_program_headers PARAMS ((FILE *, Elf_Internal_Phdr *));
155 static int get_file_header PARAMS ((FILE *));
156 static Elf_Internal_Sym * get_32bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));
157 static Elf_Internal_Sym * get_64bit_elf_symbols PARAMS ((FILE *, unsigned long, unsigned long));
158 static int * get_dynamic_data PARAMS ((FILE *, unsigned int));
159 static int get_32bit_dynamic_segment PARAMS ((FILE *));
160 static int get_64bit_dynamic_segment PARAMS ((FILE *));
161 #ifdef SUPPORT_DISASSEMBLY
162 static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
163 #endif
164 static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
165 static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
166 static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
167 static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
168 static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
169 static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
170 static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
171 static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
172 static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
173 static int process_extended_line_op PARAMS ((unsigned char *, int));
174 static void reset_state_machine PARAMS ((int));
175 static char * get_TAG_name PARAMS ((unsigned long));
176 static char * get_AT_name PARAMS ((unsigned long));
177 static char * get_FORM_name PARAMS ((unsigned long));
178 static void free_abbrevs PARAMS ((void));
179 static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
180 static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
181 static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
182 static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
183 static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
184 static void request_dump PARAMS ((unsigned int, char));
185 static const char * get_elf_class PARAMS ((unsigned char));
186 static const char * get_data_encoding PARAMS ((unsigned char));
187 static const char * get_osabi_name PARAMS ((unsigned char));
188 static int guess_is_rela PARAMS ((unsigned long));
190 typedef int Elf32_Word;
192 #ifndef TRUE
193 #define TRUE 1
194 #define FALSE 0
195 #endif
196 #define UNKNOWN -1
198 #define SECTION_NAME(X) (string_table + (X)->sh_name)
200 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
202 #define BYTE_GET(field) byte_get (field, sizeof (field))
203 #define BYTE_GET8(field) byte_get (field, -8)
205 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
207 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
208 if (fseek (file, offset, SEEK_SET)) \
210 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
211 return 0; \
214 var = (type) malloc (size); \
216 if (var == NULL) \
218 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
219 return 0; \
222 if (fread (var, size, 1, file) != 1) \
224 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
225 free (var); \
226 var = NULL; \
227 return 0; \
231 #define GET_DATA(offset, var, reason) \
232 if (fseek (file, offset, SEEK_SET)) \
234 error (_("Unable to seek to %x for %s\n"), offset, reason); \
235 return 0; \
237 else if (fread (& var, sizeof (var), 1, file) != 1) \
239 error (_("Unable to read data at %x for %s\n"), offset, reason); \
240 return 0; \
243 #define GET_ELF_SYMBOLS(file, offset, size) \
244 (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size) \
245 : get_64bit_elf_symbols (file, offset, size))
248 #ifdef ANSI_PROTOTYPES
249 static void
250 error (const char * message, ...)
252 va_list args;
254 fprintf (stderr, _("%s: Error: "), program_name);
255 va_start (args, message);
256 vfprintf (stderr, message, args);
257 va_end (args);
258 return;
261 static void
262 warn (const char * message, ...)
264 va_list args;
266 fprintf (stderr, _("%s: Warning: "), program_name);
267 va_start (args, message);
268 vfprintf (stderr, message, args);
269 va_end (args);
270 return;
272 #else
273 static void
274 error (va_alist)
275 va_dcl
277 char * message;
278 va_list args;
280 fprintf (stderr, _("%s: Error: "), program_name);
281 va_start (args);
282 message = va_arg (args, char *);
283 vfprintf (stderr, message, args);
284 va_end (args);
285 return;
288 static void
289 warn (va_alist)
290 va_dcl
292 char * message;
293 va_list args;
295 fprintf (stderr, _("%s: Warning: "), program_name);
296 va_start (args);
297 message = va_arg (args, char *);
298 vfprintf (stderr, message, args);
299 va_end (args);
300 return;
302 #endif
304 static bfd_vma
305 byte_get_little_endian (field, size)
306 unsigned char * field;
307 int size;
309 switch (size)
311 case 1:
312 return * field;
314 case 2:
315 return ((unsigned int) (field [0]))
316 | (((unsigned int) (field [1])) << 8);
318 case 8:
319 /* We want to extract data from an 8 byte wide field and
320 place it into a 4 byte wide field. Since this is a little
321 endian source we can juts use the 4 byte extraction code. */
322 /* Fall through. */
323 case 4:
324 return ((unsigned long) (field [0]))
325 | (((unsigned long) (field [1])) << 8)
326 | (((unsigned long) (field [2])) << 16)
327 | (((unsigned long) (field [3])) << 24);
329 case -8:
330 /* This is a special case, generated by the BYTE_GET8 macro.
331 It means that we are loading an 8 byte value from a field
332 in an external structure into an 8 byte value in a field
333 in an internal strcuture. */
334 return ((bfd_vma) (field [0]))
335 | (((bfd_vma) (field [1])) << 8)
336 | (((bfd_vma) (field [2])) << 16)
337 | (((bfd_vma) (field [3])) << 24)
338 | (((bfd_vma) (field [4])) << 32)
339 | (((bfd_vma) (field [5])) << 40)
340 | (((bfd_vma) (field [6])) << 48)
341 | (((bfd_vma) (field [7])) << 56);
343 default:
344 error (_("Unhandled data length: %d\n"), size);
345 abort ();
349 static bfd_vma
350 byte_get_big_endian (field, size)
351 unsigned char * field;
352 int size;
354 switch (size)
356 case 1:
357 return * field;
359 case 2:
360 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
362 case 4:
363 return ((unsigned long) (field [3]))
364 | (((unsigned long) (field [2])) << 8)
365 | (((unsigned long) (field [1])) << 16)
366 | (((unsigned long) (field [0])) << 24);
368 case 8:
369 /* Although we are extracing data from an 8 byte wide field, we
370 are returning only 4 bytes of data. */
371 return ((unsigned long) (field [7]))
372 | (((unsigned long) (field [6])) << 8)
373 | (((unsigned long) (field [5])) << 16)
374 | (((unsigned long) (field [4])) << 24);
376 case -8:
377 /* This is a special case, generated by the BYTE_GET8 macro.
378 It means that we are loading an 8 byte value from a field
379 in an external structure into an 8 byte value in a field
380 in an internal strcuture. */
381 return ((bfd_vma) (field [7]))
382 | (((bfd_vma) (field [6])) << 8)
383 | (((bfd_vma) (field [5])) << 16)
384 | (((bfd_vma) (field [4])) << 24)
385 | (((bfd_vma) (field [3])) << 32)
386 | (((bfd_vma) (field [2])) << 40)
387 | (((bfd_vma) (field [1])) << 48)
388 | (((bfd_vma) (field [0])) << 56);
390 default:
391 error (_("Unhandled data length: %d\n"), size);
392 abort ();
397 /* Guess the relocation sized based on the sized commonly used by the specific machine. */
398 static int
399 guess_is_rela (e_machine)
400 unsigned long e_machine;
402 switch (e_machine)
404 /* Targets that use REL relocations. */
405 case EM_ARM:
406 case EM_386:
407 case EM_486:
408 case EM_960:
409 case EM_CYGNUS_M32R:
410 case EM_CYGNUS_D10V:
411 case EM_MIPS:
412 case EM_MIPS_RS4_BE:
413 return FALSE;
415 /* Targets that use RELA relocations. */
416 case EM_68K:
417 case EM_SPARC:
418 case EM_PPC:
419 case EM_CYGNUS_V850:
420 case EM_CYGNUS_D30V:
421 case EM_CYGNUS_MN10200:
422 case EM_CYGNUS_MN10300:
423 case EM_CYGNUS_FR30:
424 case EM_SH:
425 case EM_ALPHA:
426 case EM_MCORE:
427 return TRUE;
429 default:
430 warn (_("Don't know about relocations on this machine architecture\n"));
431 return FALSE;
435 /* Display the contents of the relocation data found at the specified offset. */
436 static int
437 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
438 FILE * file;
439 unsigned long rel_offset;
440 unsigned long rel_size;
441 Elf_Internal_Sym * symtab;
442 unsigned long nsyms;
443 char * strtab;
444 int is_rela;
446 unsigned int i;
447 Elf_Internal_Rel * rels;
448 Elf_Internal_Rela * relas;
451 if (is_rela == UNKNOWN)
452 is_rela = guess_is_rela (elf_header.e_machine);
454 if (is_rela)
456 if (is_32bit_elf)
458 Elf32_External_Rela * erelas;
460 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
461 Elf32_External_Rela *, "relocs");
463 rel_size = rel_size / sizeof (Elf32_External_Rela);
465 relas = (Elf_Internal_Rela *)
466 malloc (rel_size * sizeof (Elf_Internal_Rela));
468 if (relas == NULL)
470 error(_("out of memory parsing relocs"));
471 return 0;
474 for (i = 0; i < rel_size; i++)
476 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
477 relas[i].r_info = BYTE_GET (erelas[i].r_info);
478 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
481 free (erelas);
483 rels = (Elf_Internal_Rel *) relas;
485 else
487 Elf64_External_Rela * erelas;
489 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
490 Elf64_External_Rela *, "relocs");
492 rel_size = rel_size / sizeof (Elf64_External_Rela);
494 relas = (Elf_Internal_Rela *)
495 malloc (rel_size * sizeof (Elf_Internal_Rela));
497 if (relas == NULL)
499 error(_("out of memory parsing relocs"));
500 return 0;
503 for (i = 0; i < rel_size; i++)
505 relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
506 relas[i].r_info = BYTE_GET8 (erelas[i].r_info);
507 relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
510 free (erelas);
512 rels = (Elf_Internal_Rel *) relas;
515 else
517 if (is_32bit_elf)
519 Elf32_External_Rel * erels;
521 GET_DATA_ALLOC (rel_offset, rel_size, erels,
522 Elf32_External_Rel *, "relocs");
524 rel_size = rel_size / sizeof (Elf32_External_Rel);
526 rels = (Elf_Internal_Rel *)
527 malloc (rel_size * sizeof (Elf_Internal_Rel));
529 if (rels == NULL)
531 error(_("out of memory parsing relocs"));
532 return 0;
535 for (i = 0; i < rel_size; i++)
537 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
538 rels[i].r_info = BYTE_GET (erels[i].r_info);
541 free (erels);
543 relas = (Elf_Internal_Rela *) rels;
545 else
547 Elf64_External_Rel * erels;
549 GET_DATA_ALLOC (rel_offset, rel_size, erels,
550 Elf64_External_Rel *, "relocs");
552 rel_size = rel_size / sizeof (Elf64_External_Rel);
554 rels = (Elf_Internal_Rel *)
555 malloc (rel_size * sizeof (Elf_Internal_Rel));
557 if (rels == NULL)
559 error(_("out of memory parsing relocs"));
560 return 0;
563 for (i = 0; i < rel_size; i++)
565 rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
566 rels[i].r_info = BYTE_GET8 (erels[i].r_info);
569 free (erels);
571 relas = (Elf_Internal_Rela *) rels;
575 if (is_rela)
576 printf
577 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
578 else
579 printf
580 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
582 for (i = 0; i < rel_size; i++)
584 const char * rtype;
585 bfd_vma offset;
586 bfd_vma info;
587 bfd_vma symtab_index;
588 bfd_vma type;
590 if (is_rela)
592 offset = relas [i].r_offset;
593 info = relas [i].r_info;
595 else
597 offset = rels [i].r_offset;
598 info = rels [i].r_info;
601 if (is_32bit_elf)
603 type = ELF32_R_TYPE (info);
604 symtab_index = ELF32_R_SYM (info);
606 else
608 type = ELF64_R_TYPE (info);
609 symtab_index = ELF64_R_SYM (info);
612 #ifdef _bfd_int64_low
613 printf (" %8.8lx %5.5lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
614 #else
615 printf (" %8.8lx %5.5lx ", offset, info);
616 #endif
618 switch (elf_header.e_machine)
620 default:
621 rtype = NULL;
622 break;
624 case EM_CYGNUS_M32R:
625 rtype = elf_m32r_reloc_type (type);
626 break;
628 case EM_386:
629 case EM_486:
630 rtype = elf_i386_reloc_type (type);
631 break;
633 case EM_68K:
634 rtype = elf_m68k_reloc_type (type);
635 break;
637 case EM_960:
638 rtype = elf_i960_reloc_type (type);
639 break;
641 case EM_OLD_SPARCV9:
642 case EM_SPARC32PLUS:
643 case EM_SPARCV9:
644 case EM_SPARC:
645 rtype = elf_sparc_reloc_type (type);
646 break;
648 case EM_CYGNUS_V850:
649 rtype = v850_reloc_type (type);
650 break;
652 case EM_CYGNUS_D10V:
653 rtype = elf_d10v_reloc_type (type);
654 break;
656 case EM_CYGNUS_D30V:
657 rtype = elf_d30v_reloc_type (type);
658 break;
660 case EM_SH:
661 rtype = elf_sh_reloc_type (type);
662 break;
664 case EM_CYGNUS_MN10300:
665 rtype = elf_mn10300_reloc_type (type);
666 break;
668 case EM_CYGNUS_MN10200:
669 rtype = elf_mn10200_reloc_type (type);
670 break;
672 case EM_CYGNUS_FR30:
673 rtype = elf_fr30_reloc_type (type);
674 break;
676 case EM_MCORE:
677 rtype = elf_mcore_reloc_type (type);
678 break;
680 case EM_PPC:
681 rtype = elf_ppc_reloc_type (type);
682 break;
684 case EM_MIPS:
685 case EM_MIPS_RS4_BE:
686 rtype = elf_mips_reloc_type (type);
687 break;
689 case EM_ALPHA:
690 rtype = elf_alpha_reloc_type (type);
691 break;
693 case EM_ARM:
694 rtype = elf_arm_reloc_type (type);
695 break;
697 case EM_CYGNUS_ARC:
698 rtype = elf_arc_reloc_type (type);
699 break;
701 case EM_PARISC:
702 rtype = elf32_hppa_reloc_type (type);
703 break;
706 if (rtype == NULL)
707 #ifdef _bfd_int64_low
708 printf (_("unrecognised: %-7lx"), _bfd_int64_low (type));
709 #else
710 printf (_("unrecognised: %-7lx"), type);
711 #endif
712 else
713 printf ("%-21.21s", rtype);
715 if (symtab_index)
717 if (symtab != NULL)
719 if (symtab_index >= nsyms)
720 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
721 else
723 Elf_Internal_Sym * psym;
725 psym = symtab + symtab_index;
727 printf (" %08lx ", (unsigned long) psym->st_value);
729 if (psym->st_name == 0)
730 printf ("%-25.25s",
731 SECTION_NAME (section_headers + psym->st_shndx));
732 else if (strtab == NULL)
733 printf (_("<string table index %3ld>"), psym->st_name);
734 else
735 printf ("%-25.25s", strtab + psym->st_name);
737 if (is_rela)
738 printf (" + %lx", (unsigned long) relas [i].r_addend);
742 else if (is_rela)
743 printf ("%34c%lx", ' ', (unsigned long) relas[i].r_addend);
745 putchar ('\n');
748 free (relas);
750 return 1;
753 static const char *
754 get_mips_dynamic_type (type)
755 unsigned long type;
757 switch (type)
759 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
760 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
761 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
762 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
763 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
764 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
765 case DT_MIPS_MSYM: return "MIPS_MSYM";
766 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
767 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
768 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
769 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
770 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
771 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
772 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
773 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
774 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
775 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
776 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
777 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
778 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
779 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
780 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
781 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
782 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
783 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
784 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
785 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
786 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
787 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
788 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
789 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
790 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
791 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
792 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
793 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
794 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
795 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
796 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
797 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
798 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
799 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
800 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
801 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
802 default:
803 return NULL;
807 static const char *
808 get_dynamic_type (type)
809 unsigned long type;
811 static char buff [32];
813 switch (type)
815 case DT_NULL: return "NULL";
816 case DT_NEEDED: return "NEEDED";
817 case DT_PLTRELSZ: return "PLTRELSZ";
818 case DT_PLTGOT: return "PLTGOT";
819 case DT_HASH: return "HASH";
820 case DT_STRTAB: return "STRTAB";
821 case DT_SYMTAB: return "SYMTAB";
822 case DT_RELA: return "RELA";
823 case DT_RELASZ: return "RELASZ";
824 case DT_RELAENT: return "RELAENT";
825 case DT_STRSZ: return "STRSZ";
826 case DT_SYMENT: return "SYMENT";
827 case DT_INIT: return "INIT";
828 case DT_FINI: return "FINI";
829 case DT_SONAME: return "SONAME";
830 case DT_RPATH: return "RPATH";
831 case DT_SYMBOLIC: return "SYMBOLIC";
832 case DT_REL: return "REL";
833 case DT_RELSZ: return "RELSZ";
834 case DT_RELENT: return "RELENT";
835 case DT_PLTREL: return "PLTREL";
836 case DT_DEBUG: return "DEBUG";
837 case DT_TEXTREL: return "TEXTREL";
838 case DT_JMPREL: return "JMPREL";
839 case DT_BIND_NOW: return "BIND_NOW";
840 case DT_INIT_ARRAY: return "INIT_ARRAY";
841 case DT_FINI_ARRAY: return "FINI_ARRAY";
842 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
843 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
845 case DT_PLTPADSZ: return "PLTPADSZ";
846 case DT_MOVEENT: return "MOVEENT";
847 case DT_MOVESZ: return "MOVESZ";
848 case DT_FEATURE_1: return "FEATURE_1";
849 case DT_POSFLAG_1: return "POSFLAG_1";
850 case DT_SYMINSZ: return "SYMINSZ";
851 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
853 case DT_ADDRRNGLO: return "ADDRRNGLO";
854 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
856 case DT_VERSYM: return "VERSYM";
858 case DT_RELACOUNT: return "RELACOUNT";
859 case DT_RELCOUNT: return "RELCOUNT";
860 case DT_FLAGS_1: return "FLAGS_1";
861 case DT_VERDEF: return "VERDEF";
862 case DT_VERDEFNUM: return "VERDEFNUM";
863 case DT_VERNEED: return "VERNEED";
864 case DT_VERNEEDNUM: return "VERNEEDNUM";
866 case DT_AUXILIARY: return "AUXILARY";
867 case DT_USED: return "USED";
868 case DT_FILTER: return "FILTER";
870 default:
871 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
873 const char * result;
875 switch (elf_header.e_machine)
877 case EM_MIPS:
878 case EM_MIPS_RS4_BE:
879 result = get_mips_dynamic_type (type);
880 break;
881 default:
882 result = NULL;
883 break;
886 if (result != NULL)
887 return result;
889 sprintf (buff, _("Processor Specific: %lx"), type);
891 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
892 sprintf (buff, _("Operating System specific: %lx"), type);
893 else
894 sprintf (buff, _("<unknown>: %lx"), type);
896 return buff;
900 static char *
901 get_file_type (e_type)
902 unsigned e_type;
904 static char buff [32];
906 switch (e_type)
908 case ET_NONE: return _("NONE (None)");
909 case ET_REL: return _("REL (Relocatable file)");
910 case ET_EXEC: return _("EXEC (Executable file)");
911 case ET_DYN: return _("DYN (Shared object file)");
912 case ET_CORE: return _("CORE (Core file)");
914 default:
915 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
916 sprintf (buff, _("Processor Specific: (%x)"), e_type);
917 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
918 sprintf (buff, _("OS Specific: (%x)"), e_type);
919 else
920 sprintf (buff, _("<unknown>: %x"), e_type);
921 return buff;
925 static char *
926 get_machine_name (e_machine)
927 unsigned e_machine;
929 static char buff [32];
931 switch (e_machine)
933 case EM_NONE: return _("None");
934 case EM_M32: return "WE32100";
935 case EM_SPARC: return "Sparc";
936 case EM_386: return "Intel 80386";
937 case EM_68K: return "MC68000";
938 case EM_88K: return "MC88000";
939 case EM_486: return "Intel 80486";
940 case EM_860: return "Intel 80860";
941 case EM_MIPS: return "MIPS R3000 big-endian";
942 case EM_S370: return "Amdahl";
943 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
944 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
945 case EM_PARISC: return "HPPA";
946 case EM_PPC_OLD: return "Power PC (old)";
947 case EM_SPARC32PLUS: return "Sparc v8+" ;
948 case EM_960: return "Intel 90860";
949 case EM_PPC: return "PowerPC";
950 case EM_V800: return "NEC V800";
951 case EM_FR20: return "Fujitsu FR20";
952 case EM_RH32: return "TRW RH32";
953 case EM_MCORE: return "MCORE";
954 case EM_ARM: return "ARM";
955 case EM_OLD_ALPHA: return "Digital Alpha (old)";
956 case EM_SH: return "Hitachi SH";
957 case EM_SPARCV9: return "Sparc v9";
958 case EM_TRICORE: return "Siemens Tricore";
959 case EM_ARC: return "Argonaut RISC Core";
960 case EM_H8_300: return "Hitachi H8/300";
961 case EM_H8_300H: return "Hitachi H8/300H";
962 case EM_H8S: return "Hitachi H8S";
963 case EM_H8_500: return "Hitachi H8/500";
964 case EM_IA_64: return "Intel Merced";
965 case EM_MIPS_X: return "Stanford MIPS-X";
966 case EM_COLDFIRE: return "Motorola Coldfire";
967 case EM_68HC12: return "Motorola M68HC12";
968 case EM_ALPHA: return "Alpha";
969 case EM_CYGNUS_D10V: return "d10v";
970 case EM_CYGNUS_D30V: return "d30v";
971 case EM_CYGNUS_ARC: return "Arc";
972 case EM_CYGNUS_M32R: return "Mitsubishi M32r";
973 case EM_CYGNUS_V850: return "NEC v850";
974 case EM_CYGNUS_MN10300: return "mn10300";
975 case EM_CYGNUS_MN10200: return "mn10200";
976 case EM_CYGNUS_FR30: return "Fujitsu FR30";
978 default:
979 sprintf (buff, _("<unknown>: %x"), e_machine);
980 return buff;
984 static char *
985 get_machine_flags (e_flags, e_machine)
986 unsigned e_flags;
987 unsigned e_machine;
989 static char buf [1024];
991 buf[0] = '\0';
992 if (e_flags)
994 switch (e_machine)
996 default:
997 break;
999 case EM_68K:
1000 if (e_flags & EF_CPU32)
1001 strcat (buf, ", cpu32");
1002 break;
1004 case EM_PPC:
1005 if (e_flags & EF_PPC_EMB)
1006 strcat (buf, ", emb");
1008 if (e_flags & EF_PPC_RELOCATABLE)
1009 strcat (buf, ", relocatable");
1011 if (e_flags & EF_PPC_RELOCATABLE_LIB)
1012 strcat (buf, ", relocatable-lib");
1013 break;
1015 case EM_CYGNUS_V850:
1016 switch (e_flags & EF_V850_ARCH)
1018 case E_V850E_ARCH:
1019 strcat (buf, ", v850e");
1020 break;
1021 case E_V850EA_ARCH:
1022 strcat (buf, ", v850ea");
1023 break;
1024 case E_V850_ARCH:
1025 strcat (buf, ", v850");
1026 break;
1027 default:
1028 strcat (buf, ", unknown v850 architecture variant");
1029 break;
1031 break;
1033 case EM_CYGNUS_M32R:
1034 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1035 strcat (buf, ", m32r");
1037 break;
1039 case EM_MIPS:
1040 case EM_MIPS_RS4_BE:
1041 if (e_flags & EF_MIPS_NOREORDER)
1042 strcat (buf, ", noreorder");
1044 if (e_flags & EF_MIPS_PIC)
1045 strcat (buf, ", pic");
1047 if (e_flags & EF_MIPS_CPIC)
1048 strcat (buf, ", cpic");
1050 if (e_flags & EF_MIPS_ABI2)
1051 strcat (buf, ", abi2");
1053 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
1054 strcat (buf, ", mips1");
1056 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
1057 strcat (buf, ", mips2");
1059 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
1060 strcat (buf, ", mips3");
1062 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
1063 strcat (buf, ", mips4");
1064 break;
1068 return buf;
1071 static const char *
1072 get_mips_segment_type (type)
1073 unsigned long type;
1075 switch (type)
1077 case PT_MIPS_REGINFO:
1078 return "REGINFO";
1079 case PT_MIPS_RTPROC:
1080 return "RTPROC";
1081 case PT_MIPS_OPTIONS:
1082 return "OPTIONS";
1083 default:
1084 break;
1087 return NULL;
1090 static const char *
1091 get_segment_type (p_type)
1092 unsigned long p_type;
1094 static char buff [32];
1096 switch (p_type)
1098 case PT_NULL: return "NULL";
1099 case PT_LOAD: return "LOAD";
1100 case PT_DYNAMIC: return "DYNAMIC";
1101 case PT_INTERP: return "INTERP";
1102 case PT_NOTE: return "NOTE";
1103 case PT_SHLIB: return "SHLIB";
1104 case PT_PHDR: return "PHDR";
1106 default:
1107 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
1109 const char * result;
1111 switch (elf_header.e_machine)
1113 case EM_MIPS:
1114 case EM_MIPS_RS4_BE:
1115 result = get_mips_segment_type (p_type);
1116 break;
1117 default:
1118 result = NULL;
1119 break;
1122 if (result != NULL)
1123 return result;
1125 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
1127 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
1128 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
1129 else
1130 sprintf (buff, _("<unknown>: %lx"), p_type);
1132 return buff;
1136 static const char *
1137 get_mips_section_type_name (sh_type)
1138 unsigned int sh_type;
1140 switch (sh_type)
1142 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1143 case SHT_MIPS_MSYM: return "MIPS_MSYM";
1144 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1145 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
1146 case SHT_MIPS_UCODE: return "MIPS_UCODE";
1147 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
1148 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
1149 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
1150 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
1151 case SHT_MIPS_RELD: return "MIPS_RELD";
1152 case SHT_MIPS_IFACE: return "MIPS_IFACE";
1153 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
1154 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1155 case SHT_MIPS_SHDR: return "MIPS_SHDR";
1156 case SHT_MIPS_FDESC: return "MIPS_FDESC";
1157 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
1158 case SHT_MIPS_DENSE: return "MIPS_DENSE";
1159 case SHT_MIPS_PDESC: return "MIPS_PDESC";
1160 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
1161 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
1162 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
1163 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
1164 case SHT_MIPS_LINE: return "MIPS_LINE";
1165 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
1166 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
1167 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
1168 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
1169 case SHT_MIPS_DWARF: return "MIPS_DWARF";
1170 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
1171 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1172 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
1173 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
1174 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1175 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1176 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1177 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1178 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1179 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1180 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1181 default:
1182 break;
1184 return NULL;
1187 static const char *
1188 get_section_type_name (sh_type)
1189 unsigned int sh_type;
1191 static char buff [32];
1193 switch (sh_type)
1195 case SHT_NULL: return "NULL";
1196 case SHT_PROGBITS: return "PROGBITS";
1197 case SHT_SYMTAB: return "SYMTAB";
1198 case SHT_STRTAB: return "STRTAB";
1199 case SHT_RELA: return "RELA";
1200 case SHT_HASH: return "HASH";
1201 case SHT_DYNAMIC: return "DYNAMIC";
1202 case SHT_NOTE: return "NOTE";
1203 case SHT_NOBITS: return "NOBITS";
1204 case SHT_REL: return "REL";
1205 case SHT_SHLIB: return "SHLIB";
1206 case SHT_DYNSYM: return "DYNSYM";
1207 case SHT_GNU_verdef: return "VERDEF";
1208 case SHT_GNU_verneed: return "VERNEED";
1209 case SHT_GNU_versym: return "VERSYM";
1210 case 0x6ffffff0: return "VERSYM";
1211 case 0x6ffffffc: return "VERDEF";
1212 case 0x7ffffffd: return "AUXILIARY";
1213 case 0x7fffffff: return "FILTER";
1215 default:
1216 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1218 const char * result;
1220 switch (elf_header.e_machine)
1222 case EM_MIPS:
1223 case EM_MIPS_RS4_BE:
1224 result = get_mips_section_type_name (sh_type);
1225 break;
1226 default:
1227 result = NULL;
1228 break;
1231 if (result != NULL)
1232 return result;
1234 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1236 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1237 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1238 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1239 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1240 else
1241 sprintf (buff, _("<unknown>: %x"), sh_type);
1243 return buff;
1247 struct option options [] =
1249 {"all", no_argument, 0, 'a'},
1250 {"file-header", no_argument, 0, 'h'},
1251 {"program-headers", no_argument, 0, 'l'},
1252 {"headers", no_argument, 0, 'e'},
1253 {"histogram", no_argument, & do_histogram, 1},
1254 {"segments", no_argument, 0, 'l'},
1255 {"sections", no_argument, 0, 'S'},
1256 {"section-headers", no_argument, 0, 'S'},
1257 {"symbols", no_argument, 0, 's'},
1258 {"syms", no_argument, 0, 's'},
1259 {"relocs", no_argument, 0, 'r'},
1260 {"dynamic", no_argument, 0, 'd'},
1261 {"version-info", no_argument, 0, 'V'},
1262 {"use-dynamic", no_argument, 0, 'D'},
1263 {"hex-dump", required_argument, 0, 'x'},
1264 {"debug-dump", optional_argument, 0, 'w'},
1265 #ifdef SUPPORT_DISASSEMBLY
1266 {"instruction-dump", required_argument, 0, 'i'},
1267 #endif
1269 {"version", no_argument, 0, 'v'},
1270 {"help", no_argument, 0, 'H'},
1271 {0, no_argument, 0, 0}
1274 static void
1275 usage ()
1277 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1278 fprintf (stdout, _(" Options are:\n"));
1279 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1280 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1281 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1282 fprintf (stdout, _(" Display the program headers\n"));
1283 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1284 fprintf (stdout, _(" Display the sections' header\n"));
1285 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1286 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1287 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1288 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1289 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1290 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1291 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1292 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1293 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1294 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1295 #ifdef SUPPORT_DISASSEMBLY
1296 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1297 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1298 #endif
1299 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1300 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1301 fprintf (stdout, _(" -H or --help Display this information\n"));
1302 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1304 exit (0);
1307 static void
1308 request_dump (section, type)
1309 unsigned int section;
1310 char type;
1312 if (section >= num_dump_sects)
1314 char * new_dump_sects;
1316 new_dump_sects = (char *) calloc (section + 1, 1);
1318 if (new_dump_sects == NULL)
1319 error (_("Out of memory allocating dump request table."));
1320 else
1322 /* Copy current flag settings. */
1323 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1325 free (dump_sects);
1327 dump_sects = new_dump_sects;
1328 num_dump_sects = section + 1;
1332 if (dump_sects)
1333 dump_sects [section] |= type;
1335 return;
1338 static void
1339 parse_args (argc, argv)
1340 int argc;
1341 char ** argv;
1343 int c;
1345 if (argc < 2)
1346 usage ();
1348 while ((c = getopt_long
1349 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1351 char * cp;
1352 int section;
1354 switch (c)
1356 case 0:
1357 /* Long options. */
1358 break;
1359 case 'H':
1360 usage ();
1361 break;
1363 case 'a':
1364 do_syms ++;
1365 do_reloc ++;
1366 do_dynamic ++;
1367 do_header ++;
1368 do_sections ++;
1369 do_segments ++;
1370 do_version ++;
1371 do_histogram ++;
1372 break;
1373 case 'e':
1374 do_header ++;
1375 do_sections ++;
1376 do_segments ++;
1377 break;
1378 case 'D':
1379 do_using_dynamic ++;
1380 break;
1381 case 'r':
1382 do_reloc ++;
1383 break;
1384 case 'h':
1385 do_header ++;
1386 break;
1387 case 'l':
1388 do_segments ++;
1389 break;
1390 case 's':
1391 do_syms ++;
1392 break;
1393 case 'S':
1394 do_sections ++;
1395 break;
1396 case 'd':
1397 do_dynamic ++;
1398 break;
1399 case 'x':
1400 do_dump ++;
1401 section = strtoul (optarg, & cp, 0);
1402 if (! * cp && section >= 0)
1404 request_dump (section, HEX_DUMP);
1405 break;
1407 goto oops;
1408 case 'w':
1409 do_dump ++;
1410 if (optarg == 0)
1411 do_debugging = 1;
1412 else
1414 do_debugging = 0;
1415 switch (optarg[0])
1417 case 'i':
1418 case 'I':
1419 do_debug_info = 1;
1420 break;
1422 case 'a':
1423 case 'A':
1424 do_debug_abbrevs = 1;
1425 break;
1427 case 'l':
1428 case 'L':
1429 do_debug_lines = 1;
1430 break;
1432 case 'p':
1433 case 'P':
1434 do_debug_pubnames = 1;
1435 break;
1437 case 'r':
1438 case 'R':
1439 do_debug_aranges = 1;
1440 break;
1442 default:
1443 warn (_("Unrecognised debug option '%s'\n"), optarg);
1444 break;
1447 break;
1448 #ifdef SUPPORT_DISASSEMBLY
1449 case 'i':
1450 do_dump ++;
1451 section = strtoul (optarg, & cp, 0);
1452 if (! * cp && section >= 0)
1454 request_dump (section, DISASS_DUMP);
1455 break;
1457 goto oops;
1458 #endif
1459 case 'v':
1460 print_version (program_name);
1461 break;
1462 case 'V':
1463 do_version ++;
1464 break;
1465 default:
1466 oops:
1467 /* xgettext:c-format */
1468 error (_("Invalid option '-%c'\n"), c);
1469 /* Drop through. */
1470 case '?':
1471 usage ();
1475 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1476 && !do_segments && !do_header && !do_dump && !do_version
1477 && !do_histogram && !do_debugging)
1478 usage ();
1479 else if (argc < 3)
1481 warn (_("Nothing to do.\n"));
1482 usage();
1486 static const char *
1487 get_elf_class (elf_class)
1488 unsigned char elf_class;
1490 static char buff [32];
1492 switch (elf_class)
1494 case ELFCLASSNONE: return _("none");
1495 case ELFCLASS32: return _("ELF32");
1496 case ELFCLASS64: return _("ELF64");
1497 default:
1498 sprintf (buff, _("<unknown: %lx>"), elf_class);
1499 return buff;
1503 static const char *
1504 get_data_encoding (encoding)
1505 unsigned char encoding;
1507 static char buff [32];
1509 switch (encoding)
1511 case ELFDATANONE: return _("none");
1512 case ELFDATA2LSB: return _("2's complement, little endian");
1513 case ELFDATA2MSB: return _("2's complement, big endian");
1514 default:
1515 sprintf (buff, _("<unknown: %lx>"), encoding);
1516 return buff;
1520 static const char *
1521 get_osabi_name (osabi)
1522 unsigned char osabi;
1524 static char buff [32];
1526 switch (osabi)
1528 case ELFOSABI_SYSV: return _("UNIX - System V");
1529 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1530 case ELFOSABI_STANDALONE: return _("Standalone App");
1531 default:
1532 sprintf (buff, _("<unknown: %lx>"), osabi);
1533 return buff;
1537 /* Decode the data held in 'elf_header'. */
1538 static int
1539 process_file_header ()
1541 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1542 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1543 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1544 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1546 error
1547 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1548 return 0;
1551 if (do_header)
1553 int i;
1555 printf (_("ELF Header:\n"));
1556 printf (_(" Magic: "));
1557 for (i = 0; i < EI_NIDENT; i ++)
1558 printf ("%2.2x ", elf_header.e_ident [i]);
1559 printf ("\n");
1560 printf (_(" Class: %s\n"),
1561 get_elf_class (elf_header.e_ident [EI_CLASS]));
1562 printf (_(" Data: %s\n"),
1563 get_data_encoding (elf_header.e_ident [EI_DATA]));
1564 printf (_(" Version: %d %s\n"),
1565 elf_header.e_ident [EI_VERSION],
1566 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
1567 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown: %lx>" : "",
1568 elf_header.e_ident [EI_VERSION]);
1569 printf (_(" OS/ABI: %s\n"),
1570 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1571 printf (_(" ABI Version: %d\n"),
1572 elf_header.e_ident [EI_ABIVERSION]);
1573 printf (_(" Type: %s\n"),
1574 get_file_type (elf_header.e_type));
1575 printf (_(" Machine: %s\n"),
1576 get_machine_name (elf_header.e_machine));
1577 printf (_(" Version: 0x%lx\n"),
1578 (unsigned long) elf_header.e_version);
1579 printf (_(" Entry point address: 0x%lx\n"),
1580 (unsigned long) elf_header.e_entry);
1581 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1582 (long) elf_header.e_phoff);
1583 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1584 (long) elf_header.e_shoff);
1585 printf (_(" Flags: 0x%lx%s\n"),
1586 (unsigned long) elf_header.e_flags,
1587 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1588 printf (_(" Size of this header: %ld (bytes)\n"),
1589 (long) elf_header.e_ehsize);
1590 printf (_(" Size of program headers: %ld (bytes)\n"),
1591 (long) elf_header.e_phentsize);
1592 printf (_(" Number of program headers: %ld\n"),
1593 (long) elf_header.e_phnum);
1594 printf (_(" Size of section headers: %ld (bytes)\n"),
1595 (long) elf_header.e_shentsize);
1596 printf (_(" Number of section headers: %ld\n"),
1597 (long) elf_header.e_shnum);
1598 printf (_(" Section header string table index: %ld\n"),
1599 (long) elf_header.e_shstrndx);
1602 return 1;
1606 static int
1607 get_32bit_program_headers (file, program_headers)
1608 FILE * file;
1609 Elf_Internal_Phdr * program_headers;
1611 Elf32_External_Phdr * phdrs;
1612 Elf32_External_Phdr * external;
1613 Elf32_Internal_Phdr * internal;
1614 unsigned int i;
1616 GET_DATA_ALLOC (elf_header.e_phoff,
1617 elf_header.e_phentsize * elf_header.e_phnum,
1618 phdrs, Elf32_External_Phdr *, "program headers");
1620 for (i = 0, internal = program_headers, external = phdrs;
1621 i < elf_header.e_phnum;
1622 i ++, internal ++, external ++)
1624 internal->p_type = BYTE_GET (external->p_type);
1625 internal->p_offset = BYTE_GET (external->p_offset);
1626 internal->p_vaddr = BYTE_GET (external->p_vaddr);
1627 internal->p_paddr = BYTE_GET (external->p_paddr);
1628 internal->p_filesz = BYTE_GET (external->p_filesz);
1629 internal->p_memsz = BYTE_GET (external->p_memsz);
1630 internal->p_flags = BYTE_GET (external->p_flags);
1631 internal->p_align = BYTE_GET (external->p_align);
1634 free (phdrs);
1636 return 1;
1639 static int
1640 get_64bit_program_headers (file, program_headers)
1641 FILE * file;
1642 Elf_Internal_Phdr * program_headers;
1644 Elf64_External_Phdr * phdrs;
1645 Elf64_External_Phdr * external;
1646 Elf64_Internal_Phdr * internal;
1647 unsigned int i;
1649 GET_DATA_ALLOC (elf_header.e_phoff,
1650 elf_header.e_phentsize * elf_header.e_phnum,
1651 phdrs, Elf64_External_Phdr *, "program headers");
1653 for (i = 0, internal = program_headers, external = phdrs;
1654 i < elf_header.e_phnum;
1655 i ++, internal ++, external ++)
1657 internal->p_type = BYTE_GET (external->p_type);
1658 internal->p_flags = BYTE_GET (external->p_flags);
1659 internal->p_offset = BYTE_GET8 (external->p_offset);
1660 internal->p_vaddr = BYTE_GET8 (external->p_vaddr);
1661 internal->p_paddr = BYTE_GET8 (external->p_paddr);
1662 internal->p_filesz = BYTE_GET8 (external->p_filesz);
1663 internal->p_memsz = BYTE_GET8 (external->p_memsz);
1664 internal->p_align = BYTE_GET8 (external->p_align);
1667 free (phdrs);
1669 return 1;
1672 static int
1673 process_program_headers (file)
1674 FILE * file;
1676 Elf_Internal_Phdr * program_headers;
1677 Elf_Internal_Phdr * segment;
1678 unsigned int i;
1680 if (elf_header.e_phnum == 0)
1682 if (do_segments)
1683 printf (_("\nThere are no program headers in this file.\n"));
1684 return 1;
1687 if (do_segments && !do_header)
1689 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1690 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1691 printf (_("There are %d program headers, starting at offset %lx:\n"),
1692 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1695 program_headers = (Elf_Internal_Phdr *) malloc
1696 (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
1698 if (program_headers == NULL)
1700 error (_("Out of memory\n"));
1701 return 0;
1704 if (is_32bit_elf)
1705 i = get_32bit_program_headers (file, program_headers);
1706 else
1707 i = get_64bit_program_headers (file, program_headers);
1709 if (i == 0)
1711 free (program_headers);
1712 return 0;
1715 if (do_segments)
1717 printf
1718 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1719 printf
1720 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1723 loadaddr = -1;
1724 dynamic_addr = 0;
1725 dynamic_size = 0;
1727 for (i = 0, segment = program_headers;
1728 i < elf_header.e_phnum;
1729 i ++, segment ++)
1731 if (do_segments)
1733 printf (" %-11.11s ", get_segment_type (segment->p_type));
1734 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1735 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1736 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1737 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1738 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1739 printf ("%c%c%c ",
1740 (segment->p_flags & PF_R ? 'R' : ' '),
1741 (segment->p_flags & PF_W ? 'W' : ' '),
1742 (segment->p_flags & PF_X ? 'E' : ' '));
1743 printf ("%#lx", (unsigned long) segment->p_align);
1746 switch (segment->p_type)
1748 case PT_LOAD:
1749 if (loadaddr == -1)
1750 loadaddr = (segment->p_vaddr & 0xfffff000)
1751 - (segment->p_offset & 0xfffff000);
1752 break;
1754 case PT_DYNAMIC:
1755 if (dynamic_addr)
1756 error (_("more than one dynamic segment\n"));
1758 dynamic_addr = segment->p_offset;
1759 dynamic_size = segment->p_filesz;
1760 break;
1762 case PT_INTERP:
1763 if (fseek (file, segment->p_offset, SEEK_SET))
1764 error (_("Unable to find program interpreter name\n"));
1765 else
1767 program_interpreter[0] = 0;
1768 fscanf (file, "%63s", program_interpreter);
1770 if (do_segments)
1771 printf (_("\n [Requesting program interpreter: %s]"),
1772 program_interpreter);
1774 break;
1777 if (do_segments)
1778 putc ('\n', stdout);
1781 if (loadaddr == -1)
1783 /* Very strange. */
1784 loadaddr = 0;
1787 if (do_segments && section_headers != NULL)
1789 printf (_("\n Section to Segment mapping:\n"));
1790 printf (_(" Segment Sections...\n"));
1792 assert (string_table != NULL);
1794 for (i = 0; i < elf_header.e_phnum; i++)
1796 int j;
1797 Elf_Internal_Shdr * section;
1799 segment = program_headers + i;
1800 section = section_headers;
1802 printf (" %2.2d ", i);
1804 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1806 if (section->sh_size > 0
1807 /* Compare allocated sections by VMA, unallocated
1808 sections by file offset. */
1809 && (section->sh_flags & SHF_ALLOC
1810 ? (section->sh_addr >= segment->p_vaddr
1811 && section->sh_addr + section->sh_size
1812 <= segment->p_vaddr + segment->p_memsz)
1813 : (section->sh_offset >= segment->p_offset
1814 && (section->sh_offset + section->sh_size
1815 <= segment->p_offset + segment->p_filesz))))
1816 printf ("%s ", SECTION_NAME (section));
1819 putc ('\n',stdout);
1823 free (program_headers);
1825 return 1;
1829 static int
1830 get_32bit_section_headers (file)
1831 FILE * file;
1833 Elf32_External_Shdr * shdrs;
1834 Elf32_Internal_Shdr * internal;
1835 unsigned int i;
1837 GET_DATA_ALLOC (elf_header.e_shoff,
1838 elf_header.e_shentsize * elf_header.e_shnum,
1839 shdrs, Elf32_External_Shdr *, "section headers");
1841 section_headers = (Elf_Internal_Shdr *) malloc
1842 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1844 if (section_headers == NULL)
1846 error (_("Out of memory\n"));
1847 return 0;
1850 for (i = 0, internal = section_headers;
1851 i < elf_header.e_shnum;
1852 i ++, internal ++)
1854 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1855 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1856 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1857 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1858 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1859 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1860 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1861 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1862 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1863 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1866 free (shdrs);
1868 return 1;
1871 static int
1872 get_64bit_section_headers (file)
1873 FILE * file;
1875 Elf64_External_Shdr * shdrs;
1876 Elf64_Internal_Shdr * internal;
1877 unsigned int i;
1879 GET_DATA_ALLOC (elf_header.e_shoff,
1880 elf_header.e_shentsize * elf_header.e_shnum,
1881 shdrs, Elf64_External_Shdr *, "section headers");
1883 section_headers = (Elf_Internal_Shdr *) malloc
1884 (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1886 if (section_headers == NULL)
1888 error (_("Out of memory\n"));
1889 return 0;
1892 for (i = 0, internal = section_headers;
1893 i < elf_header.e_shnum;
1894 i ++, internal ++)
1896 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1897 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1898 internal->sh_flags = BYTE_GET8 (shdrs[i].sh_flags);
1899 internal->sh_addr = BYTE_GET8 (shdrs[i].sh_addr);
1900 internal->sh_size = BYTE_GET8 (shdrs[i].sh_size);
1901 internal->sh_entsize = BYTE_GET8 (shdrs[i].sh_entsize);
1902 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1903 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1904 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1905 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1908 free (shdrs);
1910 return 1;
1913 static Elf_Internal_Sym *
1914 get_32bit_elf_symbols (file, offset, number)
1915 FILE * file;
1916 unsigned long offset;
1917 unsigned long number;
1919 Elf32_External_Sym * esyms;
1920 Elf_Internal_Sym * isyms;
1921 Elf_Internal_Sym * psym;
1922 unsigned int j;
1924 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1925 esyms, Elf32_External_Sym *, "symbols");
1927 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1929 if (isyms == NULL)
1931 error (_("Out of memory\n"));
1932 free (esyms);
1934 return NULL;
1937 for (j = 0, psym = isyms;
1938 j < number;
1939 j ++, psym ++)
1941 psym->st_name = BYTE_GET (esyms[j].st_name);
1942 psym->st_value = BYTE_GET (esyms[j].st_value);
1943 psym->st_size = BYTE_GET (esyms[j].st_size);
1944 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1945 psym->st_info = BYTE_GET (esyms[j].st_info);
1946 psym->st_other = BYTE_GET (esyms[j].st_other);
1949 free (esyms);
1951 return isyms;
1954 static Elf_Internal_Sym *
1955 get_64bit_elf_symbols (file, offset, number)
1956 FILE * file;
1957 unsigned long offset;
1958 unsigned long number;
1960 Elf64_External_Sym * esyms;
1961 Elf_Internal_Sym * isyms;
1962 Elf_Internal_Sym * psym;
1963 unsigned int j;
1965 GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
1966 esyms, Elf64_External_Sym *, "symbols");
1968 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1970 if (isyms == NULL)
1972 error (_("Out of memory\n"));
1973 free (esyms);
1975 return NULL;
1978 for (j = 0, psym = isyms;
1979 j < number;
1980 j ++, psym ++)
1982 psym->st_name = BYTE_GET (esyms[j].st_name);
1983 psym->st_info = BYTE_GET (esyms[j].st_info);
1984 psym->st_other = BYTE_GET (esyms[j].st_other);
1985 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1986 psym->st_value = BYTE_GET8 (esyms[j].st_value);
1987 psym->st_size = BYTE_GET8 (esyms[j].st_size);
1990 free (esyms);
1992 return isyms;
1995 static int
1996 process_section_headers (file)
1997 FILE * file;
1999 Elf_Internal_Shdr * section;
2000 int i;
2002 section_headers = NULL;
2004 if (elf_header.e_shnum == 0)
2006 if (do_sections)
2007 printf (_("\nThere are no sections in this file.\n"));
2009 return 1;
2012 if (do_sections && !do_header)
2013 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
2014 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2016 if (is_32bit_elf)
2018 if (! get_32bit_section_headers (file))
2019 return 0;
2021 else if (! get_64bit_section_headers (file))
2022 return 0;
2024 /* Read in the string table, so that we have names to display. */
2025 section = section_headers + elf_header.e_shstrndx;
2027 if (section->sh_size != 0)
2029 unsigned long string_table_offset;
2031 string_table_offset = section->sh_offset;
2033 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2034 string_table, char *, "string table");
2037 /* Scan the sections for the dynamic symbol table
2038 and dynamic string table and debug sections. */
2039 dynamic_symbols = NULL;
2040 dynamic_strings = NULL;
2041 dynamic_syminfo = NULL;
2043 for (i = 0, section = section_headers;
2044 i < elf_header.e_shnum;
2045 i ++, section ++)
2047 char * name = SECTION_NAME (section);
2049 if (section->sh_type == SHT_DYNSYM)
2051 if (dynamic_symbols != NULL)
2053 error (_("File contains multiple dynamic symbol tables\n"));
2054 continue;
2057 num_dynamic_syms = section->sh_size / section->sh_entsize;
2058 dynamic_symbols =
2059 GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
2061 else if (section->sh_type == SHT_STRTAB
2062 && strcmp (name, ".dynstr") == 0)
2064 if (dynamic_strings != NULL)
2066 error (_("File contains multiple dynamic string tables\n"));
2067 continue;
2070 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2071 dynamic_strings, char *, "dynamic strings");
2073 else if ((do_debugging || do_debug_info || do_debug_abbrevs
2074 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
2075 && strncmp (name, ".debug_", 7) == 0)
2077 name += 7;
2079 if (do_debugging
2080 || (do_debug_info && (strcmp (name, "info") == 0))
2081 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
2082 || (do_debug_lines && (strcmp (name, "line") == 0))
2083 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2084 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
2086 request_dump (i, DEBUG_DUMP);
2090 if (! do_sections)
2091 return 1;
2093 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2094 printf
2095 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
2097 for (i = 0, section = section_headers;
2098 i < elf_header.e_shnum;
2099 i ++, section ++)
2101 printf (" [%2d] %-17.17s %-15.15s ",
2103 SECTION_NAME (section),
2104 get_section_type_name (section->sh_type));
2106 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
2107 (unsigned long) section->sh_addr,
2108 (unsigned long) section->sh_offset,
2109 (unsigned long) section->sh_size,
2110 (unsigned long) section->sh_entsize);
2112 printf (" %c%c%c %2ld %3lx %ld\n",
2113 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
2114 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
2115 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
2116 (unsigned long) section->sh_link,
2117 (unsigned long) section->sh_info,
2118 (unsigned long) section->sh_addralign);
2121 return 1;
2124 /* Process the reloc section. */
2125 static int
2126 process_relocs (file)
2127 FILE * file;
2129 unsigned long rel_size;
2130 unsigned long rel_offset;
2133 if (!do_reloc)
2134 return 1;
2136 if (do_using_dynamic)
2138 int is_rela;
2140 rel_size = 0;
2141 rel_offset = 0;
2143 if (dynamic_info[DT_REL])
2145 rel_offset = dynamic_info[DT_REL];
2146 rel_size = dynamic_info[DT_RELSZ];
2147 is_rela = FALSE;
2149 else if (dynamic_info [DT_RELA])
2151 rel_offset = dynamic_info[DT_RELA];
2152 rel_size = dynamic_info[DT_RELASZ];
2153 is_rela = TRUE;
2155 else if (dynamic_info[DT_JMPREL])
2157 rel_offset = dynamic_info[DT_JMPREL];
2158 rel_size = dynamic_info[DT_PLTRELSZ];
2160 switch (dynamic_info[DT_PLTREL])
2162 case DT_REL:
2163 is_rela = FALSE;
2164 break;
2165 case DT_RELA:
2166 is_rela = TRUE;
2167 break;
2168 default:
2169 is_rela = UNKNOWN;
2170 break;
2174 if (rel_size)
2176 printf
2177 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2178 rel_offset, rel_size);
2180 dump_relocations (file, rel_offset - loadaddr, rel_size,
2181 dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
2183 else
2184 printf (_("\nThere are no dynamic relocations in this file.\n"));
2186 else
2188 Elf32_Internal_Shdr * section;
2189 unsigned long i;
2190 int found = 0;
2192 for (i = 0, section = section_headers;
2193 i < elf_header.e_shnum;
2194 i++, section ++)
2196 if ( section->sh_type != SHT_RELA
2197 && section->sh_type != SHT_REL)
2198 continue;
2200 rel_offset = section->sh_offset;
2201 rel_size = section->sh_size;
2203 if (rel_size)
2205 Elf32_Internal_Shdr * strsec;
2206 Elf32_Internal_Shdr * symsec;
2207 Elf_Internal_Sym * symtab;
2208 char * strtab;
2209 int is_rela;
2210 unsigned long nsyms;
2212 printf (_("\nRelocation section "));
2214 if (string_table == NULL)
2215 printf ("%d", section->sh_name);
2216 else
2217 printf ("'%s'", SECTION_NAME (section));
2219 printf (_(" at offset 0x%lx contains %lu entries:\n"),
2220 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2222 symsec = section_headers + section->sh_link;
2224 nsyms = symsec->sh_size / symsec->sh_entsize;
2225 symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
2227 if (symtab == NULL)
2228 continue;
2230 strsec = section_headers + symsec->sh_link;
2232 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2233 char *, "string table");
2235 is_rela = section->sh_type == SHT_RELA;
2237 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
2239 free (strtab);
2240 free (symtab);
2242 found = 1;
2246 if (! found)
2247 printf (_("\nThere are no relocations in this file.\n"));
2250 return 1;
2254 static void
2255 dynamic_segment_mips_val (entry)
2256 Elf_Internal_Dyn * entry;
2258 switch (entry->d_tag)
2260 case DT_MIPS_FLAGS:
2261 if (entry->d_un.d_val == 0)
2262 printf ("NONE\n");
2263 else
2265 static const char * opts[] =
2267 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2268 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2269 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2270 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2271 "RLD_ORDER_SAFE"
2273 unsigned int cnt;
2274 int first = 1;
2275 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2276 if (entry->d_un.d_val & (1 << cnt))
2278 printf ("%s%s", first ? "" : " ", opts[cnt]);
2279 first = 0;
2281 puts ("");
2283 break;
2285 case DT_MIPS_IVERSION:
2286 if (dynamic_strings != NULL)
2287 printf ("Interface Version: %s\n",
2288 dynamic_strings + entry->d_un.d_val);
2289 else
2290 printf ("%ld\n", (long) entry->d_un.d_ptr);
2291 break;
2293 case DT_MIPS_TIME_STAMP:
2295 char timebuf[20];
2296 time_t time = entry->d_un.d_val;
2297 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2298 printf ("Time Stamp: %s\n", timebuf);
2300 break;
2302 case DT_MIPS_RLD_VERSION:
2303 case DT_MIPS_LOCAL_GOTNO:
2304 case DT_MIPS_CONFLICTNO:
2305 case DT_MIPS_LIBLISTNO:
2306 case DT_MIPS_SYMTABNO:
2307 case DT_MIPS_UNREFEXTNO:
2308 case DT_MIPS_HIPAGENO:
2309 case DT_MIPS_DELTA_CLASS_NO:
2310 case DT_MIPS_DELTA_INSTANCE_NO:
2311 case DT_MIPS_DELTA_RELOC_NO:
2312 case DT_MIPS_DELTA_SYM_NO:
2313 case DT_MIPS_DELTA_CLASSSYM_NO:
2314 case DT_MIPS_COMPACT_SIZE:
2315 printf ("%ld\n", (long) entry->d_un.d_ptr);
2316 break;
2318 default:
2319 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2323 static int
2324 get_32bit_dynamic_segment (file)
2325 FILE * file;
2327 Elf32_External_Dyn * edyn;
2328 Elf_Internal_Dyn * entry;
2329 bfd_size_type i;
2331 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2332 edyn, Elf32_External_Dyn *, "dynamic segment");
2334 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2335 how large this .dynamic is now. We can do this even before the byte
2336 swapping since the DT_NULL tag is recognizable. */
2337 dynamic_size = 0;
2338 while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
2341 dynamic_segment = (Elf_Internal_Dyn *)
2342 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2344 if (dynamic_segment == NULL)
2346 error (_("Out of memory\n"));
2347 free (edyn);
2348 return 0;
2351 for (i = 0, entry = dynamic_segment;
2352 i < dynamic_size;
2353 i ++, entry ++)
2355 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2356 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2359 free (edyn);
2361 return 1;
2364 static int
2365 get_64bit_dynamic_segment (file)
2366 FILE * file;
2368 Elf64_External_Dyn * edyn;
2369 Elf_Internal_Dyn * entry;
2370 bfd_size_type i;
2372 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2373 edyn, Elf64_External_Dyn *, "dynamic segment");
2375 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2376 how large this .dynamic is now. We can do this even before the byte
2377 swapping since the DT_NULL tag is recognizable. */
2378 dynamic_size = 0;
2379 while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
2382 dynamic_segment = (Elf_Internal_Dyn *)
2383 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2385 if (dynamic_segment == NULL)
2387 error (_("Out of memory\n"));
2388 free (edyn);
2389 return 0;
2392 for (i = 0, entry = dynamic_segment;
2393 i < dynamic_size;
2394 i ++, entry ++)
2396 entry->d_tag = BYTE_GET8 (edyn [i].d_tag);
2397 entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
2400 free (edyn);
2402 return 1;
2405 /* Parse and display the contents of the dynamic segment. */
2406 static int
2407 process_dynamic_segment (file)
2408 FILE * file;
2410 Elf_Internal_Dyn * entry;
2411 bfd_size_type i;
2413 if (dynamic_size == 0)
2415 if (do_dynamic)
2416 printf (_("\nThere is no dynamic segment in this file.\n"));
2418 return 1;
2421 if (is_32bit_elf)
2423 if (! get_32bit_dynamic_segment (file))
2424 return 0;
2426 else if (! get_64bit_dynamic_segment (file))
2427 return 0;
2429 /* Find the appropriate symbol table. */
2430 if (dynamic_symbols == NULL)
2432 for (i = 0, entry = dynamic_segment;
2433 i < dynamic_size;
2434 ++i, ++ entry)
2436 unsigned long offset;
2438 if (entry->d_tag != DT_SYMTAB)
2439 continue;
2441 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2443 /* Since we do not know how big the symbol table is,
2444 we default to reading in the entire file (!) and
2445 processing that. This is overkill, I know, but it
2446 should work. */
2447 offset = entry->d_un.d_val - loadaddr;
2449 if (fseek (file, 0, SEEK_END))
2450 error (_("Unable to seek to end of file!"));
2452 if (is_32bit_elf)
2453 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2454 else
2455 num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
2457 if (num_dynamic_syms < 1)
2459 error (_("Unable to determine the number of symbols to load\n"));
2460 continue;
2463 dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
2467 /* Similarly find a string table. */
2468 if (dynamic_strings == NULL)
2470 for (i = 0, entry = dynamic_segment;
2471 i < dynamic_size;
2472 ++i, ++ entry)
2474 unsigned long offset;
2475 long str_tab_len;
2477 if (entry->d_tag != DT_STRTAB)
2478 continue;
2480 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2482 /* Since we do not know how big the string table is,
2483 we default to reading in the entire file (!) and
2484 processing that. This is overkill, I know, but it
2485 should work. */
2487 offset = entry->d_un.d_val - loadaddr;
2488 if (fseek (file, 0, SEEK_END))
2489 error (_("Unable to seek to end of file\n"));
2490 str_tab_len = ftell (file) - offset;
2492 if (str_tab_len < 1)
2494 error
2495 (_("Unable to determine the length of the dynamic string table\n"));
2496 continue;
2499 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2500 "dynamic string table");
2502 break;
2506 /* And find the syminfo section if available. */
2507 if (dynamic_syminfo == NULL)
2509 unsigned int syminsz = 0;
2511 for (i = 0, entry = dynamic_segment;
2512 i < dynamic_size;
2513 ++i, ++ entry)
2515 if (entry->d_tag == DT_SYMINENT)
2517 /* Note: these braces are necessary to avoid a syntax
2518 error from the SunOS4 C compiler. */
2519 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2521 else if (entry->d_tag == DT_SYMINSZ)
2522 syminsz = entry->d_un.d_val;
2523 else if (entry->d_tag == DT_SYMINFO)
2524 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2527 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2529 Elf_External_Syminfo * extsyminfo;
2530 Elf_Internal_Syminfo * syminfo;
2532 /* There is a syminfo section. Read the data. */
2533 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2534 Elf_External_Syminfo *, "symbol information");
2536 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2537 if (dynamic_syminfo == NULL)
2539 error (_("Out of memory\n"));
2540 return 0;
2543 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2544 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2545 ++i, ++syminfo)
2547 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2548 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2551 free (extsyminfo);
2555 if (do_dynamic && dynamic_addr)
2556 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2557 dynamic_addr, dynamic_size);
2558 if (do_dynamic)
2559 printf (_(" Tag Type Name/Value\n"));
2561 for (i = 0, entry = dynamic_segment;
2562 i < dynamic_size;
2563 i++, entry ++)
2565 if (do_dynamic)
2566 printf (_(" 0x%-8.8lx (%s)%*s"),
2567 (unsigned long) entry->d_tag,
2568 get_dynamic_type (entry->d_tag),
2569 27 - strlen (get_dynamic_type (entry->d_tag)),
2570 " ");
2572 switch (entry->d_tag)
2574 case DT_AUXILIARY:
2575 case DT_FILTER:
2576 if (do_dynamic)
2578 if (entry->d_tag == DT_AUXILIARY)
2579 printf (_("Auxiliary library"));
2580 else
2581 printf (_("Filter library"));
2583 if (dynamic_strings)
2584 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2585 else
2586 printf (": %#lx\n", (long) entry->d_un.d_val);
2588 break;
2590 case DT_FEATURE_1:
2591 if (do_dynamic)
2593 printf (_("Flags:"));
2594 if (entry->d_un.d_val == 0)
2595 printf (_(" None\n"));
2596 else
2598 unsigned long int val = entry->d_un.d_val;
2599 if (val & DTF_1_PARINIT)
2601 printf (" PARINIT");
2602 val ^= DTF_1_PARINIT;
2604 if (val != 0)
2605 printf (" %lx", val);
2606 puts ("");
2609 break;
2611 case DT_POSFLAG_1:
2612 if (do_dynamic)
2614 printf (_("Flags:"));
2615 if (entry->d_un.d_val == 0)
2616 printf (_(" None\n"));
2617 else
2619 unsigned long int val = entry->d_un.d_val;
2620 if (val & DF_P1_LAZYLOAD)
2622 printf (" LAZYLOAD");
2623 val ^= DF_P1_LAZYLOAD;
2625 if (val & DF_P1_GROUPPERM)
2627 printf (" GROUPPERM");
2628 val ^= DF_P1_GROUPPERM;
2630 if (val != 0)
2631 printf (" %lx", val);
2632 puts ("");
2635 break;
2637 case DT_FLAGS_1:
2638 if (do_dynamic)
2640 printf (_("Flags:"));
2641 if (entry->d_un.d_val == 0)
2642 printf (_(" None\n"));
2643 else
2645 unsigned long int val = entry->d_un.d_val;
2646 if (val & DF_1_NOW)
2648 printf (" NOW");
2649 val ^= DF_1_NOW;
2651 if (val & DF_1_GLOBAL)
2653 printf (" GLOBAL");
2654 val ^= DF_1_GLOBAL;
2656 if (val & DF_1_GROUP)
2658 printf (" GROUP");
2659 val ^= DF_1_GROUP;
2661 if (val & DF_1_NODELETE)
2663 printf (" NODELETE");
2664 val ^= DF_1_NODELETE;
2666 if (val & DF_1_LOADFLTR)
2668 printf (" LOADFLTR");
2669 val ^= DF_1_LOADFLTR;
2671 if (val & DF_1_INITFIRST)
2673 printf (" INITFIRST");
2674 val ^= DF_1_INITFIRST;
2676 if (val & DF_1_NOOPEN)
2678 printf (" NOOPEN");
2679 val ^= DF_1_NOOPEN;
2681 if (val & DF_1_ORIGIN)
2683 printf (" ORIGIN");
2684 val ^= DF_1_ORIGIN;
2686 if (val & DF_1_DIRECT)
2688 printf (" DIRECT");
2689 val ^= DF_1_DIRECT;
2691 if (val & DF_1_TRANS)
2693 printf (" TRANS");
2694 val ^= DF_1_TRANS;
2696 if (val & DF_1_INTERPOSE)
2698 printf (" INTERPOSE");
2699 val ^= DF_1_INTERPOSE;
2701 if (val != 0)
2702 printf (" %lx", val);
2703 puts ("");
2706 break;
2708 case DT_PLTREL:
2709 if (do_dynamic)
2710 puts (get_dynamic_type (entry->d_un.d_val));
2711 break;
2713 case DT_NULL :
2714 case DT_NEEDED :
2715 case DT_PLTGOT :
2716 case DT_HASH :
2717 case DT_STRTAB :
2718 case DT_SYMTAB :
2719 case DT_RELA :
2720 case DT_INIT :
2721 case DT_FINI :
2722 case DT_SONAME :
2723 case DT_RPATH :
2724 case DT_SYMBOLIC:
2725 case DT_REL :
2726 case DT_DEBUG :
2727 case DT_TEXTREL :
2728 case DT_JMPREL :
2729 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2731 if (do_dynamic)
2733 char * name;
2735 if (dynamic_strings == NULL)
2736 name = NULL;
2737 else
2738 name = dynamic_strings + entry->d_un.d_val;
2740 if (name)
2742 switch (entry->d_tag)
2744 case DT_NEEDED:
2745 printf (_("Shared library: [%s]"), name);
2747 if (strcmp (name, program_interpreter))
2748 printf ("\n");
2749 else
2750 printf (_(" program interpreter\n"));
2751 break;
2753 case DT_SONAME:
2754 printf (_("Library soname: [%s]\n"), name);
2755 break;
2757 case DT_RPATH:
2758 printf (_("Library rpath: [%s]\n"), name);
2759 break;
2761 default:
2762 printf ("%#lx\n", (long) entry->d_un.d_val);
2765 else
2766 printf ("%#lx\n", (long) entry->d_un.d_val);
2768 break;
2770 case DT_PLTRELSZ:
2771 case DT_RELASZ :
2772 case DT_STRSZ :
2773 case DT_RELSZ :
2774 case DT_RELAENT :
2775 case DT_SYMENT :
2776 case DT_RELENT :
2777 case DT_PLTPADSZ:
2778 case DT_MOVEENT :
2779 case DT_MOVESZ :
2780 case DT_INIT_ARRAYSZ:
2781 case DT_FINI_ARRAYSZ:
2782 if (do_dynamic)
2783 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2784 break;
2786 case DT_VERDEFNUM:
2787 case DT_VERNEEDNUM:
2788 case DT_RELACOUNT:
2789 case DT_RELCOUNT:
2790 if (do_dynamic)
2791 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2792 break;
2794 case DT_SYMINSZ:
2795 case DT_SYMINENT:
2796 case DT_SYMINFO:
2797 case DT_USED:
2798 case DT_INIT_ARRAY:
2799 case DT_FINI_ARRAY:
2800 if (do_dynamic)
2802 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2804 char * name;
2806 name = dynamic_strings + entry->d_un.d_val;
2808 if (* name)
2810 printf (_("Not needed object: [%s]\n"), name);
2811 break;
2815 printf ("%#lx\n", (long) entry->d_un.d_val);
2817 break;
2819 case DT_BIND_NOW:
2820 /* The value of this entry is ignored. */
2821 break;
2823 default:
2824 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2825 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2826 entry->d_un.d_val;
2828 if (do_dynamic)
2830 switch (elf_header.e_machine)
2832 case EM_MIPS:
2833 case EM_MIPS_RS4_BE:
2834 dynamic_segment_mips_val (entry);
2835 break;
2836 default:
2837 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2840 break;
2844 return 1;
2847 static char *
2848 get_ver_flags (flags)
2849 unsigned int flags;
2851 static char buff [32];
2853 buff[0] = 0;
2855 if (flags == 0)
2856 return _("none");
2858 if (flags & VER_FLG_BASE)
2859 strcat (buff, "BASE ");
2861 if (flags & VER_FLG_WEAK)
2863 if (flags & VER_FLG_BASE)
2864 strcat (buff, "| ");
2866 strcat (buff, "WEAK ");
2869 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2870 strcat (buff, "| <unknown>");
2872 return buff;
2875 /* Display the contents of the version sections. */
2876 static int
2877 process_version_sections (file)
2878 FILE * file;
2880 Elf32_Internal_Shdr * section;
2881 unsigned i;
2882 int found = 0;
2884 if (! do_version)
2885 return 1;
2887 for (i = 0, section = section_headers;
2888 i < elf_header.e_shnum;
2889 i++, section ++)
2891 switch (section->sh_type)
2893 case SHT_GNU_verdef:
2895 Elf_External_Verdef * edefs;
2896 unsigned int idx;
2897 unsigned int cnt;
2899 found = 1;
2901 printf
2902 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2903 SECTION_NAME (section), section->sh_info);
2905 printf (_(" Addr: 0x"));
2906 printf_vma (section->sh_addr);
2907 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2908 (unsigned long) section->sh_offset, section->sh_link,
2909 SECTION_NAME (section_headers + section->sh_link));
2911 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2912 edefs, Elf_External_Verdef *,
2913 "version definition section");
2915 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2917 char * vstart;
2918 Elf_External_Verdef * edef;
2919 Elf_Internal_Verdef ent;
2920 Elf_External_Verdaux * eaux;
2921 Elf_Internal_Verdaux aux;
2922 int j;
2923 int isum;
2925 vstart = ((char *) edefs) + idx;
2927 edef = (Elf_External_Verdef *) vstart;
2929 ent.vd_version = BYTE_GET (edef->vd_version);
2930 ent.vd_flags = BYTE_GET (edef->vd_flags);
2931 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2932 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2933 ent.vd_hash = BYTE_GET (edef->vd_hash);
2934 ent.vd_aux = BYTE_GET (edef->vd_aux);
2935 ent.vd_next = BYTE_GET (edef->vd_next);
2937 printf (_(" %#06x: Rev: %d Flags: %s"),
2938 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2940 printf (_(" Index: %d Cnt: %d "),
2941 ent.vd_ndx, ent.vd_cnt);
2943 vstart += ent.vd_aux;
2945 eaux = (Elf_External_Verdaux *) vstart;
2947 aux.vda_name = BYTE_GET (eaux->vda_name);
2948 aux.vda_next = BYTE_GET (eaux->vda_next);
2950 if (dynamic_strings)
2951 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2952 else
2953 printf (_("Name index: %ld\n"), aux.vda_name);
2955 isum = idx + ent.vd_aux;
2957 for (j = 1; j < ent.vd_cnt; j ++)
2959 isum += aux.vda_next;
2960 vstart += aux.vda_next;
2962 eaux = (Elf_External_Verdaux *) vstart;
2964 aux.vda_name = BYTE_GET (eaux->vda_name);
2965 aux.vda_next = BYTE_GET (eaux->vda_next);
2967 if (dynamic_strings)
2968 printf (_(" %#06x: Parent %d: %s\n"),
2969 isum, j, dynamic_strings + aux.vda_name);
2970 else
2971 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2972 isum, j, aux.vda_name);
2975 idx += ent.vd_next;
2978 free (edefs);
2980 break;
2982 case SHT_GNU_verneed:
2984 Elf_External_Verneed * eneed;
2985 unsigned int idx;
2986 unsigned int cnt;
2988 found = 1;
2990 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2991 SECTION_NAME (section), section->sh_info);
2993 printf (_(" Addr: 0x"));
2994 printf_vma (section->sh_addr);
2995 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
2996 (unsigned long) section->sh_offset, section->sh_link,
2997 SECTION_NAME (section_headers + section->sh_link));
2999 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3000 eneed, Elf_External_Verneed *,
3001 "version need section");
3003 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3005 Elf_External_Verneed * entry;
3006 Elf_Internal_Verneed ent;
3007 int j;
3008 int isum;
3009 char * vstart;
3011 vstart = ((char *) eneed) + idx;
3013 entry = (Elf_External_Verneed *) vstart;
3015 ent.vn_version = BYTE_GET (entry->vn_version);
3016 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
3017 ent.vn_file = BYTE_GET (entry->vn_file);
3018 ent.vn_aux = BYTE_GET (entry->vn_aux);
3019 ent.vn_next = BYTE_GET (entry->vn_next);
3021 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
3023 if (dynamic_strings)
3024 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
3025 else
3026 printf (_(" File: %lx"), ent.vn_file);
3028 printf (_(" Cnt: %d\n"), ent.vn_cnt);
3030 vstart += ent.vn_aux;
3032 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3034 Elf_External_Vernaux * eaux;
3035 Elf_Internal_Vernaux aux;
3037 eaux = (Elf_External_Vernaux *) vstart;
3039 aux.vna_hash = BYTE_GET (eaux->vna_hash);
3040 aux.vna_flags = BYTE_GET (eaux->vna_flags);
3041 aux.vna_other = BYTE_GET (eaux->vna_other);
3042 aux.vna_name = BYTE_GET (eaux->vna_name);
3043 aux.vna_next = BYTE_GET (eaux->vna_next);
3045 if (dynamic_strings)
3046 printf (_(" %#06x: Name: %s"),
3047 isum, dynamic_strings + aux.vna_name);
3048 else
3049 printf (_(" %#06x: Name index: %lx"),
3050 isum, aux.vna_name);
3052 printf (_(" Flags: %s Version: %d\n"),
3053 get_ver_flags (aux.vna_flags), aux.vna_other);
3055 isum += aux.vna_next;
3056 vstart += aux.vna_next;
3059 idx += ent.vn_next;
3062 free (eneed);
3064 break;
3066 case SHT_GNU_versym:
3068 Elf32_Internal_Shdr * link_section;
3069 int total;
3070 int cnt;
3071 unsigned char * edata;
3072 unsigned short * data;
3073 char * strtab;
3074 Elf_Internal_Sym * symbols;
3075 Elf32_Internal_Shdr * string_sec;
3077 link_section = section_headers + section->sh_link;
3078 total = section->sh_size / section->sh_entsize;
3080 found = 1;
3082 symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3083 link_section->sh_size / link_section->sh_entsize);
3085 string_sec = section_headers + link_section->sh_link;
3087 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3088 strtab, char *, "version string table");
3090 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3091 SECTION_NAME (section), total);
3093 printf (_(" Addr: "));
3094 printf_vma (section->sh_addr);
3095 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
3096 (unsigned long) section->sh_offset, section->sh_link,
3097 SECTION_NAME (link_section));
3099 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3100 - loadaddr,
3101 total * sizeof (short), edata,
3102 unsigned char *, "version symbol data");
3104 data = (unsigned short *) malloc (total * sizeof (short));
3106 for (cnt = total; cnt --;)
3107 data [cnt] = byte_get (edata + cnt * sizeof (short),
3108 sizeof (short));
3110 free (edata);
3112 for (cnt = 0; cnt < total; cnt += 4)
3114 int j, nn;
3116 printf (" %03x:", cnt);
3118 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3119 switch (data [cnt + j])
3121 case 0:
3122 fputs (_(" 0 (*local*) "), stdout);
3123 break;
3125 case 1:
3126 fputs (_(" 1 (*global*) "), stdout);
3127 break;
3129 default:
3130 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
3131 data [cnt + j] & 0x8000 ? 'h' : ' ');
3133 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
3134 && section_headers[symbols [cnt + j].st_shndx].sh_type
3135 == SHT_NOBITS)
3137 /* We must test both. */
3138 Elf_Internal_Verneed ivn;
3139 unsigned long offset;
3141 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3142 - loadaddr;
3146 Elf_External_Verneed evn;
3147 Elf_External_Vernaux evna;
3148 Elf_Internal_Vernaux ivna;
3149 unsigned long vna_off;
3151 GET_DATA (offset, evn, "version need");
3153 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3154 ivn.vn_next = BYTE_GET (evn.vn_next);
3156 vna_off = offset + ivn.vn_aux;
3160 GET_DATA (vna_off, evna,
3161 "version need aux (1)");
3163 ivna.vna_next = BYTE_GET (evna.vna_next);
3164 ivna.vna_other = BYTE_GET (evna.vna_other);
3166 vna_off += ivna.vna_next;
3168 while (ivna.vna_other != data [cnt + j]
3169 && ivna.vna_next != 0);
3171 if (ivna.vna_other == data [cnt + j])
3173 ivna.vna_name = BYTE_GET (evna.vna_name);
3175 nn += printf ("(%s%-*s",
3176 strtab + ivna.vna_name,
3177 12 - strlen (strtab
3178 + ivna.vna_name),
3179 ")");
3180 break;
3182 else if (ivn.vn_next == 0)
3184 if (data [cnt + j] != 0x8001)
3186 Elf_Internal_Verdef ivd;
3187 Elf_External_Verdef evd;
3189 offset = version_info
3190 [DT_VERSIONTAGIDX (DT_VERDEF)]
3191 - loadaddr;
3195 GET_DATA (offset, evd,
3196 "version definition");
3198 ivd.vd_next = BYTE_GET (evd.vd_next);
3199 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3201 offset += ivd.vd_next;
3203 while (ivd.vd_ndx
3204 != (data [cnt + j] & 0x7fff)
3205 && ivd.vd_next != 0);
3207 if (ivd.vd_ndx
3208 == (data [cnt + j] & 0x7fff))
3210 Elf_External_Verdaux evda;
3211 Elf_Internal_Verdaux ivda;
3213 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3215 GET_DATA (offset + ivd.vd_aux, evda,
3216 "version definition aux");
3218 ivda.vda_name =
3219 BYTE_GET (evda.vda_name);
3221 nn +=
3222 printf ("(%s%-*s",
3223 strtab + ivda.vda_name,
3225 - strlen (strtab
3226 + ivda.vda_name),
3227 ")");
3231 break;
3233 else
3234 offset += ivn.vn_next;
3236 while (ivn.vn_next);
3238 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
3240 Elf_Internal_Verneed ivn;
3241 unsigned long offset;
3243 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3244 - loadaddr;
3248 Elf_Internal_Vernaux ivna;
3249 Elf_External_Verneed evn;
3250 Elf_External_Vernaux evna;
3251 unsigned long a_off;
3253 GET_DATA (offset, evn, "version need");
3255 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3256 ivn.vn_next = BYTE_GET (evn.vn_next);
3258 a_off = offset + ivn.vn_aux;
3262 GET_DATA (a_off, evna,
3263 "version need aux (2)");
3265 ivna.vna_next = BYTE_GET (evna.vna_next);
3266 ivna.vna_other = BYTE_GET (evna.vna_other);
3268 a_off += ivna.vna_next;
3270 while (ivna.vna_other != data [cnt + j]
3271 && ivna.vna_next != 0);
3273 if (ivna.vna_other == data [cnt + j])
3275 ivna.vna_name = BYTE_GET (evna.vna_name);
3277 nn += printf ("(%s%-*s",
3278 strtab + ivna.vna_name,
3279 12 - strlen (strtab
3280 + ivna.vna_name),
3281 ")");
3282 break;
3285 offset += ivn.vn_next;
3287 while (ivn.vn_next);
3289 else if (data [cnt + j] != 0x8001)
3291 Elf_Internal_Verdef ivd;
3292 Elf_External_Verdef evd;
3293 unsigned long offset;
3295 offset = version_info
3296 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
3300 GET_DATA (offset, evd, "version def");
3302 ivd.vd_next = BYTE_GET (evd.vd_next);
3303 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3305 offset += ivd.vd_next;
3307 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
3308 && ivd.vd_next != 0);
3310 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
3312 Elf_External_Verdaux evda;
3313 Elf_Internal_Verdaux ivda;
3315 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3317 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
3318 evda, "version def aux");
3320 ivda.vda_name = BYTE_GET (evda.vda_name);
3322 nn += printf ("(%s%-*s",
3323 strtab + ivda.vda_name,
3324 12 - strlen (strtab
3325 + ivda.vda_name),
3326 ")");
3330 if (nn < 18)
3331 printf ("%*c", 18 - nn, ' ');
3334 putchar ('\n');
3337 free (data);
3338 free (strtab);
3339 free (symbols);
3341 break;
3343 default:
3344 break;
3348 if (! found)
3349 printf (_("\nNo version information found in this file.\n"));
3351 return 1;
3354 static char *
3355 get_symbol_binding (binding)
3356 unsigned int binding;
3358 static char buff [32];
3360 switch (binding)
3362 case STB_LOCAL: return _("LOCAL");
3363 case STB_GLOBAL: return _("GLOBAL");
3364 case STB_WEAK: return _("WEAK");
3365 default:
3366 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3367 sprintf (buff, _("<processor specific>: %d"), binding);
3368 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3369 sprintf (buff, _("<OS specific>: %d"), binding);
3370 else
3371 sprintf (buff, _("<unknown>: %d"), binding);
3372 return buff;
3376 static char *
3377 get_symbol_type (type)
3378 unsigned int type;
3380 static char buff [32];
3382 switch (type)
3384 case STT_NOTYPE: return _("NOTYPE");
3385 case STT_OBJECT: return _("OBJECT");
3386 case STT_FUNC: return _("FUNC");
3387 case STT_SECTION: return _("SECTION");
3388 case STT_FILE: return _("FILE");
3389 default:
3390 if (type >= STT_LOPROC && type <= STT_HIPROC)
3391 sprintf (buff, _("<processor specific>: %d"), type);
3392 else if (type >= STT_LOOS && type <= STT_HIOS)
3393 sprintf (buff, _("<OS specific>: %d"), type);
3394 else
3395 sprintf (buff, _("<unknown>: %d"), type);
3396 return buff;
3400 static char *
3401 get_symbol_index_type (type)
3402 unsigned int type;
3404 switch (type)
3406 case SHN_UNDEF: return "UND";
3407 case SHN_ABS: return "ABS";
3408 case SHN_COMMON: return "COM";
3409 default:
3410 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3411 return "PRC";
3412 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3413 return "RSV";
3414 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3415 return "OS ";
3416 else
3418 static char buff [32];
3420 sprintf (buff, "%3d", type);
3421 return buff;
3427 static int *
3428 get_dynamic_data (file, number)
3429 FILE * file;
3430 unsigned int number;
3432 char * e_data;
3433 int * i_data;
3435 e_data = (char *) malloc (number * 4);
3437 if (e_data == NULL)
3439 error (_("Out of memory\n"));
3440 return NULL;
3443 if (fread (e_data, 4, number, file) != number)
3445 error (_("Unable to read in dynamic data\n"));
3446 return NULL;
3449 i_data = (int *) malloc (number * sizeof (* i_data));
3451 if (i_data == NULL)
3453 error (_("Out of memory\n"));
3454 free (e_data);
3455 return NULL;
3458 while (number--)
3459 i_data [number] = byte_get (e_data + number * 4, 4);
3461 free (e_data);
3463 return i_data;
3466 /* Dump the symbol table */
3467 static int
3468 process_symbol_table (file)
3469 FILE * file;
3471 Elf32_Internal_Shdr * section;
3472 char nb [4];
3473 char nc [4];
3474 int nbuckets;
3475 int nchains;
3476 int * buckets = NULL;
3477 int * chains = NULL;
3479 if (! do_syms && !do_histogram)
3480 return 1;
3482 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3483 || do_histogram))
3485 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3487 error (_("Unable to seek to start of dynamic information"));
3488 return 0;
3491 if (fread (nb, sizeof (nb), 1, file) != 1)
3493 error (_("Failed to read in number of buckets\n"));
3494 return 0;
3497 if (fread (nc, sizeof (nc), 1, file) != 1)
3499 error (_("Failed to read in number of chains\n"));
3500 return 0;
3503 nbuckets = byte_get (nb, 4);
3504 nchains = byte_get (nc, 4);
3506 buckets = get_dynamic_data (file, nbuckets);
3507 chains = get_dynamic_data (file, nchains);
3509 if (buckets == NULL || chains == NULL)
3510 return 0;
3513 if (do_syms
3514 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3516 int hn;
3517 int si;
3519 printf (_("\nSymbol table for image:\n"));
3520 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3522 for (hn = 0; hn < nbuckets; hn++)
3524 if (! buckets [hn])
3525 continue;
3527 for (si = buckets [hn]; si; si = chains [si])
3529 Elf_Internal_Sym * psym;
3531 psym = dynamic_symbols + si;
3533 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3534 si, hn,
3535 (unsigned long) psym->st_value,
3536 (unsigned long) psym->st_size,
3537 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3538 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3539 psym->st_other);
3541 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3543 printf (" %s\n", dynamic_strings + psym->st_name);
3547 else if (do_syms && !do_using_dynamic)
3549 unsigned int i;
3551 for (i = 0, section = section_headers;
3552 i < elf_header.e_shnum;
3553 i++, section++)
3555 unsigned int si;
3556 char * strtab;
3557 Elf_Internal_Sym * symtab;
3558 Elf_Internal_Sym * psym;
3561 if ( section->sh_type != SHT_SYMTAB
3562 && section->sh_type != SHT_DYNSYM)
3563 continue;
3565 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3566 SECTION_NAME (section),
3567 (unsigned long) (section->sh_size / section->sh_entsize));
3568 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3569 stdout);
3571 symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
3572 section->sh_size / section->sh_entsize);
3573 if (symtab == NULL)
3574 continue;
3576 if (section->sh_link == elf_header.e_shstrndx)
3577 strtab = string_table;
3578 else
3580 Elf32_Internal_Shdr * string_sec;
3582 string_sec = section_headers + section->sh_link;
3584 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3585 strtab, char *, "string table");
3588 for (si = 0, psym = symtab;
3589 si < section->sh_size / section->sh_entsize;
3590 si ++, psym ++)
3592 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3594 (unsigned long) psym->st_value,
3595 (unsigned long) psym->st_size,
3596 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3597 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3598 psym->st_other);
3600 printf ("%4s", get_symbol_index_type (psym->st_shndx));
3602 printf (" %s", strtab + psym->st_name);
3604 if (section->sh_type == SHT_DYNSYM &&
3605 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3607 unsigned char data[2];
3608 unsigned short vers_data;
3609 unsigned long offset;
3610 int is_nobits;
3611 int check_def;
3613 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3614 - loadaddr;
3616 GET_DATA (offset + si * sizeof (vers_data), data,
3617 "version data");
3619 vers_data = byte_get (data, 2);
3621 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3622 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3623 : 0;
3625 check_def = (psym->st_shndx != SHN_UNDEF);
3627 if ((vers_data & 0x8000) || vers_data > 1)
3629 if (is_nobits || ! check_def)
3631 Elf_External_Verneed evn;
3632 Elf_Internal_Verneed ivn;
3633 Elf_Internal_Vernaux ivna;
3635 /* We must test both. */
3636 offset = version_info
3637 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3639 GET_DATA (offset, evn, "version need");
3641 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3642 ivn.vn_next = BYTE_GET (evn.vn_next);
3646 unsigned long vna_off;
3648 vna_off = offset + ivn.vn_aux;
3652 Elf_External_Vernaux evna;
3654 GET_DATA (vna_off, evna,
3655 "version need aux (3)");
3657 ivna.vna_other = BYTE_GET (evna.vna_other);
3658 ivna.vna_next = BYTE_GET (evna.vna_next);
3659 ivna.vna_name = BYTE_GET (evna.vna_name);
3661 vna_off += ivna.vna_next;
3663 while (ivna.vna_other != vers_data
3664 && ivna.vna_next != 0);
3666 if (ivna.vna_other == vers_data)
3667 break;
3669 offset += ivn.vn_next;
3671 while (ivn.vn_next != 0);
3673 if (ivna.vna_other == vers_data)
3675 printf ("@%s (%d)",
3676 strtab + ivna.vna_name, ivna.vna_other);
3677 check_def = 0;
3679 else if (! is_nobits)
3680 error (_("bad dynamic symbol"));
3681 else
3682 check_def = 1;
3685 if (check_def)
3687 if (vers_data != 0x8001)
3689 Elf_Internal_Verdef ivd;
3690 Elf_Internal_Verdaux ivda;
3691 Elf_External_Verdaux evda;
3692 unsigned long offset;
3694 offset =
3695 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3696 - loadaddr;
3700 Elf_External_Verdef evd;
3702 GET_DATA (offset, evd, "version def");
3704 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3705 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3706 ivd.vd_next = BYTE_GET (evd.vd_next);
3708 offset += ivd.vd_next;
3710 while (ivd.vd_ndx != (vers_data & 0x7fff)
3711 && ivd.vd_next != 0);
3713 offset -= ivd.vd_next;
3714 offset += ivd.vd_aux;
3716 GET_DATA (offset, evda, "version def aux");
3718 ivda.vda_name = BYTE_GET (evda.vda_name);
3720 if (psym->st_name != ivda.vda_name)
3721 printf ((vers_data & 0x8000)
3722 ? "@%s" : "@@%s",
3723 strtab + ivda.vda_name);
3729 putchar ('\n');
3732 free (symtab);
3733 if (strtab != string_table)
3734 free (strtab);
3737 else if (do_syms)
3738 printf
3739 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3741 if (do_histogram && buckets != NULL)
3743 int *lengths;
3744 int *counts;
3745 int hn;
3746 int si;
3747 int maxlength = 0;
3748 int nzero_counts = 0;
3749 int nsyms = 0;
3751 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3752 nbuckets);
3753 printf (_(" Length Number %% of total Coverage\n"));
3755 lengths = (int *) calloc (nbuckets, sizeof (int));
3756 if (lengths == NULL)
3758 error (_("Out of memory"));
3759 return 0;
3761 for (hn = 0; hn < nbuckets; ++hn)
3763 if (! buckets [hn])
3764 continue;
3766 for (si = buckets[hn]; si; si = chains[si])
3768 ++nsyms;
3769 if (maxlength < ++lengths[hn])
3770 ++maxlength;
3774 counts = (int *) calloc (maxlength + 1, sizeof (int));
3775 if (counts == NULL)
3777 error (_("Out of memory"));
3778 return 0;
3781 for (hn = 0; hn < nbuckets; ++hn)
3782 ++ counts [lengths [hn]];
3784 printf (" 0 %-10d (%5.1f%%)\n",
3785 counts[0], (counts[0] * 100.0) / nbuckets);
3786 for (si = 1; si <= maxlength; ++si)
3788 nzero_counts += counts[si] * si;
3789 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3790 si, counts[si], (counts[si] * 100.0) / nbuckets,
3791 (nzero_counts * 100.0) / nsyms);
3794 free (counts);
3795 free (lengths);
3798 if (buckets != NULL)
3800 free (buckets);
3801 free (chains);
3804 return 1;
3807 static int
3808 process_syminfo (file)
3809 FILE * file;
3811 int i;
3813 if (dynamic_syminfo == NULL
3814 || !do_dynamic)
3815 /* No syminfo, this is ok. */
3816 return 1;
3818 /* There better should be a dynamic symbol section. */
3819 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3820 return 0;
3822 if (dynamic_addr)
3823 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3824 dynamic_syminfo_offset, dynamic_syminfo_nent);
3826 printf (_(" Num: Name BoundTo Flags\n"));
3827 for (i = 0; i < dynamic_syminfo_nent; ++i)
3829 unsigned short int flags = dynamic_syminfo[i].si_flags;
3831 printf ("%4d: %-30s ", i,
3832 dynamic_strings + dynamic_symbols[i].st_name);
3834 switch (dynamic_syminfo[i].si_boundto)
3836 case SYMINFO_BT_SELF:
3837 fputs ("SELF ", stdout);
3838 break;
3839 case SYMINFO_BT_PARENT:
3840 fputs ("PARENT ", stdout);
3841 break;
3842 default:
3843 if (dynamic_syminfo[i].si_boundto > 0
3844 && dynamic_syminfo[i].si_boundto < dynamic_size)
3845 printf ("%-10s ",
3846 dynamic_strings
3847 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3848 else
3849 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3850 break;
3853 if (flags & SYMINFO_FLG_DIRECT)
3854 printf (" DIRECT");
3855 if (flags & SYMINFO_FLG_PASSTHRU)
3856 printf (" PASSTHRU");
3857 if (flags & SYMINFO_FLG_COPY)
3858 printf (" COPY");
3859 if (flags & SYMINFO_FLG_LAZYLOAD)
3860 printf (" LAZYLOAD");
3862 puts ("");
3865 return 1;
3868 #ifdef SUPPORT_DISASSEMBLY
3869 static void
3870 disassemble_section (section, file)
3871 Elf32_Internal_Shdr * section;
3872 FILE * file;
3874 printf (_("\nAssembly dump of section %s\n"),
3875 SECTION_NAME (section));
3877 /* XXX -- to be done --- XXX */
3879 return 1;
3881 #endif
3883 static int
3884 dump_section (section, file)
3885 Elf32_Internal_Shdr * section;
3886 FILE * file;
3888 bfd_size_type bytes;
3889 bfd_vma addr;
3890 unsigned char * data;
3891 unsigned char * start;
3893 bytes = section->sh_size;
3895 if (bytes == 0)
3897 printf (_("\nSection '%s' has no data to dump.\n"),
3898 SECTION_NAME (section));
3899 return 0;
3901 else
3902 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3904 addr = section->sh_addr;
3906 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3907 "section data");
3909 data = start;
3911 while (bytes)
3913 int j;
3914 int k;
3915 int lbytes;
3917 lbytes = (bytes > 16 ? 16 : bytes);
3919 printf (" 0x%8.8lx ", (unsigned long) addr);
3921 switch (elf_header.e_ident [EI_DATA])
3923 default:
3924 case ELFDATA2LSB:
3925 for (j = 15; j >= 0; j --)
3927 if (j < lbytes)
3928 printf ("%2.2x", data [j]);
3929 else
3930 printf (" ");
3932 if (!(j & 0x3))
3933 printf (" ");
3935 break;
3937 case ELFDATA2MSB:
3938 for (j = 0; j < 16; j++)
3940 if (j < lbytes)
3941 printf ("%2.2x", data [j]);
3942 else
3943 printf (" ");
3945 if ((j & 3) == 3)
3946 printf (" ");
3948 break;
3951 for (j = 0; j < lbytes; j++)
3953 k = data [j];
3954 if (k >= ' ' && k < 0x80)
3955 printf ("%c", k);
3956 else
3957 printf (".");
3960 putchar ('\n');
3962 data += lbytes;
3963 addr += lbytes;
3964 bytes -= lbytes;
3967 free (start);
3969 return 1;
3973 static unsigned long int
3974 read_leb128 (data, length_return, sign)
3975 unsigned char * data;
3976 int * length_return;
3977 int sign;
3979 unsigned long int result = 0;
3980 unsigned int num_read = 0;
3981 int shift = 0;
3982 unsigned char byte;
3986 byte = * data ++;
3987 num_read ++;
3989 result |= (byte & 0x7f) << shift;
3991 shift += 7;
3994 while (byte & 0x80);
3996 if (length_return != NULL)
3997 * length_return = num_read;
3999 if (sign && (shift < 32) && (byte & 0x40))
4000 result |= -1 << shift;
4002 return result;
4005 typedef struct State_Machine_Registers
4007 unsigned long address;
4008 unsigned int file;
4009 unsigned int line;
4010 unsigned int column;
4011 int is_stmt;
4012 int basic_block;
4013 int end_sequence;
4014 /* This variable hold the number of the last entry seen
4015 in the File Table. */
4016 unsigned int last_file_entry;
4017 } SMR;
4019 static SMR state_machine_regs;
4021 static void
4022 reset_state_machine (is_stmt)
4023 int is_stmt;
4025 state_machine_regs.address = 0;
4026 state_machine_regs.file = 1;
4027 state_machine_regs.line = 1;
4028 state_machine_regs.column = 0;
4029 state_machine_regs.is_stmt = is_stmt;
4030 state_machine_regs.basic_block = 0;
4031 state_machine_regs.end_sequence = 0;
4032 state_machine_regs.last_file_entry = 0;
4035 /* Handled an extend line op. Returns true if this is the end
4036 of sequence. */
4037 static int
4038 process_extended_line_op (data, is_stmt)
4039 unsigned char * data;
4040 int is_stmt;
4042 unsigned char op_code;
4043 int bytes_read;
4044 unsigned int len;
4045 unsigned char * name;
4046 unsigned long adr;
4048 len = read_leb128 (data, & bytes_read, 0);
4049 data += bytes_read;
4051 if (len == 0)
4053 warn (_("badly formed extended line op encountered!"));
4054 return bytes_read;
4057 len += bytes_read;
4058 op_code = * data ++;
4060 printf (_(" Extended opcode %d: "), op_code);
4062 switch (op_code)
4064 case DW_LNE_end_sequence:
4065 printf (_("End of Sequence\n\n"));
4066 reset_state_machine (is_stmt);
4067 break;
4069 case DW_LNE_set_address:
4070 /* XXX - assumption here that address size is 4! */
4071 adr = byte_get (data, 4);
4072 printf (_("set Address to 0x%lx\n"), adr);
4073 state_machine_regs.address = adr;
4074 break;
4076 case DW_LNE_define_file:
4077 printf (_(" define new File Table entry\n"));
4078 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4080 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4081 name = data;
4082 data += strlen (data) + 1;
4083 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4084 data += bytes_read;
4085 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4086 data += bytes_read;
4087 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4088 printf (_("%s\n\n"), name);
4089 break;
4091 default:
4092 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
4093 break;
4096 return len;
4100 static int
4101 display_debug_lines (section, start, file)
4102 Elf32_Internal_Shdr * section;
4103 unsigned char * start;
4104 FILE * file;
4106 DWARF2_External_LineInfo * external;
4107 DWARF2_Internal_LineInfo info;
4108 unsigned char * standard_opcodes;
4109 unsigned char * data = start;
4110 unsigned char * end = start + section->sh_size;
4111 unsigned char * end_of_sequence;
4112 int i;
4114 printf (_("\nDump of debug contents of section %s:\n\n"),
4115 SECTION_NAME (section));
4117 while (data < end)
4119 external = (DWARF2_External_LineInfo *) data;
4121 /* Check the length of the block. */
4122 info.li_length = BYTE_GET (external->li_length);
4123 if (info.li_length > section->sh_size)
4125 warn
4126 (_("The line info appears to be corrupt - the section is too small\n"));
4127 return 0;
4130 /* Check its version number. */
4131 info.li_version = BYTE_GET (external->li_version);
4132 if (info.li_version != 2)
4134 warn (_("Only DWARF version 2 line info is currently supported.\n"));
4135 return 0;
4138 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
4139 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
4140 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
4141 info.li_line_base = BYTE_GET (external->li_line_base);
4142 info.li_line_range = BYTE_GET (external->li_line_range);
4143 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
4145 /* Sign extend the line base field. */
4146 info.li_line_base <<= 24;
4147 info.li_line_base >>= 24;
4149 printf (_(" Length: %ld\n"), info.li_length);
4150 printf (_(" DWARF Version: %d\n"), info.li_version);
4151 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
4152 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
4153 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
4154 printf (_(" Line Base: %d\n"), info.li_line_base);
4155 printf (_(" Line Range: %d\n"), info.li_line_range);
4156 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
4158 end_of_sequence = data + info.li_length + sizeof (info.li_length);
4160 reset_state_machine (info.li_default_is_stmt);
4162 /* Display the contents of the Opcodes table. */
4163 standard_opcodes = data + sizeof (* external);
4165 printf (_("\n Opcodes:\n"));
4167 for (i = 1; i < info.li_opcode_base; i++)
4168 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
4170 /* Display the contents of the Directory table. */
4171 data = standard_opcodes + info.li_opcode_base - 1;
4173 if (* data == 0)
4174 printf (_("\n The Directory Table is empty.\n"));
4175 else
4177 printf (_("\n The Directory Table:\n"));
4179 while (* data != 0)
4181 printf (_(" %s\n"), data);
4183 data += strlen (data) + 1;
4187 /* Skip the NUL at the end of the table. */
4188 data ++;
4190 /* Display the contents of the File Name table. */
4191 if (* data == 0)
4192 printf (_("\n The File Name Table is empty.\n"));
4193 else
4195 printf (_("\n The File Name Table:\n"));
4196 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
4198 while (* data != 0)
4200 char * name;
4201 int bytes_read;
4203 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
4204 name = data;
4206 data += strlen (data) + 1;
4208 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4209 data += bytes_read;
4210 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4211 data += bytes_read;
4212 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4213 data += bytes_read;
4214 printf (_("%s\n"), name);
4218 /* Skip the NUL at the end of the table. */
4219 data ++;
4221 /* Now display the statements. */
4222 printf (_("\n Line Number Statements:\n"));
4225 while (data < end_of_sequence)
4227 unsigned char op_code;
4228 int adv;
4229 int bytes_read;
4231 op_code = * data ++;
4233 switch (op_code)
4235 case DW_LNS_extended_op:
4236 data += process_extended_line_op (data, info.li_default_is_stmt);
4237 break;
4239 case DW_LNS_copy:
4240 printf (_(" Copy\n"));
4241 break;
4243 case DW_LNS_advance_pc:
4244 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
4245 data += bytes_read;
4246 state_machine_regs.address += adv;
4247 printf (_(" Advance PC by %d to %lx\n"), adv,
4248 state_machine_regs.address);
4249 break;
4251 case DW_LNS_advance_line:
4252 adv = read_leb128 (data, & bytes_read, 1);
4253 data += bytes_read;
4254 state_machine_regs.line += adv;
4255 printf (_(" Advance Line by %d to %d\n"), adv,
4256 state_machine_regs.line);
4257 break;
4259 case DW_LNS_set_file:
4260 adv = read_leb128 (data, & bytes_read, 0);
4261 data += bytes_read;
4262 printf (_(" Set File Name to entry %d in the File Name Table\n"),
4263 adv);
4264 state_machine_regs.file = adv;
4265 break;
4267 case DW_LNS_set_column:
4268 adv = read_leb128 (data, & bytes_read, 0);
4269 data += bytes_read;
4270 printf (_(" Set column to %d\n"), adv);
4271 state_machine_regs.column = adv;
4272 break;
4274 case DW_LNS_negate_stmt:
4275 adv = state_machine_regs.is_stmt;
4276 adv = ! adv;
4277 printf (_(" Set is_stmt to %d\n"), adv);
4278 state_machine_regs.is_stmt = adv;
4279 break;
4281 case DW_LNS_set_basic_block:
4282 printf (_(" Set basic block\n"));
4283 state_machine_regs.basic_block = 1;
4284 break;
4286 case DW_LNS_const_add_pc:
4287 adv = (255 - info.li_opcode_base) / info.li_line_range;
4288 state_machine_regs.address += adv;
4289 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
4290 state_machine_regs.address);
4291 break;
4293 case DW_LNS_fixed_advance_pc:
4294 adv = byte_get (data, 2);
4295 data += 2;
4296 state_machine_regs.address += adv;
4297 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
4298 adv, state_machine_regs.address);
4299 break;
4301 default:
4302 op_code -= info.li_opcode_base;
4303 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
4304 state_machine_regs.address += adv;
4305 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
4306 op_code, adv, state_machine_regs.address);
4307 adv += (op_code % info.li_line_range) + info.li_line_base;
4308 state_machine_regs.line += adv;
4309 printf (_(" and Line by %d to %d\n"),
4310 adv, state_machine_regs.line);
4311 break;
4314 printf ("\n");
4317 return 1;
4320 static int
4321 display_debug_pubnames (section, start, file)
4322 Elf32_Internal_Shdr * section;
4323 unsigned char * start;
4324 FILE * file;
4326 DWARF2_External_PubNames * external;
4327 DWARF2_Internal_PubNames pubnames;
4328 unsigned char * end;
4330 end = start + section->sh_size;
4332 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4334 while (start < end)
4336 unsigned char * data;
4337 unsigned long offset;
4339 external = (DWARF2_External_PubNames *) start;
4341 pubnames.pn_length = BYTE_GET (external->pn_length);
4342 pubnames.pn_version = BYTE_GET (external->pn_version);
4343 pubnames.pn_offset = BYTE_GET (external->pn_offset);
4344 pubnames.pn_size = BYTE_GET (external->pn_size);
4346 data = start + sizeof (* external);
4347 start += pubnames.pn_length + sizeof (external->pn_length);
4349 if (pubnames.pn_version != 2)
4351 warn (_("Only DWARF 2 pubnames are currently supported"));
4352 continue;
4355 printf (_(" Length: %ld\n"),
4356 pubnames.pn_length);
4357 printf (_(" Version: %d\n"),
4358 pubnames.pn_version);
4359 printf (_(" Offset into .debug_info section: %ld\n"),
4360 pubnames.pn_offset);
4361 printf (_(" Size of area in .debug_info section: %ld\n"),
4362 pubnames.pn_size);
4364 printf (_("\n Offset\tName\n"));
4368 offset = byte_get (data, 4);
4370 if (offset != 0)
4372 data += 4;
4373 printf (" %ld\t\t%s\n", offset, data);
4374 data += strlen (data) + 1;
4377 while (offset != 0);
4380 printf ("\n");
4381 return 1;
4384 static char *
4385 get_TAG_name (tag)
4386 unsigned long tag;
4388 switch (tag)
4390 case DW_TAG_padding: return "DW_TAG_padding";
4391 case DW_TAG_array_type: return "DW_TAG_array_type";
4392 case DW_TAG_class_type: return "DW_TAG_class_type";
4393 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4394 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4395 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4396 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4397 case DW_TAG_label: return "DW_TAG_label";
4398 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4399 case DW_TAG_member: return "DW_TAG_member";
4400 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4401 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4402 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4403 case DW_TAG_string_type: return "DW_TAG_string_type";
4404 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4405 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4406 case DW_TAG_typedef: return "DW_TAG_typedef";
4407 case DW_TAG_union_type: return "DW_TAG_union_type";
4408 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4409 case DW_TAG_variant: return "DW_TAG_variant";
4410 case DW_TAG_common_block: return "DW_TAG_common_block";
4411 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4412 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4413 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4414 case DW_TAG_module: return "DW_TAG_module";
4415 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4416 case DW_TAG_set_type: return "DW_TAG_set_type";
4417 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4418 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4419 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4420 case DW_TAG_base_type: return "DW_TAG_base_type";
4421 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4422 case DW_TAG_const_type: return "DW_TAG_const_type";
4423 case DW_TAG_constant: return "DW_TAG_constant";
4424 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4425 case DW_TAG_file_type: return "DW_TAG_file_type";
4426 case DW_TAG_friend: return "DW_TAG_friend";
4427 case DW_TAG_namelist: return "DW_TAG_namelist";
4428 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4429 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4430 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4431 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4432 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4433 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4434 case DW_TAG_try_block: return "DW_TAG_try_block";
4435 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4436 case DW_TAG_variable: return "DW_TAG_variable";
4437 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4438 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4439 case DW_TAG_format_label: return "DW_TAG_format_label";
4440 case DW_TAG_function_template: return "DW_TAG_function_template";
4441 case DW_TAG_class_template: return "DW_TAG_class_template";
4442 default:
4444 static char buffer [100];
4446 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4447 return buffer;
4452 static char *
4453 get_AT_name (attribute)
4454 unsigned long attribute;
4456 switch (attribute)
4458 case DW_AT_sibling: return "DW_AT_sibling";
4459 case DW_AT_location: return "DW_AT_location";
4460 case DW_AT_name: return "DW_AT_name";
4461 case DW_AT_ordering: return "DW_AT_ordering";
4462 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4463 case DW_AT_byte_size: return "DW_AT_byte_size";
4464 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4465 case DW_AT_bit_size: return "DW_AT_bit_size";
4466 case DW_AT_element_list: return "DW_AT_element_list";
4467 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4468 case DW_AT_low_pc: return "DW_AT_low_pc";
4469 case DW_AT_high_pc: return "DW_AT_high_pc";
4470 case DW_AT_language: return "DW_AT_language";
4471 case DW_AT_member: return "DW_AT_member";
4472 case DW_AT_discr: return "DW_AT_discr";
4473 case DW_AT_discr_value: return "DW_AT_discr_value";
4474 case DW_AT_visibility: return "DW_AT_visibility";
4475 case DW_AT_import: return "DW_AT_import";
4476 case DW_AT_string_length: return "DW_AT_string_length";
4477 case DW_AT_common_reference: return "DW_AT_common_reference";
4478 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4479 case DW_AT_const_value: return "DW_AT_const_value";
4480 case DW_AT_containing_type: return "DW_AT_containing_type";
4481 case DW_AT_default_value: return "DW_AT_default_value";
4482 case DW_AT_inline: return "DW_AT_inline";
4483 case DW_AT_is_optional: return "DW_AT_is_optional";
4484 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4485 case DW_AT_producer: return "DW_AT_producer";
4486 case DW_AT_prototyped: return "DW_AT_prototyped";
4487 case DW_AT_return_addr: return "DW_AT_return_addr";
4488 case DW_AT_start_scope: return "DW_AT_start_scope";
4489 case DW_AT_stride_size: return "DW_AT_stride_size";
4490 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4491 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4492 case DW_AT_accessibility: return "DW_AT_accessibility";
4493 case DW_AT_address_class: return "DW_AT_address_class";
4494 case DW_AT_artificial: return "DW_AT_artificial";
4495 case DW_AT_base_types: return "DW_AT_base_types";
4496 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4497 case DW_AT_count: return "DW_AT_count";
4498 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4499 case DW_AT_decl_column: return "DW_AT_decl_column";
4500 case DW_AT_decl_file: return "DW_AT_decl_file";
4501 case DW_AT_decl_line: return "DW_AT_decl_line";
4502 case DW_AT_declaration: return "DW_AT_declaration";
4503 case DW_AT_discr_list: return "DW_AT_discr_list";
4504 case DW_AT_encoding: return "DW_AT_encoding";
4505 case DW_AT_external: return "DW_AT_external";
4506 case DW_AT_frame_base: return "DW_AT_frame_base";
4507 case DW_AT_friend: return "DW_AT_friend";
4508 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4509 case DW_AT_macro_info: return "DW_AT_macro_info";
4510 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4511 case DW_AT_priority: return "DW_AT_priority";
4512 case DW_AT_segment: return "DW_AT_segment";
4513 case DW_AT_specification: return "DW_AT_specification";
4514 case DW_AT_static_link: return "DW_AT_static_link";
4515 case DW_AT_type: return "DW_AT_type";
4516 case DW_AT_use_location: return "DW_AT_use_location";
4517 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4518 case DW_AT_virtuality: return "DW_AT_virtuality";
4519 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4520 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4521 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4522 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4523 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4524 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4525 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4526 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4527 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4528 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4529 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4530 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4531 case DW_AT_sf_names: return "DW_AT_sf_names";
4532 case DW_AT_src_info: return "DW_AT_src_info";
4533 case DW_AT_mac_info: return "DW_AT_mac_info";
4534 case DW_AT_src_coords: return "DW_AT_src_coords";
4535 case DW_AT_body_begin: return "DW_AT_body_begin";
4536 case DW_AT_body_end: return "DW_AT_body_end";
4537 default:
4539 static char buffer [100];
4541 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4542 return buffer;
4547 static char *
4548 get_FORM_name (form)
4549 unsigned long form;
4551 switch (form)
4553 case DW_FORM_addr: return "DW_FORM_addr";
4554 case DW_FORM_block2: return "DW_FORM_block2";
4555 case DW_FORM_block4: return "DW_FORM_block4";
4556 case DW_FORM_data2: return "DW_FORM_data2";
4557 case DW_FORM_data4: return "DW_FORM_data4";
4558 case DW_FORM_data8: return "DW_FORM_data8";
4559 case DW_FORM_string: return "DW_FORM_string";
4560 case DW_FORM_block: return "DW_FORM_block";
4561 case DW_FORM_block1: return "DW_FORM_block1";
4562 case DW_FORM_data1: return "DW_FORM_data1";
4563 case DW_FORM_flag: return "DW_FORM_flag";
4564 case DW_FORM_sdata: return "DW_FORM_sdata";
4565 case DW_FORM_strp: return "DW_FORM_strp";
4566 case DW_FORM_udata: return "DW_FORM_udata";
4567 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4568 case DW_FORM_ref1: return "DW_FORM_ref1";
4569 case DW_FORM_ref2: return "DW_FORM_ref2";
4570 case DW_FORM_ref4: return "DW_FORM_ref4";
4571 case DW_FORM_ref8: return "DW_FORM_ref8";
4572 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4573 case DW_FORM_indirect: return "DW_FORM_indirect";
4574 default:
4576 static char buffer [100];
4578 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4579 return buffer;
4584 /* FIXME: There are better and more effiecint ways to handle
4585 these structures. For now though, I just want something that
4586 is simple to implement. */
4587 typedef struct abbrev_attr
4589 unsigned long attribute;
4590 unsigned long form;
4591 struct abbrev_attr * next;
4593 abbrev_attr;
4595 typedef struct abbrev_entry
4597 unsigned long entry;
4598 unsigned long tag;
4599 int children;
4600 struct abbrev_attr * first_attr;
4601 struct abbrev_attr * last_attr;
4602 struct abbrev_entry * next;
4604 abbrev_entry;
4606 static abbrev_entry * first_abbrev = NULL;
4607 static abbrev_entry * last_abbrev = NULL;
4609 static void
4610 free_abbrevs PARAMS ((void))
4612 abbrev_entry * abbrev;
4614 for (abbrev = first_abbrev; abbrev;)
4616 abbrev_entry * next = abbrev->next;
4617 abbrev_attr * attr;
4619 for (attr = abbrev->first_attr; attr;)
4621 abbrev_attr * next = attr->next;
4623 free (attr);
4624 attr = next;
4627 free (abbrev);
4628 abbrev = next;
4631 last_abbrev = first_abbrev = NULL;
4634 static void
4635 add_abbrev (number, tag, children)
4636 unsigned long number;
4637 unsigned long tag;
4638 int children;
4640 abbrev_entry * entry;
4642 entry = (abbrev_entry *) malloc (sizeof (* entry));
4644 if (entry == NULL)
4645 /* ugg */
4646 return;
4648 entry->entry = number;
4649 entry->tag = tag;
4650 entry->children = children;
4651 entry->first_attr = NULL;
4652 entry->last_attr = NULL;
4653 entry->next = NULL;
4655 if (first_abbrev == NULL)
4656 first_abbrev = entry;
4657 else
4658 last_abbrev->next = entry;
4660 last_abbrev = entry;
4663 static void
4664 add_abbrev_attr (attribute, form)
4665 unsigned long attribute;
4666 unsigned long form;
4668 abbrev_attr * attr;
4670 attr = (abbrev_attr *) malloc (sizeof (* attr));
4672 if (attr == NULL)
4673 /* ugg */
4674 return;
4676 attr->attribute = attribute;
4677 attr->form = form;
4678 attr->next = NULL;
4680 if (last_abbrev->first_attr == NULL)
4681 last_abbrev->first_attr = attr;
4682 else
4683 last_abbrev->last_attr->next = attr;
4685 last_abbrev->last_attr = attr;
4688 /* Processes the (partial) contents of a .debug_abbrev section.
4689 Returns NULL if the end of the section was encountered.
4690 Returns the address after the last byte read if the end of
4691 an abbreviation set was found. */
4693 static unsigned char *
4694 process_abbrev_section (start, end)
4695 unsigned char * start;
4696 unsigned char * end;
4698 if (first_abbrev != NULL)
4699 return NULL;
4701 while (start < end)
4703 int bytes_read;
4704 unsigned long entry;
4705 unsigned long tag;
4706 unsigned long attribute;
4707 int children;
4709 entry = read_leb128 (start, & bytes_read, 0);
4710 start += bytes_read;
4712 if (entry == 0)
4713 return start;
4715 tag = read_leb128 (start, & bytes_read, 0);
4716 start += bytes_read;
4718 children = * start ++;
4720 add_abbrev (entry, tag, children);
4724 unsigned long form;
4726 attribute = read_leb128 (start, & bytes_read, 0);
4727 start += bytes_read;
4729 form = read_leb128 (start, & bytes_read, 0);
4730 start += bytes_read;
4732 if (attribute != 0)
4733 add_abbrev_attr (attribute, form);
4735 while (attribute != 0);
4738 return NULL;
4742 static int
4743 display_debug_abbrev (section, start, file)
4744 Elf32_Internal_Shdr * section;
4745 unsigned char * start;
4746 FILE * file;
4748 abbrev_entry * entry;
4749 unsigned char * end = start + section->sh_size;
4751 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4755 start = process_abbrev_section (start, end);
4757 printf (_(" Number TAG\n"));
4759 for (entry = first_abbrev; entry; entry = entry->next)
4761 abbrev_attr * attr;
4763 printf (_(" %ld %s [%s]\n"),
4764 entry->entry,
4765 get_TAG_name (entry->tag),
4766 entry->children ? _("has children") : _("no children"));
4768 for (attr = entry->first_attr; attr; attr = attr->next)
4770 printf (_(" %-18s %s\n"),
4771 get_AT_name (attr->attribute),
4772 get_FORM_name (attr->form));
4776 while (start);
4778 printf ("\n");
4780 return 1;
4784 static unsigned char *
4785 display_block (data, length)
4786 unsigned char * data;
4787 unsigned long length;
4789 printf (_(" %lu byte block: "), length);
4791 while (length --)
4792 printf ("%lx ", (unsigned long) byte_get (data ++, 1));
4794 return data;
4797 static void
4798 decode_location_expression (data, pointer_size)
4799 unsigned char * data;
4800 unsigned int pointer_size;
4802 unsigned char op;
4803 int bytes_read;
4804 unsigned long uvalue;
4806 op = * data ++;
4808 switch (op)
4810 case DW_OP_addr:
4811 printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
4812 break;
4813 case DW_OP_deref:
4814 printf ("DW_OP_deref");
4815 break;
4816 case DW_OP_const1u:
4817 printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
4818 break;
4819 case DW_OP_const1s:
4820 printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
4821 break;
4822 case DW_OP_const2u:
4823 printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
4824 break;
4825 case DW_OP_const2s:
4826 printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
4827 break;
4828 case DW_OP_const4u:
4829 printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
4830 break;
4831 case DW_OP_const4s:
4832 printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
4833 break;
4834 case DW_OP_const8u:
4835 printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
4836 (unsigned long) byte_get (data + 4, 4));
4837 break;
4838 case DW_OP_const8s:
4839 printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
4840 (long) byte_get (data + 4, 4));
4841 break;
4842 case DW_OP_constu:
4843 printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
4844 break;
4845 case DW_OP_consts:
4846 printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
4847 break;
4848 case DW_OP_dup:
4849 printf ("DW_OP_dup");
4850 break;
4851 case DW_OP_drop:
4852 printf ("DW_OP_drop");
4853 break;
4854 case DW_OP_over:
4855 printf ("DW_OP_over");
4856 break;
4857 case DW_OP_pick:
4858 printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
4859 break;
4860 case DW_OP_swap:
4861 printf ("DW_OP_swap");
4862 break;
4863 case DW_OP_rot:
4864 printf ("DW_OP_rot");
4865 break;
4866 case DW_OP_xderef:
4867 printf ("DW_OP_xderef");
4868 break;
4869 case DW_OP_abs:
4870 printf ("DW_OP_abs");
4871 break;
4872 case DW_OP_and:
4873 printf ("DW_OP_and");
4874 break;
4875 case DW_OP_div:
4876 printf ("DW_OP_div");
4877 break;
4878 case DW_OP_minus:
4879 printf ("DW_OP_minus");
4880 break;
4881 case DW_OP_mod:
4882 printf ("DW_OP_mod");
4883 break;
4884 case DW_OP_mul:
4885 printf ("DW_OP_mul");
4886 break;
4887 case DW_OP_neg:
4888 printf ("DW_OP_neg");
4889 break;
4890 case DW_OP_not:
4891 printf ("DW_OP_not");
4892 break;
4893 case DW_OP_or:
4894 printf ("DW_OP_or");
4895 break;
4896 case DW_OP_plus:
4897 printf ("DW_OP_plus");
4898 break;
4899 case DW_OP_plus_uconst:
4900 printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
4901 break;
4902 case DW_OP_shl:
4903 printf ("DW_OP_shl");
4904 break;
4905 case DW_OP_shr:
4906 printf ("DW_OP_shr");
4907 break;
4908 case DW_OP_shra:
4909 printf ("DW_OP_shra");
4910 break;
4911 case DW_OP_xor:
4912 printf ("DW_OP_xor");
4913 break;
4914 case DW_OP_bra:
4915 printf ("DW_OP_bra: %ld", byte_get (data, 2));
4916 break;
4917 case DW_OP_eq:
4918 printf ("DW_OP_eq");
4919 break;
4920 case DW_OP_ge:
4921 printf ("DW_OP_ge");
4922 break;
4923 case DW_OP_gt:
4924 printf ("DW_OP_gt");
4925 break;
4926 case DW_OP_le:
4927 printf ("DW_OP_le");
4928 break;
4929 case DW_OP_lt:
4930 printf ("DW_OP_lt");
4931 break;
4932 case DW_OP_ne:
4933 printf ("DW_OP_ne");
4934 break;
4935 case DW_OP_skip:
4936 printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
4937 break;
4938 case DW_OP_lit0:
4939 printf ("DW_OP_lit0");
4940 break;
4941 case DW_OP_lit1:
4942 printf ("DW_OP_lit1");
4943 break;
4944 case DW_OP_lit2:
4945 printf ("DW_OP_lit2");
4946 break;
4947 case DW_OP_lit3:
4948 printf ("DW_OP_lit3");
4949 break;
4950 case DW_OP_lit4:
4951 printf ("DW_OP_lit4");
4952 break;
4953 case DW_OP_lit5:
4954 printf ("DW_OP_lit5");
4955 break;
4956 case DW_OP_lit6:
4957 printf ("DW_OP_lit6");
4958 break;
4959 case DW_OP_lit7:
4960 printf ("DW_OP_lit7");
4961 break;
4962 case DW_OP_lit8:
4963 printf ("DW_OP_lit8");
4964 break;
4965 case DW_OP_lit9:
4966 printf ("DW_OP_lit9");
4967 break;
4968 case DW_OP_lit10:
4969 printf ("DW_OP_lit10");
4970 break;
4971 case DW_OP_lit11:
4972 printf ("DW_OP_lit11");
4973 break;
4974 case DW_OP_lit12:
4975 printf ("DW_OP_lit12");
4976 break;
4977 case DW_OP_lit13:
4978 printf ("DW_OP_lit13");
4979 break;
4980 case DW_OP_lit14:
4981 printf ("DW_OP_lit14");
4982 break;
4983 case DW_OP_lit15:
4984 printf ("DW_OP_lit15");
4985 break;
4986 case DW_OP_lit16:
4987 printf ("DW_OP_lit16");
4988 break;
4989 case DW_OP_lit17:
4990 printf ("DW_OP_lit17");
4991 break;
4992 case DW_OP_lit18:
4993 printf ("DW_OP_lit18");
4994 break;
4995 case DW_OP_lit19:
4996 printf ("DW_OP_lit19");
4997 break;
4998 case DW_OP_lit20:
4999 printf ("DW_OP_lit20");
5000 break;
5001 case DW_OP_lit21:
5002 printf ("DW_OP_lit21");
5003 break;
5004 case DW_OP_lit22:
5005 printf ("DW_OP_lit22");
5006 break;
5007 case DW_OP_lit23:
5008 printf ("DW_OP_lit23");
5009 break;
5010 case DW_OP_lit24:
5011 printf ("DW_OP_lit24");
5012 break;
5013 case DW_OP_lit25:
5014 printf ("DW_OP_lit25");
5015 break;
5016 case DW_OP_lit26:
5017 printf ("DW_OP_lit26");
5018 break;
5019 case DW_OP_lit27:
5020 printf ("DW_OP_lit27");
5021 break;
5022 case DW_OP_lit28:
5023 printf ("DW_OP_lit28");
5024 break;
5025 case DW_OP_lit29:
5026 printf ("DW_OP_lit29");
5027 break;
5028 case DW_OP_lit30:
5029 printf ("DW_OP_lit30");
5030 break;
5031 case DW_OP_lit31:
5032 printf ("DW_OP_lit31");
5033 break;
5034 case DW_OP_reg0:
5035 printf ("DW_OP_reg0");
5036 break;
5037 case DW_OP_reg1:
5038 printf ("DW_OP_reg1");
5039 break;
5040 case DW_OP_reg2:
5041 printf ("DW_OP_reg2");
5042 break;
5043 case DW_OP_reg3:
5044 printf ("DW_OP_reg3");
5045 break;
5046 case DW_OP_reg4:
5047 printf ("DW_OP_reg4");
5048 break;
5049 case DW_OP_reg5:
5050 printf ("DW_OP_reg5");
5051 break;
5052 case DW_OP_reg6:
5053 printf ("DW_OP_reg6");
5054 break;
5055 case DW_OP_reg7:
5056 printf ("DW_OP_reg7");
5057 break;
5058 case DW_OP_reg8:
5059 printf ("DW_OP_reg8");
5060 break;
5061 case DW_OP_reg9:
5062 printf ("DW_OP_reg9");
5063 break;
5064 case DW_OP_reg10:
5065 printf ("DW_OP_reg10");
5066 break;
5067 case DW_OP_reg11:
5068 printf ("DW_OP_reg11");
5069 break;
5070 case DW_OP_reg12:
5071 printf ("DW_OP_reg12");
5072 break;
5073 case DW_OP_reg13:
5074 printf ("DW_OP_reg13");
5075 break;
5076 case DW_OP_reg14:
5077 printf ("DW_OP_reg14");
5078 break;
5079 case DW_OP_reg15:
5080 printf ("DW_OP_reg15");
5081 break;
5082 case DW_OP_reg16:
5083 printf ("DW_OP_reg16");
5084 break;
5085 case DW_OP_reg17:
5086 printf ("DW_OP_reg17");
5087 break;
5088 case DW_OP_reg18:
5089 printf ("DW_OP_reg18");
5090 break;
5091 case DW_OP_reg19:
5092 printf ("DW_OP_reg19");
5093 break;
5094 case DW_OP_reg20:
5095 printf ("DW_OP_reg20");
5096 break;
5097 case DW_OP_reg21:
5098 printf ("DW_OP_reg21");
5099 break;
5100 case DW_OP_reg22:
5101 printf ("DW_OP_reg22");
5102 break;
5103 case DW_OP_reg23:
5104 printf ("DW_OP_reg23");
5105 break;
5106 case DW_OP_reg24:
5107 printf ("DW_OP_reg24");
5108 break;
5109 case DW_OP_reg25:
5110 printf ("DW_OP_reg25");
5111 break;
5112 case DW_OP_reg26:
5113 printf ("DW_OP_reg26");
5114 break;
5115 case DW_OP_reg27:
5116 printf ("DW_OP_reg27");
5117 break;
5118 case DW_OP_reg28:
5119 printf ("DW_OP_reg28");
5120 break;
5121 case DW_OP_reg29:
5122 printf ("DW_OP_reg29");
5123 break;
5124 case DW_OP_reg30:
5125 printf ("DW_OP_reg30");
5126 break;
5127 case DW_OP_reg31:
5128 printf ("DW_OP_reg31");
5129 break;
5130 case DW_OP_breg0:
5131 printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
5132 break;
5133 case DW_OP_breg1:
5134 printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
5135 break;
5136 case DW_OP_breg2:
5137 printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
5138 break;
5139 case DW_OP_breg3:
5140 printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
5141 break;
5142 case DW_OP_breg4:
5143 printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
5144 break;
5145 case DW_OP_breg5:
5146 printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
5147 break;
5148 case DW_OP_breg6:
5149 printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
5150 break;
5151 case DW_OP_breg7:
5152 printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
5153 break;
5154 case DW_OP_breg8:
5155 printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
5156 break;
5157 case DW_OP_breg9:
5158 printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
5159 break;
5160 case DW_OP_breg10:
5161 printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
5162 break;
5163 case DW_OP_breg11:
5164 printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
5165 break;
5166 case DW_OP_breg12:
5167 printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
5168 break;
5169 case DW_OP_breg13:
5170 printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
5171 break;
5172 case DW_OP_breg14:
5173 printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
5174 break;
5175 case DW_OP_breg15:
5176 printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
5177 break;
5178 case DW_OP_breg16:
5179 printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
5180 break;
5181 case DW_OP_breg17:
5182 printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
5183 break;
5184 case DW_OP_breg18:
5185 printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
5186 break;
5187 case DW_OP_breg19:
5188 printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
5189 break;
5190 case DW_OP_breg20:
5191 printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
5192 break;
5193 case DW_OP_breg21:
5194 printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
5195 break;
5196 case DW_OP_breg22:
5197 printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
5198 break;
5199 case DW_OP_breg23:
5200 printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
5201 break;
5202 case DW_OP_breg24:
5203 printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
5204 break;
5205 case DW_OP_breg25:
5206 printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
5207 break;
5208 case DW_OP_breg26:
5209 printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
5210 break;
5211 case DW_OP_breg27:
5212 printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
5213 break;
5214 case DW_OP_breg28:
5215 printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
5216 break;
5217 case DW_OP_breg29:
5218 printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
5219 break;
5220 case DW_OP_breg30:
5221 printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
5222 break;
5223 case DW_OP_breg31:
5224 printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
5225 break;
5226 case DW_OP_regx:
5227 printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
5228 break;
5229 case DW_OP_fbreg:
5230 printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
5231 break;
5232 case DW_OP_bregx:
5233 uvalue = read_leb128 (data, &bytes_read, 0);
5234 printf ("DW_OP_bregx: %lu %ld", uvalue,
5235 read_leb128 (data + bytes_read, NULL, 1));
5236 break;
5237 case DW_OP_piece:
5238 printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
5239 break;
5240 case DW_OP_deref_size:
5241 printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
5242 break;
5243 case DW_OP_xderef_size:
5244 printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
5245 break;
5246 case DW_OP_nop:
5247 printf ("DW_OP_nop");
5248 break;
5250 default:
5251 if (op >= DW_OP_lo_user
5252 && op <= DW_OP_hi_user)
5253 printf (_("(User defined location op)"));
5254 else
5255 printf (_("(Unknown location op)"));
5256 break;
5261 static unsigned char *
5262 read_and_display_attr (attribute, form, data, pointer_size)
5263 unsigned long attribute;
5264 unsigned long form;
5265 unsigned char * data;
5266 unsigned long pointer_size;
5268 unsigned long uvalue;
5269 unsigned char * block_start;
5270 int bytes_read;
5271 int is_ref = 0;
5273 printf (" %-18s:", get_AT_name (attribute));
5275 switch (form)
5277 case DW_FORM_ref_addr:
5278 case DW_FORM_ref1:
5279 case DW_FORM_ref2:
5280 case DW_FORM_ref4:
5281 case DW_FORM_ref8:
5282 case DW_FORM_ref_udata:
5283 is_ref = 1;
5286 switch (form)
5288 case DW_FORM_ref_addr:
5289 case DW_FORM_addr:
5290 uvalue = byte_get (data, pointer_size);
5291 printf (is_ref ? " <%x>" : " %#x", uvalue);
5292 data += pointer_size;
5293 break;
5295 case DW_FORM_ref1:
5296 case DW_FORM_flag:
5297 case DW_FORM_data1:
5298 uvalue = byte_get (data ++, 1);
5299 printf (is_ref ? " <%x>" : " %d", uvalue);
5300 break;
5302 case DW_FORM_ref2:
5303 case DW_FORM_data2:
5304 uvalue = byte_get (data, 2);
5305 data += 2;
5306 printf (is_ref ? " <%x>" : " %d", uvalue);
5307 break;
5309 case DW_FORM_ref4:
5310 case DW_FORM_data4:
5311 uvalue = byte_get (data, 4);
5312 data += 4;
5313 printf (is_ref ? " <%x>" : " %d", uvalue);
5314 break;
5316 case DW_FORM_ref8:
5317 case DW_FORM_data8:
5318 uvalue = byte_get (data, 4);
5319 printf (" %lx", uvalue);
5320 printf (" %lx", (unsigned long) byte_get (data + 4, 4));
5321 data += 8;
5322 break;
5324 case DW_FORM_string:
5325 printf (" %s", data);
5326 data += strlen (data) + 1;
5327 break;
5329 case DW_FORM_sdata:
5330 uvalue = read_leb128 (data, & bytes_read, 1);
5331 data += bytes_read;
5332 printf (" %ld", (long) uvalue);
5333 break;
5335 case DW_FORM_ref_udata:
5336 case DW_FORM_udata:
5337 uvalue = read_leb128 (data, & bytes_read, 0);
5338 data += bytes_read;
5339 printf (is_ref ? " <%lx>" : " %ld", uvalue);
5340 break;
5342 case DW_FORM_block:
5343 uvalue = read_leb128 (data, & bytes_read, 0);
5344 block_start = data + bytes_read;
5345 data = display_block (block_start, uvalue);
5346 uvalue = * block_start;
5347 break;
5349 case DW_FORM_block1:
5350 uvalue = byte_get (data, 1);
5351 block_start = data + 1;
5352 data = display_block (block_start, uvalue);
5353 uvalue = * block_start;
5354 break;
5356 case DW_FORM_block2:
5357 uvalue = byte_get (data, 2);
5358 block_start = data + 2;
5359 data = display_block (block_start, uvalue);
5360 uvalue = * block_start;
5361 break;
5363 case DW_FORM_block4:
5364 uvalue = byte_get (data, 4);
5365 block_start = data + 4;
5366 data = display_block (block_start, uvalue);
5367 uvalue = * block_start;
5368 break;
5370 case DW_FORM_strp:
5371 case DW_FORM_indirect:
5372 warn (_("Unable to handle FORM: %d"), form);
5373 break;
5375 default:
5376 warn (_("Unrecognised form: %d"), form);
5377 break;
5380 /* For some attributes we can display futher information. */
5382 printf ("\t");
5384 switch (attribute)
5386 case DW_AT_inline:
5387 switch (uvalue)
5389 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
5390 case DW_INL_inlined: printf (_("(inlined)")); break;
5391 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
5392 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
5393 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
5395 break;
5397 case DW_AT_frame_base:
5398 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
5399 printf ("(reg %ld)", uvalue - DW_OP_reg0);
5400 break;
5402 case DW_AT_language:
5403 switch (uvalue)
5405 case DW_LANG_C: printf ("(non-ANSI C)"); break;
5406 case DW_LANG_C89: printf ("(ANSI C)"); break;
5407 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
5408 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
5409 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
5410 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
5411 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
5412 case DW_LANG_Ada83: printf ("(Ada)"); break;
5413 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
5414 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
5415 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
5416 default: printf ("(Unknown: %lx)", uvalue); break;
5418 break;
5420 case DW_AT_encoding:
5421 switch (uvalue)
5423 case DW_ATE_void: printf ("(void)"); break;
5424 case DW_ATE_address: printf ("(machine address)"); break;
5425 case DW_ATE_boolean: printf ("(boolean)"); break;
5426 case DW_ATE_complex_float: printf ("(complex float)"); break;
5427 case DW_ATE_float: printf ("(float)"); break;
5428 case DW_ATE_signed: printf ("(signed)"); break;
5429 case DW_ATE_signed_char: printf ("(signed char)"); break;
5430 case DW_ATE_unsigned: printf ("(unsigned)"); break;
5431 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
5432 default:
5433 if (uvalue >= DW_ATE_lo_user
5434 && uvalue <= DW_ATE_hi_user)
5435 printf ("(user defined type)");
5436 else
5437 printf ("(unknown type)");
5438 break;
5440 break;
5442 case DW_AT_accessibility:
5443 switch (uvalue)
5445 case DW_ACCESS_public: printf ("(public)"); break;
5446 case DW_ACCESS_protected: printf ("(protected)"); break;
5447 case DW_ACCESS_private: printf ("(private)"); break;
5448 default: printf ("(unknown accessibility)"); break;
5450 break;
5452 case DW_AT_visibility:
5453 switch (uvalue)
5455 case DW_VIS_local: printf ("(local)"); break;
5456 case DW_VIS_exported: printf ("(exported)"); break;
5457 case DW_VIS_qualified: printf ("(qualified)"); break;
5458 default: printf ("(unknown visibility)"); break;
5460 break;
5462 case DW_AT_virtuality:
5463 switch (uvalue)
5465 case DW_VIRTUALITY_none: printf ("(none)"); break;
5466 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
5467 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
5468 default: printf ("(unknown virtuality)"); break;
5470 break;
5472 case DW_AT_identifier_case:
5473 switch (uvalue)
5475 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
5476 case DW_ID_up_case: printf ("(up_case)"); break;
5477 case DW_ID_down_case: printf ("(down_case)"); break;
5478 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
5479 default: printf ("(unknown case)"); break;
5481 break;
5483 case DW_AT_calling_convention:
5484 switch (uvalue)
5486 case DW_CC_normal: printf ("(normal)"); break;
5487 case DW_CC_program: printf ("(program)"); break;
5488 case DW_CC_nocall: printf ("(nocall)"); break;
5489 default:
5490 if (uvalue >= DW_CC_lo_user
5491 && uvalue <= DW_CC_hi_user)
5492 printf ("(user defined)");
5493 else
5494 printf ("(unknown convention)");
5496 break;
5498 case DW_AT_location:
5499 case DW_AT_data_member_location:
5500 case DW_AT_vtable_elem_location:
5501 printf ("(");
5502 decode_location_expression (block_start, pointer_size);
5503 printf (")");
5504 break;
5506 default:
5507 break;
5510 printf ("\n");
5511 return data;
5514 static int
5515 display_debug_info (section, start, file)
5516 Elf32_Internal_Shdr * section;
5517 unsigned char * start;
5518 FILE * file;
5520 unsigned char * end = start + section->sh_size;
5521 unsigned char * section_begin = start;
5523 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5525 while (start < end)
5527 DWARF2_External_CompUnit * external;
5528 DWARF2_Internal_CompUnit compunit;
5529 unsigned char * tags;
5530 int i;
5531 int level;
5533 external = (DWARF2_External_CompUnit *) start;
5535 compunit.cu_length = BYTE_GET (external->cu_length);
5536 compunit.cu_version = BYTE_GET (external->cu_version);
5537 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
5538 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
5540 tags = start + sizeof (* external);
5541 start += compunit.cu_length + sizeof (external->cu_length);
5543 if (compunit.cu_version != 2)
5545 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
5546 continue;
5549 printf (_(" Compilation Unit:\n"));
5550 printf (_(" Length: %ld\n"), compunit.cu_length);
5551 printf (_(" Version: %d\n"), compunit.cu_version);
5552 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
5553 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
5555 if (first_abbrev != NULL)
5556 free_abbrevs ();
5558 /* Read in the abbrevs used by this compilation unit. */
5561 Elf32_Internal_Shdr * sec;
5562 unsigned char * begin;
5564 /* Locate the .debug_abbrev section and process it. */
5565 for (i = 0, sec = section_headers;
5566 i < elf_header.e_shnum;
5567 i ++, sec ++)
5568 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
5569 break;
5571 if (i == -1 || sec->sh_size == 0)
5573 warn (_("Unable to locate .debug_abbrev section!\n"));
5574 return 0;
5577 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
5578 "debug_abbrev section data");
5580 process_abbrev_section (begin + compunit.cu_abbrev_offset,
5581 begin + sec->sh_size);
5583 free (begin);
5586 level = 0;
5587 while (tags < start)
5589 int bytes_read;
5590 int abbrev_number;
5591 abbrev_entry * entry;
5592 abbrev_attr * attr;
5594 abbrev_number = read_leb128 (tags, & bytes_read, 0);
5595 tags += bytes_read;
5597 /* A null DIE marks the end of a list of children. */
5598 if (abbrev_number == 0)
5600 --level;
5601 continue;
5604 /* Scan through the abbreviation list until we reach the
5605 correct entry. */
5606 for (entry = first_abbrev;
5607 entry && entry->entry != abbrev_number;
5608 entry = entry->next)
5609 continue;
5611 if (entry == NULL)
5613 warn (_("Unable to locate entry %d in the abbreviation table\n"),
5614 abbrev_number);
5615 return 0;
5618 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
5619 level, tags - section_begin - bytes_read,
5620 abbrev_number,
5621 get_TAG_name (entry->tag));
5623 for (attr = entry->first_attr; attr; attr = attr->next)
5624 tags = read_and_display_attr (attr->attribute,
5625 attr->form,
5626 tags,
5627 compunit.cu_pointer_size);
5629 if (entry->children)
5630 ++level;
5634 printf ("\n");
5636 return 1;
5639 static int
5640 display_debug_aranges (section, start, file)
5641 Elf32_Internal_Shdr * section;
5642 unsigned char * start;
5643 FILE * file;
5645 unsigned char * end = start + section->sh_size;
5647 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5649 while (start < end)
5651 DWARF2_External_ARange * external;
5652 DWARF2_Internal_ARange arange;
5653 unsigned char * ranges;
5654 unsigned long length;
5655 unsigned long address;
5657 external = (DWARF2_External_ARange *) start;
5659 arange.ar_length = BYTE_GET (external->ar_length);
5660 arange.ar_version = BYTE_GET (external->ar_version);
5661 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
5662 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
5663 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
5665 printf (_(" Length: %ld\n"), arange.ar_length);
5666 printf (_(" Version: %d\n"), arange.ar_version);
5667 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
5668 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
5669 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
5671 printf (_("\n Address Length\n"));
5673 ranges = start + sizeof (* external);
5675 for (;;)
5677 address = byte_get (ranges, arange.ar_pointer_size);
5679 if (address == 0)
5680 break;
5682 ranges += arange.ar_pointer_size;
5684 length = byte_get (ranges, arange.ar_pointer_size);
5686 ranges += arange.ar_pointer_size;
5688 printf (" %8.8lx %lu\n", address, length);
5691 start += arange.ar_length + sizeof (external->ar_length);
5694 printf ("\n");
5696 return 1;
5700 static int
5701 display_debug_not_supported (section, start, file)
5702 Elf32_Internal_Shdr * section;
5703 unsigned char * start;
5704 FILE * file;
5706 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5707 SECTION_NAME (section));
5709 return 1;
5712 /* A structure containing the name of a debug section and a pointer
5713 to a function that can decode it. */
5714 struct
5716 char * name;
5717 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5719 debug_displays[] =
5721 { ".debug_info", display_debug_info },
5722 { ".debug_abbrev", display_debug_abbrev },
5723 { ".debug_line", display_debug_lines },
5724 { ".debug_aranges", display_debug_aranges },
5725 { ".debug_pubnames", display_debug_pubnames },
5726 { ".debug_macinfo", display_debug_not_supported },
5727 { ".debug_frame", display_debug_not_supported },
5728 { ".debug_str", display_debug_not_supported },
5729 { ".debug_static_func", display_debug_not_supported },
5730 { ".debug_static_vars", display_debug_not_supported },
5731 { ".debug_types", display_debug_not_supported },
5732 { ".debug_weaknames", display_debug_not_supported }
5735 static int
5736 display_debug_section (section, file)
5737 Elf32_Internal_Shdr * section;
5738 FILE * file;
5740 char * name = SECTION_NAME (section);
5741 bfd_size_type length;
5742 unsigned char * start;
5743 int i;
5745 length = section->sh_size;
5746 if (length == 0)
5748 printf (_("\nSection '%s' has no debugging data.\n"), name);
5749 return 0;
5752 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5753 "debug section data");
5755 /* See if we know how to display the contents of this section. */
5756 for (i = NUM_ELEM (debug_displays); i--;)
5757 if (strcmp (debug_displays[i].name, name) == 0)
5759 debug_displays[i].display (section, start, file);
5760 break;
5763 if (i == -1)
5764 printf (_("Unrecognised debug section: %s\n"), name);
5766 free (start);
5768 /* If we loaded in the abbrev section at some point,
5769 we must release it here. */
5770 if (first_abbrev != NULL)
5771 free_abbrevs ();
5773 return 1;
5776 static int
5777 process_section_contents (file)
5778 FILE * file;
5780 Elf32_Internal_Shdr * section;
5781 unsigned int i;
5783 if (! do_dump)
5784 return 1;
5786 for (i = 0, section = section_headers;
5787 i < elf_header.e_shnum
5788 && i < num_dump_sects;
5789 i ++, section ++)
5791 #ifdef SUPPORT_DISASSEMBLY
5792 if (dump_sects[i] & DISASS_DUMP)
5793 disassemble_section (section, file);
5794 #endif
5795 if (dump_sects[i] & HEX_DUMP)
5796 dump_section (section, file);
5798 if (dump_sects[i] & DEBUG_DUMP)
5799 display_debug_section (section, file);
5802 if (i < num_dump_sects)
5803 warn (_("Some sections were not dumped because they do not exist!\n"));
5805 return 1;
5808 static void
5809 process_mips_fpe_exception (mask)
5810 int mask;
5812 if (mask)
5814 int first = 1;
5815 if (mask & OEX_FPU_INEX)
5816 fputs ("INEX", stdout), first = 0;
5817 if (mask & OEX_FPU_UFLO)
5818 printf ("%sUFLO", first ? "" : "|"), first = 0;
5819 if (mask & OEX_FPU_OFLO)
5820 printf ("%sOFLO", first ? "" : "|"), first = 0;
5821 if (mask & OEX_FPU_DIV0)
5822 printf ("%sDIV0", first ? "" : "|"), first = 0;
5823 if (mask & OEX_FPU_INVAL)
5824 printf ("%sINVAL", first ? "" : "|");
5826 else
5827 fputs ("0", stdout);
5830 static int
5831 process_mips_specific (file)
5832 FILE * file;
5834 Elf_Internal_Dyn * entry;
5835 size_t liblist_offset = 0;
5836 size_t liblistno = 0;
5837 size_t conflictsno = 0;
5838 size_t options_offset = 0;
5839 size_t conflicts_offset = 0;
5841 /* We have a lot of special sections. Thanks SGI! */
5842 if (dynamic_segment == NULL)
5843 /* No information available. */
5844 return 0;
5846 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5847 switch (entry->d_tag)
5849 case DT_MIPS_LIBLIST:
5850 liblist_offset = entry->d_un.d_val - loadaddr;
5851 break;
5852 case DT_MIPS_LIBLISTNO:
5853 liblistno = entry->d_un.d_val;
5854 break;
5855 case DT_MIPS_OPTIONS:
5856 options_offset = entry->d_un.d_val - loadaddr;
5857 break;
5858 case DT_MIPS_CONFLICT:
5859 conflicts_offset = entry->d_un.d_val - loadaddr;
5860 break;
5861 case DT_MIPS_CONFLICTNO:
5862 conflictsno = entry->d_un.d_val;
5863 break;
5864 default:
5865 break;
5868 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5870 Elf32_External_Lib * elib;
5871 size_t cnt;
5873 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5874 elib, Elf32_External_Lib *, "liblist");
5876 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5877 fputs (" Library Time Stamp Checksum Version Flags\n",
5878 stdout);
5880 for (cnt = 0; cnt < liblistno; ++cnt)
5882 Elf32_Lib liblist;
5883 time_t time;
5884 char timebuf[20];
5886 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5887 time = BYTE_GET (elib[cnt].l_time_stamp);
5888 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5889 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5890 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5892 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5894 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5895 dynamic_strings + liblist.l_name, timebuf,
5896 liblist.l_checksum, liblist.l_version);
5898 if (liblist.l_flags == 0)
5899 puts (" NONE");
5900 else
5902 static const struct
5904 const char *name;
5905 int bit;
5906 } l_flags_vals[] =
5908 { " EXACT_MATCH", LL_EXACT_MATCH },
5909 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5910 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5911 { " EXPORTS", LL_EXPORTS },
5912 { " DELAY_LOAD", LL_DELAY_LOAD },
5913 { " DELTA", LL_DELTA }
5915 int flags = liblist.l_flags;
5916 int fcnt;
5918 for (fcnt = 0;
5919 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5920 ++fcnt)
5921 if ((flags & l_flags_vals[fcnt].bit) != 0)
5923 fputs (l_flags_vals[fcnt].name, stdout);
5924 flags ^= l_flags_vals[fcnt].bit;
5926 if (flags != 0)
5927 printf (" %#x", (unsigned int) flags);
5929 puts ("");
5933 free (elib);
5936 if (options_offset != 0)
5938 Elf_External_Options * eopt;
5939 Elf_Internal_Shdr * sect = section_headers;
5940 Elf_Internal_Options * iopt;
5941 Elf_Internal_Options * option;
5942 size_t offset;
5943 int cnt;
5945 /* Find the section header so that we get the size. */
5946 while (sect->sh_type != SHT_MIPS_OPTIONS)
5947 ++sect;
5949 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5950 Elf_External_Options *, "options");
5952 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5953 * sizeof (*iopt));
5954 if (iopt == NULL)
5956 error (_("Out of memory"));
5957 return 0;
5960 offset = cnt = 0;
5961 option = iopt;
5962 while (offset < sect->sh_size)
5964 Elf_External_Options * eoption;
5966 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5968 option->kind = BYTE_GET (eoption->kind);
5969 option->size = BYTE_GET (eoption->size);
5970 option->section = BYTE_GET (eoption->section);
5971 option->info = BYTE_GET (eoption->info);
5973 offset += option->size;
5974 ++option;
5975 ++cnt;
5978 printf (_("\nSection '%s' contains %d entries:\n"),
5979 string_table + sect->sh_name, cnt);
5981 option = iopt;
5982 while (cnt-- > 0)
5984 size_t len;
5986 switch (option->kind)
5988 case ODK_NULL:
5989 /* This shouldn't happen. */
5990 printf (" NULL %d %lx", option->section, option->info);
5991 break;
5992 case ODK_REGINFO:
5993 printf (" REGINFO ");
5994 if (elf_header.e_machine == EM_MIPS)
5996 /* 32bit form. */
5997 Elf32_External_RegInfo *ereg;
5998 Elf32_RegInfo reginfo;
6000 ereg = (Elf32_External_RegInfo *) (option + 1);
6001 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6002 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6003 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6004 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6005 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6006 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
6008 printf ("GPR %08lx GP 0x%lx\n",
6009 reginfo.ri_gprmask,
6010 (unsigned long) reginfo.ri_gp_value);
6011 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6012 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6013 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6015 else
6017 /* 64 bit form. */
6018 Elf64_External_RegInfo * ereg;
6019 Elf64_Internal_RegInfo reginfo;
6021 ereg = (Elf64_External_RegInfo *) (option + 1);
6022 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6023 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6024 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6025 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6026 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6027 reginfo.ri_gp_value = BYTE_GET8 (ereg->ri_gp_value);
6029 printf ("GPR %08lx GP 0x",
6030 reginfo.ri_gprmask);
6031 printf_vma (reginfo.ri_gp_value);
6032 printf ("\n");
6034 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
6035 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6036 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6038 ++option;
6039 continue;
6040 case ODK_EXCEPTIONS:
6041 fputs (" EXCEPTIONS fpe_min(", stdout);
6042 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
6043 fputs (") fpe_max(", stdout);
6044 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
6045 fputs (")", stdout);
6047 if (option->info & OEX_PAGE0)
6048 fputs (" PAGE0", stdout);
6049 if (option->info & OEX_SMM)
6050 fputs (" SMM", stdout);
6051 if (option->info & OEX_FPDBUG)
6052 fputs (" FPDBUG", stdout);
6053 if (option->info & OEX_DISMISS)
6054 fputs (" DISMISS", stdout);
6055 break;
6056 case ODK_PAD:
6057 fputs (" PAD ", stdout);
6058 if (option->info & OPAD_PREFIX)
6059 fputs (" PREFIX", stdout);
6060 if (option->info & OPAD_POSTFIX)
6061 fputs (" POSTFIX", stdout);
6062 if (option->info & OPAD_SYMBOL)
6063 fputs (" SYMBOL", stdout);
6064 break;
6065 case ODK_HWPATCH:
6066 fputs (" HWPATCH ", stdout);
6067 if (option->info & OHW_R4KEOP)
6068 fputs (" R4KEOP", stdout);
6069 if (option->info & OHW_R8KPFETCH)
6070 fputs (" R8KPFETCH", stdout);
6071 if (option->info & OHW_R5KEOP)
6072 fputs (" R5KEOP", stdout);
6073 if (option->info & OHW_R5KCVTL)
6074 fputs (" R5KCVTL", stdout);
6075 break;
6076 case ODK_FILL:
6077 fputs (" FILL ", stdout);
6078 /* XXX Print content of info word? */
6079 break;
6080 case ODK_TAGS:
6081 fputs (" TAGS ", stdout);
6082 /* XXX Print content of info word? */
6083 break;
6084 case ODK_HWAND:
6085 fputs (" HWAND ", stdout);
6086 if (option->info & OHWA0_R4KEOP_CHECKED)
6087 fputs (" R4KEOP_CHECKED", stdout);
6088 if (option->info & OHWA0_R4KEOP_CLEAN)
6089 fputs (" R4KEOP_CLEAN", stdout);
6090 break;
6091 case ODK_HWOR:
6092 fputs (" HWOR ", stdout);
6093 if (option->info & OHWA0_R4KEOP_CHECKED)
6094 fputs (" R4KEOP_CHECKED", stdout);
6095 if (option->info & OHWA0_R4KEOP_CLEAN)
6096 fputs (" R4KEOP_CLEAN", stdout);
6097 break;
6098 case ODK_GP_GROUP:
6099 printf (" GP_GROUP %#06lx self-contained %#06lx",
6100 option->info & OGP_GROUP,
6101 (option->info & OGP_SELF) >> 16);
6102 break;
6103 case ODK_IDENT:
6104 printf (" IDENT %#06lx self-contained %#06lx",
6105 option->info & OGP_GROUP,
6106 (option->info & OGP_SELF) >> 16);
6107 break;
6108 default:
6109 /* This shouldn't happen. */
6110 printf (" %3d ??? %d %lx",
6111 option->kind, option->section, option->info);
6112 break;
6115 len = sizeof (*eopt);
6116 while (len < option->size)
6117 if (((char *) option)[len] >= ' '
6118 && ((char *) option)[len] < 0x7f)
6119 printf ("%c", ((char *) option)[len++]);
6120 else
6121 printf ("\\%03o", ((char *) option)[len++]);
6123 fputs ("\n", stdout);
6124 ++option;
6127 free (eopt);
6130 if (conflicts_offset != 0 && conflictsno != 0)
6132 Elf32_External_Conflict * econf32;
6133 Elf64_External_Conflict * econf64;
6134 Elf32_Conflict * iconf;
6135 size_t cnt;
6137 if (dynamic_symbols == NULL)
6139 error (_("conflict list with without table"));
6140 return 0;
6143 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
6144 if (iconf == NULL)
6146 error (_("Out of memory"));
6147 return 0;
6150 if (is_32bit_elf)
6152 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
6153 econf32, Elf32_External_Conflict *, "conflict");
6155 for (cnt = 0; cnt < conflictsno; ++cnt)
6156 iconf[cnt] = BYTE_GET (econf32[cnt]);
6158 else
6160 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
6161 econf64, Elf64_External_Conflict *, "conflict");
6163 for (cnt = 0; cnt < conflictsno; ++cnt)
6164 iconf[cnt] = BYTE_GET (econf64[cnt]);
6167 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
6168 puts (_(" Num: Index Value Name"));
6170 for (cnt = 0; cnt < conflictsno; ++cnt)
6172 Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
6174 printf ("%5u: %8lu %#10lx %s\n",
6175 cnt, iconf[cnt], (unsigned long) psym->st_value,
6176 dynamic_strings + psym->st_name);
6180 free (iconf);
6183 return 1;
6186 static int
6187 process_arch_specific (file)
6188 FILE * file;
6190 switch (elf_header.e_machine)
6192 case EM_MIPS:
6193 case EM_MIPS_RS4_BE:
6194 return process_mips_specific (file);
6195 break;
6196 default:
6197 break;
6199 return 1;
6202 static int
6203 get_file_header (file)
6204 FILE * file;
6206 /* Read in the identity array. */
6207 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
6208 return 0;
6210 /* Determine how to read the rest of the header. */
6211 switch (elf_header.e_ident [EI_DATA])
6213 default: /* fall through */
6214 case ELFDATANONE: /* fall through */
6215 case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
6216 case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
6219 /* For now we only support 32 bit and 64 bit ELF files. */
6220 is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
6222 /* Read in the rest of the header. */
6223 if (is_32bit_elf)
6225 Elf32_External_Ehdr ehdr32;
6227 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
6228 return 0;
6230 elf_header.e_type = BYTE_GET (ehdr32.e_type);
6231 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
6232 elf_header.e_version = BYTE_GET (ehdr32.e_version);
6233 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
6234 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
6235 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
6236 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
6237 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
6238 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
6239 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
6240 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
6241 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
6242 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
6244 else
6246 Elf64_External_Ehdr ehdr64;
6248 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
6249 return 0;
6251 elf_header.e_type = BYTE_GET (ehdr64.e_type);
6252 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
6253 elf_header.e_version = BYTE_GET (ehdr64.e_version);
6254 elf_header.e_entry = BYTE_GET8 (ehdr64.e_entry);
6255 elf_header.e_phoff = BYTE_GET8 (ehdr64.e_phoff);
6256 elf_header.e_shoff = BYTE_GET8 (ehdr64.e_shoff);
6257 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
6258 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
6259 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
6260 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
6261 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
6262 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
6263 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
6266 return 1;
6269 static void
6270 process_file (file_name)
6271 char * file_name;
6273 FILE * file;
6274 struct stat statbuf;
6275 unsigned int i;
6277 if (stat (file_name, & statbuf) < 0)
6279 error (_("Cannot stat input file %s.\n"), file_name);
6280 return;
6283 file = fopen (file_name, "rb");
6284 if (file == NULL)
6286 error (_("Input file %s not found.\n"), file_name);
6287 return;
6290 if (! get_file_header (file))
6292 error (_("%s: Failed to read file header\n"), file_name);
6293 fclose (file);
6294 return;
6297 /* Initialise per file variables. */
6298 for (i = NUM_ELEM (version_info); i--;)
6299 version_info[i] = 0;
6301 for (i = NUM_ELEM (dynamic_info); i--;)
6302 dynamic_info[i] = 0;
6304 /* Process the file. */
6305 if (show_name)
6306 printf (_("\nFile: %s\n"), file_name);
6308 if (! process_file_header ())
6310 fclose (file);
6311 return;
6314 process_section_headers (file);
6316 process_program_headers (file);
6318 process_dynamic_segment (file);
6320 process_relocs (file);
6322 process_symbol_table (file);
6324 process_syminfo (file);
6326 process_version_sections (file);
6328 process_section_contents (file);
6330 process_arch_specific (file);
6332 fclose (file);
6334 if (section_headers)
6336 free (section_headers);
6337 section_headers = NULL;
6340 if (string_table)
6342 free (string_table);
6343 string_table = NULL;
6346 if (dynamic_strings)
6348 free (dynamic_strings);
6349 dynamic_strings = NULL;
6352 if (dynamic_symbols)
6354 free (dynamic_symbols);
6355 dynamic_symbols = NULL;
6356 num_dynamic_syms = 0;
6359 if (dynamic_syminfo)
6361 free (dynamic_syminfo);
6362 dynamic_syminfo = NULL;
6366 #ifdef SUPPORT_DISASSEMBLY
6367 /* Needed by the i386 disassembler. For extra credit, someone could
6368 fix this so that we insert symbolic addresses here, esp for GOT/PLT
6369 symbols */
6371 void
6372 print_address (unsigned int addr, FILE * outfile)
6374 fprintf (outfile,"0x%8.8x", addr);
6377 /* Needed by the i386 disassembler. */
6378 void
6379 db_task_printsym (unsigned int addr)
6381 print_address (addr, stderr);
6383 #endif
6386 main (argc, argv)
6387 int argc;
6388 char ** argv;
6390 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
6391 setlocale (LC_MESSAGES, "");
6392 #endif
6393 bindtextdomain (PACKAGE, LOCALEDIR);
6394 textdomain (PACKAGE);
6396 parse_args (argc, argv);
6398 if (optind < (argc - 1))
6399 show_name = 1;
6401 while (optind < argc)
6402 process_file (argv [optind ++]);
6404 if (dump_sects != NULL)
6405 free (dump_sects);
6407 return 0;