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"
63 #ifdef ANSI_PROTOTYPES
69 char * program_name
= "readelf";
70 unsigned int dynamic_addr
;
71 unsigned int dynamic_size
;
72 unsigned int rela_addr
;
73 unsigned int rela_size
;
74 char * dynamic_strings
;
76 Elf_Internal_Sym
* dynamic_symbols
;
77 Elf_Internal_Syminfo
* dynamic_syminfo
;
78 unsigned long int dynamic_syminfo_offset
;
79 unsigned int dynamic_syminfo_nent
;
80 char program_interpreter
[64];
81 int dynamic_info
[DT_JMPREL
+ 1];
84 Elf_Internal_Ehdr elf_header
;
85 Elf_Internal_Shdr
* section_headers
;
86 Elf_Internal_Dyn
* dynamic_segment
;
101 static unsigned long int (* byte_get
) PARAMS ((unsigned char *, int));
103 #define NUM_DUMP_SECTS 100
104 char dump_sects
[NUM_DUMP_SECTS
];
107 #define DISASS_DUMP 2
109 /* Forward declarations for dumb compilers. */
110 static const char * get_mips_dynamic_type
PARAMS ((unsigned long type
));
111 static const char * get_dynamic_type
PARAMS ((unsigned long type
));
112 static int dump_relocations
113 PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym
*, char *));
114 static char * get_file_type
PARAMS ((unsigned e_type
));
115 static char * get_machine_name
PARAMS ((unsigned e_machine
));
116 static char * get_machine_data
PARAMS ((unsigned e_data
));
117 static char * get_machine_flags
PARAMS ((unsigned, unsigned e_machine
));
118 static const char * get_mips_segment_type
PARAMS ((unsigned long type
));
119 static const char * get_segment_type
PARAMS ((unsigned long p_type
));
120 static const char * get_mips_section_type_name
PARAMS ((unsigned int sh_type
));
121 static const char * get_section_type_name
PARAMS ((unsigned int sh_type
));
122 static char * get_symbol_binding
PARAMS ((unsigned int binding
));
123 static char * get_symbol_type
PARAMS ((unsigned int type
));
124 static void usage
PARAMS ((void));
125 static void parse_args
PARAMS ((int argc
, char ** argv
));
126 static int process_file_header
PARAMS ((void));
127 static int process_program_headers
PARAMS ((FILE *));
128 static int process_section_headers
PARAMS ((FILE *));
129 static void dynamic_segment_mips_val
PARAMS ((Elf_Internal_Dyn
*entry
));
130 static int process_dynamic_segment
PARAMS ((FILE *));
131 static int process_symbol_table
PARAMS ((FILE *));
132 static int process_section_contents
PARAMS ((FILE *));
133 static void process_file
PARAMS ((char * file_name
));
134 static int process_relocs
PARAMS ((FILE *));
135 static int process_version_sections
PARAMS ((FILE *));
136 static char * get_ver_flags
PARAMS ((unsigned int flags
));
137 static char * get_symbol_index_type
PARAMS ((unsigned int type
));
138 static int get_section_headers
PARAMS ((FILE * file
));
139 static int get_file_header
PARAMS ((FILE * file
));
140 static Elf_Internal_Sym
* get_elf_symbols
141 PARAMS ((FILE * file
, unsigned long offset
, unsigned long number
));
142 static int * get_dynamic_data
PARAMS ((FILE * file
, unsigned int number
));
144 typedef int Elf32_Word
;
146 #define SECTION_NAME(X) (string_table + (X)->sh_name)
148 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
150 #define BYTE_GET(field) byte_get (field, sizeof (field))
152 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
154 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
155 if (fseek (file, offset, SEEK_SET)) \
157 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
161 var = (type) malloc (size); \
165 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
169 if (fread (var, size, 1, file) != 1) \
171 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
178 #define GET_DATA(offset, var, reason) \
179 if (fseek (file, offset, SEEK_SET)) \
181 error (_("Unable to seek to %x for %s\n"), offset, reason); \
184 else if (fread (& var, sizeof (var), 1, file) != 1) \
186 error (_("Unable to read data at %x for %s\n"), offset, reason); \
190 #ifdef ANSI_PROTOTYPES
192 error (const char * message
, ...)
196 fprintf (stderr
, _("%s: Error: "), program_name
);
197 va_start (args
, message
);
198 vfprintf (stderr
, message
, args
);
204 warn (const char * message
, ...)
208 fprintf (stderr
, _("%s: Warning: "), program_name
);
209 va_start (args
, message
);
210 vfprintf (stderr
, message
, args
);
222 fprintf (stderr
, _("%s: Error: "), program_name
);
224 message
= va_arg (args
, char *);
225 vfprintf (stderr
, message
, args
);
237 fprintf (stderr
, _("%s: Warning: "), program_name
);
239 message
= va_arg (args
, char *);
240 vfprintf (stderr
, message
, args
);
246 static unsigned long int
247 byte_get_little_endian (field
, size
)
248 unsigned char * field
;
257 return ((unsigned int) (field
[0]))
258 | (((unsigned int) (field
[1])) << 8);
261 return ((unsigned long) (field
[0]))
262 | (((unsigned long) (field
[1])) << 8)
263 | (((unsigned long) (field
[2])) << 16)
264 | (((unsigned long) (field
[3])) << 24);
267 error (_("Unhandled data length: %d\n"), size
);
272 static unsigned long int
273 byte_get_big_endian (field
, size
)
274 unsigned char * field
;
283 return ((unsigned int) (field
[1])) | (((int) (field
[0])) << 8);
286 return ((unsigned long) (field
[3]))
287 | (((unsigned long) (field
[2])) << 8)
288 | (((unsigned long) (field
[1])) << 16)
289 | (((unsigned long) (field
[0])) << 24);
292 error (_("Unhandled data length: %d\n"), size
);
298 /* Display the contents of the relocation data
299 found at the specified offset. */
301 dump_relocations (file
, rel_offset
, rel_size
, symtab
, strtab
)
303 unsigned long rel_offset
;
304 unsigned long rel_size
;
305 Elf_Internal_Sym
* symtab
;
310 Elf_Internal_Rel
* rels
;
311 Elf_Internal_Rela
* relas
;
314 /* Compute number of relocations and read them in. */
315 switch (elf_header
.e_machine
)
324 Elf32_External_Rel
* erels
;
326 GET_DATA_ALLOC (rel_offset
, rel_size
, erels
,
327 Elf32_External_Rel
*, "relocs");
329 rel_size
= rel_size
/ sizeof (Elf32_External_Rel
);
331 rels
= (Elf_Internal_Rel
*) malloc (rel_size
*
332 sizeof (Elf_Internal_Rel
));
334 for (i
= 0; i
< rel_size
; i
++)
336 rels
[i
].r_offset
= BYTE_GET (erels
[i
].r_offset
);
337 rels
[i
].r_info
= BYTE_GET (erels
[i
].r_info
);
343 relas
= (Elf_Internal_Rela
*) rels
;
353 case EM_CYGNUS_MN10200
:
354 case EM_CYGNUS_MN10300
:
359 Elf32_External_Rela
* erelas
;
361 GET_DATA_ALLOC (rel_offset
, rel_size
, erelas
,
362 Elf32_External_Rela
*, "relocs");
364 rel_size
= rel_size
/ sizeof (Elf32_External_Rela
);
366 relas
= (Elf_Internal_Rela
*) malloc (rel_size
*
367 sizeof (Elf_Internal_Rela
));
369 for (i
= 0; i
< rel_size
; i
++)
371 relas
[i
].r_offset
= BYTE_GET (erelas
[i
].r_offset
);
372 relas
[i
].r_info
= BYTE_GET (erelas
[i
].r_info
);
373 relas
[i
].r_addend
= BYTE_GET (erelas
[i
].r_addend
);
379 rels
= (Elf_Internal_Rel
*) relas
;
384 warn (_("Don't know about relocations on this machine architecture\n"));
390 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
393 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
395 for (i
= 0; i
< rel_size
; i
++)
398 unsigned long offset
;
404 offset
= relas
[i
].r_offset
;
405 info
= relas
[i
].r_info
;
409 offset
= rels
[i
].r_offset
;
410 info
= rels
[i
].r_info
;
413 printf (" %8.8lx %5.5lx ", offset
, info
);
415 switch (elf_header
.e_machine
)
422 rtype
= elf_m32r_reloc_type (ELF32_R_TYPE (info
));
427 rtype
= elf_i386_reloc_type (ELF32_R_TYPE (info
));
431 rtype
= elf_m68k_reloc_type (ELF32_R_TYPE (info
));
435 rtype
= elf_sparc_reloc_type (ELF32_R_TYPE (info
));
439 rtype
= v850_reloc_type (ELF32_R_TYPE (info
));
443 rtype
= elf_d10v_reloc_type (ELF32_R_TYPE (info
));
447 rtype
= elf_d30v_reloc_type (ELF32_R_TYPE (info
));
451 rtype
= elf_sh_reloc_type (ELF32_R_TYPE (info
));
454 case EM_CYGNUS_MN10300
:
455 rtype
= elf_mn10300_reloc_type (ELF32_R_TYPE (info
));
458 case EM_CYGNUS_MN10200
:
459 rtype
= elf_mn10200_reloc_type (ELF32_R_TYPE (info
));
463 rtype
= elf_fr30_reloc_type (ELF32_R_TYPE (info
));
467 rtype
= elf_ppc_reloc_type (ELF32_R_TYPE (info
));
472 rtype
= elf_mips_reloc_type (ELF32_R_TYPE (info
));
476 rtype
= elf_alpha_reloc_type (ELF32_R_TYPE (info
));
480 rtype
= elf_arm_reloc_type (ELF32_R_TYPE (info
));
484 rtype
= elf_arc_reloc_type (ELF32_R_TYPE (info
));
488 rtype
= elf32_hppa_reloc_type (ELF32_R_TYPE (info
));
493 printf (_("unrecognised: %-7x"), ELF32_R_TYPE (info
));
495 printf ("%-21.21s", rtype
);
497 symtab_index
= ELF32_R_SYM (info
);
499 if (symtab_index
&& symtab
!= NULL
)
501 Elf_Internal_Sym
* psym
;
503 psym
= symtab
+ symtab_index
;
505 printf (" %08lx ", (unsigned long) psym
->st_value
);
507 if (psym
->st_name
== 0)
509 SECTION_NAME (section_headers
+ psym
->st_shndx
));
510 else if (strtab
== NULL
)
511 printf (_("<string table index %3d>"), psym
->st_name
);
513 printf ("%-25.25s", strtab
+ psym
->st_name
);
516 printf (" + %lx", (unsigned long) relas
[i
].r_addend
);
528 get_mips_dynamic_type (type
)
533 case DT_MIPS_RLD_VERSION
: return "MIPS_RLD_VERSION";
534 case DT_MIPS_TIME_STAMP
: return "MIPS_TIME_STAMP";
535 case DT_MIPS_ICHECKSUM
: return "MIPS_ICHECKSUM";
536 case DT_MIPS_IVERSION
: return "MIPS_IVERSION";
537 case DT_MIPS_FLAGS
: return "MIPS_FLAGS";
538 case DT_MIPS_BASE_ADDRESS
: return "MIPS_BASE_ADDRESS";
539 case DT_MIPS_MSYM
: return "MIPS_MSYM";
540 case DT_MIPS_CONFLICT
: return "MIPS_CONFLICT";
541 case DT_MIPS_LIBLIST
: return "MIPS_LIBLIST";
542 case DT_MIPS_LOCAL_GOTNO
: return "MIPS_LOCAL_GOTNO";
543 case DT_MIPS_CONFLICTNO
: return "MIPS_CONFLICTNO";
544 case DT_MIPS_LIBLISTNO
: return "MIPS_LIBLISTNO";
545 case DT_MIPS_SYMTABNO
: return "MIPS_SYMTABNO";
546 case DT_MIPS_UNREFEXTNO
: return "MIPS_UNREFEXTNO";
547 case DT_MIPS_GOTSYM
: return "MIPS_GOTSYM";
548 case DT_MIPS_HIPAGENO
: return "MIPS_HIPAGENO";
549 case DT_MIPS_RLD_MAP
: return "MIPS_RLD_MAP";
550 case DT_MIPS_DELTA_CLASS
: return "MIPS_DELTA_CLASS";
551 case DT_MIPS_DELTA_CLASS_NO
: return "MIPS_DELTA_CLASS_NO";
552 case DT_MIPS_DELTA_INSTANCE
: return "MIPS_DELTA_INSTANCE";
553 case DT_MIPS_DELTA_INSTANCE_NO
: return "MIPS_DELTA_INSTANCE_NO";
554 case DT_MIPS_DELTA_RELOC
: return "MIPS_DELTA_RELOC";
555 case DT_MIPS_DELTA_RELOC_NO
: return "MIPS_DELTA_RELOC_NO";
556 case DT_MIPS_DELTA_SYM
: return "MIPS_DELTA_SYM";
557 case DT_MIPS_DELTA_SYM_NO
: return "MIPS_DELTA_SYM_NO";
558 case DT_MIPS_DELTA_CLASSSYM
: return "MIPS_DELTA_CLASSSYM";
559 case DT_MIPS_DELTA_CLASSSYM_NO
: return "MIPS_DELTA_CLASSSYM_NO";
560 case DT_MIPS_CXX_FLAGS
: return "MIPS_CXX_FLAGS";
561 case DT_MIPS_PIXIE_INIT
: return "MIPS_PIXIE_INIT";
562 case DT_MIPS_SYMBOL_LIB
: return "MIPS_SYMBOL_LIB";
563 case DT_MIPS_LOCALPAGE_GOTIDX
: return "MIPS_LOCALPAGE_GOTIDX";
564 case DT_MIPS_LOCAL_GOTIDX
: return "MIPS_LOCAL_GOTIDX";
565 case DT_MIPS_HIDDEN_GOTIDX
: return "MIPS_HIDDEN_GOTIDX";
566 case DT_MIPS_PROTECTED_GOTIDX
: return "MIPS_PROTECTED_GOTIDX";
567 case DT_MIPS_OPTIONS
: return "MIPS_OPTIONS";
568 case DT_MIPS_INTERFACE
: return "MIPS_INTERFACE";
569 case DT_MIPS_DYNSTR_ALIGN
: return "MIPS_DYNSTR_ALIGN";
570 case DT_MIPS_INTERFACE_SIZE
: return "MIPS_INTERFACE_SIZE";
571 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR
: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
572 case DT_MIPS_PERF_SUFFIX
: return "MIPS_PERF_SUFFIX";
573 case DT_MIPS_COMPACT_SIZE
: return "MIPS_COMPACT_SIZE";
574 case DT_MIPS_GP_VALUE
: return "MIPS_GP_VALUE";
575 case DT_MIPS_AUX_DYNAMIC
: return "MIPS_AUX_DYNAMIC";
582 get_dynamic_type (type
)
585 static char buff
[32];
589 case DT_NULL
: return "NULL";
590 case DT_NEEDED
: return "NEEDED";
591 case DT_PLTRELSZ
: return "PLTRELSZ";
592 case DT_PLTGOT
: return "PLTGOT";
593 case DT_HASH
: return "HASH";
594 case DT_STRTAB
: return "STRTAB";
595 case DT_SYMTAB
: return "SYMTAB";
596 case DT_RELA
: return "RELA";
597 case DT_RELASZ
: return "RELASZ";
598 case DT_RELAENT
: return "RELAENT";
599 case DT_STRSZ
: return "STRSZ";
600 case DT_SYMENT
: return "SYMENT";
601 case DT_INIT
: return "INIT";
602 case DT_FINI
: return "FINI";
603 case DT_SONAME
: return "SONAME";
604 case DT_RPATH
: return "RPATH";
605 case DT_SYMBOLIC
: return "SYMBOLIC";
606 case DT_REL
: return "REL";
607 case DT_RELSZ
: return "RELSZ";
608 case DT_RELENT
: return "RELENT";
609 case DT_PLTREL
: return "PLTREL";
610 case DT_DEBUG
: return "DEBUG";
611 case DT_TEXTREL
: return "TEXTREL";
612 case DT_JMPREL
: return "JMPREL";
613 case DT_VERDEF
: return "VERDEF";
614 case DT_VERDEFNUM
: return "VERDEFNUM";
615 case DT_VERNEED
: return "VERNEED";
616 case DT_VERNEEDNUM
: return "VERNEEDNUM";
617 case DT_VERSYM
: return "VERSYN";
618 case DT_AUXILIARY
: return "AUXILARY";
619 case DT_FILTER
: return "FILTER";
620 case DT_POSFLAG_1
: return "POSFLAG_1";
621 case DT_SYMINSZ
: return "SYMINSZ";
622 case DT_SYMINENT
: return "SYMINENT";
623 case DT_SYMINFO
: return "SYMINFO";
624 case DT_RELACOUNT
: return "RELACOUNT";
625 case DT_RELCOUNT
: return "RELCOUNT";
626 case DT_FLAGS_1
: return "FLAGS_1";
627 case DT_USED
: return "USED";
630 if ((type
>= DT_LOPROC
) && (type
<= DT_HIPROC
))
632 const char *result
= NULL
;
633 switch (elf_header
.e_machine
)
637 result
= get_mips_dynamic_type (type
);
642 sprintf (buff
, _("Processor Specific"), type
);
648 sprintf (buff
, _("<unknown>: %x"), type
);
654 get_file_type (e_type
)
657 static char buff
[32];
661 case ET_NONE
: return _("NONE (None)");
662 case ET_REL
: return _("REL (Relocatable file)");
663 case ET_EXEC
: return _("EXEC (Executable file)");
664 case ET_DYN
: return _("DYN (Shared object file)");
665 case ET_CORE
: return _("CORE (Core file)");
668 if ((e_type
>= ET_LOPROC
) && (e_type
<= ET_HIPROC
))
669 sprintf (buff
, _("Processor Specific: (%x)"), e_type
);
671 sprintf (buff
, _("<unknown>: %x"), e_type
);
677 get_machine_name (e_machine
)
680 static char buff
[32];
684 case EM_NONE
: return _("None");
685 case EM_M32
: return "WE32100";
686 case EM_SPARC
: return "Sparc";
687 case EM_386
: return "Intel 80386";
688 case EM_68K
: return "MC68000";
689 case EM_88K
: return "MC88000";
690 case EM_486
: return "Intel 80486";
691 case EM_860
: return "Intel 80860";
692 case EM_MIPS
: return "MIPS R3000 big-endian";
693 case EM_S370
: return "Amdahl";
694 case EM_MIPS_RS4_BE
: return "MIPS R4000 big-endian";
695 case EM_OLD_SPARCV9
: return "Sparc v9 (old)";
696 case EM_PARISC
: return "HPPA";
697 case EM_PPC_OLD
: return "Power PC (old)";
698 case EM_SPARC32PLUS
: return "Sparc v8+" ;
699 case EM_960
: return "Intel 90860";
700 case EM_PPC
: return "PowerPC";
701 case EM_V800
: return "NEC V800";
702 case EM_FR20
: return "Fujitsu FR20";
703 case EM_RH32
: return "TRW RH32";
704 case EM_MMA
: return "Fujitsu MMA";
705 case EM_ARM
: return "ARM";
706 case EM_OLD_ALPHA
: return "Digital Alpha (old)";
707 case EM_SH
: return "Hitachi SH";
708 case EM_SPARCV9
: return "Sparc v9";
709 case EM_ALPHA
: return "Alpha";
710 case EM_CYGNUS_D10V
: return "d10v";
711 case EM_CYGNUS_D30V
: return "d30v";
712 case EM_CYGNUS_ARC
: return "Arc";
713 case EM_CYGNUS_M32R
: return "M32r";
714 case EM_CYGNUS_V850
: return "v850";
715 case EM_CYGNUS_MN10300
: return "mn10300";
716 case EM_CYGNUS_MN10200
: return "mn10200";
717 case EM_CYGNUS_FR30
: return "FR30";
720 sprintf (buff
, _("<unknown>: %x"), e_machine
);
726 get_machine_flags (e_flags
, e_machine
)
730 static char buf
[1024];
741 if (e_flags
& EF_PPC_EMB
)
742 strcat (buf
, ", emb");
744 if (e_flags
& EF_PPC_RELOCATABLE
)
745 strcat (buf
, ", relocatable");
747 if (e_flags
& EF_PPC_RELOCATABLE_LIB
)
748 strcat (buf
, ", relocatable-lib");
752 if ((e_flags
& EF_M32R_ARCH
) == E_M32R_ARCH
)
753 strcat (buf
, ", m32r");
755 /* start-sanitize-m32rx */
757 if ((e_flags
& EF_M32R_ARCH
) == E_M32RX_ARCH
)
758 strcat (buf
, ", m32rx");
760 /* end-sanitize-m32rx */
765 if (e_flags
& EF_MIPS_NOREORDER
)
766 strcat (buf
, ", noreorder");
768 if (e_flags
& EF_MIPS_PIC
)
769 strcat (buf
, ", pic");
771 if (e_flags
& EF_MIPS_CPIC
)
772 strcat (buf
, ", cpic");
774 if (e_flags
& EF_MIPS_ABI2
)
775 strcat (buf
, ", abi2");
777 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_1
)
778 strcat (buf
, ", mips1");
780 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_2
)
781 strcat (buf
, ", mips2");
783 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_3
)
784 strcat (buf
, ", mips3");
786 if ((e_flags
& EF_MIPS_ARCH
) == E_MIPS_ARCH_4
)
787 strcat (buf
, ", mips4");
796 get_machine_data (e_data
)
799 static char buff
[32];
803 case ELFDATA2LSB
: return _("ELFDATA2LSB (little endian)");
804 case ELFDATA2MSB
: return _("ELFDATA2MSB (big endian)");
806 sprintf (buff
, _("<unknown>: %x"), e_data
);
812 get_mips_segment_type (type
)
817 case PT_MIPS_REGINFO
:
821 case PT_MIPS_OPTIONS
:
831 get_segment_type (p_type
)
832 unsigned long p_type
;
834 static char buff
[32];
838 case PT_NULL
: return "NULL";
839 case PT_LOAD
: return "LOAD";
840 case PT_DYNAMIC
: return "DYNAMIC";
841 case PT_INTERP
: return "INTERP";
842 case PT_NOTE
: return "NOTE";
843 case PT_SHLIB
: return "SHLIB";
844 case PT_PHDR
: return "PHDR";
847 if ((p_type
>= PT_LOPROC
) && (p_type
<= PT_HIPROC
))
850 switch (elf_header
.e_machine
)
854 result
= get_mips_segment_type (p_type
);
862 sprintf (buff
, "LOPROC+%d", p_type
- PT_LOPROC
);
869 sprintf (buff
, _("<unknown>: %x"), p_type
);
876 get_mips_section_type_name (sh_type
)
877 unsigned int sh_type
;
881 case SHT_MIPS_LIBLIST
: return "MIPS_LIBLIST";
882 case SHT_MIPS_MSYM
: return "MIPS_MSYM";
883 case SHT_MIPS_CONFLICT
: return "MIPS_CONFLICT";
884 case SHT_MIPS_GPTAB
: return "MIPS_GPTAB";
885 case SHT_MIPS_UCODE
: return "MIPS_UCODE";
886 case SHT_MIPS_DEBUG
: return "MIPS_DEBUG";
887 case SHT_MIPS_REGINFO
: return "MIPS_REGINFO";
888 case SHT_MIPS_PACKAGE
: return "MIPS_PACKAGE";
889 case SHT_MIPS_PACKSYM
: return "MIPS_PACKSYM";
890 case SHT_MIPS_RELD
: return "MIPS_RELD";
891 case SHT_MIPS_IFACE
: return "MIPS_IFACE";
892 case SHT_MIPS_CONTENT
: return "MIPS_CONTENT";
893 case SHT_MIPS_OPTIONS
: return "MIPS_OPTIONS";
894 case SHT_MIPS_SHDR
: return "MIPS_SHDR";
895 case SHT_MIPS_FDESC
: return "MIPS_FDESC";
896 case SHT_MIPS_EXTSYM
: return "MIPS_EXTSYM";
897 case SHT_MIPS_DENSE
: return "MIPS_DENSE";
898 case SHT_MIPS_PDESC
: return "MIPS_PDESC";
899 case SHT_MIPS_LOCSYM
: return "MIPS_LOCSYM";
900 case SHT_MIPS_AUXSYM
: return "MIPS_AUXSYM";
901 case SHT_MIPS_OPTSYM
: return "MIPS_OPTSYM";
902 case SHT_MIPS_LOCSTR
: return "MIPS_LOCSTR";
903 case SHT_MIPS_LINE
: return "MIPS_LINE";
904 case SHT_MIPS_RFDESC
: return "MIPS_RFDESC";
905 case SHT_MIPS_DELTASYM
: return "MIPS_DELTASYM";
906 case SHT_MIPS_DELTAINST
: return "MIPS_DELTAINST";
907 case SHT_MIPS_DELTACLASS
: return "MIPS_DELTACLASS";
908 case SHT_MIPS_DWARF
: return "MIPS_DWARF";
909 case SHT_MIPS_DELTADECL
: return "MIPS_DELTADECL";
910 case SHT_MIPS_SYMBOL_LIB
: return "MIPS_SYMBOL_LIB";
911 case SHT_MIPS_EVENTS
: return "MIPS_EVENTS";
912 case SHT_MIPS_TRANSLATE
: return "MIPS_TRANSLATE";
913 case SHT_MIPS_PIXIE
: return "MIPS_PIXIE";
914 case SHT_MIPS_XLATE
: return "MIPS_XLATE";
915 case SHT_MIPS_XLATE_DEBUG
: return "MIPS_XLATE_DEBUG";
916 case SHT_MIPS_WHIRL
: return "MIPS_WHIRL";
917 case SHT_MIPS_EH_REGION
: return "MIPS_EH_REGION";
918 case SHT_MIPS_XLATE_OLD
: return "MIPS_XLATE_OLD";
919 case SHT_MIPS_PDR_EXCEPTION
: return "MIPS_PDR_EXCEPTION";
927 get_section_type_name (sh_type
)
928 unsigned int sh_type
;
930 static char buff
[32];
934 case SHT_NULL
: return "NULL";
935 case SHT_PROGBITS
: return "PROGBITS";
936 case SHT_SYMTAB
: return "SYMTAB";
937 case SHT_STRTAB
: return "STRTAB";
938 case SHT_RELA
: return "RELA";
939 case SHT_HASH
: return "HASH";
940 case SHT_DYNAMIC
: return "DYNAMIC";
941 case SHT_NOTE
: return "NOTE";
942 case SHT_NOBITS
: return "NOBITS";
943 case SHT_REL
: return "REL";
944 case SHT_SHLIB
: return "SHLIB";
945 case SHT_DYNSYM
: return "DYNSYM";
946 case SHT_GNU_verdef
: return "VERDEF";
947 case SHT_GNU_verneed
: return "VERNEED";
948 case SHT_GNU_versym
: return "VERSYM";
949 case 0x6ffffff0: return "VERSYM";
950 case 0x6ffffffc: return "VERDEF";
951 case 0x7ffffffd: return "AUXILIARY";
952 case 0x7fffffff: return "FILTER";
955 if ((sh_type
>= SHT_LOPROC
) && (sh_type
<= SHT_HIPROC
))
959 switch (elf_header
.e_machine
)
963 result
= get_mips_section_type_name (sh_type
);
972 sprintf (buff
, _("SHT_LOPROC+%d"), sh_type
- SHT_LOPROC
);
977 else if ((sh_type
>= SHT_LOUSER
) && (sh_type
<= SHT_HIUSER
))
978 sprintf (buff
, _("SHT_LOUSER+%d"), sh_type
- SHT_LOUSER
);
980 sprintf (buff
, _("<unknown>: %x"), sh_type
);
985 struct option options
[] =
987 {"all", no_argument
, 0, 'a'},
988 {"file-header", no_argument
, 0, 'h'},
989 {"program-headers", no_argument
, 0, 'l'},
990 {"headers", no_argument
, 0, 'e'},
991 {"histogram", no_argument
, &do_histogram
, 1},
992 {"segments", no_argument
, 0, 'l'},
993 {"sections", no_argument
, 0, 'S'},
994 {"section-headers", no_argument
, 0, 'S'},
995 {"symbols", no_argument
, 0, 's'},
996 {"syms", no_argument
, 0, 's'},
997 {"relocs", no_argument
, 0, 'r'},
998 {"dynamic", no_argument
, 0, 'd'},
999 {"version-info", no_argument
, 0, 'V'},
1000 {"use-dynamic", no_argument
, 0, 'D'},
1002 {"hex-dump", required_argument
, 0, 'x'},
1003 #ifdef SUPPORT_DISASSEMBLY
1004 {"instruction-dump", required_argument
, 0, 'i'},
1007 {"version", no_argument
, 0, 'v'},
1008 {"help", no_argument
, 0, 'H'},
1010 {0, no_argument
, 0, 0}
1016 fprintf (stdout
, _("Usage: readelf {options} elf-file(s)\n"));
1017 fprintf (stdout
, _(" Options are:\n"));
1018 fprintf (stdout
, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1019 fprintf (stdout
, _(" -h or --file-header Display the ELF file header\n"));
1020 fprintf (stdout
, _(" -l or --program-headers or --segments\n"));
1021 fprintf (stdout
, _(" Display the program headers\n"));
1022 fprintf (stdout
, _(" -S or --section-headers or --sections\n"));
1023 fprintf (stdout
, _(" Display the sections' header\n"));
1024 fprintf (stdout
, _(" -e or --headers Equivalent to: -h -l -S\n"));
1025 fprintf (stdout
, _(" -s or --syms or --symbols Display the symbol table\n"));
1026 fprintf (stdout
, _(" -r or --relocs Display the relocations (if present)\n"));
1027 fprintf (stdout
, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1028 fprintf (stdout
, _(" -V or --version-info Display the version sections (if present)\n"));
1029 fprintf (stdout
, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1030 fprintf (stdout
, _(" -x <number> or --hex-dump=<number>\n"));
1031 fprintf (stdout
, _(" Dump the contents of section <number>\n"));
1032 #ifdef SUPPORT_DISASSEMBLY
1033 fprintf (stdout
, _(" -i <number> or --instruction-dump=<number>\n"));
1034 fprintf (stdout
, _(" Disassemble the contents of section <number>\n"));
1036 fprintf (stdout
, _(" --histogram Display histogram of bucket list lengths\n"));
1037 fprintf (stdout
, _(" -v or --version Display the version number of readelf\n"));
1038 fprintf (stdout
, _(" -H or --help Display this information\n"));
1039 fprintf (stdout
, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1045 parse_args (argc
, argv
)
1054 while ((c
= getopt_long
1055 (argc
, argv
, "ersahldSDx:i:vV", options
, NULL
)) != EOF
)
1085 do_using_dynamic
++;
1107 section
= strtoul (optarg
, & cp
, 0);
1108 if (! * cp
&& section
>= 0 && section
< NUM_DUMP_SECTS
)
1110 dump_sects
[section
] |= HEX_DUMP
;
1114 #ifdef SUPPORT_DISASSEMBLY
1117 section
= strtoul (optarg
, & cp
, 0);
1118 if (! * cp
&& section
>= 0 && section
< NUM_DUMP_SECTS
)
1120 dump_sects
[section
] |= DISASS_DUMP
;
1126 print_version (program_name
);
1133 /* xgettext:c-format */
1134 error (_("Invalid option '-%c'\n"), c
);
1141 if (!do_dynamic
&& !do_syms
&& !do_reloc
&& !do_sections
1142 && !do_segments
&& !do_header
&& !do_dump
&& !do_version
1147 warn (_("Nothing to do.\n"));
1152 /* Decode the data held in 'elf_header'. */
1154 process_file_header ()
1156 if ( elf_header
.e_ident
[EI_MAG0
] != ELFMAG0
1157 || elf_header
.e_ident
[EI_MAG1
] != ELFMAG1
1158 || elf_header
.e_ident
[EI_MAG2
] != ELFMAG2
1159 || elf_header
.e_ident
[EI_MAG3
] != ELFMAG3
)
1162 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1166 binary_class
= elf_header
.e_ident
[EI_CLASS
];
1167 if (binary_class
!= ELFCLASS32
)
1169 error (_("Not a 32 bit ELF file\n"));
1177 printf (_("ELF Header:\n"));
1178 printf (_(" Magic: "));
1179 for (i
= 0; i
< EI_NIDENT
; i
++)
1180 printf ("%2.2x ", elf_header
.e_ident
[i
]);
1182 printf (_(" Type: %s\n"),
1183 get_file_type (elf_header
.e_type
));
1184 printf (_(" Machine: %s\n"),
1185 get_machine_name (elf_header
.e_machine
));
1186 printf (_(" Version: 0x%lx\n"),
1187 (unsigned long) elf_header
.e_version
);
1188 printf (_(" Data: %s\n"),
1189 get_machine_data (elf_header
.e_ident
[EI_DATA
]));
1190 printf (_(" Entry point address: 0x%lx\n"),
1191 (unsigned long) elf_header
.e_entry
);
1192 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1193 (long) elf_header
.e_phoff
);
1194 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1195 (long) elf_header
.e_shoff
);
1196 printf (_(" Flags: 0x%lx%s\n"),
1197 (unsigned long) elf_header
.e_flags
,
1198 get_machine_flags (elf_header
.e_flags
, elf_header
.e_machine
));
1199 printf (_(" Size of this header: %ld (bytes)\n"),
1200 (long) elf_header
.e_ehsize
);
1201 printf (_(" Size of program headers: %ld (bytes)\n"),
1202 (long) elf_header
.e_phentsize
);
1203 printf (_(" Number of program headers: %ld\n"),
1204 (long) elf_header
.e_phnum
);
1205 printf (_(" Size of section headers: %ld (bytes)\n"),
1206 (long) elf_header
.e_shentsize
);
1207 printf (_(" Number of section headers: %ld\n"),
1208 (long) elf_header
.e_shnum
);
1209 printf (_(" Section header string table index: %ld\n"),
1210 (long) elf_header
.e_shstrndx
);
1218 process_program_headers (file
)
1221 Elf32_External_Phdr
* phdrs
;
1222 Elf32_Internal_Phdr
* program_headers
;
1223 Elf32_Internal_Phdr
* segment
;
1226 if (elf_header
.e_phnum
== 0)
1229 printf (_("\nThere are no program headers in this file.\n"));
1233 if (do_segments
&& !do_header
)
1235 printf (_("\nElf file is %s\n"), get_file_type (elf_header
.e_type
));
1236 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header
.e_entry
);
1237 printf (_("There are %d program headers, starting at offset %lx:\n"),
1238 elf_header
.e_phnum
, (unsigned long) elf_header
.e_phoff
);
1241 GET_DATA_ALLOC (elf_header
.e_phoff
,
1242 elf_header
.e_phentsize
* elf_header
.e_phnum
,
1243 phdrs
, Elf32_External_Phdr
*, "program headers");
1245 program_headers
= (Elf32_Internal_Phdr
*) malloc
1246 (elf_header
.e_phnum
* sizeof (Elf32_Internal_Phdr
));
1248 if (program_headers
== NULL
)
1250 error (_("Out of memory\n"));
1254 for (i
= 0, segment
= program_headers
;
1255 i
< elf_header
.e_phnum
;
1258 segment
->p_type
= BYTE_GET (phdrs
[i
].p_type
);
1259 segment
->p_offset
= BYTE_GET (phdrs
[i
].p_offset
);
1260 segment
->p_vaddr
= BYTE_GET (phdrs
[i
].p_vaddr
);
1261 segment
->p_paddr
= BYTE_GET (phdrs
[i
].p_paddr
);
1262 segment
->p_filesz
= BYTE_GET (phdrs
[i
].p_filesz
);
1263 segment
->p_memsz
= BYTE_GET (phdrs
[i
].p_memsz
);
1264 segment
->p_flags
= BYTE_GET (phdrs
[i
].p_flags
);
1265 segment
->p_align
= BYTE_GET (phdrs
[i
].p_align
);
1273 (_("\nProgram Header%s:\n"), elf_header
.e_phnum
> 1 ? "s" : "");
1275 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1281 for (i
= 0, segment
= program_headers
;
1282 i
< elf_header
.e_phnum
;
1287 printf (" %-11.11s ", get_segment_type (segment
->p_type
));
1288 printf ("0x%6.6lx ", (unsigned long) segment
->p_offset
);
1289 printf ("0x%8.8lx ", (unsigned long) segment
->p_vaddr
);
1290 printf ("0x%8.8lx ", (unsigned long) segment
->p_paddr
);
1291 printf ("0x%5.5lx ", (unsigned long) segment
->p_filesz
);
1292 printf ("0x%5.5lx ", (unsigned long) segment
->p_memsz
);
1294 (segment
->p_flags
& PF_R
? 'R' : ' '),
1295 (segment
->p_flags
& PF_W
? 'W' : ' '),
1296 (segment
->p_flags
& PF_X
? 'E' : ' '));
1297 printf ("%#lx", (unsigned long) segment
->p_align
);
1300 switch (segment
->p_type
)
1304 loadaddr
= (segment
->p_vaddr
& 0xfffff000)
1305 - (segment
->p_offset
& 0xfffff000);
1310 error (_("more than one dynamic segment\n"));
1312 dynamic_addr
= segment
->p_offset
;
1313 dynamic_size
= segment
->p_filesz
;
1317 if (fseek (file
, segment
->p_offset
, SEEK_SET
))
1318 error (_("Unable to find program interpreter name\n"));
1321 program_interpreter
[0] = 0;
1322 fscanf (file
, "%63s", program_interpreter
);
1325 printf (_("\n [Requesting program interpreter: %s]"),
1326 program_interpreter
);
1332 putc ('\n', stdout
);
1341 if (do_segments
&& section_headers
!= NULL
)
1343 printf (_("\n Section to Segment mapping:\n"));
1344 printf (_(" Segment Sections...\n"));
1346 assert (string_table
!= NULL
);
1348 for (i
= 0; i
< elf_header
.e_phnum
; i
++)
1351 Elf32_Internal_Shdr
* section
;
1353 segment
= program_headers
+ i
;
1354 section
= section_headers
;
1356 printf (" %2.2d ", i
);
1358 for (j
= 0; j
< elf_header
.e_shnum
; j
++, section
++)
1360 if (section
->sh_size
> 0
1361 /* Compare allocated sections by VMA, unallocated
1362 sections by file offset. */
1363 && (section
->sh_flags
& SHF_ALLOC
1364 ? (section
->sh_addr
>= segment
->p_vaddr
1365 && section
->sh_addr
+ section
->sh_size
1366 <= segment
->p_vaddr
+ segment
->p_memsz
)
1367 : (section
->sh_offset
>= segment
->p_offset
1368 && (section
->sh_offset
+ section
->sh_size
1369 <= segment
->p_offset
+ segment
->p_filesz
))))
1370 printf ("%s ", SECTION_NAME (section
));
1377 free (program_headers
);
1384 get_section_headers (file
)
1387 Elf32_External_Shdr
* shdrs
;
1388 Elf32_Internal_Shdr
* internal
;
1391 GET_DATA_ALLOC (elf_header
.e_shoff
,
1392 elf_header
.e_shentsize
* elf_header
.e_shnum
,
1393 shdrs
, Elf32_External_Shdr
*, "section headers");
1395 section_headers
= (Elf32_Internal_Shdr
*) malloc
1396 (elf_header
.e_shnum
* sizeof (Elf32_Internal_Shdr
));
1398 if (section_headers
== NULL
)
1400 error (_("Out of memory\n"));
1404 for (i
= 0, internal
= section_headers
;
1405 i
< elf_header
.e_shnum
;
1408 internal
->sh_name
= BYTE_GET (shdrs
[i
].sh_name
);
1409 internal
->sh_type
= BYTE_GET (shdrs
[i
].sh_type
);
1410 internal
->sh_flags
= BYTE_GET (shdrs
[i
].sh_flags
);
1411 internal
->sh_addr
= BYTE_GET (shdrs
[i
].sh_addr
);
1412 internal
->sh_offset
= BYTE_GET (shdrs
[i
].sh_offset
);
1413 internal
->sh_size
= BYTE_GET (shdrs
[i
].sh_size
);
1414 internal
->sh_link
= BYTE_GET (shdrs
[i
].sh_link
);
1415 internal
->sh_info
= BYTE_GET (shdrs
[i
].sh_info
);
1416 internal
->sh_addralign
= BYTE_GET (shdrs
[i
].sh_addralign
);
1417 internal
->sh_entsize
= BYTE_GET (shdrs
[i
].sh_entsize
);
1425 static Elf_Internal_Sym
*
1426 get_elf_symbols (file
, offset
, number
)
1428 unsigned long offset
;
1429 unsigned long number
;
1431 Elf32_External_Sym
* esyms
;
1432 Elf_Internal_Sym
* isyms
;
1433 Elf_Internal_Sym
* psym
;
1436 GET_DATA_ALLOC (offset
, number
* sizeof (Elf32_External_Sym
),
1437 esyms
, Elf32_External_Sym
*, "symbols");
1439 isyms
= (Elf_Internal_Sym
*) malloc (number
* sizeof (Elf_Internal_Sym
));
1443 error (_("Out of memory\n"));
1449 for (j
= 0, psym
= isyms
;
1453 psym
->st_name
= BYTE_GET (esyms
[j
].st_name
);
1454 psym
->st_value
= BYTE_GET (esyms
[j
].st_value
);
1455 psym
->st_size
= BYTE_GET (esyms
[j
].st_size
);
1456 psym
->st_shndx
= BYTE_GET (esyms
[j
].st_shndx
);
1457 psym
->st_info
= BYTE_GET (esyms
[j
].st_info
);
1458 psym
->st_other
= BYTE_GET (esyms
[j
].st_other
);
1467 process_section_headers (file
)
1470 Elf32_Internal_Shdr
* section
;
1473 section_headers
= NULL
;
1475 if (elf_header
.e_shnum
== 0)
1478 printf (_("\nThere are no sections in this file.\n"));
1483 if (do_sections
&& !do_header
)
1484 printf (_("There are %d section headers, starting at offset %x:\n"),
1485 elf_header
.e_shnum
, elf_header
.e_shoff
);
1487 if (! get_section_headers (file
))
1490 /* Read in the string table, so that we have names to display. */
1491 section
= section_headers
+ elf_header
.e_shstrndx
;
1493 if (section
->sh_size
!= 0)
1495 unsigned long string_table_offset
;
1497 string_table_offset
= section
->sh_offset
;
1499 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
1500 string_table
, char *, "string table");
1503 /* Scan the sections for the dynamic symbol table
1504 and dynamic string table. */
1505 dynamic_symbols
= NULL
;
1506 dynamic_strings
= NULL
;
1507 dynamic_syminfo
= NULL
;
1508 for (i
= 0, section
= section_headers
;
1509 i
< elf_header
.e_shnum
;
1512 if (section
->sh_type
== SHT_DYNSYM
)
1514 if (dynamic_symbols
!= NULL
)
1516 error (_("File contains multiple dynamic symbol tables\n"));
1520 dynamic_symbols
= get_elf_symbols
1521 (file
, section
->sh_offset
, section
->sh_size
/ section
->sh_entsize
);
1523 else if (section
->sh_type
== SHT_STRTAB
1524 && strcmp (SECTION_NAME (section
), ".dynstr") == 0)
1526 if (dynamic_strings
!= NULL
)
1528 error (_("File contains multiple dynamic string tables\n"));
1532 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
1533 dynamic_strings
, char *, "dynamic strings");
1540 printf (_("\nSection Header%s:\n"), elf_header
.e_shnum
> 1 ? "s" : "");
1542 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1544 for (i
= 0, section
= section_headers
;
1545 i
< elf_header
.e_shnum
;
1548 printf (" [%2d] %-17.17s %-15.15s ",
1550 SECTION_NAME (section
),
1551 get_section_type_name (section
->sh_type
));
1553 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1554 (unsigned long) section
->sh_addr
,
1555 (unsigned long) section
->sh_offset
,
1556 (unsigned long) section
->sh_size
,
1557 (unsigned long) section
->sh_entsize
);
1559 printf (" %c%c%c %2ld %3lx %ld \n",
1560 (section
->sh_flags
& SHF_WRITE
? 'W' : ' '),
1561 (section
->sh_flags
& SHF_ALLOC
? 'A' : ' '),
1562 (section
->sh_flags
& SHF_EXECINSTR
? 'X' : ' '),
1563 (unsigned long) section
->sh_link
,
1564 (unsigned long) section
->sh_info
,
1565 (unsigned long) section
->sh_addralign
);
1571 /* Process the reloc section. */
1573 process_relocs (file
)
1576 unsigned long rel_size
;
1577 unsigned long rel_offset
;
1583 if (do_using_dynamic
)
1588 if (dynamic_info
[DT_REL
])
1590 rel_offset
= dynamic_info
[DT_REL
];
1591 rel_size
= dynamic_info
[DT_RELSZ
];
1593 else if (dynamic_info
[DT_RELA
])
1595 rel_offset
= dynamic_info
[DT_RELA
];
1596 rel_size
= dynamic_info
[DT_RELASZ
];
1598 else if (dynamic_info
[DT_JMPREL
])
1600 rel_offset
= dynamic_info
[DT_JMPREL
];
1601 rel_size
= dynamic_info
[DT_PLTRELSZ
];
1607 (_("\nRelocation section at offset 0x%x contains %d bytes:\n"),
1608 rel_offset
, rel_size
);
1610 dump_relocations (file
, rel_offset
- loadaddr
, rel_size
,
1611 dynamic_symbols
, dynamic_strings
);
1614 printf (_("\nThere are no dynamic relocations in this file.\n"));
1618 Elf32_Internal_Shdr
* section
;
1622 for (i
= 0, section
= section_headers
;
1623 i
< elf_header
.e_shnum
;
1626 if ( section
->sh_type
!= SHT_RELA
1627 && section
->sh_type
!= SHT_REL
)
1630 rel_offset
= section
->sh_offset
;
1631 rel_size
= section
->sh_size
;
1635 Elf32_Internal_Shdr
* strsec
;
1636 Elf32_Internal_Shdr
* symsec
;
1637 Elf_Internal_Sym
* symtab
;
1640 printf (_("\nRelocation section "));
1642 if (string_table
== NULL
)
1643 printf ("%d", section
->sh_name
);
1645 printf ("'%s'", SECTION_NAME (section
));
1647 printf (_(" at offset 0x%x contains %d entries:\n"),
1648 rel_offset
, rel_size
/ section
->sh_entsize
);
1650 symsec
= section_headers
+ section
->sh_link
;
1652 symtab
= get_elf_symbols (file
, symsec
->sh_offset
,
1653 symsec
->sh_size
/ symsec
->sh_entsize
);
1658 strsec
= section_headers
+ symsec
->sh_link
;
1660 GET_DATA_ALLOC (strsec
->sh_offset
, strsec
->sh_size
, strtab
,
1661 char *, "string table");
1663 dump_relocations (file
, rel_offset
, rel_size
, symtab
, strtab
);
1673 printf (_("\nThere are no relocations in this file.\n"));
1681 dynamic_segment_mips_val (entry
)
1682 Elf_Internal_Dyn
*entry
;
1685 switch (entry
->d_tag
)
1688 if (entry
->d_un
.d_val
== 0)
1692 static const char *opts
[] =
1694 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
1695 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
1696 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
1697 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
1702 for (cnt
= 0; cnt
< sizeof (opts
) / sizeof (opts
[0]); ++cnt
)
1703 if (entry
->d_un
.d_val
& (1 << cnt
))
1705 printf ("%s%s", first
? "" : " ", opts
[cnt
]);
1712 case DT_MIPS_IVERSION
:
1713 if (dynamic_strings
!= NULL
)
1714 printf ("Interface Version: %s\n",
1715 dynamic_strings
+ entry
->d_un
.d_val
);
1717 printf ("%#ld\n", (long) entry
->d_un
.d_ptr
);
1720 case DT_MIPS_TIME_STAMP
:
1723 time_t time
= entry
->d_un
.d_val
;
1724 strftime (timebuf
, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time
));
1725 printf ("Time Stamp: %s\n", timebuf
);
1729 case DT_MIPS_RLD_VERSION
:
1730 case DT_MIPS_LOCAL_GOTNO
:
1731 case DT_MIPS_CONFLICTNO
:
1732 case DT_MIPS_LIBLISTNO
:
1733 case DT_MIPS_SYMTABNO
:
1734 case DT_MIPS_UNREFEXTNO
:
1735 case DT_MIPS_HIPAGENO
:
1736 case DT_MIPS_DELTA_CLASS_NO
:
1737 case DT_MIPS_DELTA_INSTANCE_NO
:
1738 case DT_MIPS_DELTA_RELOC_NO
:
1739 case DT_MIPS_DELTA_SYM_NO
:
1740 case DT_MIPS_DELTA_CLASSSYM_NO
:
1741 case DT_MIPS_COMPACT_SIZE
:
1742 printf ("%#ld\n", (long) entry
->d_un
.d_ptr
);
1746 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
1750 /* Parse the dynamic segment */
1752 process_dynamic_segment (file
)
1755 Elf_Internal_Dyn
* entry
;
1756 Elf32_External_Dyn
* edyn
;
1759 if (dynamic_size
== 0)
1762 printf (_("\nThere is no dynamic segment in this file.\n"));
1767 GET_DATA_ALLOC (dynamic_addr
, dynamic_size
,
1768 edyn
, Elf32_External_Dyn
*, "dynamic segment");
1770 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
1771 how large .dynamic is now. We can do this even before the byte
1772 swapping since the DT_NULL tag is recognizable. */
1774 while (*(Elf32_Word
*) edyn
[dynamic_size
++].d_tag
!= DT_NULL
)
1777 dynamic_segment
= (Elf_Internal_Dyn
*)
1778 malloc (dynamic_size
* sizeof (Elf_Internal_Dyn
));
1780 if (dynamic_segment
== NULL
)
1782 error (_("Out of memory\n"));
1787 for (i
= 0, entry
= dynamic_segment
;
1791 entry
->d_tag
= BYTE_GET (edyn
[i
].d_tag
);
1792 entry
->d_un
.d_val
= BYTE_GET (edyn
[i
].d_un
.d_val
);
1797 /* Find the appropriate symbol table. */
1798 if (dynamic_symbols
== NULL
)
1800 for (i
= 0, entry
= dynamic_segment
;
1804 unsigned long offset
;
1807 if (entry
->d_tag
!= DT_SYMTAB
)
1810 dynamic_info
[DT_SYMTAB
] = entry
->d_un
.d_val
;
1812 /* Since we do not know how big the symbol table is,
1813 we default to reading in the entire file (!) and
1814 processing that. This is overkill, I know, but it
1817 offset
= entry
->d_un
.d_val
- loadaddr
;
1819 if (fseek (file
, 0, SEEK_END
))
1820 error (_("Unable to seek to end of file!"));
1822 num_syms
= (ftell (file
) - offset
) / sizeof (Elf32_External_Sym
);
1826 error (_("Unable to determine the number of symbols to load\n"));
1830 dynamic_symbols
= get_elf_symbols (file
, offset
, num_syms
);
1834 /* Similarly find a string table. */
1835 if (dynamic_strings
== NULL
)
1837 for (i
= 0, entry
= dynamic_segment
;
1841 unsigned long offset
;
1844 if (entry
->d_tag
!= DT_STRTAB
)
1847 dynamic_info
[DT_STRTAB
] = entry
->d_un
.d_val
;
1849 /* Since we do not know how big the string table is,
1850 we default to reading in the entire file (!) and
1851 processing that. This is overkill, I know, but it
1854 offset
= entry
->d_un
.d_val
- loadaddr
;
1855 if (fseek (file
, 0, SEEK_END
))
1856 error (_("Unable to seek to end of file\n"));
1857 str_tab_len
= ftell (file
) - offset
;
1859 if (str_tab_len
< 1)
1862 (_("Unable to determine the length of the dynamic string table\n"));
1866 GET_DATA_ALLOC (offset
, str_tab_len
, dynamic_strings
, char *,
1867 "dynamic string table");
1873 /* And find the syminfo section if available. */
1874 if (dynamic_syminfo
== NULL
)
1876 unsigned int syminsz
= 0;
1878 for (i
= 0, entry
= dynamic_segment
;
1882 if (entry
->d_tag
== DT_SYMINENT
)
1883 assert (sizeof (Elf_External_Syminfo
) == entry
->d_un
.d_val
);
1884 else if (entry
->d_tag
== DT_SYMINSZ
)
1885 syminsz
= entry
->d_un
.d_val
;
1886 else if (entry
->d_tag
== DT_SYMINFO
)
1887 dynamic_syminfo_offset
= entry
->d_un
.d_val
- loadaddr
;
1890 if (dynamic_syminfo_offset
!= 0 && syminsz
!= 0)
1892 Elf_External_Syminfo
*extsyminfo
;
1893 Elf_Internal_Syminfo
*syminfo
;
1895 /* There is a syminfo section. Read the data. */
1896 GET_DATA_ALLOC (dynamic_syminfo_offset
, syminsz
, extsyminfo
,
1897 Elf_External_Syminfo
*, "symbol information");
1899 dynamic_syminfo
= (Elf_Internal_Syminfo
*) malloc (syminsz
);
1900 if (dynamic_syminfo
== NULL
)
1902 error (_("Out of memory\n"));
1906 dynamic_syminfo_nent
= syminsz
/ sizeof (Elf_External_Syminfo
);
1907 for (i
= 0, syminfo
= dynamic_syminfo
; i
< dynamic_syminfo_nent
;
1910 syminfo
->si_boundto
= BYTE_GET (extsyminfo
[i
].si_boundto
);
1911 syminfo
->si_flags
= BYTE_GET (extsyminfo
[i
].si_flags
);
1918 if (do_dynamic
&& dynamic_addr
)
1919 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
1920 dynamic_addr
, dynamic_size
);
1922 printf (_(" Tag Type Name/Value\n"));
1924 for (i
= 0, entry
= dynamic_segment
;
1929 printf (_(" 0x%-8.8lx (%s)%*s"),
1930 (unsigned long) entry
->d_tag
,
1931 get_dynamic_type (entry
->d_tag
),
1932 27 - strlen (get_dynamic_type (entry
->d_tag
)),
1935 switch (entry
->d_tag
)
1941 if (entry
->d_tag
== DT_AUXILIARY
)
1942 printf (_("Auxiliary library"));
1944 printf (_("Filter library"));
1946 if (dynamic_strings
)
1947 printf (": [%s]\n", dynamic_strings
+ entry
->d_un
.d_val
);
1949 printf (": %#lx\n", (long) entry
->d_un
.d_val
);
1956 printf (_("Flags:"));
1957 if (entry
->d_un
.d_val
== 0)
1958 printf (_(" None\n"));
1961 if (entry
->d_un
.d_val
& DF_P1_LAZYLOAD
)
1962 printf (" LAZYLOAD");
1963 if (entry
->d_un
.d_val
& DF_P1_LAZYLOAD
)
1964 printf (" GROUPPERM");
1973 printf (_("Flags:"));
1974 if (entry
->d_un
.d_val
== 0)
1975 printf (_(" None\n"));
1978 if (entry
->d_un
.d_val
& DF_1_NOW
)
1980 if (entry
->d_un
.d_val
& DF_1_GLOBAL
)
1982 if (entry
->d_un
.d_val
& DF_1_GROUP
)
1984 if (entry
->d_un
.d_val
& DF_1_NODELETE
)
1985 printf (" NODELETE");
1986 if (entry
->d_un
.d_val
& DF_1_LOADFLTR
)
1987 printf (" LOADFLTR");
1988 if (entry
->d_un
.d_val
& DF_1_INITFIRST
)
1989 printf (" INITFIRST");
1990 if (entry
->d_un
.d_val
& DF_1_NOOPEN
)
1992 if (entry
->d_un
.d_val
& DF_1_ORIGIN
)
1994 if (entry
->d_un
.d_val
& DF_1_DIRECT
)
1996 if (entry
->d_un
.d_val
& DF_1_TRANS
)
1998 if (entry
->d_un
.d_val
& DF_1_INTERPOSE
)
1999 printf (" INTERPOSE");
2023 dynamic_info
[entry
->d_tag
] = entry
->d_un
.d_val
;
2029 if (dynamic_strings
== NULL
)
2032 name
= dynamic_strings
+ entry
->d_un
.d_val
;
2036 switch (entry
->d_tag
)
2039 printf (_("Shared library: [%s]"), name
);
2041 if (strcmp (name
, program_interpreter
))
2044 printf (_(" program interpreter\n"));
2048 printf (_("Library soname: [%s]\n"), name
);
2052 printf (_("Library rpath: [%s]\n"), name
);
2056 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
2060 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
2075 printf ("%ld\n", entry
->d_un
.d_val
);
2086 if (dynamic_strings
== NULL
)
2089 name
= dynamic_strings
+ entry
->d_un
.d_val
;
2095 switch (entry
->d_tag
)
2098 printf (_("Not needed object: [%s]\n"), name
);
2102 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
2106 printf ("%#lx\n", (long) entry
->d_un
.d_val
);
2111 if ((entry
->d_tag
>= DT_VERSYM
) && (entry
->d_tag
<= DT_VERNEEDNUM
))
2113 version_info
[DT_VERSIONTAGIDX (entry
->d_tag
)] =
2117 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
2120 switch (elf_header
.e_machine
)
2123 case EM_MIPS_RS4_BE
:
2124 dynamic_segment_mips_val (entry
);
2128 printf ("%#lx\n", (long) entry
->d_un
.d_ptr
);
2138 get_ver_flags (flags
)
2141 static char buff
[32];
2148 if (flags
& VER_FLG_BASE
)
2149 strcat (buff
, "BASE ");
2151 if (flags
& VER_FLG_WEAK
)
2153 if (flags
& VER_FLG_BASE
)
2154 strcat (buff
, "| ");
2156 strcat (buff
, "WEAK ");
2159 if (flags
& ~(VER_FLG_BASE
| VER_FLG_WEAK
))
2160 strcat (buff
, "| <unknown>");
2165 /* Display the contents of the version sections. */
2167 process_version_sections (file
)
2170 Elf32_Internal_Shdr
* section
;
2177 for (i
= 0, section
= section_headers
;
2178 i
< elf_header
.e_shnum
;
2181 switch (section
->sh_type
)
2183 case SHT_GNU_verdef
:
2185 Elf_External_Verdef
* edefs
;
2192 (_("\nVersion definition section '%s' contains %d entries:\n"),
2193 SECTION_NAME (section
), section
->sh_info
);
2195 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2196 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2197 SECTION_NAME (section_headers
+ section
->sh_link
));
2199 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
2200 edefs
, Elf_External_Verdef
*,
2201 "version definition section");
2203 for (idx
= cnt
= 0; cnt
< section
->sh_info
; ++ cnt
)
2206 Elf_External_Verdef
* edef
;
2207 Elf_Internal_Verdef ent
;
2208 Elf_External_Verdaux
* eaux
;
2209 Elf_Internal_Verdaux aux
;
2213 vstart
= ((char *) edefs
) + idx
;
2215 edef
= (Elf_External_Verdef
*) vstart
;
2217 ent
.vd_version
= BYTE_GET (edef
->vd_version
);
2218 ent
.vd_flags
= BYTE_GET (edef
->vd_flags
);
2219 ent
.vd_ndx
= BYTE_GET (edef
->vd_ndx
);
2220 ent
.vd_cnt
= BYTE_GET (edef
->vd_cnt
);
2221 ent
.vd_hash
= BYTE_GET (edef
->vd_hash
);
2222 ent
.vd_aux
= BYTE_GET (edef
->vd_aux
);
2223 ent
.vd_next
= BYTE_GET (edef
->vd_next
);
2225 printf (_(" %#06x: Rev: %d Flags: %s"),
2226 idx
, ent
.vd_version
, get_ver_flags (ent
.vd_flags
));
2228 printf (_(" Index: %ld Cnt: %ld "), ent
.vd_ndx
, ent
.vd_cnt
);
2230 vstart
+= ent
.vd_aux
;
2232 eaux
= (Elf_External_Verdaux
*) vstart
;
2234 aux
.vda_name
= BYTE_GET (eaux
->vda_name
);
2235 aux
.vda_next
= BYTE_GET (eaux
->vda_next
);
2237 if (dynamic_strings
)
2238 printf (_("Name: %s\n"), dynamic_strings
+ aux
.vda_name
);
2240 printf (_("Name index: %ld\n"), aux
.vda_name
);
2242 isum
= idx
+ ent
.vd_aux
;
2244 for (j
= 1; j
< ent
.vd_cnt
; j
++)
2246 isum
+= aux
.vda_next
;
2247 vstart
+= aux
.vda_next
;
2249 eaux
= (Elf_External_Verdaux
*) vstart
;
2251 aux
.vda_name
= BYTE_GET (eaux
->vda_name
);
2252 aux
.vda_next
= BYTE_GET (eaux
->vda_next
);
2254 if (dynamic_strings
)
2255 printf (_(" %#06x: Parent %d: %s\n"),
2256 isum
, j
, dynamic_strings
+ aux
.vda_name
);
2258 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2259 isum
, j
, aux
.vda_name
);
2269 case SHT_GNU_verneed
:
2271 Elf_External_Verneed
* eneed
;
2277 printf (_("\nVersion needs section '%s' contains %d entries:\n"),
2278 SECTION_NAME (section
), section
->sh_info
);
2281 (_(" Addr: %#08x Offset: %#08x Link to section: %d (%s)\n"),
2282 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2283 SECTION_NAME (section_headers
+ section
->sh_link
));
2285 GET_DATA_ALLOC (section
->sh_offset
, section
->sh_size
,
2286 eneed
, Elf_External_Verneed
*,
2287 "version need section");
2289 for (idx
= cnt
= 0; cnt
< section
->sh_info
; ++cnt
)
2291 Elf_External_Verneed
* entry
;
2292 Elf_Internal_Verneed ent
;
2297 vstart
= ((char *) eneed
) + idx
;
2299 entry
= (Elf_External_Verneed
*) vstart
;
2301 ent
.vn_version
= BYTE_GET (entry
->vn_version
);
2302 ent
.vn_cnt
= BYTE_GET (entry
->vn_cnt
);
2303 ent
.vn_file
= BYTE_GET (entry
->vn_file
);
2304 ent
.vn_aux
= BYTE_GET (entry
->vn_aux
);
2305 ent
.vn_next
= BYTE_GET (entry
->vn_next
);
2307 printf (_(" %#06x: Version: %d"), idx
, ent
.vn_version
);
2309 if (dynamic_strings
)
2310 printf (_(" File: %s"), dynamic_strings
+ ent
.vn_file
);
2312 printf (_(" File: %lx"), ent
.vn_file
);
2314 printf (_(" Cnt: %d\n"), ent
.vn_cnt
);
2316 vstart
+= ent
.vn_aux
;
2318 for (j
= 0, isum
= idx
+ ent
.vn_aux
; j
< ent
.vn_cnt
; ++j
)
2320 Elf_External_Vernaux
* eaux
;
2321 Elf_Internal_Vernaux aux
;
2323 eaux
= (Elf_External_Vernaux
*) vstart
;
2325 aux
.vna_hash
= BYTE_GET (eaux
->vna_hash
);
2326 aux
.vna_flags
= BYTE_GET (eaux
->vna_flags
);
2327 aux
.vna_other
= BYTE_GET (eaux
->vna_other
);
2328 aux
.vna_name
= BYTE_GET (eaux
->vna_name
);
2329 aux
.vna_next
= BYTE_GET (eaux
->vna_next
);
2331 if (dynamic_strings
)
2332 printf (_(" %#06x: Name: %s"),
2333 isum
, dynamic_strings
+ aux
.vna_name
);
2335 printf (_(" %#06x: Name index: %lx"),
2336 isum
, aux
.vna_name
);
2338 printf (_(" Flags: %s Version: %d\n"),
2339 get_ver_flags (aux
.vna_flags
), aux
.vna_other
);
2341 isum
+= aux
.vna_next
;
2342 vstart
+= aux
.vna_next
;
2352 case SHT_GNU_versym
:
2354 Elf32_Internal_Shdr
* link_section
;
2357 unsigned char * edata
;
2358 unsigned short * data
;
2360 Elf_Internal_Sym
* symbols
;
2361 Elf32_Internal_Shdr
* string_sec
;
2363 link_section
= section_headers
+ section
->sh_link
;
2364 total
= section
->sh_size
/ section
->sh_entsize
;
2368 symbols
= get_elf_symbols
2369 (file
, link_section
->sh_offset
,
2370 link_section
->sh_size
/ link_section
->sh_entsize
);
2372 string_sec
= section_headers
+ link_section
->sh_link
;
2374 GET_DATA_ALLOC (string_sec
->sh_offset
, string_sec
->sh_size
,
2375 strtab
, char *, "version string table");
2377 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2378 SECTION_NAME (section
), total
);
2380 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2381 section
->sh_addr
, section
->sh_offset
, section
->sh_link
,
2382 SECTION_NAME (link_section
));
2384 GET_DATA_ALLOC (version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)]
2386 total
* sizeof (short), edata
,
2387 char *, "version symbol data");
2389 data
= (unsigned short *) malloc (total
* sizeof (short));
2391 for (cnt
= total
; cnt
--;)
2392 data
[cnt
] = byte_get (edata
+ cnt
* sizeof (short), sizeof (short));
2396 for (cnt
= 0; cnt
< total
; cnt
+= 4)
2400 printf (" %03x:", cnt
);
2402 for (j
= 0; (j
< 4) && (cnt
+ j
) < total
; ++j
)
2403 switch (data
[cnt
+ j
])
2406 fputs (_(" 0 (*local*) "), stdout
);
2410 fputs (_(" 1 (*global*) "), stdout
);
2414 nn
= printf ("%4x%c", data
[cnt
+ j
] & 0x7fff,
2415 data
[cnt
+ j
] & 0x8000 ? 'h' : ' ');
2417 if (symbols
[cnt
+ j
].st_shndx
< SHN_LORESERVE
2418 && section_headers
[symbols
[cnt
+ j
].st_shndx
].sh_type
2421 /* We must test both. */
2422 Elf_Internal_Verneed ivn
;
2423 unsigned long offset
;
2425 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERNEED
)]
2430 Elf_External_Verneed evn
;
2431 Elf_External_Vernaux evna
;
2432 Elf_Internal_Vernaux ivna
;
2433 unsigned long vna_off
;
2435 GET_DATA (offset
, evn
, "version need");
2437 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2438 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2440 vna_off
= offset
+ ivn
.vn_aux
;
2444 GET_DATA (vna_off
, evna
,
2445 "version need aux (1)");
2447 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2448 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2450 vna_off
+= ivna
.vna_next
;
2452 while (ivna
.vna_other
!= data
[cnt
+ j
]
2453 && ivna
.vna_next
!= 0);
2455 if (ivna
.vna_other
== data
[cnt
+ j
])
2457 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2459 nn
+= printf ("(%s%-*s",
2460 strtab
+ ivna
.vna_name
,
2466 else if (ivn
.vn_next
== 0)
2468 if (data
[cnt
+ j
] != 0x8001)
2470 Elf_Internal_Verdef ivd
;
2471 Elf_External_Verdef evd
;
2473 offset
= version_info
2474 [DT_VERSIONTAGIDX (DT_VERDEF
)]
2479 GET_DATA (offset
, evd
,
2480 "version definition");
2482 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2483 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2485 offset
+= ivd
.vd_next
;
2488 != (data
[cnt
+ j
] & 0x7fff)
2489 && ivd
.vd_next
!= 0);
2492 == (data
[cnt
+ j
] & 0x7fff))
2494 Elf_External_Verdaux evda
;
2495 Elf_Internal_Verdaux ivda
;
2497 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2499 GET_DATA (offset
+ ivd
.vd_aux
, evda
,
2500 "version definition aux");
2503 BYTE_GET (evda
.vda_name
);
2507 strtab
+ ivda
.vda_name
,
2518 offset
+= ivn
.vn_next
;
2520 while (ivn
.vn_next
);
2522 else if (symbols
[cnt
+ j
].st_shndx
== SHN_UNDEF
)
2524 Elf_Internal_Verneed ivn
;
2525 unsigned long offset
;
2527 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERNEED
)]
2532 Elf_Internal_Vernaux ivna
;
2533 Elf_External_Verneed evn
;
2534 Elf_External_Vernaux evna
;
2535 unsigned long a_off
;
2537 GET_DATA (offset
, evn
, "version need");
2539 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2540 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2542 a_off
= offset
+ ivn
.vn_aux
;
2546 GET_DATA (a_off
, evna
,
2547 "version need aux (2)");
2549 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2550 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2552 a_off
+= ivna
.vna_next
;
2554 while (ivna
.vna_other
!= data
[cnt
+ j
]
2555 && ivna
.vna_next
!= 0);
2557 if (ivna
.vna_other
== data
[cnt
+ j
])
2559 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2561 nn
+= printf ("(%s%-*s",
2562 strtab
+ ivna
.vna_name
,
2569 offset
+= ivn
.vn_next
;
2571 while (ivn
.vn_next
);
2573 else if (data
[cnt
+ j
] != 0x8001)
2575 Elf_Internal_Verdef ivd
;
2576 Elf_External_Verdef evd
;
2577 unsigned long offset
;
2579 offset
= version_info
2580 [DT_VERSIONTAGIDX (DT_VERDEF
)] - loadaddr
;
2584 GET_DATA (offset
, evd
, "version def");
2586 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2587 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2589 offset
+= ivd
.vd_next
;
2591 while (ivd
.vd_ndx
!= (data
[cnt
+ j
] & 0x7fff)
2592 && ivd
.vd_next
!= 0);
2594 if (ivd
.vd_ndx
== (data
[cnt
+ j
] & 0x7fff))
2596 Elf_External_Verdaux evda
;
2597 Elf_Internal_Verdaux ivda
;
2599 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2601 GET_DATA (offset
- ivd
.vd_next
+ ivd
.vd_aux
,
2602 evda
, "version def aux");
2604 ivda
.vda_name
= BYTE_GET (evda
.vda_name
);
2606 nn
+= printf ("(%s%-*s",
2607 strtab
+ ivda
.vda_name
,
2615 printf ("%*c", 18 - nn
, ' ');
2633 printf (_("\nNo version information found in this file.\n"));
2639 get_symbol_binding (binding
)
2640 unsigned int binding
;
2642 static char buff
[32];
2646 case STB_LOCAL
: return _("LOCAL");
2647 case STB_GLOBAL
: return _("GLOBAL");
2648 case STB_WEAK
: return _("WEAK");
2650 if (binding
>= STB_LOPROC
&& binding
<= STB_HIPROC
)
2651 sprintf (buff
, _("<processor specific>: %d"), binding
);
2653 sprintf (buff
, _("<unknown>: %d"), binding
);
2659 get_symbol_type (type
)
2662 static char buff
[32];
2666 case STT_NOTYPE
: return _("NOTYPE");
2667 case STT_OBJECT
: return _("OBJECT");
2668 case STT_FUNC
: return _("FUNC");
2669 case STT_SECTION
: return _("SECTION");
2670 case STT_FILE
: return _("FILE");
2672 if (type
>= STT_LOPROC
&& type
<= STT_HIPROC
)
2673 sprintf (buff
, _("<processor specific>: %d"), type
);
2675 sprintf (buff
, _("<unknown>: %d"), type
);
2681 get_symbol_index_type (type
)
2686 case SHN_UNDEF
: return "UND";
2687 case SHN_ABS
: return "ABS";
2688 case SHN_COMMON
: return "COM";
2690 if (type
>= SHN_LOPROC
&& type
<= SHN_HIPROC
)
2692 else if (type
>= SHN_LORESERVE
&& type
<= SHN_HIRESERVE
)
2696 static char buff
[32];
2698 sprintf (buff
, "%3d", type
);
2706 get_dynamic_data (file
, number
)
2708 unsigned int number
;
2713 e_data
= (char *) malloc (number
* 4);
2717 error (_("Out of memory\n"));
2721 if (fread (e_data
, 4, number
, file
) != number
)
2723 error (_("Unable to read in dynamic data\n"));
2727 i_data
= (int *) malloc (number
* sizeof (* i_data
));
2731 error (_("Out of memory\n"));
2737 i_data
[number
] = byte_get (e_data
+ number
* 4, 4);
2744 /* Dump the symbol table */
2746 process_symbol_table (file
)
2749 Elf32_Internal_Shdr
* section
;
2754 int * buckets
= NULL
;
2755 int * chains
= NULL
;
2757 if (! do_syms
&& !do_histogram
)
2760 if (dynamic_info
[DT_HASH
] && ((do_using_dynamic
&& dynamic_strings
!= NULL
)
2763 if (fseek (file
, dynamic_info
[DT_HASH
] - loadaddr
, SEEK_SET
))
2765 error (_("Unable to seek to start of dynamic information"));
2769 if (fread (& nb
, sizeof (nb
), 1, file
) != 1)
2771 error (_("Failed to read in number of buckets\n"));
2775 if (fread (& nc
, sizeof (nc
), 1, file
) != 1)
2777 error (_("Failed to read in number of chains\n"));
2781 nbuckets
= byte_get (nb
, 4);
2782 nchains
= byte_get (nc
, 4);
2784 buckets
= get_dynamic_data (file
, nbuckets
);
2785 chains
= get_dynamic_data (file
, nchains
);
2787 if (buckets
== NULL
|| chains
== NULL
)
2792 && dynamic_info
[DT_HASH
] && do_using_dynamic
&& dynamic_strings
!= NULL
)
2797 printf (_("\nSymbol table for image:\n"));
2798 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
2800 for (hn
= 0; hn
< nbuckets
; hn
++)
2805 for (si
= buckets
[hn
]; si
; si
= chains
[si
])
2807 Elf_Internal_Sym
* psym
;
2809 psym
= dynamic_symbols
+ si
;
2811 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
2813 (unsigned long) psym
->st_value
,
2814 (unsigned long) psym
->st_size
,
2815 get_symbol_type (ELF_ST_TYPE (psym
->st_info
)),
2816 get_symbol_binding (ELF_ST_BIND (psym
->st_info
)),
2819 printf ("%3.3s", get_symbol_index_type (psym
->st_shndx
));
2821 printf (" %s\n", dynamic_strings
+ psym
->st_name
);
2825 else if (do_syms
&& !do_using_dynamic
)
2829 for (i
= 0, section
= section_headers
;
2830 i
< elf_header
.e_shnum
;
2835 Elf_Internal_Sym
* symtab
;
2836 Elf_Internal_Sym
* psym
;
2839 if ( section
->sh_type
!= SHT_SYMTAB
2840 && section
->sh_type
!= SHT_DYNSYM
)
2843 printf (_("\nSymbol table '%s' contains %d entries:\n"),
2844 SECTION_NAME (section
),
2845 section
->sh_size
/ section
->sh_entsize
);
2846 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
2849 symtab
= get_elf_symbols (file
, section
->sh_offset
,
2850 section
->sh_size
/ section
->sh_entsize
);
2854 if (section
->sh_link
== elf_header
.e_shstrndx
)
2855 strtab
= string_table
;
2858 Elf32_Internal_Shdr
* string_sec
;
2860 string_sec
= section_headers
+ section
->sh_link
;
2862 GET_DATA_ALLOC (string_sec
->sh_offset
, string_sec
->sh_size
,
2863 strtab
, char *, "string table");
2866 for (si
= 0, psym
= symtab
;
2867 si
< section
->sh_size
/ section
->sh_entsize
;
2870 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
2872 (unsigned long) psym
->st_value
,
2873 (unsigned long) psym
->st_size
,
2874 get_symbol_type (ELF_ST_TYPE (psym
->st_info
)),
2875 get_symbol_binding (ELF_ST_BIND (psym
->st_info
)),
2878 if (psym
->st_shndx
== 0)
2879 fputs (" UND", stdout
);
2880 else if ((psym
->st_shndx
& 0xffff) == 0xfff1)
2881 fputs (" ABS", stdout
);
2882 else if ((psym
->st_shndx
& 0xffff) == 0xfff2)
2883 fputs (" COM", stdout
);
2885 printf ("%4x", psym
->st_shndx
);
2887 printf (" %s", strtab
+ psym
->st_name
);
2889 if (section
->sh_type
== SHT_DYNSYM
&&
2890 version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)] != 0)
2892 unsigned char data
[2];
2893 unsigned short vers_data
;
2894 unsigned long offset
;
2898 offset
= version_info
[DT_VERSIONTAGIDX (DT_VERSYM
)]
2901 GET_DATA (offset
+ si
* sizeof (vers_data
), data
,
2904 vers_data
= byte_get (data
, 2);
2906 is_nobits
= psym
->st_shndx
< SHN_LORESERVE
?
2907 (section_headers
[psym
->st_shndx
].sh_type
== SHT_NOBITS
)
2910 check_def
= (psym
->st_shndx
!= SHN_UNDEF
);
2912 if ((vers_data
& 0x8000) || vers_data
> 1)
2914 if (is_nobits
|| ! check_def
)
2916 Elf_External_Verneed evn
;
2917 Elf_Internal_Verneed ivn
;
2918 Elf_Internal_Vernaux ivna
;
2920 /* We must test both. */
2921 offset
= version_info
2922 [DT_VERSIONTAGIDX (DT_VERNEED
)] - loadaddr
;
2924 GET_DATA (offset
, evn
, "version need");
2926 ivn
.vn_aux
= BYTE_GET (evn
.vn_aux
);
2927 ivn
.vn_next
= BYTE_GET (evn
.vn_next
);
2931 unsigned long vna_off
;
2933 vna_off
= offset
+ ivn
.vn_aux
;
2937 Elf_External_Vernaux evna
;
2939 GET_DATA (vna_off
, evna
,
2940 "version need aux (3)");
2942 ivna
.vna_other
= BYTE_GET (evna
.vna_other
);
2943 ivna
.vna_next
= BYTE_GET (evna
.vna_next
);
2944 ivna
.vna_name
= BYTE_GET (evna
.vna_name
);
2946 vna_off
+= ivna
.vna_next
;
2948 while (ivna
.vna_other
!= vers_data
2949 && ivna
.vna_next
!= 0);
2951 if (ivna
.vna_other
== vers_data
)
2954 offset
+= ivn
.vn_next
;
2956 while (ivn
.vn_next
!= 0);
2958 if (ivna
.vna_other
== vers_data
)
2961 strtab
+ ivna
.vna_name
, ivna
.vna_other
);
2964 else if (! is_nobits
)
2965 error (_("bad dynamic symbol"));
2972 if (vers_data
!= 0x8001)
2974 Elf_Internal_Verdef ivd
;
2975 Elf_Internal_Verdaux ivda
;
2976 Elf_External_Verdaux evda
;
2977 unsigned long offset
;
2980 version_info
[DT_VERSIONTAGIDX (DT_VERDEF
)]
2985 Elf_External_Verdef evd
;
2987 GET_DATA (offset
, evd
, "version def");
2989 ivd
.vd_ndx
= BYTE_GET (evd
.vd_ndx
);
2990 ivd
.vd_aux
= BYTE_GET (evd
.vd_aux
);
2991 ivd
.vd_next
= BYTE_GET (evd
.vd_next
);
2993 offset
+= ivd
.vd_next
;
2995 while (ivd
.vd_ndx
!= (vers_data
& 0x7fff)
2996 && ivd
.vd_next
!= 0);
2998 offset
-= ivd
.vd_next
;
2999 offset
+= ivd
.vd_aux
;
3001 GET_DATA (offset
, evda
, "version def aux");
3003 ivda
.vda_name
= BYTE_GET (evda
.vda_name
);
3005 if (psym
->st_name
!= ivda
.vda_name
)
3006 printf ((vers_data
& 0x8000)
3008 strtab
+ ivda
.vda_name
);
3018 if (strtab
!= string_table
)
3024 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3033 int nzero_counts
= 0;
3036 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3038 printf (_(" Length Number %% of total Coverage\n"));
3040 lengths
= (int *) calloc (nbuckets
, sizeof (int));
3041 if (lengths
== NULL
)
3043 error (_("Out of memory"));
3046 for (hn
= 0; hn
< nbuckets
; ++hn
)
3051 for (si
= buckets
[hn
]; si
; si
= chains
[si
])
3054 if (maxlength
< ++lengths
[hn
])
3059 counts
= (int *) calloc (maxlength
+ 1, sizeof (int));
3062 error (_("Out of memory"));
3066 for (hn
= 0; hn
< nbuckets
; ++hn
)
3067 ++counts
[lengths
[hn
]];
3069 printf (" 0 %-10d (%5.1f%%)\n",
3070 counts
[0], (counts
[0] * 100.0) / nbuckets
);
3071 for (si
= 1; si
<= maxlength
; ++si
)
3073 nzero_counts
+= counts
[si
] * si
;
3074 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3075 si
, counts
[si
], (counts
[si
] * 100.0) / nbuckets
,
3076 (nzero_counts
* 100.0) / nsyms
);
3083 if (buckets
!= NULL
)
3093 process_syminfo (file
)
3098 if (dynamic_syminfo
== NULL
3100 /* No syminfo, this is ok. */
3103 /* There better should be a dynamic symbol section. */
3104 if (dynamic_symbols
== NULL
|| dynamic_strings
== NULL
)
3108 printf (_("\nDynamic info segment at offset 0x%x contains %d entries:\n"),
3109 dynamic_syminfo_offset
, dynamic_syminfo_nent
);
3111 printf (_(" Num: Name BoundTo Flags\n"));
3112 for (i
= 0; i
< dynamic_syminfo_nent
; ++i
)
3114 unsigned short int flags
= dynamic_syminfo
[i
].si_flags
;
3116 printf ("%4d: %-30s ", i
,
3117 dynamic_strings
+ dynamic_symbols
[i
].st_name
);
3119 switch (dynamic_syminfo
[i
].si_boundto
)
3121 case SYMINFO_BT_SELF
:
3122 fputs ("SELF ", stdout
);
3124 case SYMINFO_BT_PARENT
:
3125 fputs ("PARENT ", stdout
);
3128 if (dynamic_syminfo
[i
].si_boundto
> 0
3129 && dynamic_syminfo
[i
].si_boundto
< dynamic_size
)
3132 + dynamic_segment
[dynamic_syminfo
[i
].si_boundto
].d_un
.d_val
);
3134 printf ("%-10d ", dynamic_syminfo
[i
].si_boundto
);
3138 if (flags
& SYMINFO_FLG_DIRECT
)
3140 if (flags
& SYMINFO_FLG_PASSTHRU
)
3141 printf (" PASSTHRU");
3142 if (flags
& SYMINFO_FLG_COPY
)
3144 if (flags
& SYMINFO_FLG_LAZYLOAD
)
3145 printf (" LAZYLOAD");
3154 process_section_contents (file
)
3157 Elf32_Internal_Shdr
* section
;
3163 for (i
= 0, section
= section_headers
;
3164 i
< elf_header
.e_shnum
;
3167 #ifdef SUPPORT_DISASSEMBLY
3168 /* See if we need an assembly dump of this section */
3170 if ((i
< NUM_DUMP_SECTS
) && (dump_sects
[i
] & DISASS_DUMP
))
3172 printf (_("\nAssembly dump of section %s\n"),
3173 SECTION_NAME (section
));
3175 /* XXX -- to be done --- XXX */
3178 /* See if we need a hex dump of this section. */
3179 if ((i
< NUM_DUMP_SECTS
) && (dump_sects
[i
] & HEX_DUMP
))
3183 unsigned char * data
;
3186 bytes
= section
->sh_size
;
3190 printf (_("\nSection %d has no data to dump.\n"), i
);
3194 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section
));
3196 addr
= section
->sh_addr
;
3198 GET_DATA_ALLOC (section
->sh_offset
, bytes
, start
, char *,
3209 lbytes
= (bytes
> 16 ? 16 : bytes
);
3211 printf (" 0x%8.8x ", addr
);
3213 switch (elf_header
.e_ident
[EI_DATA
])
3216 for (j
= 15; j
>= 0; j
--)
3219 printf ("%2.2x", data
[j
]);
3229 for (j
= 0; j
< 16; j
++)
3232 printf ("%2.2x", data
[j
]);
3242 for (j
= 0; j
< lbytes
; j
++)
3245 if (k
>= ' ' && k
< 0x80)
3266 process_mips_fpe_exception (mask
)
3272 if (mask
& OEX_FPU_INEX
)
3273 fputs ("INEX", stdout
), first
= 0;
3274 if (mask
& OEX_FPU_UFLO
)
3275 printf ("%sUFLO", first
? "" : "|"), first
= 0;
3276 if (mask
& OEX_FPU_OFLO
)
3277 printf ("%sOFLO", first
? "" : "|"), first
= 0;
3278 if (mask
& OEX_FPU_DIV0
)
3279 printf ("%sDIV0", first
? "" : "|"), first
= 0;
3280 if (mask
& OEX_FPU_INVAL
)
3281 printf ("%sINVAL", first
? "" : "|");
3284 fputs ("0", stdout
);
3288 process_mips_specific (file
)
3291 Elf_Internal_Dyn
*entry
;
3292 size_t liblist_offset
= 0;
3293 size_t liblistno
= 0;
3294 size_t conflictsno
= 0;
3295 size_t options_offset
= 0;
3296 size_t conflicts_offset
= 0;
3298 /* We have a lot of special sections. Thanks SGI! */
3299 if (dynamic_segment
== NULL
)
3300 /* No information available. */
3303 for (entry
= dynamic_segment
; entry
->d_tag
!= DT_NULL
; ++entry
)
3304 switch (entry
->d_tag
)
3306 case DT_MIPS_LIBLIST
:
3307 liblist_offset
= entry
->d_un
.d_val
- loadaddr
;
3309 case DT_MIPS_LIBLISTNO
:
3310 liblistno
= entry
->d_un
.d_val
;
3312 case DT_MIPS_OPTIONS
:
3313 options_offset
= entry
->d_un
.d_val
- loadaddr
;
3315 case DT_MIPS_CONFLICT
:
3316 conflicts_offset
= entry
->d_un
.d_val
- loadaddr
;
3318 case DT_MIPS_CONFLICTNO
:
3319 conflictsno
= entry
->d_un
.d_val
;
3325 if (liblist_offset
!= 0 && liblistno
!= 0 && do_dynamic
)
3327 Elf32_External_Lib
*elib
;
3330 GET_DATA_ALLOC (liblist_offset
, liblistno
* sizeof (Elf32_External_Lib
),
3331 elib
, Elf32_External_Lib
*, "liblist");
3333 printf ("\nSection '.liblist' contains %d entries:\n", liblistno
);
3334 fputs (" Library Time Stamp Checksum Version Flags\n",
3337 for (cnt
= 0; cnt
< liblistno
; ++cnt
)
3343 liblist
.l_name
= BYTE_GET (elib
[cnt
].l_name
);
3344 time
= BYTE_GET (elib
[cnt
].l_time_stamp
);
3345 liblist
.l_checksum
= BYTE_GET (elib
[cnt
].l_checksum
);
3346 liblist
.l_version
= BYTE_GET (elib
[cnt
].l_version
);
3347 liblist
.l_flags
= BYTE_GET (elib
[cnt
].l_flags
);
3349 strftime (timebuf
, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time
));
3351 printf ("%3d: %-20s %s %#10lx %-7ld", cnt
,
3352 dynamic_strings
+ liblist
.l_name
, timebuf
,
3353 liblist
.l_checksum
, liblist
.l_version
);
3355 if (liblist
.l_flags
== 0)
3365 { " EXACT_MATCH", LL_EXACT_MATCH
},
3366 { " IGNORE_INT_VER", LL_IGNORE_INT_VER
},
3367 { " REQUIRE_MINOR", LL_REQUIRE_MINOR
},
3368 { " EXPORTS", LL_EXPORTS
},
3369 { " DELAY_LOAD", LL_DELAY_LOAD
},
3370 { " DELTA", LL_DELTA
}
3372 int flags
= liblist
.l_flags
;
3376 fcnt
< sizeof (l_flags_vals
) / sizeof (l_flags_vals
[0]);
3378 if ((flags
& l_flags_vals
[fcnt
].bit
) != 0)
3380 fputs (l_flags_vals
[fcnt
].name
, stdout
);
3381 flags
^= l_flags_vals
[fcnt
].bit
;
3384 printf (" %#lx", flags
);
3393 if (options_offset
!= 0)
3395 Elf_External_Options
*eopt
;
3396 Elf_Internal_Shdr
*sect
= section_headers
;
3397 Elf_Internal_Options
*iopt
;
3398 Elf_Internal_Options
*option
;
3402 /* Find the section header so that we get the size. */
3403 while (sect
->sh_type
!= SHT_MIPS_OPTIONS
)
3406 GET_DATA_ALLOC (options_offset
, sect
->sh_size
, eopt
,
3407 Elf_External_Options
*, "options");
3409 iopt
= (Elf_Internal_Options
*) malloc ((sect
->sh_size
/ sizeof (eopt
))
3413 error (_("Out of memory"));
3419 while (offset
< sect
->sh_size
)
3421 Elf_External_Options
*eoption
;
3423 eoption
= (Elf_External_Options
*) ((char *) eopt
+ offset
);
3425 option
->kind
= BYTE_GET (eoption
->kind
);
3426 option
->size
= BYTE_GET (eoption
->size
);
3427 option
->section
= BYTE_GET (eoption
->section
);
3428 option
->info
= BYTE_GET (eoption
->info
);
3430 offset
+= option
->size
;
3435 printf (_("\nSection '%s' contains %d entries:\n"),
3436 string_table
+ sect
->sh_name
, cnt
);
3443 switch (option
->kind
)
3446 /* This shouldn't happen. */
3447 printf (" NULL %d %x", option
->section
, option
->info
);
3450 printf (" REGINFO ");
3451 if (elf_header
.e_machine
== EM_MIPS
)
3454 Elf32_External_RegInfo
*ereg
;
3455 Elf32_RegInfo reginfo
;
3457 ereg
= (Elf32_External_RegInfo
*) (option
+ 1);
3458 reginfo
.ri_gprmask
= BYTE_GET (ereg
->ri_gprmask
);
3459 reginfo
.ri_cprmask
[0] = BYTE_GET (ereg
->ri_cprmask
[0]);
3460 reginfo
.ri_cprmask
[1] = BYTE_GET (ereg
->ri_cprmask
[1]);
3461 reginfo
.ri_cprmask
[2] = BYTE_GET (ereg
->ri_cprmask
[2]);
3462 reginfo
.ri_cprmask
[3] = BYTE_GET (ereg
->ri_cprmask
[3]);
3463 reginfo
.ri_gp_value
= BYTE_GET (ereg
->ri_gp_value
);
3465 printf ("GPR %08lx GP %ld\n",
3466 reginfo
.ri_gprmask
, reginfo
.ri_gp_value
);
3467 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
3468 reginfo
.ri_cprmask
[0], reginfo
.ri_cprmask
[1],
3469 reginfo
.ri_cprmask
[2], reginfo
.ri_cprmask
[3]);
3474 Elf64_External_RegInfo
*ereg
;
3475 Elf64_Internal_RegInfo reginfo
;
3477 ereg
= (Elf64_External_RegInfo
*) (option
+ 1);
3478 reginfo
.ri_gprmask
= BYTE_GET (ereg
->ri_gprmask
);
3479 reginfo
.ri_cprmask
[0] = BYTE_GET (ereg
->ri_cprmask
[0]);
3480 reginfo
.ri_cprmask
[1] = BYTE_GET (ereg
->ri_cprmask
[1]);
3481 reginfo
.ri_cprmask
[2] = BYTE_GET (ereg
->ri_cprmask
[2]);
3482 reginfo
.ri_cprmask
[3] = BYTE_GET (ereg
->ri_cprmask
[3]);
3483 reginfo
.ri_gp_value
= BYTE_GET (ereg
->ri_gp_value
);
3485 printf ("GPR %08lx GP %ld\n",
3486 reginfo
.ri_gprmask
, reginfo
.ri_gp_value
);
3487 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
3488 reginfo
.ri_cprmask
[0], reginfo
.ri_cprmask
[1],
3489 reginfo
.ri_cprmask
[2], reginfo
.ri_cprmask
[3]);
3493 case ODK_EXCEPTIONS
:
3494 fputs (" EXCEPTIONS fpe_min(", stdout
);
3495 process_mips_fpe_exception (option
->info
& OEX_FPU_MIN
);
3496 fputs (") fpe_max(", stdout
);
3497 process_mips_fpe_exception ((option
->info
& OEX_FPU_MAX
) >> 8);
3498 fputs (")", stdout
);
3500 if (option
->info
& OEX_PAGE0
)
3501 fputs (" PAGE0", stdout
);
3502 if (option
->info
& OEX_SMM
)
3503 fputs (" SMM", stdout
);
3504 if (option
->info
& OEX_FPDBUG
)
3505 fputs (" FPDBUG", stdout
);
3506 if (option
->info
& OEX_DISMISS
)
3507 fputs (" DISMISS", stdout
);
3510 fputs (" PAD ", stdout
);
3511 if (option
->info
& OPAD_PREFIX
)
3512 fputs (" PREFIX", stdout
);
3513 if (option
->info
& OPAD_POSTFIX
)
3514 fputs (" POSTFIX", stdout
);
3515 if (option
->info
& OPAD_SYMBOL
)
3516 fputs (" SYMBOL", stdout
);
3519 fputs (" HWPATCH ", stdout
);
3520 if (option
->info
& OHW_R4KEOP
)
3521 fputs (" R4KEOP", stdout
);
3522 if (option
->info
& OHW_R8KPFETCH
)
3523 fputs (" R8KPFETCH", stdout
);
3524 if (option
->info
& OHW_R5KEOP
)
3525 fputs (" R5KEOP", stdout
);
3526 if (option
->info
& OHW_R5KCVTL
)
3527 fputs (" R5KCVTL", stdout
);
3530 fputs (" FILL ", stdout
);
3531 /* XXX Print content of info word? */
3534 fputs (" TAGS ", stdout
);
3535 /* XXX Print content of info word? */
3538 fputs (" HWAND ", stdout
);
3539 if (option
->info
& OHWA0_R4KEOP_CHECKED
)
3540 fputs (" R4KEOP_CHECKED", stdout
);
3541 if (option
->info
& OHWA0_R4KEOP_CLEAN
)
3542 fputs (" R4KEOP_CLEAN", stdout
);
3545 fputs (" HWOR ", stdout
);
3546 if (option
->info
& OHWA0_R4KEOP_CHECKED
)
3547 fputs (" R4KEOP_CHECKED", stdout
);
3548 if (option
->info
& OHWA0_R4KEOP_CLEAN
)
3549 fputs (" R4KEOP_CLEAN", stdout
);
3552 printf (" GP_GROUP %#06x self-contained %#06x",
3553 option
->info
& OGP_GROUP
,
3554 (option
->info
& OGP_SELF
) >> 16);
3557 printf (" IDENT %#06x self-contained %#06x",
3558 option
->info
& OGP_GROUP
,
3559 (option
->info
& OGP_SELF
) >> 16);
3562 /* This shouldn't happen. */
3563 printf (" %3d ??? %d %x",
3564 option
->kind
, option
->section
, option
->info
);
3568 len
= sizeof (*eopt
);
3569 while (len
< option
->size
)
3570 if (((char *) option
)[len
] >= ' '
3571 && ((char *) option
)[len
] < 0x7f)
3572 printf ("%c", ((char *) option
)[len
++]);
3574 printf ("\\%03o", ((char *) option
)[len
++]);
3576 fputs ("\n", stdout
);
3583 if (conflicts_offset
!= 0 && conflictsno
!= 0)
3585 Elf32_External_Conflict
*econf32
;
3586 Elf64_External_Conflict
*econf64
;
3587 Elf32_Conflict
*iconf
;
3590 if (dynamic_symbols
== NULL
)
3592 error (_("conflict list with without table"));
3596 iconf
= (Elf32_Conflict
*) malloc (conflictsno
* sizeof (*iconf
));
3599 error (_("Out of memory"));
3603 if (binary_class
== ELFCLASS32
)
3605 GET_DATA_ALLOC (conflicts_offset
, conflictsno
* sizeof (*econf32
),
3606 econf32
, Elf32_External_Conflict
*, "conflict");
3608 for (cnt
= 0; cnt
< conflictsno
; ++cnt
)
3609 iconf
[cnt
] = BYTE_GET (econf32
[cnt
]);
3613 GET_DATA_ALLOC (conflicts_offset
, conflictsno
* sizeof (*econf64
),
3614 econf64
, Elf64_External_Conflict
*, "conflict");
3616 for (cnt
= 0; cnt
< conflictsno
; ++cnt
)
3617 iconf
[cnt
] = BYTE_GET (econf64
[cnt
]);
3620 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno
);
3621 puts (_(" Num: Index Value Name"));
3623 for (cnt
= 0; cnt
< conflictsno
; ++cnt
)
3625 Elf_Internal_Sym
*psym
= &dynamic_symbols
[iconf
[cnt
]];
3627 printf ("%5u: %8u %#10x %s\n",
3628 cnt
, iconf
[cnt
], (unsigned long) psym
->st_value
,
3629 dynamic_strings
+ psym
->st_name
);
3640 process_arch_specific (file
)
3643 switch (elf_header
.e_machine
)
3646 case EM_MIPS_RS4_BE
:
3647 return process_mips_specific (file
);
3656 get_file_header (file
)
3659 Elf32_External_Ehdr ehdr
;
3661 if (fread (& ehdr
, sizeof (ehdr
), 1, file
) != 1)
3664 memcpy (elf_header
.e_ident
, ehdr
.e_ident
, EI_NIDENT
);
3666 if (elf_header
.e_ident
[EI_DATA
] == ELFDATA2LSB
)
3667 byte_get
= byte_get_little_endian
;
3669 byte_get
= byte_get_big_endian
;
3671 elf_header
.e_entry
= BYTE_GET (ehdr
.e_entry
);
3672 elf_header
.e_phoff
= BYTE_GET (ehdr
.e_phoff
);
3673 elf_header
.e_shoff
= BYTE_GET (ehdr
.e_shoff
);
3674 elf_header
.e_version
= BYTE_GET (ehdr
.e_version
);
3675 elf_header
.e_flags
= BYTE_GET (ehdr
.e_flags
);
3676 elf_header
.e_type
= BYTE_GET (ehdr
.e_type
);
3677 elf_header
.e_machine
= BYTE_GET (ehdr
.e_machine
);
3678 elf_header
.e_ehsize
= BYTE_GET (ehdr
.e_ehsize
);
3679 elf_header
.e_phentsize
= BYTE_GET (ehdr
.e_phentsize
);
3680 elf_header
.e_phnum
= BYTE_GET (ehdr
.e_phnum
);
3681 elf_header
.e_shentsize
= BYTE_GET (ehdr
.e_shentsize
);
3682 elf_header
.e_shnum
= BYTE_GET (ehdr
.e_shnum
);
3683 elf_header
.e_shstrndx
= BYTE_GET (ehdr
.e_shstrndx
);
3689 process_file (file_name
)
3693 struct stat statbuf
;
3696 if (stat (file_name
, & statbuf
) < 0)
3698 error (_("Cannot stat input file %s.\n"), file_name
);
3702 file
= fopen (file_name
, "rb");
3705 error (_("Input file %s not found.\n"), file_name
);
3709 if (! get_file_header (file
))
3711 error (_("%s: Failed to read file header\n"), file_name
);
3716 /* Initialise per file variables. */
3717 for (i
= NUM_ELEM (version_info
); i
--;)
3718 version_info
[i
] = 0;
3720 for (i
= NUM_ELEM (dynamic_info
); i
--;)
3721 dynamic_info
[i
] = 0;
3723 /* Process the file. */
3725 printf (_("\nFile: %s\n"), file_name
);
3727 if (! process_file_header ())
3733 process_section_headers (file
);
3735 process_program_headers (file
);
3737 process_dynamic_segment (file
);
3739 process_relocs (file
);
3741 process_symbol_table (file
);
3743 process_syminfo (file
);
3745 process_version_sections (file
);
3747 process_section_contents (file
);
3749 process_arch_specific (file
);
3753 if (section_headers
)
3755 free (section_headers
);
3756 section_headers
= NULL
;
3761 free (string_table
);
3762 string_table
= NULL
;
3765 if (dynamic_strings
)
3767 free (dynamic_strings
);
3768 dynamic_strings
= NULL
;
3771 if (dynamic_symbols
)
3773 free (dynamic_symbols
);
3774 dynamic_symbols
= NULL
;
3777 if (dynamic_syminfo
)
3779 free (dynamic_syminfo
);
3780 dynamic_syminfo
= NULL
;
3784 #ifdef SUPPORT_DISASSEMBLY
3785 /* Needed by the i386 disassembler. For extra credit, someone could
3786 fix this so that we insert symbolic addresses here, esp for GOT/PLT
3790 print_address (unsigned int addr
, FILE * outfile
)
3792 fprintf (outfile
,"0x%8.8x", addr
);
3795 /* Needed by the i386 disassembler. */
3797 db_task_printsym (unsigned int addr
)
3799 print_address (addr
, stderr
);
3808 parse_args (argc
, argv
);
3810 if (optind
< (argc
- 1))
3813 while (optind
< argc
)
3814 process_file (argv
[optind
++]);