1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998 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
32 #include "elf/common.h"
33 #include "elf/external.h"
34 #include "elf/internal.h"
36 /* The following headers use the elf/reloc-macros.h file to
37 automatically generate relocation recognition functions
38 such as elf_mips_reloc_type() */
40 #define RELOC_MACROS_GEN_FUNC
46 #include "elf/alpha.h"
49 #include "elf/sparc.h"
54 #include "elf/mn10200.h"
55 #include "elf/mn10300.h"
62 #ifdef ANSI_PROTOTYPES
68 char * program_name
= "readelf";
69 unsigned int dynamic_addr
;
70 unsigned int dynamic_size
;
71 unsigned int rela_addr
;
72 unsigned int rela_size
;
73 char * dynamic_strings
;
75 Elf_Internal_Sym
* dynamic_symbols
;
76 char program_interpreter
[64];
77 int dynamic_info
[DT_JMPREL
+ 1];
78 int version_info
[16];
80 Elf_Internal_Ehdr elf_header
;
81 Elf_Internal_Shdr
* section_headers
;
82 Elf_Internal_Dyn
* dynamic_segment
;
94 static unsigned long int (* byte_get
) PARAMS ((unsigned char *, int));
96 #define NUM_DUMP_SECTS 100
97 char dump_sects
[NUM_DUMP_SECTS
];
100 #define DISASS_DUMP 2
102 /* Forward declarations for dumb compilers. */
103 static const char * get_mips_dynamic_type
PARAMS ((unsigned long type
));
104 static const char * get_dynamic_type
PARAMS ((unsigned long type
));
105 static int dump_relocations
106 PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym
*, char *));
107 static char * get_file_type
PARAMS ((unsigned e_type
));
108 static char * get_machine_name
PARAMS ((unsigned e_machine
));
109 static char * get_machine_data
PARAMS ((unsigned e_data
));
110 static char * get_machine_flags
PARAMS ((unsigned, unsigned e_machine
));
111 static const char * get_mips_segment_type
PARAMS ((unsigned long type
));
112 static const char * get_segment_type
PARAMS ((unsigned long p_type
));
113 static const char * get_mips_section_type_name
PARAMS ((unsigned int sh_type
));
114 static const char * get_section_type_name
PARAMS ((unsigned int sh_type
));
115 static char * get_symbol_binding
PARAMS ((unsigned int binding
));
116 static char * get_symbol_type
PARAMS ((unsigned int type
));
117 static void usage
PARAMS ((void));
118 static void parse_args
PARAMS ((int argc
, char ** argv
));
119 static int process_file_header
PARAMS ((void));
120 static int process_program_headers
PARAMS ((FILE *));
121 static int process_section_headers
PARAMS ((FILE *));
122 static void dynamic_segment_mips_val
PARAMS ((Elf_Internal_Dyn
*entry
));
123 static int process_dynamic_segment
PARAMS ((FILE *));
124 static int process_symbol_table
PARAMS ((FILE *));
125 static int process_section_contents
PARAMS ((FILE *));
126 static void process_file
PARAMS ((char * file_name
));
127 static int process_relocs
PARAMS ((FILE *));
128 static int process_version_sections
PARAMS ((FILE *));
129 static char * get_ver_flags
PARAMS ((unsigned int flags
));
130 static char * get_symbol_index_type
PARAMS ((unsigned int type
));
131 static int get_section_headers
PARAMS ((FILE * file
));
132 static int get_file_header
PARAMS ((FILE * file
));
133 static Elf_Internal_Sym
* get_elf_symbols
134 PARAMS ((FILE * file
, unsigned long offset
, unsigned long number
));
135 static int * get_dynamic_data
PARAMS ((FILE * file
, unsigned int number
));
137 typedef int Elf32_Word
;
139 #define SECTION_NAME(X) (string_table + (X)->sh_name)
141 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
143 #define BYTE_GET(field) byte_get (field, sizeof (field))
145 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
147 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
148 if (fseek (file, offset, SEEK_SET)) \
150 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
154 var = (type) malloc (size); \
158 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
162 if (fread (var, size, 1, file) != 1) \
164 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
171 #define GET_DATA(offset, var, reason) \
172 if (fseek (file, offset, SEEK_SET)) \
174 error (_("Unable to seek to %x for %s\n"), offset, reason); \
177 else if (fread (& var, sizeof (var), 1, file) != 1) \
179 error (_("Unable to read data at %x for %s\n"), offset, reason); \
183 #ifdef ANSI_PROTOTYPES
185 error (const char * message
, ...)
189 fprintf (stderr
, _("%s: Error: "), program_name
);
190 va_start (args
, message
);
191 vfprintf (stderr
, message
, args
);
197 warn (const char * message
, ...)
201 fprintf (stderr
, _("%s: Warning: "), program_name
);
202 va_start (args
, message
);
203 vfprintf (stderr
, message
, args
);
215 fprintf (stderr
, _("%s: Error: "), program_name
);
217 message
= va_arg (args
, char *);
218 vfprintf (stderr
, message
, args
);
230 fprintf (stderr
, _("%s: Warning: "), program_name
);
232 message
= va_arg (args
, char *);
233 vfprintf (stderr
, message
, args
);
239 static unsigned long int
240 byte_get_little_endian (field
, size
)
241 unsigned char * field
;
250 return ((unsigned int) (field
[0]))
251 | (((unsigned int) (field
[1])) << 8);
254 return ((unsigned long) (field
[0]))
255 | (((unsigned long) (field
[1])) << 8)
256 | (((unsigned long) (field
[2])) << 16)
257 | (((unsigned long) (field
[3])) << 24);
260 error (_("Unhandled data length: %d\n"), size
);
265 static unsigned long int
266 byte_get_big_endian (field
, size
)
267 unsigned char * field
;
276 return ((unsigned int) (field
[1])) | (((int) (field
[0])) << 8);
279 return ((unsigned long) (field
[3]))
280 | (((unsigned long) (field
[2])) << 8)
281 | (((unsigned long) (field
[1])) << 16)
282 | (((unsigned long) (field
[0])) << 24);
285 error (_("Unhandled data length: %d\n"), size
);
291 /* Display the contents of the relocation data
292 found at the specified offset. */
294 dump_relocations (file
, rel_offset
, rel_size
, symtab
, strtab
)
296 unsigned long rel_offset
;
297 unsigned long rel_size
;
298 Elf_Internal_Sym
* symtab
;
303 Elf_Internal_Rel
* rels
;
304 Elf_Internal_Rela
* relas
;
307 /* Compute number of relocations and read them in. */
308 switch (elf_header
.e_machine
)
318 Elf32_External_Rel
* erels
;
320 GET_DATA_ALLOC (rel_offset
, rel_size
, erels
,
321 Elf32_External_Rel
*, "relocs");
323 rel_size
= rel_size
/ sizeof (Elf32_External_Rel
);
325 rels
= (Elf_Internal_Rel
*) malloc (rel_size
*
326 sizeof (Elf_Internal_Rel
));
328 for (i
= 0; i
< rel_size
; i
++)
330 rels
[i
].r_offset
= BYTE_GET (erels
[i
].r_offset
);
331 rels
[i
].r_info
= BYTE_GET (erels
[i
].r_info
);
337 relas
= (Elf_Internal_Rela
*) rels
;
346 case EM_CYGNUS_MN10200
:
347 case EM_CYGNUS_MN10300
:
351 Elf32_External_Rela
* erelas
;
353 GET_DATA_ALLOC (rel_offset
, rel_size
, erelas
,
354 Elf32_External_Rela
*, "relocs");
356 rel_size
= rel_size
/ sizeof (Elf32_External_Rela
);
358 relas
= (Elf_Internal_Rela
*) malloc (rel_size
*
359 sizeof (Elf_Internal_Rela
));
361 for (i
= 0; i
< rel_size
; i
++)
363 relas
[i
].r_offset
= BYTE_GET (erelas
[i
].r_offset
);
364 relas
[i
].r_info
= BYTE_GET (erelas
[i
].r_info
);
365 relas
[i
].r_addend
= BYTE_GET (erelas
[i
].r_addend
);
371 rels
= (Elf_Internal_Rel
*) relas
;
376 warn (_("Don't know about relocations on this machine architecture\n"));
382 (_(" Offset Value Type Symbol's Value Symbol's Name Addend\n"));
385 (_(" Offset Value Type Symbol's Value Symbol's Name\n"));
387 for (i
= 0; i
< rel_size
; i
++)
390 unsigned long offset
;
396 offset
= relas
[i
].r_offset
;
397 info
= relas
[i
].r_info
;
401 offset
= rels
[i
].r_offset
;
402 info
= rels
[i
].r_info
;
405 printf (" %8.8lx %5.5lx ", offset
, info
);
407 switch (elf_header
.e_machine
)
414 rtype
= elf_m32r_reloc_type (ELF32_R_TYPE (info
));
419 rtype
= elf_i386_reloc_type (ELF32_R_TYPE (info
));
423 rtype
= elf_m68k_reloc_type (ELF32_R_TYPE (info
));
427 rtype
= elf_sparc_reloc_type (ELF32_R_TYPE (info
));
431 rtype
= v850_reloc_type (ELF32_R_TYPE (info
));
435 rtype
= elf_d10v_reloc_type (ELF32_R_TYPE (info
));
439 rtype
= elf_d30v_reloc_type (ELF32_R_TYPE (info
));
443 rtype
= elf_sh_reloc_type (ELF32_R_TYPE (info
));
446 case EM_CYGNUS_MN10300
:
447 rtype
= elf_mn10300_reloc_type (ELF32_R_TYPE (info
));
450 case EM_CYGNUS_MN10200
:
451 rtype
= elf_mn10200_reloc_type (ELF32_R_TYPE (info
));
455 rtype
= elf_ppc_reloc_type (ELF32_R_TYPE (info
));
460 rtype
= elf_mips_reloc_type (ELF32_R_TYPE (info
));
464 rtype
= elf_alpha_reloc_type (ELF32_R_TYPE (info
));
468 rtype
= elf_arm_reloc_type (ELF32_R_TYPE (info
));
472 rtype
= elf_arc_reloc_type (ELF32_R_TYPE (info
));
476 rtype
= elf32_hppa_reloc_type (ELF32_R_TYPE (info
));
481 printf (_("unrecognised: %-7x"), ELF32_R_TYPE (info
));
483 printf ("%-21.21s", rtype
);
485 symtab_index
= ELF32_R_SYM (info
);
487 if (symtab_index
&& symtab
!= NULL
)
489 Elf_Internal_Sym
* psym
;
491 psym
= symtab
+ symtab_index
;
493 printf (" %08lx ", (unsigned long) psym
->st_value
);
495 if (psym
->st_name
== 0)
497 SECTION_NAME (section_headers
+ psym
->st_shndx
));
498 else if (strtab
== NULL
)
499 printf (_("<string table index %3d>"), psym
->st_name
);
501 printf ("%-25.25s", strtab
+ psym
->st_name
);
504 printf (" + %lx", (unsigned long) relas
[i
].r_addend
);
516 get_mips_dynamic_type (type
)
521 case DT_MIPS_RLD_VERSION
: return "MIPS_RLD_VERSION";
522 case DT_MIPS_TIME_STAMP
: return "MIPS_TIME_STAMP";
523 case DT_MIPS_ICHECKSUM
: return "MIPS_ICHECKSUM";
524 case DT_MIPS_IVERSION
: return "MIPS_IVERSION";
525 case DT_MIPS_FLAGS
: return "MIPS_FLAGS";
526 case DT_MIPS_BASE_ADDRESS
: return "MIPS_BASE_ADDRESS";
527 case DT_MIPS_MSYM
: return "MIPS_MSYM";
528 case DT_MIPS_CONFLICT
: return "MIPS_CONFLICT";
529 case DT_MIPS_LIBLIST
: return "MIPS_LIBLIST";
530 case DT_MIPS_LOCAL_GOTNO
: return "MIPS_LOCAL_GOTNO";
531 case DT_MIPS_CONFLICTNO
: return "MIPS_CONFLICTNO";
532 case DT_MIPS_LIBLISTNO
: return "MIPS_LIBLISTNO";
533 case DT_MIPS_SYMTABNO
: return "MIPS_SYMTABNO";
534 case DT_MIPS_UNREFEXTNO
: return "MIPS_UNREFEXTNO";
535 case DT_MIPS_GOTSYM
: return "MIPS_GOTSYM";
536 case DT_MIPS_HIPAGENO
: return "MIPS_HIPAGENO";
537 case DT_MIPS_RLD_MAP
: return "MIPS_RLD_MAP";
538 case DT_MIPS_DELTA_CLASS
: return "MIPS_DELTA_CLASS";
539 case DT_MIPS_DELTA_CLASS_NO
: return "MIPS_DELTA_CLASS_NO";
540 case DT_MIPS_DELTA_INSTANCE
: return "MIPS_DELTA_INSTANCE";
541 case DT_MIPS_DELTA_INSTANCE_NO
: return "MIPS_DELTA_INSTANCE_NO";
542 case DT_MIPS_DELTA_RELOC
: return "MIPS_DELTA_RELOC";
543 case DT_MIPS_DELTA_RELOC_NO
: return "MIPS_DELTA_RELOC_NO";
544 case DT_MIPS_DELTA_SYM
: return "MIPS_DELTA_SYM";
545 case DT_MIPS_DELTA_SYM_NO
: return "MIPS_DELTA_SYM_NO";
546 case DT_MIPS_DELTA_CLASSSYM
: return "MIPS_DELTA_CLASSSYM";
547 case DT_MIPS_DELTA_CLASSSYM_NO
: return "MIPS_DELTA_CLASSSYM_NO";
548 case DT_MIPS_CXX_FLAGS
: return "MIPS_CXX_FLAGS";
549 case DT_MIPS_PIXIE_INIT
: return "MIPS_PIXIE_INIT";
550 case DT_MIPS_SYMBOL_LIB
: return "MIPS_SYMBOL_LIB";
551 case DT_MIPS_LOCALPAGE_GOTIDX
: return "MIPS_LOCALPAGE_GOTIDX";
552 case DT_MIPS_LOCAL_GOTIDX
: return "MIPS_LOCAL_GOTIDX";
553 case DT_MIPS_HIDDEN_GOTIDX
: return "MIPS_HIDDEN_GOTIDX";
554 case DT_MIPS_PROTECTED_GOTIDX
: return "MIPS_PROTECTED_GOTIDX";
555 case DT_MIPS_OPTIONS
: return "MIPS_OPTIONS";
556 case DT_MIPS_INTERFACE
: return "MIPS_INTERFACE";
557 case DT_MIPS_DYNSTR_ALIGN
: return "MIPS_DYNSTR_ALIGN";
558 case DT_MIPS_INTERFACE_SIZE
: return "MIPS_INTERFACE_SIZE";
559 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR
: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
560 case DT_MIPS_PERF_SUFFIX
: return "MIPS_PERF_SUFFIX";
561 case DT_MIPS_COMPACT_SIZE
: return "MIPS_COMPACT_SIZE";
562 case DT_MIPS_GP_VALUE
: return "MIPS_GP_VALUE";
563 case DT_MIPS_AUX_DYNAMIC
: return "MIPS_AUX_DYNAMIC";
570 get_dynamic_type (type
)
573 static char buff
[32];
577 case DT_NULL
: return _("NULL");
578 case DT_NEEDED
: return _("NEEDED");
579 case DT_PLTRELSZ
: return _("PLTRELSZ");
580 case DT_PLTGOT
: return _("PLTGOT");
581 case DT_HASH
: return _("HASH");
582 case DT_STRTAB
: return _("STRTAB");
583 case DT_SYMTAB
: return _("SYMTAB");
584 case DT_RELA
: return _("RELA");
585 case DT_RELASZ
: return _("RELASZ");
586 case DT_RELAENT
: return _("RELAENT");
587 case DT_STRSZ
: return _("STRSZ");
588 case DT_SYMENT
: return _("SYMENT");
589 case DT_INIT
: return _("INIT");
590 case DT_FINI
: return _("FINI");
591 case DT_SONAME
: return _("SONAME");
592 case DT_RPATH
: return _("RPATH");
593 case DT_SYMBOLIC
: return _("SYMBOLIC");
594 case DT_REL
: return _("REL");
595 case DT_RELSZ
: return _("RELSZ");
596 case DT_RELENT
: return _("RELENT");
597 case DT_PLTREL
: return _("PLTREL");
598 case DT_DEBUG
: return _("DEBUG");
599 case DT_TEXTREL
: return _("TEXTREL");
600 case DT_JMPREL
: return _("JMPREL");
601 case DT_VERDEF
: return _("VERDEF");
602 case DT_VERDEFNUM
: return _("VERDEFNUM");
603 case DT_VERNEED
: return _("VERNEED");
604 case DT_VERNEEDNUM
: return _("VERNEEDNUM");
605 case DT_VERSYM
: return _("VERSYN");
606 case DT_AUXILIARY
: return _("AUXILARY");
607 case DT_FILTER
: return _("FILTER");
610 if ((type
>= DT_LOPROC
) && (type
<= DT_HIPROC
))
612 const char *result
= NULL
;
613 switch (elf_header
.e_machine
)
617 result
= get_mips_dynamic_type (type
);
623 sprintf (buff
, _("Processor Specific: (%x)"), type
);
629 sprintf (buff
, _("<unknown>: %x"), type
);
635 get_file_type (e_type
)
638 static char buff
[32];
642 case ET_NONE
: return _("NONE (None)");
643 case ET_REL
: return _("REL (Relocatable file)");
644 case ET_EXEC
: return _("EXEC (Executable file)");
645 case ET_DYN
: return _("DYN (Shared object file)");
646 case ET_CORE
: return _("CORE (Core file)");
649 if ((e_type
>= ET_LOPROC
) && (e_type
<= ET_HIPROC
))
650 sprintf (buff
, _("Processor Specific: (%x)"), e_type
);
652 sprintf (buff
, _("<unknown>: %x"), e_type
);
658 get_machine_name (e_machine
)
661 static char buff
[32];
665 case EM_NONE
: return _("None");
666 case EM_M32
: return "WE32100";
667 case EM_SPARC
: return "Sparc";
668 case EM_386
: return "Intel 80386";
669 case EM_68K
: return "MC68000";
670 case EM_88K
: return "MC88000";
671 case EM_486
: return "Intel 80486";
672 case EM_860
: return "Intel 80860";
673 case EM_MIPS
: return "MIPS R3000 big-endian";
674 case EM_S370
: return "Amdahl";
675 case EM_MIPS_RS4_BE
: return "MIPS R4000 big-endian";
676 case EM_OLD_SPARCV9
: return "Sparc v9 (old)";
677 case EM_PARISC
: return "HPPA";
678 case EM_PPC_OLD
: return "Power PC (old)";
679 case EM_SPARC32PLUS
: return "Sparc v8+" ;
680 case EM_960
: return "Intel 90860";
681 case EM_PPC
: return "PowerPC";
682 case EM_V800
: return "NEC V800";
683 case EM_FR20
: return "Fujitsu FR20";
684 case EM_RH32
: return "TRW RH32";
685 case EM_MMA
: return "Fujitsu MMA";
686 case EM_ARM
: return "ARM";
687 case EM_OLD_ALPHA
: return "Digital Alpha (old)";
688 case EM_SH
: return "Hitachi SH";
689 case EM_SPARCV9
: return "Sparc v9";
690 case EM_ALPHA
: return "Alpha";
691 case EM_CYGNUS_D10V
: return "d10v";
692 case EM_CYGNUS_D30V
: return "d30v";
693 case EM_CYGNUS_ARC
: return "Arc";
694 case EM_CYGNUS_M32R
: return "M32r";
695 case EM_CYGNUS_V850
: return "v850";
696 case EM_CYGNUS_MN10300
: return "mn10300";
697 case EM_CYGNUS_MN10200
: return "mn10200";
700 sprintf (buff
, _("<unknown>: %x"), e_machine
);
706 get_machine_flags (e_flags
, e_machine
)
710 static char buf
[1024];
721 if (e_flags
& EF_PPC_EMB
)
722 strcat (buf
, ", emb");
724 if (e_flags
& EF_PPC_RELOCATABLE
)
725 strcat (buf
, ", relocatable");
727 if (e_flags
& EF_PPC_RELOCATABLE_LIB
)
728 strcat (buf
, ", relocatable-lib");
732 if ((e_flags
& EF_M32R_ARCH
) == E_M32R_ARCH
)
733 strcat (buf
, ", m32r");
735 /* start-sanitize-m32rx */
737 if ((e_flags
& EF_M32R_ARCH
) == E_M32RX_ARCH
)
738 strcat (buf
, ", m32rx");
740 /* end-sanitize-m32rx */
745 if (e_flags
& EF_MIPS_NOREORDER
)
746 strcat (buf
, ", noreorder");
748 if (e_flags
& EF_MIPS_PIC
)
749 strcat (buf
, ", pic");
751 if (e_flags
& EF_MIPS_CPIC
)
752 strcat (buf
, ", cpic");
754 if (e_flags
& EF_MIPS_ABI2
)
755 strcat (buf
, ", abi2");
757 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_1
)
758 strcat (buf
, ", mips1");
760 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_2
)
761 strcat (buf
, ", mips2");
763 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_3
)
764 strcat (buf
, ", mips3");
766 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_4
)
767 strcat (buf
, ", mips4");
776 get_machine_data (e_data
)
779 static char buff
[32];
783 case ELFDATA2LSB
: return _("ELFDATA2LSB (little endian)");
784 case ELFDATA2MSB
: return _("ELFDATA2MSB (big endian)");
786 sprintf (buff
, _("<unknown>: %x"), e_data
);
792 get_mips_segment_type (type
)
797 case PT_MIPS_REGINFO
:
801 case PT_MIPS_OPTIONS
:
811 get_segment_type (p_type
)
812 unsigned long p_type
;
814 static char buff
[32];
818 case PT_NULL
: return "NULL";
819 case PT_LOAD
: return "LOAD";
820 case PT_DYNAMIC
: return "DYNAMIC";
821 case PT_INTERP
: return "INTERP";
822 case PT_NOTE
: return "NOTE";
823 case PT_SHLIB
: return "SHLIB";
824 case PT_PHDR
: return "PHDR";
827 if ((p_type
>= PT_LOPROC
) && (p_type
<= PT_HIPROC
))
830 switch (elf_header
.e_machine
)
834 result
= get_mips_segment_type (p_type
);
842 sprintf (buff
, "LOPROC+%d", p_type
- PT_LOPROC
);
849 sprintf (buff
, _("<unknown>: %x"), p_type
);
856 get_mips_section_type_name (sh_type
)
857 unsigned int sh_type
;
861 case SHT_MIPS_LIBLIST
:
862 return "MIPS_LIBLIST";
865 case SHT_MIPS_CONFLICT
:
866 return "MIPS_CONFLICT";
873 case SHT_MIPS_REGINFO
:
874 return "MIPS_REGINFO";
875 case SHT_MIPS_PACKAGE
:
876 return "MIPS_PACKAGE";
877 case SHT_MIPS_PACKSYM
:
878 return "MIPS_PACKSYM";
883 case SHT_MIPS_CONTENT
:
884 return "MIPS_CONTENT";
885 case SHT_MIPS_OPTIONS
:
886 return "MIPS_OPTIONS";
891 case SHT_MIPS_EXTSYM
:
892 return "MIPS_EXTSYM";
897 case SHT_MIPS_LOCSYM
:
898 return "MIPS_LOCSYM";
899 case SHT_MIPS_AUXSYM
:
900 return "MIPS_AUXSYM";
901 case SHT_MIPS_OPTSYM
:
902 return "MIPS_OPTSYM";
903 case SHT_MIPS_LOCSTR
:
904 return "MIPS_LOCSTR";
907 case SHT_MIPS_RFDESC
:
908 return "MIPS_RFDESC";
909 case SHT_MIPS_DELTASYM
:
910 return "MIPS_DELTASYM";
911 case SHT_MIPS_DELTAINST
:
912 return "MIPS_DELTAINST";
913 case SHT_MIPS_DELTACLASS
:
914 return "MIPS_DELTACLASS";
917 case SHT_MIPS_DELTADECL
:
918 return "MIPS_DELTADECL";
919 case SHT_MIPS_SYMBOL_LIB
:
920 return "MIPS_SYMBOL_LIB";
921 case SHT_MIPS_EVENTS
:
922 return "MIPS_EVENTS";
923 case SHT_MIPS_TRANSLATE
:
924 return "MIPS_TRANSLATE";
929 case SHT_MIPS_XLATE_DEBUG
:
930 return "MIPS_XLATE_DEBUG";
933 case SHT_MIPS_EH_REGION
:
934 return "MIPS_EH_REGION";
935 case SHT_MIPS_XLATE_OLD
:
936 return "MIPS_XLATE_OLD";
937 case SHT_MIPS_PDR_EXCEPTION
:
938 return "MIPS_PDR_EXCEPTION";
946 get_section_type_name (sh_type
)
947 unsigned int sh_type
;
949 static char buff
[32];
953 case SHT_NULL
: return "NULL";
954 case SHT_PROGBITS
: return "PROGBITS";
955 case SHT_SYMTAB
: return "SYMTAB";
956 case SHT_STRTAB
: return "STRTAB";
957 case SHT_RELA
: return "RELA";
958 case SHT_HASH
: return "HASH";
959 case SHT_DYNAMIC
: return "DYNAMIC";
960 case SHT_NOTE
: return "NOTE";
961 case SHT_NOBITS
: return "NOBITS";
962 case SHT_REL
: return "REL";
963 case SHT_SHLIB
: return "SHLIB";
964 case SHT_DYNSYM
: return "DYNSYM";
965 case SHT_GNU_verdef
: return "VERDEF";
966 case SHT_GNU_verneed
: return "VERNEED";
967 case SHT_GNU_versym
: return "VERSYM";
968 case 0x6ffffff0: return "VERSYM";
969 case 0x6ffffffc: return "VERDEF";
970 case 0x7ffffffd: return "AUXILIARY";
971 case 0x7fffffff: return "FILTER";
974 if ((sh_type
>= SHT_LOPROC
) && (sh_type
<= SHT_HIPROC
))
978 switch (elf_header
.e_machine
)
982 result
= get_mips_section_type_name (sh_type
);
991 sprintf (buff
, _("SHT_LOPROC+%d"), sh_type
- SHT_LOPROC
);
996 else if ((sh_type
>= SHT_LOUSER
) && (sh_type
<= SHT_HIUSER
))
997 sprintf (buff
, _("SHT_LOUSER+%d"), sh_type
- SHT_LOUSER
);
999 sprintf (buff
, _("<unknown>: %x"), sh_type
);
1004 struct option options
[] =
1006 {"all", no_argument
, 0, 'a'},
1007 {"file-header", no_argument
, 0, 'h'},
1008 {"program-headers", no_argument
, 0, 'l'},
1009 {"headers", no_argument
, 0, 'e'},
1010 {"segments", no_argument
, 0, 'l'},
1011 {"sections", no_argument
, 0, 'S'},
1012 {"section-headers", no_argument
, 0, 'S'},
1013 {"symbols", no_argument
, 0, 's'},
1014 {"relocs", no_argument
, 0, 'r'},
1015 {"dynamic", no_argument
, 0, 'd'},
1016 {"version-info", no_argument
, 0, 'V'},
1017 {"use-dynamic", no_argument
, 0, 'D'},
1019 {"hex-dump", required_argument
, 0, 'x'},
1020 #ifdef SUPPORT_DISASSEMBLY
1021 {"instruction-dump", required_argument
, 0, 'i'},
1024 {"version", no_argument
, 0, 'v'},
1025 {"help", no_argument
, 0, 'H'},
1027 {0, no_argument
, 0, 0}
1033 fprintf (stdout
, _("Usage: readelf {options} elf-file(s)\n"));
1034 fprintf (stdout
, _(" Options are:\n"));
1035 fprintf (stdout
, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V\n"));
1036 fprintf (stdout
, _(" -h or --file-header Display the ELF file header\n"));
1037 fprintf (stdout
, _(" -l or --program-headers or --segments\n"));
1038 fprintf (stdout
, _(" Display the program headers\n"));
1039 fprintf (stdout
, _(" -S or --section-headers or --sections\n"));
1040 fprintf (stdout
, _(" Display the sections' header\n"));
1041 fprintf (stdout
, _(" -e or --headers Equivalent to: -h -l -S\n"));
1042 fprintf (stdout
, _(" -s or --symbols Display the symbol table\n"));
1043 fprintf (stdout
, _(" -r or --relocs Display the relocations (if present)\n"));
1044 fprintf (stdout
, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1045 fprintf (stdout
, _(" -V or --version-info Display the version sections (if present)\n"));
1046 fprintf (stdout
, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1047 fprintf (stdout
, _(" -x <number> or --hex-dump=<number>\n"));
1048 fprintf (stdout
, _(" Dump the contents of section <number>\n"));
1049 #ifdef SUPPORT_DISASSEMBLY
1050 fprintf (stdout
, _(" -i <number> or --instruction-dump=<number>\n"));
1051 fprintf (stdout
, _(" Disassemble the contents of section <number>\n"));
1053 fprintf (stdout
, _(" -v or --version Display the version number of readelf\n"));
1054 fprintf (stdout
, _(" -H or --help Display this information\n"));
1055 fprintf (stdout
, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1061 parse_args (argc
, argv
)
1070 while ((c
= getopt_long
1071 (argc
, argv
, "ersahldSDx:i:vV", options
, NULL
)) != EOF
)
1097 do_using_dynamic
++;
1119 section
= strtoul (optarg
, & cp
, 0);
1120 if (! * cp
&& section
>= 0 && section
< NUM_DUMP_SECTS
)
1122 dump_sects
[section
] |= HEX_DUMP
;
1126 #ifdef SUPPORT_DISASSEMBLY
1129 section
= strtoul (optarg
, & cp
, 0);
1130 if (! * cp
&& section
>= 0 && section
< NUM_DUMP_SECTS
)
1132 dump_sects
[section
] |= DISASS_DUMP
;
1138 print_version (program_name
);
1145 /* xgettext:c-format */
1146 error (_("Invalid option '-%c'\n"), c
);
1153 if (!do_dynamic
&& !do_syms
&& !do_reloc
&& !do_sections
1154 && !do_segments
&& !do_header
&& !do_dump
&& !do_version
)
1158 warn (_("Nothing to do.\n"));
1163 /* Decode the data held in 'elf_header'. */
1165 process_file_header ()
1167 if ( elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
1168 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
1169 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
1170 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
1173 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1177 if (elf_header
.e_ident
[EI_CLASS
] != ELFCLASS32
)
1179 error (_("Not a 32 bit ELF file\n"));
1187 printf (_("ELF Header:\n"));
1188 printf (_(" Magic: "));
1189 for (i
= 0; i
< EI_NIDENT
; i
++)
1190 printf ("%2.2x ", elf_header
.e_ident
[i
]);
1192 printf (_(" Type: %s\n"),
1193 get_file_type (elf_header
.e_type
));
1194 printf (_(" Machine: %s\n"),
1195 get_machine_name (elf_header
.e_machine
));
1196 printf (_(" Version: 0x%lx\n"),
1197 (unsigned long) elf_header
.e_version
);
1198 printf (_(" Data: %s\n"),
1199 get_machine_data (elf_header
.e_ident
[EI_DATA
]));
1200 printf (_(" Entry point address: 0x%lx\n"),
1201 (unsigned long) elf_header
.e_entry
);
1202 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1203 (long) elf_header
.e_phoff
);
1204 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1205 (long) elf_header
.e_shoff
);
1206 printf (_(" Flags: 0x%lx%s\n"),
1207 (unsigned long) elf_header
.e_flags
,
1208 get_machine_flags (elf_header
.e_flags
, elf_header
.e_machine
));
1209 printf (_(" Size of this header: %ld (bytes)\n"),
1210 (long) elf_header
.e_ehsize
);
1211 printf (_(" Size of program headers: %ld (bytes)\n"),
1212 (long) elf_header
.e_phentsize
);
1213 printf (_(" Number of program headers: %ld\n"),
1214 (long) elf_header
.e_phnum
);
1215 printf (_(" Size of section headers: %ld (bytes)\n"),
1216 (long) elf_header
.e_shentsize
);
1217 printf (_(" Number of section headers: %ld\n"),
1218 (long) elf_header
.e_shnum
);
1219 printf (_(" Section header string table index: %ld\n"),
1220 (long) elf_header
.e_shstrndx
);
1228 process_program_headers (file
)
1231 Elf32_External_Phdr
* phdrs
;
1232 Elf32_Internal_Phdr
* program_headers
;
1233 Elf32_Internal_Phdr
* segment
;
1236 if (elf_header
.e_phnum
== 0)
1239 printf (_("\nThere are no program headers in this file.\n"));
1243 if (do_segments
&& !do_header
)
1245 printf (_("\nElf file is %s\n"), get_file_type (elf_header
.e_type
));
1246 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header
.e_entry
);
1247 printf (_("There are %d program headers, starting at offset %lx:\n"),
1248 elf_header
.e_phnum
, (unsigned long) elf_header
.e_phoff
);
1251 GET_DATA_ALLOC (elf_header
.e_phoff
,
1252 elf_header
.e_phentsize
* elf_header
.e_phnum
,
1253 phdrs
, Elf32_External_Phdr
*, "program headers");
1255 program_headers
= (Elf32_Internal_Phdr
*) malloc
1256 (elf_header
.e_phnum
* sizeof (Elf32_Internal_Phdr
));
1258 if (program_headers
== NULL
)
1260 error (_("Out of memory\n"));
1264 for (i
= 0, segment
= program_headers
;
1265 i
< elf_header
.e_phnum
;
1268 segment
->p_type
= BYTE_GET (phdrs
[i
].p_type
);
1269 segment
->p_offset
= BYTE_GET (phdrs
[i
].p_offset
);
1270 segment
->p_vaddr
= BYTE_GET (phdrs
[i
].p_vaddr
);
1271 segment
->p_paddr
= BYTE_GET (phdrs
[i
].p_paddr
);
1272 segment
->p_filesz
= BYTE_GET (phdrs
[i
].p_filesz
);
1273 segment
->p_memsz
= BYTE_GET (phdrs
[i
].p_memsz
);
1274 segment
->p_flags
= BYTE_GET (phdrs
[i
].p_flags
);
1275 segment
->p_align
= BYTE_GET (phdrs
[i
].p_align
);
1283 (_("\nProgram Header%s:\n"), elf_header
.e_phnum
> 1 ? "s" : "");
1285 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1291 for (i
= 0, segment
= program_headers
;
1292 i
< elf_header
.e_phnum
;
1297 printf (" %-11.11s ", get_segment_type (segment
->p_type
));
1298 printf ("0x%5.5lx ", (unsigned long) segment
->p_offset
);
1299 printf ("0x%8.8lx ", (unsigned long) segment
->p_vaddr
);
1300 printf ("0x%8.8lx ", (unsigned long) segment
->p_paddr
);
1301 printf ("0x%5.5lx ", (unsigned long) segment
->p_filesz
);
1302 printf ("0x%5.5lx ", (unsigned long) segment
->p_memsz
);
1304 (segment
->p_flags
& PF_R
? 'R' : ' '),
1305 (segment
->p_flags
& PF_W
? 'W' : ' '),
1306 (segment
->p_flags
& PF_X
? 'E' : ' '));
1307 printf ("%#lx", (unsigned long) segment
->p_align
);
1310 switch (segment
->p_type
)
1314 loadaddr
= (segment
->p_vaddr
& 0xfffff000)
1315 - (segment
->p_offset
& 0xfffff000);
1320 error (_("more than one dynamic segment\n"));
1322 dynamic_addr
= segment
->p_offset
;
1323 dynamic_size
= segment
->p_filesz
;
1327 if (fseek (file
, segment
->p_offset
, SEEK_SET
))
1328 error (_("Unable to find program interpreter name\n"));
1331 program_interpreter
[0] = 0;
1332 fscanf (file
, "%63s", program_interpreter
);
1335 printf (_("\n [Requesting program interpreter: %s]"),
1336 program_interpreter
);
1342 putc ('\n', stdout
);
1351 if (do_segments
&& section_headers
!= NULL
)
1353 printf (_("\n Section to Segment mapping:\n"));
1354 printf (_(" Segment Sections...\n"));
1356 assert (string_table
!= NULL
);
1358 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
1361 Elf32_Internal_Shdr
* section
;
1363 segment
= program_headers
+ i
;
1364 section
= section_headers
;
1366 printf (" %2.2d ", i
);
1368 for (j
= 0; j
< elf_header
.e_shnum
; j
++, section
++)
1370 if (section
->sh_size
> 0
1371 /* Compare allocated sections by VMA, unallocated
1372 sections by file offset. */
1373 && (section
->sh_flags
& SHF_ALLOC
1374 ? (section
->sh_addr
>= segment
->p_vaddr
1375 && section
->sh_addr
+ section
->sh_size
1376 <= segment
->p_vaddr
+ segment
->p_memsz
)
1377 : (section
->sh_offset
>= segment
->p_offset
1378 && (section
->sh_offset
+ section
->sh_size
1379 <= segment
->p_offset
+ segment
->p_filesz
))))
1380 printf ("%s ", SECTION_NAME (section
));
1387 free (program_headers
);
1394 get_section_headers (file
)
1397 Elf32_External_Shdr
* shdrs
;
1398 Elf32_Internal_Shdr
* internal
;
1401 GET_DATA_ALLOC (elf_header
.e_shoff
,
1402 elf_header
.e_shentsize
* elf_header
.e_shnum
,
1403 shdrs
, Elf32_External_Shdr
*, "section headers");
1405 section_headers
= (Elf32_Internal_Shdr
*) malloc
1406 (elf_header
.e_shnum
* sizeof (Elf32_Internal_Shdr
));
1408 if (section_headers
== NULL
)
1410 error (_("Out of memory\n"));
1414 for (i
= 0, internal
= section_headers
;
1415 i
< elf_header
.e_shnum
;
1418 internal
->sh_name
= BYTE_GET (shdrs
[i
].sh_name
);
1419 internal
->sh_type
= BYTE_GET (shdrs
[i
].sh_type
);
1420 internal
->sh_flags
= BYTE_GET (shdrs
[i
].sh_flags
);
1421 internal
->sh_addr
= BYTE_GET (shdrs
[i
].sh_addr
);
1422 internal
->sh_offset
= BYTE_GET (shdrs
[i
].sh_offset
);
1423 internal
->sh_size
= BYTE_GET (shdrs
[i
].sh_size
);
1424 internal
->sh_link
= BYTE_GET (shdrs
[i
].sh_link
);
1425 internal
->sh_info
= BYTE_GET (shdrs
[i
].sh_info
);
1426 internal
->sh_addralign
= BYTE_GET (shdrs
[i
].sh_addralign
);
1427 internal
->sh_entsize
= BYTE_GET (shdrs
[i
].sh_entsize
);
1435 static Elf_Internal_Sym
*
1436 get_elf_symbols (file
, offset
, number
)
1438 unsigned long offset
;
1439 unsigned long number
;
1441 Elf32_External_Sym
* esyms
;
1442 Elf_Internal_Sym
* isyms
;
1443 Elf_Internal_Sym
* psym
;
1446 GET_DATA_ALLOC (offset
, number
* sizeof (Elf32_External_Sym
),
1447 esyms
, Elf32_External_Sym
*, "symbols");
1449 isyms
= (Elf_Internal_Sym
*) malloc (number
* sizeof (Elf_Internal_Sym
));
1453 error (_("Out of memory\n"));
1459 for (j
= 0, psym
= isyms
;
1463 psym
->st_name
= BYTE_GET (esyms
[j
].st_name
);
1464 psym
->st_value
= BYTE_GET (esyms
[j
].st_value
);
1465 psym
->st_size
= BYTE_GET (esyms
[j
].st_size
);
1466 psym
->st_shndx
= BYTE_GET (esyms
[j
].st_shndx
);
1467 psym
->st_info
= BYTE_GET (esyms
[j
].st_info
);
1468 psym
->st_other
= BYTE_GET (esyms
[j
].st_other
);
1477 process_section_headers (file
)
1480 Elf32_Internal_Shdr
* section
;
1483 section_headers
= NULL
;
1485 if (elf_header
.e_shnum
== 0)
1488 printf (_("\nThere are no sections in this file.\n"));
1493 if (do_sections
&& !do_header
)
1494 printf (_("There are %d section headers, starting at offset %x:\n"),
1495 elf_header
.e_shnum
, elf_header
.e_shoff
);
1497 if (! get_section_headers (file
))
1500 /* Read in the string table, so that we have names to display. */
1501 section
= section_headers
+ elf_header
.e_shstrndx
;
1503 if (section
->sh_size
!= 0)
1505 unsigned long string_table_offset
;
1507 string_table_offset
= section
->sh_offset
;
1509 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
1510 string_table
, char *, "string table");
1513 /* Scan the sections for the dynamic symbol table
1514 and dynamic string table. */
1515 dynamic_symbols
= NULL
;
1516 dynamic_strings
= NULL
;
1517 for (i
= 0, section
= section_headers
;
1518 i
< elf_header
.e_shnum
;
1521 if (section
->sh_type
== SHT_DYNSYM
)
1523 if (dynamic_symbols
!= NULL
)
1525 error (_("File contains multiple dynamic symbol tables\n"));
1529 dynamic_symbols
= get_elf_symbols
1530 (file
, section
->sh_offset
, section
->sh_size
/ section
->sh_entsize
);
1532 else if (section
->sh_type
== SHT_STRTAB
1533 && strcmp (SECTION_NAME (section
), ".dynstr") == 0)
1535 if (dynamic_strings
!= NULL
)
1537 error (_("File contains multiple dynamic string tables\n"));
1541 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
1542 dynamic_strings
, char *, "dynamic strings");
1549 printf (_("\nSection Header%s:\n"), elf_header
.e_shnum
> 1 ? "s" : "");
1551 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1553 for (i
= 0, section
= section_headers
;
1554 i
< elf_header
.e_shnum
;
1557 printf (" [%2d] %-17.17s %-15.15s ",
1559 SECTION_NAME (section
),
1560 get_section_type_name (section
->sh_type
));
1562 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1563 (unsigned long) section
->sh_addr
,
1564 (unsigned long) section
->sh_offset
,
1565 (unsigned long) section
->sh_size
,
1566 (unsigned long) section
->sh_entsize
);
1568 printf (" %c%c%c %2ld %3lx %ld \n",
1569 (section
->sh_flags
& SHF_WRITE
? 'W' : ' '),
1570 (section
->sh_flags
& SHF_ALLOC
? 'A' : ' '),
1571 (section
->sh_flags
& SHF_EXECINSTR
? 'X' : ' '),
1572 (unsigned long) section
->sh_link
,
1573 (unsigned long) section
->sh_info
,
1574 (unsigned long) section
->sh_addralign
);
1580 /* Process the reloc section. */
1582 process_relocs (file
)
1585 unsigned long rel_size
;
1586 unsigned long rel_offset
;
1592 if (do_using_dynamic
)
1597 if (dynamic_info
[DT_REL
])
1599 rel_offset
= dynamic_info
[DT_REL
];
1600 rel_size
= dynamic_info
[DT_RELSZ
];
1602 else if (dynamic_info
[DT_RELA
])
1604 rel_offset
= dynamic_info
[DT_RELA
];
1605 rel_size
= dynamic_info
[DT_RELASZ
];
1607 else if (dynamic_info
[DT_JMPREL
])
1609 rel_offset
= dynamic_info
[DT_JMPREL
];
1610 rel_size
= dynamic_info
[DT_PLTRELSZ
];
1616 (_("\nRelocation section at offset 0x%x contains %d bytes:\n"),
1617 rel_offset
, rel_size
);
1619 dump_relocations (file
, rel_offset
- loadaddr
, rel_size
,
1620 dynamic_symbols
, dynamic_strings
);
1623 printf (_("\nThere are no dynamic relocations in this file.\n"));
1627 Elf32_Internal_Shdr
* section
;
1631 for (i
= 0, section
= section_headers
;
1632 i
< elf_header
.e_shnum
;
1635 if ( section
->sh_type
!= SHT_RELA
1636 && section
->sh_type
!= SHT_REL
)
1639 rel_offset
= section
->sh_offset
;
1640 rel_size
= section
->sh_size
;
1644 Elf32_Internal_Shdr
* strsec
;
1645 Elf32_Internal_Shdr
* symsec
;
1646 Elf_Internal_Sym
* symtab
;
1649 printf (_("\nRelocation section "));
1651 if (string_table
== NULL
)
1652 printf ("%d", section
->sh_name
);
1654 printf ("'%s'", SECTION_NAME (section
));
1656 printf (_(" at offset 0x%x contains %d entries:\n"),
1657 rel_offset
, rel_size
/ section
->sh_entsize
);
1659 symsec
= section_headers
+ section
->sh_link
;
1661 symtab
= get_elf_symbols (file
, symsec
->sh_offset
,
1662 symsec
->sh_size
/ symsec
->sh_entsize
);
1667 strsec
= section_headers
+ symsec
->sh_link
;
1669 GET_DATA_ALLOC (strsec
->sh_offset
, strsec
->sh_size
, strtab
,
1670 char *, "string table");
1672 dump_relocations (file
, rel_offset
, rel_size
, symtab
, strtab
);
1682 printf (_("\nThere are no relocations in this file.\n"));
1690 dynamic_segment_mips_val (entry
)
1691 Elf_Internal_Dyn
*entry
;
1693 switch (entry
->d_tag
)
1695 case DT_MIPS_LOCAL_GOTNO
:
1696 case DT_MIPS_CONFLICTNO
:
1697 case DT_MIPS_LIBLISTNO
:
1698 case DT_MIPS_SYMTABNO
:
1699 case DT_MIPS_UNREFEXTNO
:
1700 case DT_MIPS_HIPAGENO
:
1701 case DT_MIPS_DELTA_CLASS_NO
:
1702 case DT_MIPS_DELTA_INSTANCE_NO
:
1703 case DT_MIPS_DELTA_RELOC_NO
:
1704 case DT_MIPS_DELTA_SYM_NO
:
1705 case DT_MIPS_DELTA_CLASSSYM_NO
:
1707 printf ("%#ld\n", (long) entry
->d_un
.d_ptr
);
1711 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
1715 /* Parse the dynamic segment */
1717 process_dynamic_segment (file
)
1720 Elf_Internal_Dyn
* entry
;
1721 Elf32_External_Dyn
* edyn
;
1724 if (dynamic_size
== 0)
1727 printf (_("\nThere is no dynamic segment in this file.\n"));
1732 GET_DATA_ALLOC (dynamic_addr
, dynamic_size
,
1733 edyn
, Elf32_External_Dyn
*, "dynamic segment");
1735 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
1736 how large .dynamic is now. We can do this even before the byte
1737 swapping since the DT_NULL tag is recognizable. */
1739 while (*(Elf32_Word
*) edyn
[dynamic_size
++].d_tag
!= DT_NULL
)
1742 dynamic_segment
= (Elf_Internal_Dyn
*)
1743 malloc (dynamic_size
* sizeof (Elf_Internal_Dyn
));
1745 if (dynamic_segment
== NULL
)
1747 error (_("Out of memory\n"));
1752 for (i
= 0, entry
= dynamic_segment
;
1756 entry
->d_tag
= BYTE_GET (edyn
[i
].d_tag
);
1757 entry
->d_un
.d_val
= BYTE_GET (edyn
[i
].d_un
.d_val
);
1762 /* Find the appropriate symbol table. */
1763 if (dynamic_symbols
== NULL
)
1765 for (i
= 0, entry
= dynamic_segment
;
1769 unsigned long offset
;
1772 if (entry
->d_tag
!= DT_SYMTAB
)
1775 dynamic_info
[DT_SYMTAB
] = entry
->d_un
.d_val
;
1777 /* Since we do not know how big the symbol table is,
1778 we default to reading in the entire file (!) and
1779 processing that. This is overkill, I know, but it
1782 offset
= entry
->d_un
.d_val
- loadaddr
;
1784 if (fseek (file
, 0, SEEK_END
))
1785 error (_("Unable to seek to end of file!"));
1787 num_syms
= (ftell (file
) - offset
) / sizeof (Elf32_External_Sym
);
1791 error (_("Unable to determine the number of symbols to load\n"));
1795 dynamic_symbols
= get_elf_symbols (file
, offset
, num_syms
);
1799 /* Similarly find a string table. */
1800 if (dynamic_strings
== NULL
)
1802 for (i
= 0, entry
= dynamic_segment
;
1806 unsigned long offset
;
1809 if (entry
->d_tag
!= DT_STRTAB
)
1812 dynamic_info
[DT_STRTAB
] = entry
->d_un
.d_val
;
1814 /* Since we do not know how big the string table is,
1815 we default to reading in the entire file (!) and
1816 processing that. This is overkill, I know, but it
1819 offset
= entry
->d_un
.d_val
- loadaddr
;
1820 if (fseek (file
, 0, SEEK_END
))
1821 error (_("Unable to seek to end of file\n"));
1822 str_tab_len
= ftell (file
) - offset
;
1824 if (str_tab_len
< 1)
1827 (_("Unable to determine the length of the dynamic string table\n"));
1831 GET_DATA_ALLOC (offset
, str_tab_len
, dynamic_strings
, char *,
1832 "dynamic string table");
1838 if (do_dynamic
&& dynamic_addr
)
1839 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
1840 dynamic_addr
, dynamic_size
);
1842 printf (_(" Tag Type Name/Value\n"));
1844 for (i
= 0, entry
= dynamic_segment
;
1849 printf (_(" 0x%-8.8lx (%s)%*s"),
1850 (unsigned long) entry
->d_tag
,
1851 get_dynamic_type (entry
->d_tag
),
1852 27 - strlen (get_dynamic_type (entry
->d_tag
)),
1855 switch (entry
->d_tag
)
1861 if (entry
->d_tag
== DT_AUXILIARY
)
1862 printf (_("Auxiliary library"));
1864 printf (_("Filter library"));
1866 if (dynamic_strings
)
1867 printf (": [%s]\n", dynamic_strings
+ entry
->d_un
.d_val
);
1869 printf (": %#lx\n", (long) entry
->d_un
.d_val
);
1897 dynamic_info
[entry
->d_tag
] = entry
->d_un
.d_val
;
1903 if (dynamic_strings
== NULL
)
1906 name
= dynamic_strings
+ entry
->d_un
.d_val
;
1910 switch (entry
->d_tag
)
1913 printf (_("Shared library: [%s]"), name
);
1915 if (strcmp (name
, program_interpreter
))
1918 printf (_(" program interpreter\n"));
1922 printf (_("Library soname: [%s]\n"), name
);
1926 printf (_("Library rpath: [%s]\n"), name
);
1930 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
1934 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
1939 if ((entry
->d_tag
>= DT_VERSYM
) && (entry
->d_tag
<= DT_VERNEEDNUM
))
1941 version_info
[DT_VERSIONTAGIDX (entry
->d_tag
)] =
1945 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
1948 switch (elf_header
.e_machine
)
1951 case EM_MIPS_RS4_BE
:
1952 dynamic_segment_mips_val (entry
);
1956 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
1966 get_ver_flags (flags
)
1969 static char buff
[32];
1976 if (flags
& VER_FLG_BASE
)
1977 strcat (buff
, "BASE ");
1979 if (flags
& VER_FLG_WEAK
)
1981 if (flags
& VER_FLG_BASE
)
1982 strcat (buff
, "| ");
1984 strcat (buff
, "WEAK ");
1987 if (flags
& ~(VER_FLG_BASE
| VER_FLG_WEAK
))
1988 strcat (buff
, "| <unknown>");
1993 /* Display the contents of the version sections. */
1995 process_version_sections (file
)
1998 Elf32_Internal_Shdr
* section
;
2005 for (i
= 0, section
= section_headers
;
2006 i
< elf_header
.e_shnum
;
2009 switch (section
->sh_type
)
2011 case SHT_GNU_verdef
:
2013 Elf_External_Verdef
* edefs
;
2020 (_("\nVersion definition section '%s' contains %d entries:\n"),
2021 SECTION_NAME (section
), section
->sh_info
);
2023 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2024 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2025 SECTION_NAME (section_headers
+ section
->sh_link
));
2027 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
2028 edefs
, Elf_External_Verdef
*,
2029 "version definition section");
2031 for (idx
= cnt
= 0; cnt
< section
->sh_info
; ++ cnt
)
2034 Elf_External_Verdef
* edef
;
2035 Elf_Internal_Verdef ent
;
2036 Elf_External_Verdaux
* eaux
;
2037 Elf_Internal_Verdaux aux
;
2041 vstart
= ((char *) edefs
) + idx
;
2043 edef
= (Elf_External_Verdef
*) vstart
;
2045 ent
.vd_version
= BYTE_GET (edef
->vd_version
);
2046 ent
.vd_flags
= BYTE_GET (edef
->vd_flags
);
2047 ent
.vd_ndx
= BYTE_GET (edef
->vd_ndx
);
2048 ent
.vd_cnt
= BYTE_GET (edef
->vd_cnt
);
2049 ent
.vd_hash
= BYTE_GET (edef
->vd_hash
);
2050 ent
.vd_aux
= BYTE_GET (edef
->vd_aux
);
2051 ent
.vd_next
= BYTE_GET (edef
->vd_next
);
2053 printf (_(" %#06x: Rev: %d Flags: %s"),
2054 idx
, ent
.vd_version
, get_ver_flags (ent
.vd_flags
));
2056 printf (_(" Index: %ld Cnt: %ld "), ent
.vd_ndx
, ent
.vd_cnt
);
2058 vstart
+= ent
.vd_aux
;
2060 eaux
= (Elf_External_Verdaux
*) vstart
;
2062 aux
.vda_name
= BYTE_GET (eaux
->vda_name
);
2063 aux
.vda_next
= BYTE_GET (eaux
->vda_next
);
2065 if (dynamic_strings
)
2066 printf (_("Name: %s\n"), dynamic_strings
+ aux
.vda_name
);
2068 printf (_("Name index: %ld\n"), aux
.vda_name
);
2070 isum
= idx
+ ent
.vd_aux
;
2072 for (j
= 1; j
< ent
.vd_cnt
; j
++)
2074 isum
+= aux
.vda_next
;
2075 vstart
+= aux
.vda_next
;
2077 eaux
= (Elf_External_Verdaux
*) vstart
;
2079 aux
.vda_name
= BYTE_GET (eaux
->vda_name
);
2080 aux
.vda_next
= BYTE_GET (eaux
->vda_next
);
2082 if (dynamic_strings
)
2083 printf (_(" %#06x: Parent %d: %s\n"),
2084 isum
, j
, dynamic_strings
+ aux
.vda_name
);
2086 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2087 isum
, j
, aux
.vda_name
);
2097 case SHT_GNU_verneed
:
2099 Elf_External_Verneed
* eneed
;
2105 printf (_("\nVersion needs section '%s' contains %d entries:\n"),
2106 SECTION_NAME (section
), section
->sh_info
);
2109 (_(" Addr: %#08x Offset: %#08x Link to section: %d (%s)\n"),
2110 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2111 SECTION_NAME (section_headers
+ section
->sh_link
));
2113 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
2114 eneed
, Elf_External_Verneed
*,
2115 "version need section");
2117 for (idx
= cnt
= 0; cnt
< section
->sh_info
; ++cnt
)
2119 Elf_External_Verneed
* entry
;
2120 Elf_Internal_Verneed ent
;
2125 vstart
= ((char *) eneed
) + idx
;
2127 entry
= (Elf_External_Verneed
*) vstart
;
2129 ent
.vn_version
= BYTE_GET (entry
->vn_version
);
2130 ent
.vn_cnt
= BYTE_GET (entry
->vn_cnt
);
2131 ent
.vn_file
= BYTE_GET (entry
->vn_file
);
2132 ent
.vn_aux
= BYTE_GET (entry
->vn_aux
);
2133 ent
.vn_next
= BYTE_GET (entry
->vn_next
);
2135 printf (_(" %#06x: Version: %d"), idx
, ent
.vn_version
);
2137 if (dynamic_strings
)
2138 printf (_(" File: %s"), dynamic_strings
+ ent
.vn_file
);
2140 printf (_(" File: %lx"), ent
.vn_file
);
2142 printf (_(" Cnt: %d\n"), ent
.vn_cnt
);
2144 vstart
+= ent
.vn_aux
;
2146 for (j
= 0, isum
= idx
+ ent
.vn_aux
; j
< ent
.vn_cnt
; ++j
)
2148 Elf_External_Vernaux
* eaux
;
2149 Elf_Internal_Vernaux aux
;
2151 eaux
= (Elf_External_Vernaux
*) vstart
;
2153 aux
.vna_hash
= BYTE_GET (eaux
->vna_hash
);
2154 aux
.vna_flags
= BYTE_GET (eaux
->vna_flags
);
2155 aux
.vna_other
= BYTE_GET (eaux
->vna_other
);
2156 aux
.vna_name
= BYTE_GET (eaux
->vna_name
);
2157 aux
.vna_next
= BYTE_GET (eaux
->vna_next
);
2159 if (dynamic_strings
)
2160 printf (_(" %#06x: Name: %s"),
2161 isum
, dynamic_strings
+ aux
.vna_name
);
2163 printf (_(" %#06x: Name index: %lx"),
2164 isum
, aux
.vna_name
);
2166 printf (_(" Flags: %s Version: %d\n"),
2167 get_ver_flags (aux
.vna_flags
), aux
.vna_other
);
2169 isum
+= aux
.vna_next
;
2170 vstart
+= aux
.vna_next
;
2180 case SHT_GNU_versym
:
2182 Elf32_Internal_Shdr
* link_section
;
2185 unsigned char * edata
;
2186 unsigned short * data
;
2188 Elf_Internal_Sym
* symbols
;
2189 Elf32_Internal_Shdr
* string_sec
;
2191 link_section
= section_headers
+ section
->sh_link
;
2192 total
= section
->sh_size
/ section
->sh_entsize
;
2196 symbols
= get_elf_symbols
2197 (file
, link_section
->sh_offset
,
2198 link_section
->sh_size
/ link_section
->sh_entsize
);
2200 string_sec
= section_headers
+ link_section
->sh_link
;
2202 GET_DATA_ALLOC (string_sec
->sh_offset
, string_sec
->sh_size
,
2203 strtab
, char *, "version string table");
2205 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2206 SECTION_NAME (section
), total
);
2208 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2209 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2210 SECTION_NAME (link_section
));
2212 GET_DATA_ALLOC (version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)]
2214 total
* sizeof (short), edata
,
2215 char *, "version symbol data");
2217 data
= (unsigned short *) malloc (total
* sizeof (short));
2219 for (cnt
= total
; cnt
--;)
2220 data
[cnt
] = byte_get (edata
+ cnt
* sizeof (short), sizeof (short));
2224 for (cnt
= 0; cnt
< total
; cnt
+= 4)
2228 printf (" %03x:", cnt
);
2230 for (j
= 0; (j
< 4) && (cnt
+ j
) < total
; ++j
)
2231 switch (data
[cnt
+ j
])
2234 fputs (_(" 0 (*local*) "), stdout
);
2238 fputs (_(" 1 (*global*) "), stdout
);
2242 nn
= printf ("%4x%c", data
[cnt
+ j
] & 0x7fff,
2243 data
[cnt
+ j
] & 0x8000 ? 'h' : ' ');
2245 if (symbols
[cnt
+ j
].st_shndx
< SHN_LORESERVE
2246 && section_headers
[symbols
[cnt
+ j
].st_shndx
].sh_type
2249 /* We must test both. */
2250 Elf_Internal_Verneed ivn
;
2251 unsigned long offset
;
2253 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERNEED
)]
2258 Elf_External_Verneed evn
;
2259 Elf_External_Vernaux evna
;
2260 Elf_Internal_Vernaux ivna
;
2261 unsigned long vna_off
;
2263 GET_DATA (offset
, evn
, "version need");
2265 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2266 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2268 vna_off
= offset
+ ivn
.vn_aux
;
2272 GET_DATA (vna_off
, evna
,
2273 "version need aux (1)");
2275 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2276 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2278 vna_off
+= ivna
.vna_next
;
2280 while (ivna
.vna_other
!= data
[cnt
+ j
]
2281 && ivna
.vna_next
!= 0);
2283 if (ivna
.vna_other
== data
[cnt
+ j
])
2285 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2287 nn
+= printf ("(%s%-*s",
2288 strtab
+ ivna
.vna_name
,
2294 else if (ivn
.vn_next
== 0)
2296 if (data
[cnt
+ j
] != 0x8001)
2298 Elf_Internal_Verdef ivd
;
2299 Elf_External_Verdef evd
;
2301 offset
= version_info
2302 [DT_VERSIONTAGIDX (DT_VERDEF
)]
2307 GET_DATA (offset
, evd
,
2308 "version definition");
2310 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2311 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2313 offset
+= ivd
.vd_next
;
2316 != (data
[cnt
+ j
] & 0x7fff)
2317 && ivd
.vd_next
!= 0);
2320 == (data
[cnt
+ j
] & 0x7fff))
2322 Elf_External_Verdaux evda
;
2323 Elf_Internal_Verdaux ivda
;
2325 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2327 GET_DATA (offset
+ ivd
.vd_aux
, evda
,
2328 "version definition aux");
2331 BYTE_GET (evda
.vda_name
);
2335 strtab
+ ivda
.vda_name
,
2346 offset
+= ivn
.vn_next
;
2348 while (ivn
.vn_next
);
2350 else if (symbols
[cnt
+ j
].st_shndx
== SHN_UNDEF
)
2352 Elf_Internal_Verneed ivn
;
2353 unsigned long offset
;
2355 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERNEED
)]
2360 Elf_Internal_Vernaux ivna
;
2361 Elf_External_Verneed evn
;
2362 Elf_External_Vernaux evna
;
2363 unsigned long a_off
;
2365 GET_DATA (offset
, evn
, "version need");
2367 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2368 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2370 a_off
= offset
+ ivn
.vn_aux
;
2374 GET_DATA (a_off
, evna
,
2375 "version need aux (2)");
2377 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2378 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2380 a_off
+= ivna
.vna_next
;
2382 while (ivna
.vna_other
!= data
[cnt
+ j
]
2383 && ivna
.vna_next
!= 0);
2385 if (ivna
.vna_other
== data
[cnt
+ j
])
2387 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2389 nn
+= printf ("(%s%-*s",
2390 strtab
+ ivna
.vna_name
,
2397 offset
+= ivn
.vn_next
;
2399 while (ivn
.vn_next
);
2401 else if (data
[cnt
+ j
] != 0x8001)
2403 Elf_Internal_Verdef ivd
;
2404 Elf_External_Verdef evd
;
2405 unsigned long offset
;
2407 offset
= version_info
2408 [DT_VERSIONTAGIDX (DT_VERDEF
)] - loadaddr
;
2412 GET_DATA (offset
, evd
, "version def");
2414 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2415 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2417 offset
+= ivd
.vd_next
;
2419 while (ivd
.vd_ndx
!= (data
[cnt
+ j
] & 0x7fff)
2420 && ivd
.vd_next
!= 0);
2422 if (ivd
.vd_ndx
== (data
[cnt
+ j
] & 0x7fff))
2424 Elf_External_Verdaux evda
;
2425 Elf_Internal_Verdaux ivda
;
2427 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2429 GET_DATA (offset
- ivd
.vd_next
+ ivd
.vd_aux
,
2430 evda
, "version def aux");
2432 ivda
.vda_name
= BYTE_GET (evda
.vda_name
);
2434 nn
+= printf ("(%s%-*s",
2435 strtab
+ ivda
.vda_name
,
2443 printf ("%*c", 18 - nn
, ' ');
2461 printf (_("\nNo version information found in this file.\n"));
2467 get_symbol_binding (binding
)
2468 unsigned int binding
;
2470 static char buff
[32];
2474 case STB_LOCAL
: return _("LOCAL");
2475 case STB_GLOBAL
: return _("GLOBAL");
2476 case STB_WEAK
: return _("WEAK");
2478 if (binding
>= STB_LOPROC
&& binding
<= STB_HIPROC
)
2479 sprintf (buff
, _("<processor specific>: %d"), binding
);
2481 sprintf (buff
, _("<unknown>: %d"), binding
);
2487 get_symbol_type (type
)
2490 static char buff
[32];
2494 case STT_NOTYPE
: return _("NOTYPE");
2495 case STT_OBJECT
: return _("OBJECT");
2496 case STT_FUNC
: return _("FUNC");
2497 case STT_SECTION
: return _("SECTION");
2498 case STT_FILE
: return _("FILE");
2500 if (type
>= STT_LOPROC
&& type
<= STT_HIPROC
)
2501 sprintf (buff
, _("<processor specific>: %d"), type
);
2503 sprintf (buff
, _("<unknown>: %d"), type
);
2509 get_symbol_index_type (type
)
2514 case SHN_UNDEF
: return "UND";
2515 case SHN_ABS
: return "ABS";
2516 case SHN_COMMON
: return "COM";
2518 if (type
>= SHN_LOPROC
&& type
<= SHN_HIPROC
)
2520 else if (type
>= SHN_LORESERVE
&& type
<= SHN_HIRESERVE
)
2524 static char buff
[32];
2526 sprintf (buff
, "%3d", type
);
2534 get_dynamic_data (file
, number
)
2536 unsigned int number
;
2541 e_data
= (char *) malloc (number
* 4);
2545 error (_("Out of memory\n"));
2549 if (fread (e_data
, 4, number
, file
) != number
)
2551 error (_("Unable to read in dynamic data\n"));
2555 i_data
= (int *) malloc (number
* sizeof (* i_data
));
2559 error (_("Out of memory\n"));
2565 i_data
[number
] = byte_get (e_data
+ number
* 4, 4);
2572 /* Dump the symbol table */
2574 process_symbol_table (file
)
2577 Elf32_Internal_Shdr
* section
;
2582 if (dynamic_info
[DT_HASH
] && do_using_dynamic
&& dynamic_strings
!= NULL
)
2593 if (fseek (file
, dynamic_info
[DT_HASH
] - loadaddr
, SEEK_SET
))
2595 error (_("Unable to seek to start of dynamic information"));
2599 if (fread (& nb
, sizeof (nb
), 1, file
) != 1)
2601 error (_("Failed to read in number of buckets\n"));
2605 if (fread (& nc
, sizeof (nc
), 1, file
) != 1)
2607 error (_("Failed to read in number of chains\n"));
2611 nbuckets
= byte_get (nb
, 4);
2612 nchains
= byte_get (nc
, 4);
2614 buckets
= get_dynamic_data (file
, nbuckets
);
2615 chains
= get_dynamic_data (file
, nchains
);
2617 if (buckets
== NULL
|| chains
== NULL
)
2620 printf (_("\nSymbol table for image:\n"));
2621 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
2623 for (hn
= 0; hn
< nbuckets
; hn
++)
2628 for (si
= buckets
[hn
]; si
; si
= chains
[si
])
2630 Elf_Internal_Sym
* psym
;
2632 psym
= dynamic_symbols
+ si
;
2634 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
2636 (unsigned long) psym
->st_value
,
2637 (unsigned long) psym
->st_size
,
2638 get_symbol_type (ELF_ST_TYPE (psym
->st_info
)),
2639 get_symbol_binding (ELF_ST_BIND (psym
->st_info
)),
2642 printf ("%3.3s", get_symbol_index_type (psym
->st_shndx
));
2644 printf (" %s\n", dynamic_strings
+ psym
->st_name
);
2651 else if (!do_using_dynamic
)
2655 for (i
= 0, section
= section_headers
;
2656 i
< elf_header
.e_shnum
;
2661 Elf_Internal_Sym
* symtab
;
2662 Elf_Internal_Sym
* psym
;
2665 if ( section
->sh_type
!= SHT_SYMTAB
2666 && section
->sh_type
!= SHT_DYNSYM
)
2669 printf (_("\nSymbol table '%s' contains %d entries:\n"),
2670 SECTION_NAME (section
),
2671 section
->sh_size
/ section
->sh_entsize
);
2672 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
2675 symtab
= get_elf_symbols (file
, section
->sh_offset
,
2676 section
->sh_size
/ section
->sh_entsize
);
2680 if (section
->sh_link
== elf_header
.e_shstrndx
)
2681 strtab
= string_table
;
2684 Elf32_Internal_Shdr
* string_sec
;
2686 string_sec
= section_headers
+ section
->sh_link
;
2688 GET_DATA_ALLOC (string_sec
->sh_offset
, string_sec
->sh_size
,
2689 strtab
, char *, "string table");
2692 for (si
= 0, psym
= symtab
;
2693 si
< section
->sh_size
/ section
->sh_entsize
;
2696 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
2698 (unsigned long) psym
->st_value
,
2699 (unsigned long) psym
->st_size
,
2700 get_symbol_type (ELF_ST_TYPE (psym
->st_info
)),
2701 get_symbol_binding (ELF_ST_BIND (psym
->st_info
)),
2704 if (psym
->st_shndx
== 0)
2705 fputs (" UND", stdout
);
2706 else if ((psym
->st_shndx
& 0xffff) == 0xfff1)
2707 fputs (" ABS", stdout
);
2708 else if ((psym
->st_shndx
& 0xffff) == 0xfff2)
2709 fputs (" COM", stdout
);
2711 printf ("%4x", psym
->st_shndx
);
2713 printf (" %s", strtab
+ psym
->st_name
);
2715 if (section
->sh_type
== SHT_DYNSYM
&&
2716 version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)] != 0)
2718 unsigned char data
[2];
2719 unsigned short vers_data
;
2720 unsigned long offset
;
2724 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)]
2727 GET_DATA (offset
+ si
* sizeof (vers_data
), data
,
2730 vers_data
= byte_get (data
, 2);
2732 is_nobits
= psym
->st_shndx
< SHN_LORESERVE
?
2733 (section_headers
[psym
->st_shndx
].sh_type
== SHT_NOBITS
)
2736 check_def
= (psym
->st_shndx
!= SHN_UNDEF
);
2738 if ((vers_data
& 0x8000) || vers_data
> 1)
2740 if (is_nobits
|| ! check_def
)
2742 Elf_External_Verneed evn
;
2743 Elf_Internal_Verneed ivn
;
2744 Elf_Internal_Vernaux ivna
;
2746 /* We must test both. */
2747 offset
= version_info
2748 [DT_VERSIONTAGIDX (DT_VERNEED
)] - loadaddr
;
2750 GET_DATA (offset
, evn
, "version need");
2752 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2753 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2757 unsigned long vna_off
;
2759 vna_off
= offset
+ ivn
.vn_aux
;
2763 Elf_External_Vernaux evna
;
2765 GET_DATA (vna_off
, evna
,
2766 "version need aux (3)");
2768 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2769 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2770 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2772 vna_off
+= ivna
.vna_next
;
2774 while (ivna
.vna_other
!= vers_data
2775 && ivna
.vna_next
!= 0);
2777 if (ivna
.vna_other
== vers_data
)
2780 offset
+= ivn
.vn_next
;
2782 while (ivn
.vn_next
!= 0);
2784 if (ivna
.vna_other
== vers_data
)
2787 strtab
+ ivna
.vna_name
, ivna
.vna_other
);
2790 else if (! is_nobits
)
2791 error (_("bad dynamic symbol"));
2798 if (vers_data
!= 0x8001)
2800 Elf_Internal_Verdef ivd
;
2801 Elf_Internal_Verdaux ivda
;
2802 Elf_External_Verdaux evda
;
2803 unsigned long offset
;
2806 version_info
[DT_VERSIONTAGIDX (DT_VERDEF
)]
2811 Elf_External_Verdef evd
;
2813 GET_DATA (offset
, evd
, "version def");
2815 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2816 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2817 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2819 offset
+= ivd
.vd_next
;
2821 while (ivd
.vd_ndx
!= (vers_data
& 0x7fff)
2822 && ivd
.vd_next
!= 0);
2824 offset
-= ivd
.vd_next
;
2825 offset
+= ivd
.vd_aux
;
2827 GET_DATA (offset
, evda
, "version def aux");
2829 ivda
.vda_name
= BYTE_GET (evda
.vda_name
);
2831 if (psym
->st_name
!= ivda
.vda_name
)
2832 printf ((vers_data
& 0x8000)
2834 strtab
+ ivda
.vda_name
);
2844 if (strtab
!= string_table
)
2850 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
2856 process_section_contents (file
)
2859 Elf32_Internal_Shdr
* section
;
2865 for (i
= 0, section
= section_headers
;
2866 i
< elf_header
.e_shnum
;
2869 #ifdef SUPPORT_DISASSEMBLY
2870 /* See if we need an assembly dump of this section */
2872 if ((i
< NUM_DUMP_SECTS
) && (dump_sects
[i
] & DISASS_DUMP
))
2874 printf (_("\nAssembly dump of section %s\n"),
2875 SECTION_NAME (section
));
2877 /* XXX -- to be done --- XXX */
2880 /* See if we need a hex dump of this section. */
2881 if ((i
< NUM_DUMP_SECTS
) && (dump_sects
[i
] & HEX_DUMP
))
2885 unsigned char * data
;
2888 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section
));
2890 bytes
= section
->sh_size
;
2891 addr
= section
->sh_addr
;
2893 GET_DATA_ALLOC (section
->sh_offset
, bytes
, start
, char *,
2904 lbytes
= (bytes
> 16 ? 16 : bytes
);
2906 printf (" 0x%8.8x ", addr
);
2908 switch (elf_header
.e_ident
[EI_DATA
])
2911 for (j
= 15; j
>= 0; j
--)
2914 printf ("%2.2x", data
[j
]);
2924 for (j
= 0; j
< 16; j
++)
2927 printf ("%2.2x", data
[j
]);
2937 for (j
= 0; j
< lbytes
; j
++)
2940 if (k
>= ' ' && k
< 0x80)
2961 process_mips_fpe_exception (mask
)
2967 if (mask
& OEX_FPU_INEX
)
2968 fputs ("INEX", stdout
), first
= 0;
2969 if (mask
& OEX_FPU_UFLO
)
2970 printf ("%sUFLO", first
? "" : "|"), first
= 0;
2971 if (mask
& OEX_FPU_OFLO
)
2972 printf ("%sOFLO", first
? "" : "|"), first
= 0;
2973 if (mask
& OEX_FPU_DIV0
)
2974 printf ("%sDIV0", first
? "" : "|"), first
= 0;
2975 if (mask
& OEX_FPU_INVAL
)
2976 printf ("%sINVAL", first
? "" : "|");
2979 fputs ("0", stdout
);
2983 process_mips_specific (file
)
2986 Elf_Internal_Dyn
* entry
;
2987 size_t liblist_offset
= 0;
2988 size_t liblistno
= 0;
2989 size_t options_offset
= 0;
2991 /* We have a lot of special sections. Thanks SGI! */
2992 if (dynamic_segment
== NULL
)
2993 /* No information available. */
2996 for (entry
= dynamic_segment
; entry
->d_tag
!= DT_NULL
; ++entry
)
2997 switch (entry
->d_tag
)
2999 case DT_MIPS_LIBLIST
:
3000 liblist_offset
= entry
->d_un
.d_val
- loadaddr
;
3002 case DT_MIPS_LIBLISTNO
:
3003 liblistno
= entry
->d_un
.d_val
;
3005 case DT_MIPS_OPTIONS
:
3006 options_offset
= entry
->d_un
.d_val
- loadaddr
;
3012 if (liblist_offset
!= 0 && liblistno
!= 0 && do_dynamic
)
3014 Elf32_External_Lib
*elib
;
3017 GET_DATA_ALLOC (liblist_offset
, liblistno
* sizeof (Elf32_External_Lib
),
3018 elib
, Elf32_External_Lib
*, "liblist");
3020 printf ("\nSection '.liblist' contains %d entries:\n", liblistno
);
3021 fputs (" Library Time Stamp Checksum Version Flags\n",
3024 for (cnt
= 0; cnt
< liblistno
; ++cnt
)
3030 liblist
.l_name
= BYTE_GET (elib
[cnt
].l_name
);
3031 time
= BYTE_GET (elib
[cnt
].l_time_stamp
);
3032 liblist
.l_checksum
= BYTE_GET (elib
[cnt
].l_checksum
);
3033 liblist
.l_version
= BYTE_GET (elib
[cnt
].l_version
);
3034 liblist
.l_flags
= BYTE_GET (elib
[cnt
].l_flags
);
3036 strftime (timebuf
, 17, "%Y-%m-%dT%H:%M", gmtime (&time
));
3038 printf ("%3d: %-20s %s %#10lx %-7ld %#lx\n", cnt
,
3039 dynamic_strings
+ liblist
.l_name
, timebuf
,
3040 liblist
.l_checksum
, liblist
.l_version
, liblist
.l_flags
);
3046 if (options_offset
!= 0)
3048 Elf_External_Options
*eopt
;
3049 Elf_Internal_Shdr
*sect
= section_headers
;
3050 Elf_Internal_Options
*iopt
;
3051 Elf_Internal_Options
*option
;
3055 /* Find the section header so that we get the size. */
3056 while (sect
->sh_type
!= SHT_MIPS_OPTIONS
)
3059 GET_DATA_ALLOC (options_offset
, sect
->sh_size
, eopt
,
3060 Elf_External_Options
*, "options");
3062 iopt
= (Elf_Internal_Options
*) malloc ((sect
->sh_size
/ sizeof (eopt
))
3066 error (_("Out of memory"));
3072 while (offset
< sect
->sh_size
)
3074 Elf_External_Options
*eoption
;
3076 eoption
= (Elf_External_Options
*) ((char *) eopt
+ offset
);
3078 option
->kind
= BYTE_GET (eoption
->kind
);
3079 option
->size
= BYTE_GET (eoption
->size
);
3080 option
->section
= BYTE_GET (eoption
->section
);
3081 option
->info
= BYTE_GET (eoption
->info
);
3083 offset
+= option
->size
;
3088 printf (_("\nSection '%s' contains %d entries:\n"),
3089 string_table
+ sect
->sh_name
, cnt
);
3096 switch (option
->kind
)
3099 /* This shouldn't happen. */
3100 printf (" NULL %d %x", option
->section
, option
->info
);
3103 printf (" REGINFO ");
3104 if (elf_header
.e_machine
== EM_MIPS
)
3107 Elf32_External_RegInfo
*ereg
;
3108 Elf32_RegInfo reginfo
;
3110 ereg
= (Elf32_External_RegInfo
*) (option
+ 1);
3111 reginfo
.ri_gprmask
= BYTE_GET (ereg
->ri_gprmask
);
3112 reginfo
.ri_cprmask
[0] = BYTE_GET (ereg
->ri_cprmask
[0]);
3113 reginfo
.ri_cprmask
[1] = BYTE_GET (ereg
->ri_cprmask
[1]);
3114 reginfo
.ri_cprmask
[2] = BYTE_GET (ereg
->ri_cprmask
[2]);
3115 reginfo
.ri_cprmask
[3] = BYTE_GET (ereg
->ri_cprmask
[3]);
3116 reginfo
.ri_gp_value
= BYTE_GET (ereg
->ri_gp_value
);
3118 printf ("GPR %08lx GP %ld\n",
3119 reginfo
.ri_gprmask
, reginfo
.ri_gp_value
);
3120 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
3121 reginfo
.ri_cprmask
[0], reginfo
.ri_cprmask
[1],
3122 reginfo
.ri_cprmask
[2], reginfo
.ri_cprmask
[3]);
3127 Elf64_External_RegInfo
*ereg
;
3128 Elf64_Internal_RegInfo reginfo
;
3130 ereg
= (Elf64_External_RegInfo
*) (option
+ 1);
3131 reginfo
.ri_gprmask
= BYTE_GET (ereg
->ri_gprmask
);
3132 reginfo
.ri_cprmask
[0] = BYTE_GET (ereg
->ri_cprmask
[0]);
3133 reginfo
.ri_cprmask
[1] = BYTE_GET (ereg
->ri_cprmask
[1]);
3134 reginfo
.ri_cprmask
[2] = BYTE_GET (ereg
->ri_cprmask
[2]);
3135 reginfo
.ri_cprmask
[3] = BYTE_GET (ereg
->ri_cprmask
[3]);
3136 reginfo
.ri_gp_value
= BYTE_GET (ereg
->ri_gp_value
);
3138 printf ("GPR %08lx GP %ld\n",
3139 reginfo
.ri_gprmask
, reginfo
.ri_gp_value
);
3140 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
3141 reginfo
.ri_cprmask
[0], reginfo
.ri_cprmask
[1],
3142 reginfo
.ri_cprmask
[2], reginfo
.ri_cprmask
[3]);
3146 case ODK_EXCEPTIONS
:
3147 fputs (" EXCEPTIONS fpe_min(", stdout
);
3148 process_mips_fpe_exception (option
->info
& OEX_FPU_MIN
);
3149 fputs (") fpe_max(", stdout
);
3150 process_mips_fpe_exception ((option
->info
& OEX_FPU_MAX
) >> 8);
3151 fputs (")", stdout
);
3153 if (option
->info
& OEX_PAGE0
)
3154 fputs (" PAGE0", stdout
);
3155 if (option
->info
& OEX_SMM
)
3156 fputs (" SMM", stdout
);
3157 if (option
->info
& OEX_FPDBUG
)
3158 fputs (" FPDBUG", stdout
);
3159 if (option
->info
& OEX_DISMISS
)
3160 fputs (" DISMISS", stdout
);
3163 fputs (" PAD ", stdout
);
3164 if (option
->info
& OPAD_PREFIX
)
3165 fputs (" PREFIX", stdout
);
3166 if (option
->info
& OPAD_POSTFIX
)
3167 fputs (" POSTFIX", stdout
);
3168 if (option
->info
& OPAD_SYMBOL
)
3169 fputs (" SYMBOL", stdout
);
3172 fputs (" HWPATCH ", stdout
);
3173 if (option
->info
& OHW_R4KEOP
)
3174 fputs (" R4KEOP", stdout
);
3175 if (option
->info
& OHW_R8KPFETCH
)
3176 fputs (" R8KPFETCH", stdout
);
3177 if (option
->info
& OHW_R5KEOP
)
3178 fputs (" R5KEOP", stdout
);
3179 if (option
->info
& OHW_R5KCVTL
)
3180 fputs (" R5KCVTL", stdout
);
3183 fputs (" FILL ", stdout
);
3184 /* XXX Print content of info word? */
3187 fputs (" TAGS ", stdout
);
3188 /* XXX Print content of info word? */
3191 fputs (" HWAND ", stdout
);
3192 if (option
->info
& OHWA0_R4KEOP_CHECKED
)
3193 fputs (" R4KEOP_CHECKED", stdout
);
3194 if (option
->info
& OHWA0_R4KEOP_CLEAN
)
3195 fputs (" R4KEOP_CLEAN", stdout
);
3198 fputs (" HWOR ", stdout
);
3199 if (option
->info
& OHWA0_R4KEOP_CHECKED
)
3200 fputs (" R4KEOP_CHECKED", stdout
);
3201 if (option
->info
& OHWA0_R4KEOP_CLEAN
)
3202 fputs (" R4KEOP_CLEAN", stdout
);
3205 printf (" GP_GROUP %#06x self-contained %#06x",
3206 option
->info
& OGP_GROUP
,
3207 (option
->info
& OGP_SELF
) >> 16);
3210 printf (" IDENT %#06x self-contained %#06x",
3211 option
->info
& OGP_GROUP
,
3212 (option
->info
& OGP_SELF
) >> 16);
3215 /* This shouldn't happen. */
3216 printf (" %3d ??? %d %x",
3217 option
->kind
, option
->section
, option
->info
);
3221 len
= sizeof (*eopt
);
3222 while (len
< option
->size
)
3223 if (((char *) option
)[len
] >= ' '
3224 && ((char *) option
)[len
] < 0x7f)
3225 printf ("%c", ((char *) option
)[len
++]);
3227 printf ("\\%03o", ((char *) option
)[len
++]);
3229 fputs ("\n", stdout
);
3240 process_arch_specific (file
)
3243 switch (elf_header
.e_machine
)
3246 case EM_MIPS_RS4_BE
:
3247 return process_mips_specific (file
);
3256 get_file_header (file
)
3259 Elf32_External_Ehdr ehdr
;
3261 if (fread (& ehdr
, sizeof (ehdr
), 1, file
) != 1)
3264 memcpy (elf_header
.e_ident
, ehdr
.e_ident
, EI_NIDENT
);
3266 if (elf_header
.e_ident
[EI_DATA
] == ELFDATA2LSB
)
3267 byte_get
= byte_get_little_endian
;
3269 byte_get
= byte_get_big_endian
;
3271 elf_header
.e_entry
= BYTE_GET (ehdr
.e_entry
);
3272 elf_header
.e_phoff
= BYTE_GET (ehdr
.e_phoff
);
3273 elf_header
.e_shoff
= BYTE_GET (ehdr
.e_shoff
);
3274 elf_header
.e_version
= BYTE_GET (ehdr
.e_version
);
3275 elf_header
.e_flags
= BYTE_GET (ehdr
.e_flags
);
3276 elf_header
.e_type
= BYTE_GET (ehdr
.e_type
);
3277 elf_header
.e_machine
= BYTE_GET (ehdr
.e_machine
);
3278 elf_header
.e_ehsize
= BYTE_GET (ehdr
.e_ehsize
);
3279 elf_header
.e_phentsize
= BYTE_GET (ehdr
.e_phentsize
);
3280 elf_header
.e_phnum
= BYTE_GET (ehdr
.e_phnum
);
3281 elf_header
.e_shentsize
= BYTE_GET (ehdr
.e_shentsize
);
3282 elf_header
.e_shnum
= BYTE_GET (ehdr
.e_shnum
);
3283 elf_header
.e_shstrndx
= BYTE_GET (ehdr
.e_shstrndx
);
3289 process_file (file_name
)
3293 struct stat statbuf
;
3296 if (stat (file_name
, & statbuf
) < 0)
3298 error (_("Cannot stat input file %s.\n"), file_name
);
3302 file
= fopen (file_name
, "rb");
3305 error (_("Input file %s not found.\n"), file_name
);
3309 if (! get_file_header (file
))
3311 error (_("%s: Failed to read file header\n"), file_name
);
3316 /* Initialise per file variables. */
3317 for (i
= NUM_ELEM (version_info
); i
--;)
3318 version_info
[i
] = 0;
3320 for (i
= NUM_ELEM (dynamic_info
); i
--;)
3321 dynamic_info
[i
] = 0;
3324 /* Process the file. */
3326 printf (_("\nFile: %s\n"), file_name
);
3328 if (! process_file_header ())
3334 process_section_headers (file
);
3336 process_program_headers (file
);
3338 process_dynamic_segment (file
);
3340 process_relocs (file
);
3342 process_symbol_table (file
);
3344 process_version_sections (file
);
3346 process_section_contents (file
);
3348 process_arch_specific (file
);
3352 if (section_headers
)
3354 free (section_headers
);
3355 section_headers
= NULL
;
3360 free (string_table
);
3361 string_table
= NULL
;
3364 if (dynamic_strings
)
3366 free (dynamic_strings
);
3367 dynamic_strings
= NULL
;
3370 if (dynamic_symbols
)
3372 free (dynamic_symbols
);
3373 dynamic_symbols
= NULL
;
3377 #ifdef SUPPORT_DISASSEMBLY
3378 /* Needed by the i386 disassembler. For extra credit, someone could
3379 fix this so that we insert symbolic addresses here, esp for GOT/PLT
3383 print_address (unsigned int addr
, FILE * outfile
)
3385 fprintf (outfile
,"0x%8.8x", addr
);
3388 /* Needed by the i386 disassembler. */
3390 db_task_printsym (unsigned int addr
)
3392 print_address (addr
, stderr
);
3401 parse_args (argc
, argv
);
3403 if (optind
< (argc
- 1))
3406 while (optind
< argc
)
3407 process_file (argv
[optind
++]);