1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@cygnus.com>
7 This file is part of GNU Binutils.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #include "elf/common.h"
33 #include "elf/external.h"
34 #include "elf/internal.h"
35 #include "elf/dwarf2.h"
37 /* The following headers use the elf/reloc-macros.h file to
38 automatically generate relocation recognition functions
39 such as elf_mips_reloc_type() */
41 #define RELOC_MACROS_GEN_FUNC
47 #include "elf/alpha.h"
50 #include "elf/sparc.h"
55 #include "elf/mn10200.h"
56 #include "elf/mn10300.h"
64 #ifdef ANSI_PROTOTYPES
70 char * program_name = "readelf";
71 unsigned int dynamic_addr;
72 unsigned int dynamic_size;
73 unsigned int rela_addr;
74 unsigned int rela_size;
75 char * dynamic_strings;
77 Elf_Internal_Sym * dynamic_symbols;
78 Elf_Internal_Syminfo * dynamic_syminfo;
79 unsigned long dynamic_syminfo_offset;
80 unsigned int dynamic_syminfo_nent;
81 char program_interpreter [64];
82 int dynamic_info[DT_JMPREL + 1];
85 Elf_Internal_Ehdr elf_header;
86 Elf_Internal_Shdr * section_headers;
87 Elf_Internal_Dyn * dynamic_segment;
101 int do_debug_abbrevs;
103 int do_debug_pubnames;
106 static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
108 /* XXX - An arbitary constant, limiting the number of sections
109 for whcih we can display information. */
110 #define NUM_DUMP_SECTS 100
111 char dump_sects [NUM_DUMP_SECTS];
113 #define HEX_DUMP (1 << 0)
114 #define DISASS_DUMP (1 << 1)
115 #define DEBUG_DUMP (1 << 2)
117 /* Forward declarations for dumb compilers. */
118 static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
119 static const char * get_dynamic_type PARAMS ((unsigned long type));
120 static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *));
121 static char * get_file_type PARAMS ((unsigned e_type));
122 static char * get_machine_name PARAMS ((unsigned e_machine));
123 static char * get_machine_data PARAMS ((unsigned e_data));
124 static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
125 static const char * get_mips_segment_type PARAMS ((unsigned long type));
126 static const char * get_segment_type PARAMS ((unsigned long p_type));
127 static const char * get_mips_section_type_name PARAMS ((unsigned int sh_type));
128 static const char * get_section_type_name PARAMS ((unsigned int sh_type));
129 static char * get_symbol_binding PARAMS ((unsigned int binding));
130 static char * get_symbol_type PARAMS ((unsigned int type));
131 static void usage PARAMS ((void));
132 static void parse_args PARAMS ((int argc, char ** argv));
133 static int process_file_header PARAMS ((void));
134 static int process_program_headers PARAMS ((FILE *));
135 static int process_section_headers PARAMS ((FILE *));
136 static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *entry));
137 static int process_dynamic_segment PARAMS ((FILE *));
138 static int process_symbol_table PARAMS ((FILE *));
139 static int process_section_contents PARAMS ((FILE *));
140 static void process_file PARAMS ((char * file_name));
141 static int process_relocs PARAMS ((FILE *));
142 static int process_version_sections PARAMS ((FILE *));
143 static char * get_ver_flags PARAMS ((unsigned int flags));
144 static char * get_symbol_index_type PARAMS ((unsigned int type));
145 static int get_section_headers PARAMS ((FILE * file));
146 static int get_file_header PARAMS ((FILE * file));
147 static Elf_Internal_Sym * get_elf_symbols PARAMS ((FILE * file, unsigned long offset, unsigned long number));
148 static int * get_dynamic_data PARAMS ((FILE * file, unsigned int number));
149 static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
150 static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
151 static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
152 static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
153 static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
154 static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
155 static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
156 static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
157 static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
158 static int process_extended_line_op PARAMS ((unsigned char *, long *));
159 static char * get_TAG_name PARAMS ((unsigned long));
160 static char * get_AT_name PARAMS ((unsigned long));
161 static char * get_FORM_name PARAMS ((unsigned long));
162 static void free_abbrevs PARAMS ((void));
163 static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
164 static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
165 static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
166 static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
168 typedef int Elf32_Word;
170 #define SECTION_NAME(X) (string_table + (X)->sh_name)
172 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
174 #define BYTE_GET(field) byte_get (field, sizeof (field))
176 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
178 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
179 if (fseek (file, offset, SEEK_SET)) \
181 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
185 var = (type) malloc (size); \
189 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
193 if (fread (var, size, 1, file) != 1) \
195 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
202 #define GET_DATA(offset, var, reason) \
203 if (fseek (file, offset, SEEK_SET)) \
205 error (_("Unable to seek to %x for %s\n"), offset, reason); \
208 else if (fread (& var, sizeof (var), 1, file) != 1) \
210 error (_("Unable to read data at %x for %s\n"), offset, reason); \
214 #ifdef ANSI_PROTOTYPES
216 error (const char * message, ...)
220 fprintf (stderr, _("%s: Error: "), program_name);
221 va_start (args, message);
222 vfprintf (stderr, message, args);
228 warn (const char * message, ...)
232 fprintf (stderr, _("%s: Warning: "), program_name);
233 va_start (args, message);
234 vfprintf (stderr, message, args);
246 fprintf (stderr, _("%s: Error: "), program_name);
248 message = va_arg (args, char *);
249 vfprintf (stderr, message, args);
261 fprintf (stderr, _("%s: Warning: "), program_name);
263 message = va_arg (args, char *);
264 vfprintf (stderr, message, args);
270 static unsigned long int
271 byte_get_little_endian (field, size)
272 unsigned char * field;
281 return ((unsigned int) (field [0]))
282 | (((unsigned int) (field [1])) << 8);
285 return ((unsigned long) (field [0]))
286 | (((unsigned long) (field [1])) << 8)
287 | (((unsigned long) (field [2])) << 16)
288 | (((unsigned long) (field [3])) << 24);
291 error (_("Unhandled data length: %d\n"), size);
296 static unsigned long int
297 byte_get_big_endian (field, size)
298 unsigned char * field;
307 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
310 return ((unsigned long) (field [3]))
311 | (((unsigned long) (field [2])) << 8)
312 | (((unsigned long) (field [1])) << 16)
313 | (((unsigned long) (field [0])) << 24);
316 error (_("Unhandled data length: %d\n"), size);
322 /* Display the contents of the relocation data
323 found at the specified offset. */
325 dump_relocations (file, rel_offset, rel_size, symtab, strtab)
327 unsigned long rel_offset;
328 unsigned long rel_size;
329 Elf_Internal_Sym * symtab;
334 Elf_Internal_Rel * rels;
335 Elf_Internal_Rela * relas;
338 /* Compute number of relocations and read them in. */
339 switch (elf_header.e_machine)
348 Elf32_External_Rel * erels;
350 GET_DATA_ALLOC (rel_offset, rel_size, erels,
351 Elf32_External_Rel *, "relocs");
353 rel_size = rel_size / sizeof (Elf32_External_Rel);
355 rels = (Elf_Internal_Rel *) malloc (rel_size *
356 sizeof (Elf_Internal_Rel));
358 for (i = 0; i < rel_size; i++)
360 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
361 rels[i].r_info = BYTE_GET (erels[i].r_info);
367 relas = (Elf_Internal_Rela *) rels;
377 case EM_CYGNUS_MN10200:
378 case EM_CYGNUS_MN10300:
383 Elf32_External_Rela * erelas;
385 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
386 Elf32_External_Rela *, "relocs");
388 rel_size = rel_size / sizeof (Elf32_External_Rela);
390 relas = (Elf_Internal_Rela *) malloc (rel_size *
391 sizeof (Elf_Internal_Rela));
393 for (i = 0; i < rel_size; i++)
395 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
396 relas[i].r_info = BYTE_GET (erelas[i].r_info);
397 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
403 rels = (Elf_Internal_Rel *) relas;
408 warn (_("Don't know about relocations on this machine architecture\n"));
414 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
417 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
419 for (i = 0; i < rel_size; i++)
422 unsigned long offset;
428 offset = relas [i].r_offset;
429 info = relas [i].r_info;
433 offset = rels [i].r_offset;
434 info = rels [i].r_info;
437 printf (" %8.8lx %5.5lx ", offset, info);
439 switch (elf_header.e_machine)
446 rtype = elf_m32r_reloc_type (ELF32_R_TYPE (info));
451 rtype = elf_i386_reloc_type (ELF32_R_TYPE (info));
455 rtype = elf_m68k_reloc_type (ELF32_R_TYPE (info));
459 rtype = elf_sparc_reloc_type (ELF32_R_TYPE (info));
463 rtype = v850_reloc_type (ELF32_R_TYPE (info));
467 rtype = elf_d10v_reloc_type (ELF32_R_TYPE (info));
471 rtype = elf_d30v_reloc_type (ELF32_R_TYPE (info));
475 rtype = elf_sh_reloc_type (ELF32_R_TYPE (info));
478 case EM_CYGNUS_MN10300:
479 rtype = elf_mn10300_reloc_type (ELF32_R_TYPE (info));
482 case EM_CYGNUS_MN10200:
483 rtype = elf_mn10200_reloc_type (ELF32_R_TYPE (info));
487 rtype = elf_fr30_reloc_type (ELF32_R_TYPE (info));
491 rtype = elf_ppc_reloc_type (ELF32_R_TYPE (info));
496 rtype = elf_mips_reloc_type (ELF32_R_TYPE (info));
500 rtype = elf_alpha_reloc_type (ELF32_R_TYPE (info));
504 rtype = elf_arm_reloc_type (ELF32_R_TYPE (info));
508 rtype = elf_arc_reloc_type (ELF32_R_TYPE (info));
512 rtype = elf32_hppa_reloc_type (ELF32_R_TYPE (info));
517 printf (_("unrecognised: %-7x"), ELF32_R_TYPE (info));
519 printf ("%-21.21s", rtype);
521 symtab_index = ELF32_R_SYM (info);
523 if (symtab_index && symtab != NULL)
525 Elf_Internal_Sym * psym;
527 psym = symtab + symtab_index;
529 printf (" %08lx ", (unsigned long) psym->st_value);
531 if (psym->st_name == 0)
533 SECTION_NAME (section_headers + psym->st_shndx));
534 else if (strtab == NULL)
535 printf (_("<string table index %3d>"), psym->st_name);
537 printf ("%-25.25s", strtab + psym->st_name);
540 printf (" + %lx", (unsigned long) relas [i].r_addend);
552 get_mips_dynamic_type (type)
557 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
558 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
559 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
560 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
561 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
562 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
563 case DT_MIPS_MSYM: return "MIPS_MSYM";
564 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
565 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
566 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
567 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
568 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
569 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
570 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
571 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
572 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
573 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
574 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
575 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
576 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
577 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
578 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
579 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
580 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
581 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
582 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
583 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
584 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
585 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
586 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
587 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
588 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
589 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
590 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
591 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
592 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
593 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
594 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
595 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
596 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
597 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
598 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
599 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
606 get_dynamic_type (type)
609 static char buff [32];
613 case DT_NULL: return "NULL";
614 case DT_NEEDED: return "NEEDED";
615 case DT_PLTRELSZ: return "PLTRELSZ";
616 case DT_PLTGOT: return "PLTGOT";
617 case DT_HASH: return "HASH";
618 case DT_STRTAB: return "STRTAB";
619 case DT_SYMTAB: return "SYMTAB";
620 case DT_RELA: return "RELA";
621 case DT_RELASZ: return "RELASZ";
622 case DT_RELAENT: return "RELAENT";
623 case DT_STRSZ: return "STRSZ";
624 case DT_SYMENT: return "SYMENT";
625 case DT_INIT: return "INIT";
626 case DT_FINI: return "FINI";
627 case DT_SONAME: return "SONAME";
628 case DT_RPATH: return "RPATH";
629 case DT_SYMBOLIC: return "SYMBOLIC";
630 case DT_REL: return "REL";
631 case DT_RELSZ: return "RELSZ";
632 case DT_RELENT: return "RELENT";
633 case DT_PLTREL: return "PLTREL";
634 case DT_DEBUG: return "DEBUG";
635 case DT_TEXTREL: return "TEXTREL";
636 case DT_JMPREL: return "JMPREL";
637 case DT_VERDEF: return "VERDEF";
638 case DT_VERDEFNUM: return "VERDEFNUM";
639 case DT_VERNEED: return "VERNEED";
640 case DT_VERNEEDNUM: return "VERNEEDNUM";
641 case DT_VERSYM: return "VERSYN";
642 case DT_AUXILIARY: return "AUXILARY";
643 case DT_FILTER: return "FILTER";
644 case DT_POSFLAG_1: return "POSFLAG_1";
645 case DT_SYMINSZ: return "SYMINSZ";
646 case DT_SYMINENT: return "SYMINENT";
647 case DT_SYMINFO: return "SYMINFO";
648 case DT_RELACOUNT: return "RELACOUNT";
649 case DT_RELCOUNT: return "RELCOUNT";
650 case DT_FLAGS_1: return "FLAGS_1";
651 case DT_USED: return "USED";
654 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
656 const char *result = NULL;
657 switch (elf_header.e_machine)
661 result = get_mips_dynamic_type (type);
666 sprintf (buff, _("Processor Specific"), type);
672 sprintf (buff, _("<unknown>: %x"), type);
678 get_file_type (e_type)
681 static char buff [32];
685 case ET_NONE: return _("NONE (None)");
686 case ET_REL: return _("REL (Relocatable file)");
687 case ET_EXEC: return _("EXEC (Executable file)");
688 case ET_DYN: return _("DYN (Shared object file)");
689 case ET_CORE: return _("CORE (Core file)");
692 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
693 sprintf (buff, _("Processor Specific: (%x)"), e_type);
695 sprintf (buff, _("<unknown>: %x"), e_type);
701 get_machine_name (e_machine)
704 static char buff [32];
708 case EM_NONE: return _("None");
709 case EM_M32: return "WE32100";
710 case EM_SPARC: return "Sparc";
711 case EM_386: return "Intel 80386";
712 case EM_68K: return "MC68000";
713 case EM_88K: return "MC88000";
714 case EM_486: return "Intel 80486";
715 case EM_860: return "Intel 80860";
716 case EM_MIPS: return "MIPS R3000 big-endian";
717 case EM_S370: return "Amdahl";
718 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
719 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
720 case EM_PARISC: return "HPPA";
721 case EM_PPC_OLD: return "Power PC (old)";
722 case EM_SPARC32PLUS: return "Sparc v8+" ;
723 case EM_960: return "Intel 90860";
724 case EM_PPC: return "PowerPC";
725 case EM_V800: return "NEC V800";
726 case EM_FR20: return "Fujitsu FR20";
727 case EM_RH32: return "TRW RH32";
728 case EM_MMA: return "Fujitsu MMA";
729 case EM_ARM: return "ARM";
730 case EM_OLD_ALPHA: return "Digital Alpha (old)";
731 case EM_SH: return "Hitachi SH";
732 case EM_SPARCV9: return "Sparc v9";
733 case EM_ALPHA: return "Alpha";
734 case EM_CYGNUS_D10V: return "d10v";
735 case EM_CYGNUS_D30V: return "d30v";
736 case EM_CYGNUS_ARC: return "Arc";
737 case EM_CYGNUS_M32R: return "M32r";
738 case EM_CYGNUS_V850: return "v850";
739 case EM_CYGNUS_MN10300: return "mn10300";
740 case EM_CYGNUS_MN10200: return "mn10200";
741 case EM_CYGNUS_FR30: return "FR30";
744 sprintf (buff, _("<unknown>: %x"), e_machine);
750 get_machine_flags (e_flags, e_machine)
754 static char buf [1024];
765 if (e_flags & EF_PPC_EMB)
766 strcat (buf, ", emb");
768 if (e_flags & EF_PPC_RELOCATABLE)
769 strcat (buf, ", relocatable");
771 if (e_flags & EF_PPC_RELOCATABLE_LIB)
772 strcat (buf, ", relocatable-lib");
776 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
777 strcat (buf, ", m32r");
779 /* start-sanitize-m32rx */
781 if ((e_flags & EF_M32R_ARCH) == E_M32RX_ARCH)
782 strcat (buf, ", m32rx");
784 /* end-sanitize-m32rx */
789 if (e_flags & EF_MIPS_NOREORDER)
790 strcat (buf, ", noreorder");
792 if (e_flags & EF_MIPS_PIC)
793 strcat (buf, ", pic");
795 if (e_flags & EF_MIPS_CPIC)
796 strcat (buf, ", cpic");
798 if (e_flags & EF_MIPS_ABI2)
799 strcat (buf, ", abi2");
801 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
802 strcat (buf, ", mips1");
804 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
805 strcat (buf, ", mips2");
807 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
808 strcat (buf, ", mips3");
810 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
811 strcat (buf, ", mips4");
820 get_machine_data (e_data)
823 static char buff [32];
827 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
828 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
830 sprintf (buff, _("<unknown>: %x"), e_data);
836 get_mips_segment_type (type)
841 case PT_MIPS_REGINFO:
845 case PT_MIPS_OPTIONS:
855 get_segment_type (p_type)
856 unsigned long p_type;
858 static char buff [32];
862 case PT_NULL: return "NULL";
863 case PT_LOAD: return "LOAD";
864 case PT_DYNAMIC: return "DYNAMIC";
865 case PT_INTERP: return "INTERP";
866 case PT_NOTE: return "NOTE";
867 case PT_SHLIB: return "SHLIB";
868 case PT_PHDR: return "PHDR";
871 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
874 switch (elf_header.e_machine)
878 result = get_mips_segment_type (p_type);
886 sprintf (buff, "LOPROC+%d", p_type - PT_LOPROC);
893 sprintf (buff, _("<unknown>: %x"), p_type);
900 get_mips_section_type_name (sh_type)
901 unsigned int sh_type;
905 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
906 case SHT_MIPS_MSYM: return "MIPS_MSYM";
907 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
908 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
909 case SHT_MIPS_UCODE: return "MIPS_UCODE";
910 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
911 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
912 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
913 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
914 case SHT_MIPS_RELD: return "MIPS_RELD";
915 case SHT_MIPS_IFACE: return "MIPS_IFACE";
916 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
917 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
918 case SHT_MIPS_SHDR: return "MIPS_SHDR";
919 case SHT_MIPS_FDESC: return "MIPS_FDESC";
920 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
921 case SHT_MIPS_DENSE: return "MIPS_DENSE";
922 case SHT_MIPS_PDESC: return "MIPS_PDESC";
923 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
924 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
925 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
926 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
927 case SHT_MIPS_LINE: return "MIPS_LINE";
928 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
929 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
930 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
931 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
932 case SHT_MIPS_DWARF: return "MIPS_DWARF";
933 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
934 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
935 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
936 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
937 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
938 case SHT_MIPS_XLATE: return "MIPS_XLATE";
939 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
940 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
941 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
942 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
943 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
951 get_section_type_name (sh_type)
952 unsigned int sh_type;
954 static char buff [32];
958 case SHT_NULL: return "NULL";
959 case SHT_PROGBITS: return "PROGBITS";
960 case SHT_SYMTAB: return "SYMTAB";
961 case SHT_STRTAB: return "STRTAB";
962 case SHT_RELA: return "RELA";
963 case SHT_HASH: return "HASH";
964 case SHT_DYNAMIC: return "DYNAMIC";
965 case SHT_NOTE: return "NOTE";
966 case SHT_NOBITS: return "NOBITS";
967 case SHT_REL: return "REL";
968 case SHT_SHLIB: return "SHLIB";
969 case SHT_DYNSYM: return "DYNSYM";
970 case SHT_GNU_verdef: return "VERDEF";
971 case SHT_GNU_verneed: return "VERNEED";
972 case SHT_GNU_versym: return "VERSYM";
973 case 0x6ffffff0: return "VERSYM";
974 case 0x6ffffffc: return "VERDEF";
975 case 0x7ffffffd: return "AUXILIARY";
976 case 0x7fffffff: return "FILTER";
979 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
983 switch (elf_header.e_machine)
987 result = get_mips_section_type_name (sh_type);
996 sprintf (buff, _("SHT_LOPROC+%d"), sh_type - SHT_LOPROC);
1001 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1002 sprintf (buff, _("SHT_LOUSER+%d"), sh_type - SHT_LOUSER);
1004 sprintf (buff, _("<unknown>: %x"), sh_type);
1009 struct option options [] =
1011 {"all", no_argument, 0, 'a'},
1012 {"file-header", no_argument, 0, 'h'},
1013 {"program-headers", no_argument, 0, 'l'},
1014 {"headers", no_argument, 0, 'e'},
1015 {"histogram", no_argument, & do_histogram, 1},
1016 {"segments", no_argument, 0, 'l'},
1017 {"sections", no_argument, 0, 'S'},
1018 {"section-headers", no_argument, 0, 'S'},
1019 {"symbols", no_argument, 0, 's'},
1020 {"syms", no_argument, 0, 's'},
1021 {"relocs", no_argument, 0, 'r'},
1022 {"dynamic", no_argument, 0, 'd'},
1023 {"version-info", no_argument, 0, 'V'},
1024 {"use-dynamic", no_argument, 0, 'D'},
1025 {"hex-dump", required_argument, 0, 'x'},
1026 {"debug-dump", optional_argument, 0, 'w'},
1027 #ifdef SUPPORT_DISASSEMBLY
1028 {"instruction-dump", required_argument, 0, 'i'},
1031 {"version", no_argument, 0, 'v'},
1032 {"help", no_argument, 0, 'H'},
1033 {0, no_argument, 0, 0}
1039 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1040 fprintf (stdout, _(" Options are:\n"));
1041 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1042 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1043 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1044 fprintf (stdout, _(" Display the program headers\n"));
1045 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1046 fprintf (stdout, _(" Display the sections' header\n"));
1047 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1048 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1049 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1050 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1051 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1052 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1053 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1054 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1055 fprintf (stdout, _(" -w[liap] or --debug-dump[=line,=info,=abbrev,=pubnames]\n"));
1056 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1057 #ifdef SUPPORT_DISASSEMBLY
1058 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1059 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1061 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1062 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1063 fprintf (stdout, _(" -H or --help Display this information\n"));
1064 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1070 parse_args (argc, argv)
1079 while ((c = getopt_long
1080 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1110 do_using_dynamic ++;
1132 section = strtoul (optarg, & cp, 0);
1133 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1135 dump_sects [section] |= HEX_DUMP;
1155 do_debug_abbrevs = 1;
1165 do_debug_pubnames = 1;
1169 warn (_("Unrecognised debug option '%s'\n"), optarg);
1174 #ifdef SUPPORT_DISASSEMBLY
1177 section = strtoul (optarg, & cp, 0);
1178 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1180 dump_sects [section] |= DISASS_DUMP;
1186 print_version (program_name);
1193 /* xgettext:c-format */
1194 error (_("Invalid option '-%c'\n"), c);
1201 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1202 && !do_segments && !do_header && !do_dump && !do_version
1203 && !do_histogram && !do_debugging)
1207 warn (_("Nothing to do.\n"));
1212 /* Decode the data held in 'elf_header'. */
1214 process_file_header ()
1216 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1217 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1218 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1219 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1222 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1226 binary_class = elf_header.e_ident [EI_CLASS];
1227 if (binary_class != ELFCLASS32)
1229 error (_("Not a 32 bit ELF file\n"));
1237 printf (_("ELF Header:\n"));
1238 printf (_(" Magic: "));
1239 for (i = 0; i < EI_NIDENT; i ++)
1240 printf ("%2.2x ", elf_header.e_ident [i]);
1242 printf (_(" Type: %s\n"),
1243 get_file_type (elf_header.e_type));
1244 printf (_(" Machine: %s\n"),
1245 get_machine_name (elf_header.e_machine));
1246 printf (_(" Version: 0x%lx\n"),
1247 (unsigned long) elf_header.e_version);
1248 printf (_(" Data: %s\n"),
1249 get_machine_data (elf_header.e_ident [EI_DATA]));
1250 printf (_(" Entry point address: 0x%lx\n"),
1251 (unsigned long) elf_header.e_entry);
1252 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1253 (long) elf_header.e_phoff);
1254 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1255 (long) elf_header.e_shoff);
1256 printf (_(" Flags: 0x%lx%s\n"),
1257 (unsigned long) elf_header.e_flags,
1258 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1259 printf (_(" Size of this header: %ld (bytes)\n"),
1260 (long) elf_header.e_ehsize);
1261 printf (_(" Size of program headers: %ld (bytes)\n"),
1262 (long) elf_header.e_phentsize);
1263 printf (_(" Number of program headers: %ld\n"),
1264 (long) elf_header.e_phnum);
1265 printf (_(" Size of section headers: %ld (bytes)\n"),
1266 (long) elf_header.e_shentsize);
1267 printf (_(" Number of section headers: %ld\n"),
1268 (long) elf_header.e_shnum);
1269 printf (_(" Section header string table index: %ld\n"),
1270 (long) elf_header.e_shstrndx);
1278 process_program_headers (file)
1281 Elf32_External_Phdr * phdrs;
1282 Elf32_Internal_Phdr * program_headers;
1283 Elf32_Internal_Phdr * segment;
1286 if (elf_header.e_phnum == 0)
1289 printf (_("\nThere are no program headers in this file.\n"));
1293 if (do_segments && !do_header)
1295 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1296 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1297 printf (_("There are %d program headers, starting at offset %lx:\n"),
1298 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1301 GET_DATA_ALLOC (elf_header.e_phoff,
1302 elf_header.e_phentsize * elf_header.e_phnum,
1303 phdrs, Elf32_External_Phdr *, "program headers");
1305 program_headers = (Elf32_Internal_Phdr *) malloc
1306 (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
1308 if (program_headers == NULL)
1310 error (_("Out of memory\n"));
1314 for (i = 0, segment = program_headers;
1315 i < elf_header.e_phnum;
1318 segment->p_type = BYTE_GET (phdrs[i].p_type);
1319 segment->p_offset = BYTE_GET (phdrs[i].p_offset);
1320 segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
1321 segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
1322 segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
1323 segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
1324 segment->p_flags = BYTE_GET (phdrs[i].p_flags);
1325 segment->p_align = BYTE_GET (phdrs[i].p_align);
1333 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1335 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1341 for (i = 0, segment = program_headers;
1342 i < elf_header.e_phnum;
1347 printf (" %-11.11s ", get_segment_type (segment->p_type));
1348 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1349 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1350 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1351 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1352 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1354 (segment->p_flags & PF_R ? 'R' : ' '),
1355 (segment->p_flags & PF_W ? 'W' : ' '),
1356 (segment->p_flags & PF_X ? 'E' : ' '));
1357 printf ("%#lx", (unsigned long) segment->p_align);
1360 switch (segment->p_type)
1364 loadaddr = (segment->p_vaddr & 0xfffff000)
1365 - (segment->p_offset & 0xfffff000);
1370 error (_("more than one dynamic segment\n"));
1372 dynamic_addr = segment->p_offset;
1373 dynamic_size = segment->p_filesz;
1377 if (fseek (file, segment->p_offset, SEEK_SET))
1378 error (_("Unable to find program interpreter name\n"));
1381 program_interpreter[0] = 0;
1382 fscanf (file, "%63s", program_interpreter);
1385 printf (_("\n [Requesting program interpreter: %s]"),
1386 program_interpreter);
1392 putc ('\n', stdout);
1401 if (do_segments && section_headers != NULL)
1403 printf (_("\n Section to Segment mapping:\n"));
1404 printf (_(" Segment Sections...\n"));
1406 assert (string_table != NULL);
1408 for (i = 0; i < elf_header.e_phnum; i++)
1411 Elf32_Internal_Shdr * section;
1413 segment = program_headers + i;
1414 section = section_headers;
1416 printf (" %2.2d ", i);
1418 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1420 if (section->sh_size > 0
1421 /* Compare allocated sections by VMA, unallocated
1422 sections by file offset. */
1423 && (section->sh_flags & SHF_ALLOC
1424 ? (section->sh_addr >= segment->p_vaddr
1425 && section->sh_addr + section->sh_size
1426 <= segment->p_vaddr + segment->p_memsz)
1427 : (section->sh_offset >= segment->p_offset
1428 && (section->sh_offset + section->sh_size
1429 <= segment->p_offset + segment->p_filesz))))
1430 printf ("%s ", SECTION_NAME (section));
1437 free (program_headers);
1444 get_section_headers (file)
1447 Elf32_External_Shdr * shdrs;
1448 Elf32_Internal_Shdr * internal;
1451 GET_DATA_ALLOC (elf_header.e_shoff,
1452 elf_header.e_shentsize * elf_header.e_shnum,
1453 shdrs, Elf32_External_Shdr *, "section headers");
1455 section_headers = (Elf32_Internal_Shdr *) malloc
1456 (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
1458 if (section_headers == NULL)
1460 error (_("Out of memory\n"));
1464 for (i = 0, internal = section_headers;
1465 i < elf_header.e_shnum;
1468 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1469 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1470 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1471 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1472 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1473 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1474 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1475 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1476 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1477 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1485 static Elf_Internal_Sym *
1486 get_elf_symbols (file, offset, number)
1488 unsigned long offset;
1489 unsigned long number;
1491 Elf32_External_Sym * esyms;
1492 Elf_Internal_Sym * isyms;
1493 Elf_Internal_Sym * psym;
1496 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1497 esyms, Elf32_External_Sym *, "symbols");
1499 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1503 error (_("Out of memory\n"));
1509 for (j = 0, psym = isyms;
1513 psym->st_name = BYTE_GET (esyms[j].st_name);
1514 psym->st_value = BYTE_GET (esyms[j].st_value);
1515 psym->st_size = BYTE_GET (esyms[j].st_size);
1516 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1517 psym->st_info = BYTE_GET (esyms[j].st_info);
1518 psym->st_other = BYTE_GET (esyms[j].st_other);
1527 process_section_headers (file)
1530 Elf32_Internal_Shdr * section;
1533 section_headers = NULL;
1535 if (elf_header.e_shnum == 0)
1538 printf (_("\nThere are no sections in this file.\n"));
1543 if (do_sections && !do_header)
1544 printf (_("There are %d section headers, starting at offset %x:\n"),
1545 elf_header.e_shnum, elf_header.e_shoff);
1547 if (! get_section_headers (file))
1550 /* Read in the string table, so that we have names to display. */
1551 section = section_headers + elf_header.e_shstrndx;
1553 if (section->sh_size != 0)
1555 unsigned long string_table_offset;
1557 string_table_offset = section->sh_offset;
1559 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1560 string_table, char *, "string table");
1563 /* Scan the sections for the dynamic symbol table
1564 and dynamic string table and debug sections. */
1565 dynamic_symbols = NULL;
1566 dynamic_strings = NULL;
1567 dynamic_syminfo = NULL;
1568 for (i = 0, section = section_headers;
1569 i < elf_header.e_shnum;
1572 char * name = SECTION_NAME (section);
1574 if (section->sh_type == SHT_DYNSYM)
1576 if (dynamic_symbols != NULL)
1578 error (_("File contains multiple dynamic symbol tables\n"));
1582 dynamic_symbols = get_elf_symbols
1583 (file, section->sh_offset,
1584 section->sh_size / section->sh_entsize);
1586 else if (section->sh_type == SHT_STRTAB
1587 && strcmp (name, ".dynstr") == 0)
1589 if (dynamic_strings != NULL)
1591 error (_("File contains multiple dynamic string tables\n"));
1595 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1596 dynamic_strings, char *, "dynamic strings");
1598 else if ((do_debugging || do_debug_info || do_debug_abbrevs
1599 || do_debug_lines || do_debug_pubnames)
1600 && strncmp (name, ".debug_", 7) == 0)
1605 || (do_debug_info && (strcmp (name, "info") == 0))
1606 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
1607 || (do_debug_lines && (strcmp (name, "line") == 0))
1608 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
1610 dump_sects [i] |= DEBUG_DUMP;
1617 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1619 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1621 for (i = 0, section = section_headers;
1622 i < elf_header.e_shnum;
1625 printf (" [%2d] %-17.17s %-15.15s ",
1627 SECTION_NAME (section),
1628 get_section_type_name (section->sh_type));
1630 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1631 (unsigned long) section->sh_addr,
1632 (unsigned long) section->sh_offset,
1633 (unsigned long) section->sh_size,
1634 (unsigned long) section->sh_entsize);
1636 printf (" %c%c%c %2ld %3lx %ld\n",
1637 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1638 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1639 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1640 (unsigned long) section->sh_link,
1641 (unsigned long) section->sh_info,
1642 (unsigned long) section->sh_addralign);
1648 /* Process the reloc section. */
1650 process_relocs (file)
1653 unsigned long rel_size;
1654 unsigned long rel_offset;
1660 if (do_using_dynamic)
1665 if (dynamic_info[DT_REL])
1667 rel_offset = dynamic_info[DT_REL];
1668 rel_size = dynamic_info[DT_RELSZ];
1670 else if (dynamic_info [DT_RELA])
1672 rel_offset = dynamic_info[DT_RELA];
1673 rel_size = dynamic_info[DT_RELASZ];
1675 else if (dynamic_info[DT_JMPREL])
1677 rel_offset = dynamic_info[DT_JMPREL];
1678 rel_size = dynamic_info[DT_PLTRELSZ];
1684 (_("\nRelocation section at offset 0x%x contains %d bytes:\n"),
1685 rel_offset, rel_size);
1687 dump_relocations (file, rel_offset - loadaddr, rel_size,
1688 dynamic_symbols, dynamic_strings);
1691 printf (_("\nThere are no dynamic relocations in this file.\n"));
1695 Elf32_Internal_Shdr * section;
1699 for (i = 0, section = section_headers;
1700 i < elf_header.e_shnum;
1703 if ( section->sh_type != SHT_RELA
1704 && section->sh_type != SHT_REL)
1707 rel_offset = section->sh_offset;
1708 rel_size = section->sh_size;
1712 Elf32_Internal_Shdr * strsec;
1713 Elf32_Internal_Shdr * symsec;
1714 Elf_Internal_Sym * symtab;
1717 printf (_("\nRelocation section "));
1719 if (string_table == NULL)
1720 printf ("%d", section->sh_name);
1722 printf ("'%s'", SECTION_NAME (section));
1724 printf (_(" at offset 0x%x contains %d entries:\n"),
1725 rel_offset, rel_size / section->sh_entsize);
1727 symsec = section_headers + section->sh_link;
1729 symtab = get_elf_symbols (file, symsec->sh_offset,
1730 symsec->sh_size / symsec->sh_entsize);
1735 strsec = section_headers + symsec->sh_link;
1737 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1738 char *, "string table");
1740 dump_relocations (file, rel_offset, rel_size, symtab, strtab);
1750 printf (_("\nThere are no relocations in this file.\n"));
1758 dynamic_segment_mips_val (entry)
1759 Elf_Internal_Dyn *entry;
1762 switch (entry->d_tag)
1765 if (entry->d_un.d_val == 0)
1769 static const char *opts[] =
1771 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
1772 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
1773 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
1774 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
1779 for (cnt = 0; cnt < sizeof (opts) / sizeof (opts[0]); ++cnt)
1780 if (entry->d_un.d_val & (1 << cnt))
1782 printf ("%s%s", first ? "" : " ", opts[cnt]);
1789 case DT_MIPS_IVERSION:
1790 if (dynamic_strings != NULL)
1791 printf ("Interface Version: %s\n",
1792 dynamic_strings + entry->d_un.d_val);
1794 printf ("%#ld\n", (long) entry->d_un.d_ptr);
1797 case DT_MIPS_TIME_STAMP:
1800 time_t time = entry->d_un.d_val;
1801 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
1802 printf ("Time Stamp: %s\n", timebuf);
1806 case DT_MIPS_RLD_VERSION:
1807 case DT_MIPS_LOCAL_GOTNO:
1808 case DT_MIPS_CONFLICTNO:
1809 case DT_MIPS_LIBLISTNO:
1810 case DT_MIPS_SYMTABNO:
1811 case DT_MIPS_UNREFEXTNO:
1812 case DT_MIPS_HIPAGENO:
1813 case DT_MIPS_DELTA_CLASS_NO:
1814 case DT_MIPS_DELTA_INSTANCE_NO:
1815 case DT_MIPS_DELTA_RELOC_NO:
1816 case DT_MIPS_DELTA_SYM_NO:
1817 case DT_MIPS_DELTA_CLASSSYM_NO:
1818 case DT_MIPS_COMPACT_SIZE:
1819 printf ("%#ld\n", (long) entry->d_un.d_ptr);
1823 printf ("%#lx\n", (long) entry->d_un.d_ptr);
1827 /* Parse the dynamic segment */
1829 process_dynamic_segment (file)
1832 Elf_Internal_Dyn * entry;
1833 Elf32_External_Dyn * edyn;
1836 if (dynamic_size == 0)
1839 printf (_("\nThere is no dynamic segment in this file.\n"));
1844 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
1845 edyn, Elf32_External_Dyn *, "dynamic segment");
1847 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
1848 how large .dynamic is now. We can do this even before the byte
1849 swapping since the DT_NULL tag is recognizable. */
1851 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
1854 dynamic_segment = (Elf_Internal_Dyn *)
1855 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
1857 if (dynamic_segment == NULL)
1859 error (_("Out of memory\n"));
1864 for (i = 0, entry = dynamic_segment;
1868 entry->d_tag = BYTE_GET (edyn [i].d_tag);
1869 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
1874 /* Find the appropriate symbol table. */
1875 if (dynamic_symbols == NULL)
1877 for (i = 0, entry = dynamic_segment;
1881 unsigned long offset;
1884 if (entry->d_tag != DT_SYMTAB)
1887 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
1889 /* Since we do not know how big the symbol table is,
1890 we default to reading in the entire file (!) and
1891 processing that. This is overkill, I know, but it
1894 offset = entry->d_un.d_val - loadaddr;
1896 if (fseek (file, 0, SEEK_END))
1897 error (_("Unable to seek to end of file!"));
1899 num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
1903 error (_("Unable to determine the number of symbols to load\n"));
1907 dynamic_symbols = get_elf_symbols (file, offset, num_syms);
1911 /* Similarly find a string table. */
1912 if (dynamic_strings == NULL)
1914 for (i = 0, entry = dynamic_segment;
1918 unsigned long offset;
1921 if (entry->d_tag != DT_STRTAB)
1924 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
1926 /* Since we do not know how big the string table is,
1927 we default to reading in the entire file (!) and
1928 processing that. This is overkill, I know, but it
1931 offset = entry->d_un.d_val - loadaddr;
1932 if (fseek (file, 0, SEEK_END))
1933 error (_("Unable to seek to end of file\n"));
1934 str_tab_len = ftell (file) - offset;
1936 if (str_tab_len < 1)
1939 (_("Unable to determine the length of the dynamic string table\n"));
1943 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
1944 "dynamic string table");
1950 /* And find the syminfo section if available. */
1951 if (dynamic_syminfo == NULL)
1953 unsigned int syminsz = 0;
1955 for (i = 0, entry = dynamic_segment;
1959 if (entry->d_tag == DT_SYMINENT)
1960 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
1961 else if (entry->d_tag == DT_SYMINSZ)
1962 syminsz = entry->d_un.d_val;
1963 else if (entry->d_tag == DT_SYMINFO)
1964 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
1967 if (dynamic_syminfo_offset != 0 && syminsz != 0)
1969 Elf_External_Syminfo *extsyminfo;
1970 Elf_Internal_Syminfo *syminfo;
1972 /* There is a syminfo section. Read the data. */
1973 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
1974 Elf_External_Syminfo *, "symbol information");
1976 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
1977 if (dynamic_syminfo == NULL)
1979 error (_("Out of memory\n"));
1983 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
1984 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
1987 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
1988 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
1995 if (do_dynamic && dynamic_addr)
1996 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
1997 dynamic_addr, dynamic_size);
1999 printf (_(" Tag Type Name/Value\n"));
2001 for (i = 0, entry = dynamic_segment;
2006 printf (_(" 0x%-8.8lx (%s)%*s"),
2007 (unsigned long) entry->d_tag,
2008 get_dynamic_type (entry->d_tag),
2009 27 - strlen (get_dynamic_type (entry->d_tag)),
2012 switch (entry->d_tag)
2018 if (entry->d_tag == DT_AUXILIARY)
2019 printf (_("Auxiliary library"));
2021 printf (_("Filter library"));
2023 if (dynamic_strings)
2024 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2026 printf (": %#lx\n", (long) entry->d_un.d_val);
2033 printf (_("Flags:"));
2034 if (entry->d_un.d_val == 0)
2035 printf (_(" None\n"));
2038 if (entry->d_un.d_val & DF_P1_LAZYLOAD)
2039 printf (" LAZYLOAD");
2040 if (entry->d_un.d_val & DF_P1_LAZYLOAD)
2041 printf (" GROUPPERM");
2050 printf (_("Flags:"));
2051 if (entry->d_un.d_val == 0)
2052 printf (_(" None\n"));
2055 if (entry->d_un.d_val & DF_1_NOW)
2057 if (entry->d_un.d_val & DF_1_GLOBAL)
2059 if (entry->d_un.d_val & DF_1_GROUP)
2061 if (entry->d_un.d_val & DF_1_NODELETE)
2062 printf (" NODELETE");
2063 if (entry->d_un.d_val & DF_1_LOADFLTR)
2064 printf (" LOADFLTR");
2065 if (entry->d_un.d_val & DF_1_INITFIRST)
2066 printf (" INITFIRST");
2067 if (entry->d_un.d_val & DF_1_NOOPEN)
2069 if (entry->d_un.d_val & DF_1_ORIGIN)
2071 if (entry->d_un.d_val & DF_1_DIRECT)
2073 if (entry->d_un.d_val & DF_1_TRANS)
2075 if (entry->d_un.d_val & DF_1_INTERPOSE)
2076 printf (" INTERPOSE");
2083 puts (get_dynamic_type (entry->d_un.d_val));
2102 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2108 if (dynamic_strings == NULL)
2111 name = dynamic_strings + entry->d_un.d_val;
2115 switch (entry->d_tag)
2118 printf (_("Shared library: [%s]"), name);
2120 if (strcmp (name, program_interpreter))
2123 printf (_(" program interpreter\n"));
2127 printf (_("Library soname: [%s]\n"), name);
2131 printf (_("Library rpath: [%s]\n"), name);
2135 printf ("%#lx\n", (long) entry->d_un.d_val);
2139 printf ("%#lx\n", (long) entry->d_un.d_val);
2151 printf ("%ld (bytes)\n", entry->d_un.d_val);
2159 printf ("%ld\n", entry->d_un.d_val);
2170 if (dynamic_strings == NULL)
2173 name = dynamic_strings + entry->d_un.d_val;
2179 switch (entry->d_tag)
2182 printf (_("Not needed object: [%s]\n"), name);
2186 printf ("%#lx\n", (long) entry->d_un.d_val);
2190 printf ("%#lx\n", (long) entry->d_un.d_val);
2195 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2197 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2201 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2204 switch (elf_header.e_machine)
2207 case EM_MIPS_RS4_BE:
2208 dynamic_segment_mips_val (entry);
2212 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2222 get_ver_flags (flags)
2225 static char buff [32];
2232 if (flags & VER_FLG_BASE)
2233 strcat (buff, "BASE ");
2235 if (flags & VER_FLG_WEAK)
2237 if (flags & VER_FLG_BASE)
2238 strcat (buff, "| ");
2240 strcat (buff, "WEAK ");
2243 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2244 strcat (buff, "| <unknown>");
2249 /* Display the contents of the version sections. */
2251 process_version_sections (file)
2254 Elf32_Internal_Shdr * section;
2261 for (i = 0, section = section_headers;
2262 i < elf_header.e_shnum;
2265 switch (section->sh_type)
2267 case SHT_GNU_verdef:
2269 Elf_External_Verdef * edefs;
2276 (_("\nVersion definition section '%s' contains %d entries:\n"),
2277 SECTION_NAME (section), section->sh_info);
2279 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2280 section->sh_addr, section->sh_offset, section->sh_link,
2281 SECTION_NAME (section_headers + section->sh_link));
2283 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2284 edefs, Elf_External_Verdef *,
2285 "version definition section");
2287 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2290 Elf_External_Verdef * edef;
2291 Elf_Internal_Verdef ent;
2292 Elf_External_Verdaux * eaux;
2293 Elf_Internal_Verdaux aux;
2297 vstart = ((char *) edefs) + idx;
2299 edef = (Elf_External_Verdef *) vstart;
2301 ent.vd_version = BYTE_GET (edef->vd_version);
2302 ent.vd_flags = BYTE_GET (edef->vd_flags);
2303 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2304 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2305 ent.vd_hash = BYTE_GET (edef->vd_hash);
2306 ent.vd_aux = BYTE_GET (edef->vd_aux);
2307 ent.vd_next = BYTE_GET (edef->vd_next);
2309 printf (_(" %#06x: Rev: %d Flags: %s"),
2310 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2312 printf (_(" Index: %ld Cnt: %ld "),
2313 ent.vd_ndx, ent.vd_cnt);
2315 vstart += ent.vd_aux;
2317 eaux = (Elf_External_Verdaux *) vstart;
2319 aux.vda_name = BYTE_GET (eaux->vda_name);
2320 aux.vda_next = BYTE_GET (eaux->vda_next);
2322 if (dynamic_strings)
2323 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2325 printf (_("Name index: %ld\n"), aux.vda_name);
2327 isum = idx + ent.vd_aux;
2329 for (j = 1; j < ent.vd_cnt; j ++)
2331 isum += aux.vda_next;
2332 vstart += aux.vda_next;
2334 eaux = (Elf_External_Verdaux *) vstart;
2336 aux.vda_name = BYTE_GET (eaux->vda_name);
2337 aux.vda_next = BYTE_GET (eaux->vda_next);
2339 if (dynamic_strings)
2340 printf (_(" %#06x: Parent %d: %s\n"),
2341 isum, j, dynamic_strings + aux.vda_name);
2343 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2344 isum, j, aux.vda_name);
2354 case SHT_GNU_verneed:
2356 Elf_External_Verneed * eneed;
2362 printf (_("\nVersion needs section '%s' contains %d entries:\n"),
2363 SECTION_NAME (section), section->sh_info);
2366 (_(" Addr: %#08x Offset: %#08x Link to section: %d (%s)\n"),
2367 section->sh_addr, section->sh_offset, section->sh_link,
2368 SECTION_NAME (section_headers + section->sh_link));
2370 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2371 eneed, Elf_External_Verneed *,
2372 "version need section");
2374 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2376 Elf_External_Verneed * entry;
2377 Elf_Internal_Verneed ent;
2382 vstart = ((char *) eneed) + idx;
2384 entry = (Elf_External_Verneed *) vstart;
2386 ent.vn_version = BYTE_GET (entry->vn_version);
2387 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
2388 ent.vn_file = BYTE_GET (entry->vn_file);
2389 ent.vn_aux = BYTE_GET (entry->vn_aux);
2390 ent.vn_next = BYTE_GET (entry->vn_next);
2392 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
2394 if (dynamic_strings)
2395 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
2397 printf (_(" File: %lx"), ent.vn_file);
2399 printf (_(" Cnt: %d\n"), ent.vn_cnt);
2401 vstart += ent.vn_aux;
2403 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
2405 Elf_External_Vernaux * eaux;
2406 Elf_Internal_Vernaux aux;
2408 eaux = (Elf_External_Vernaux *) vstart;
2410 aux.vna_hash = BYTE_GET (eaux->vna_hash);
2411 aux.vna_flags = BYTE_GET (eaux->vna_flags);
2412 aux.vna_other = BYTE_GET (eaux->vna_other);
2413 aux.vna_name = BYTE_GET (eaux->vna_name);
2414 aux.vna_next = BYTE_GET (eaux->vna_next);
2416 if (dynamic_strings)
2417 printf (_(" %#06x: Name: %s"),
2418 isum, dynamic_strings + aux.vna_name);
2420 printf (_(" %#06x: Name index: %lx"),
2421 isum, aux.vna_name);
2423 printf (_(" Flags: %s Version: %d\n"),
2424 get_ver_flags (aux.vna_flags), aux.vna_other);
2426 isum += aux.vna_next;
2427 vstart += aux.vna_next;
2437 case SHT_GNU_versym:
2439 Elf32_Internal_Shdr * link_section;
2442 unsigned char * edata;
2443 unsigned short * data;
2445 Elf_Internal_Sym * symbols;
2446 Elf32_Internal_Shdr * string_sec;
2448 link_section = section_headers + section->sh_link;
2449 total = section->sh_size / section->sh_entsize;
2453 symbols = get_elf_symbols
2454 (file, link_section->sh_offset,
2455 link_section->sh_size / link_section->sh_entsize);
2457 string_sec = section_headers + link_section->sh_link;
2459 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2460 strtab, char *, "version string table");
2462 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2463 SECTION_NAME (section), total);
2465 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2466 section->sh_addr, section->sh_offset, section->sh_link,
2467 SECTION_NAME (link_section));
2469 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2471 total * sizeof (short), edata,
2472 char *, "version symbol data");
2474 data = (unsigned short *) malloc (total * sizeof (short));
2476 for (cnt = total; cnt --;)
2477 data [cnt] = byte_get (edata + cnt * sizeof (short),
2482 for (cnt = 0; cnt < total; cnt += 4)
2486 printf (" %03x:", cnt);
2488 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2489 switch (data [cnt + j])
2492 fputs (_(" 0 (*local*) "), stdout);
2496 fputs (_(" 1 (*global*) "), stdout);
2500 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
2501 data [cnt + j] & 0x8000 ? 'h' : ' ');
2503 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2504 && section_headers[symbols [cnt + j].st_shndx].sh_type
2507 /* We must test both. */
2508 Elf_Internal_Verneed ivn;
2509 unsigned long offset;
2511 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2516 Elf_External_Verneed evn;
2517 Elf_External_Vernaux evna;
2518 Elf_Internal_Vernaux ivna;
2519 unsigned long vna_off;
2521 GET_DATA (offset, evn, "version need");
2523 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2524 ivn.vn_next = BYTE_GET (evn.vn_next);
2526 vna_off = offset + ivn.vn_aux;
2530 GET_DATA (vna_off, evna,
2531 "version need aux (1)");
2533 ivna.vna_next = BYTE_GET (evna.vna_next);
2534 ivna.vna_other = BYTE_GET (evna.vna_other);
2536 vna_off += ivna.vna_next;
2538 while (ivna.vna_other != data [cnt + j]
2539 && ivna.vna_next != 0);
2541 if (ivna.vna_other == data [cnt + j])
2543 ivna.vna_name = BYTE_GET (evna.vna_name);
2545 nn += printf ("(%s%-*s",
2546 strtab + ivna.vna_name,
2552 else if (ivn.vn_next == 0)
2554 if (data [cnt + j] != 0x8001)
2556 Elf_Internal_Verdef ivd;
2557 Elf_External_Verdef evd;
2559 offset = version_info
2560 [DT_VERSIONTAGIDX (DT_VERDEF)]
2565 GET_DATA (offset, evd,
2566 "version definition");
2568 ivd.vd_next = BYTE_GET (evd.vd_next);
2569 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2571 offset += ivd.vd_next;
2574 != (data [cnt + j] & 0x7fff)
2575 && ivd.vd_next != 0);
2578 == (data [cnt + j] & 0x7fff))
2580 Elf_External_Verdaux evda;
2581 Elf_Internal_Verdaux ivda;
2583 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2585 GET_DATA (offset + ivd.vd_aux, evda,
2586 "version definition aux");
2589 BYTE_GET (evda.vda_name);
2593 strtab + ivda.vda_name,
2604 offset += ivn.vn_next;
2606 while (ivn.vn_next);
2608 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2610 Elf_Internal_Verneed ivn;
2611 unsigned long offset;
2613 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2618 Elf_Internal_Vernaux ivna;
2619 Elf_External_Verneed evn;
2620 Elf_External_Vernaux evna;
2621 unsigned long a_off;
2623 GET_DATA (offset, evn, "version need");
2625 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2626 ivn.vn_next = BYTE_GET (evn.vn_next);
2628 a_off = offset + ivn.vn_aux;
2632 GET_DATA (a_off, evna,
2633 "version need aux (2)");
2635 ivna.vna_next = BYTE_GET (evna.vna_next);
2636 ivna.vna_other = BYTE_GET (evna.vna_other);
2638 a_off += ivna.vna_next;
2640 while (ivna.vna_other != data [cnt + j]
2641 && ivna.vna_next != 0);
2643 if (ivna.vna_other == data [cnt + j])
2645 ivna.vna_name = BYTE_GET (evna.vna_name);
2647 nn += printf ("(%s%-*s",
2648 strtab + ivna.vna_name,
2655 offset += ivn.vn_next;
2657 while (ivn.vn_next);
2659 else if (data [cnt + j] != 0x8001)
2661 Elf_Internal_Verdef ivd;
2662 Elf_External_Verdef evd;
2663 unsigned long offset;
2665 offset = version_info
2666 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2670 GET_DATA (offset, evd, "version def");
2672 ivd.vd_next = BYTE_GET (evd.vd_next);
2673 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2675 offset += ivd.vd_next;
2677 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
2678 && ivd.vd_next != 0);
2680 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
2682 Elf_External_Verdaux evda;
2683 Elf_Internal_Verdaux ivda;
2685 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2687 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
2688 evda, "version def aux");
2690 ivda.vda_name = BYTE_GET (evda.vda_name);
2692 nn += printf ("(%s%-*s",
2693 strtab + ivda.vda_name,
2701 printf ("%*c", 18 - nn, ' ');
2719 printf (_("\nNo version information found in this file.\n"));
2725 get_symbol_binding (binding)
2726 unsigned int binding;
2728 static char buff [32];
2732 case STB_LOCAL: return _("LOCAL");
2733 case STB_GLOBAL: return _("GLOBAL");
2734 case STB_WEAK: return _("WEAK");
2736 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
2737 sprintf (buff, _("<processor specific>: %d"), binding);
2739 sprintf (buff, _("<unknown>: %d"), binding);
2745 get_symbol_type (type)
2748 static char buff [32];
2752 case STT_NOTYPE: return _("NOTYPE");
2753 case STT_OBJECT: return _("OBJECT");
2754 case STT_FUNC: return _("FUNC");
2755 case STT_SECTION: return _("SECTION");
2756 case STT_FILE: return _("FILE");
2758 if (type >= STT_LOPROC && type <= STT_HIPROC)
2759 sprintf (buff, _("<processor specific>: %d"), type);
2761 sprintf (buff, _("<unknown>: %d"), type);
2767 get_symbol_index_type (type)
2772 case SHN_UNDEF: return "UND";
2773 case SHN_ABS: return "ABS";
2774 case SHN_COMMON: return "COM";
2776 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
2778 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
2782 static char buff [32];
2784 sprintf (buff, "%3d", type);
2792 get_dynamic_data (file, number)
2794 unsigned int number;
2799 e_data = (char *) malloc (number * 4);
2803 error (_("Out of memory\n"));
2807 if (fread (e_data, 4, number, file) != number)
2809 error (_("Unable to read in dynamic data\n"));
2813 i_data = (int *) malloc (number * sizeof (* i_data));
2817 error (_("Out of memory\n"));
2823 i_data [number] = byte_get (e_data + number * 4, 4);
2830 /* Dump the symbol table */
2832 process_symbol_table (file)
2835 Elf32_Internal_Shdr * section;
2840 int * buckets = NULL;
2841 int * chains = NULL;
2843 if (! do_syms && !do_histogram)
2846 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
2849 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
2851 error (_("Unable to seek to start of dynamic information"));
2855 if (fread (& nb, sizeof (nb), 1, file) != 1)
2857 error (_("Failed to read in number of buckets\n"));
2861 if (fread (& nc, sizeof (nc), 1, file) != 1)
2863 error (_("Failed to read in number of chains\n"));
2867 nbuckets = byte_get (nb, 4);
2868 nchains = byte_get (nc, 4);
2870 buckets = get_dynamic_data (file, nbuckets);
2871 chains = get_dynamic_data (file, nchains);
2873 if (buckets == NULL || chains == NULL)
2878 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
2883 printf (_("\nSymbol table for image:\n"));
2884 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
2886 for (hn = 0; hn < nbuckets; hn++)
2891 for (si = buckets [hn]; si; si = chains [si])
2893 Elf_Internal_Sym * psym;
2895 psym = dynamic_symbols + si;
2897 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
2899 (unsigned long) psym->st_value,
2900 (unsigned long) psym->st_size,
2901 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
2902 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
2905 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
2907 printf (" %s\n", dynamic_strings + psym->st_name);
2911 else if (do_syms && !do_using_dynamic)
2915 for (i = 0, section = section_headers;
2916 i < elf_header.e_shnum;
2921 Elf_Internal_Sym * symtab;
2922 Elf_Internal_Sym * psym;
2925 if ( section->sh_type != SHT_SYMTAB
2926 && section->sh_type != SHT_DYNSYM)
2929 printf (_("\nSymbol table '%s' contains %d entries:\n"),
2930 SECTION_NAME (section),
2931 section->sh_size / section->sh_entsize);
2932 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
2935 symtab = get_elf_symbols (file, section->sh_offset,
2936 section->sh_size / section->sh_entsize);
2940 if (section->sh_link == elf_header.e_shstrndx)
2941 strtab = string_table;
2944 Elf32_Internal_Shdr * string_sec;
2946 string_sec = section_headers + section->sh_link;
2948 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2949 strtab, char *, "string table");
2952 for (si = 0, psym = symtab;
2953 si < section->sh_size / section->sh_entsize;
2956 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
2958 (unsigned long) psym->st_value,
2959 (unsigned long) psym->st_size,
2960 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
2961 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
2964 if (psym->st_shndx == 0)
2965 fputs (" UND", stdout);
2966 else if ((psym->st_shndx & 0xffff) == 0xfff1)
2967 fputs (" ABS", stdout);
2968 else if ((psym->st_shndx & 0xffff) == 0xfff2)
2969 fputs (" COM", stdout);
2971 printf ("%4x", psym->st_shndx);
2973 printf (" %s", strtab + psym->st_name);
2975 if (section->sh_type == SHT_DYNSYM &&
2976 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
2978 unsigned char data[2];
2979 unsigned short vers_data;
2980 unsigned long offset;
2984 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2987 GET_DATA (offset + si * sizeof (vers_data), data,
2990 vers_data = byte_get (data, 2);
2992 is_nobits = psym->st_shndx < SHN_LORESERVE ?
2993 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
2996 check_def = (psym->st_shndx != SHN_UNDEF);
2998 if ((vers_data & 0x8000) || vers_data > 1)
3000 if (is_nobits || ! check_def)
3002 Elf_External_Verneed evn;
3003 Elf_Internal_Verneed ivn;
3004 Elf_Internal_Vernaux ivna;
3006 /* We must test both. */
3007 offset = version_info
3008 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3010 GET_DATA (offset, evn, "version need");
3012 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3013 ivn.vn_next = BYTE_GET (evn.vn_next);
3017 unsigned long vna_off;
3019 vna_off = offset + ivn.vn_aux;
3023 Elf_External_Vernaux evna;
3025 GET_DATA (vna_off, evna,
3026 "version need aux (3)");
3028 ivna.vna_other = BYTE_GET (evna.vna_other);
3029 ivna.vna_next = BYTE_GET (evna.vna_next);
3030 ivna.vna_name = BYTE_GET (evna.vna_name);
3032 vna_off += ivna.vna_next;
3034 while (ivna.vna_other != vers_data
3035 && ivna.vna_next != 0);
3037 if (ivna.vna_other == vers_data)
3040 offset += ivn.vn_next;
3042 while (ivn.vn_next != 0);
3044 if (ivna.vna_other == vers_data)
3047 strtab + ivna.vna_name, ivna.vna_other);
3050 else if (! is_nobits)
3051 error (_("bad dynamic symbol"));
3058 if (vers_data != 0x8001)
3060 Elf_Internal_Verdef ivd;
3061 Elf_Internal_Verdaux ivda;
3062 Elf_External_Verdaux evda;
3063 unsigned long offset;
3066 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3071 Elf_External_Verdef evd;
3073 GET_DATA (offset, evd, "version def");
3075 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3076 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3077 ivd.vd_next = BYTE_GET (evd.vd_next);
3079 offset += ivd.vd_next;
3081 while (ivd.vd_ndx != (vers_data & 0x7fff)
3082 && ivd.vd_next != 0);
3084 offset -= ivd.vd_next;
3085 offset += ivd.vd_aux;
3087 GET_DATA (offset, evda, "version def aux");
3089 ivda.vda_name = BYTE_GET (evda.vda_name);
3091 if (psym->st_name != ivda.vda_name)
3092 printf ((vers_data & 0x8000)
3094 strtab + ivda.vda_name);
3104 if (strtab != string_table)
3110 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3112 if (do_histogram && buckets != NULL)
3119 int nzero_counts = 0;
3122 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3124 printf (_(" Length Number %% of total Coverage\n"));
3126 lengths = (int *) calloc (nbuckets, sizeof (int));
3127 if (lengths == NULL)
3129 error (_("Out of memory"));
3132 for (hn = 0; hn < nbuckets; ++hn)
3137 for (si = buckets[hn]; si; si = chains[si])
3140 if (maxlength < ++lengths[hn])
3145 counts = (int *) calloc (maxlength + 1, sizeof (int));
3148 error (_("Out of memory"));
3152 for (hn = 0; hn < nbuckets; ++hn)
3153 ++counts[lengths[hn]];
3155 printf (" 0 %-10d (%5.1f%%)\n",
3156 counts[0], (counts[0] * 100.0) / nbuckets);
3157 for (si = 1; si <= maxlength; ++si)
3159 nzero_counts += counts[si] * si;
3160 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3161 si, counts[si], (counts[si] * 100.0) / nbuckets,
3162 (nzero_counts * 100.0) / nsyms);
3169 if (buckets != NULL)
3179 process_syminfo (file)
3184 if (dynamic_syminfo == NULL
3186 /* No syminfo, this is ok. */
3189 /* There better should be a dynamic symbol section. */
3190 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3194 printf (_("\nDynamic info segment at offset 0x%x contains %d entries:\n"),
3195 dynamic_syminfo_offset, dynamic_syminfo_nent);
3197 printf (_(" Num: Name BoundTo Flags\n"));
3198 for (i = 0; i < dynamic_syminfo_nent; ++i)
3200 unsigned short int flags = dynamic_syminfo[i].si_flags;
3202 printf ("%4d: %-30s ", i,
3203 dynamic_strings + dynamic_symbols[i].st_name);
3205 switch (dynamic_syminfo[i].si_boundto)
3207 case SYMINFO_BT_SELF:
3208 fputs ("SELF ", stdout);
3210 case SYMINFO_BT_PARENT:
3211 fputs ("PARENT ", stdout);
3214 if (dynamic_syminfo[i].si_boundto > 0
3215 && dynamic_syminfo[i].si_boundto < dynamic_size)
3218 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3220 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3224 if (flags & SYMINFO_FLG_DIRECT)
3226 if (flags & SYMINFO_FLG_PASSTHRU)
3227 printf (" PASSTHRU");
3228 if (flags & SYMINFO_FLG_COPY)
3230 if (flags & SYMINFO_FLG_LAZYLOAD)
3231 printf (" LAZYLOAD");
3239 #ifdef SUPPORT_DISASSEMBLY
3241 disassemble_section (section, file)
3242 Elf32_Internal_Shdr * section;
3245 printf (_("\nAssembly dump of section %s\n"),
3246 SECTION_NAME (section));
3248 /* XXX -- to be done --- XXX */
3255 dump_section (section, file)
3256 Elf32_Internal_Shdr * section;
3261 unsigned char * data;
3264 bytes = section->sh_size;
3268 printf (_("\nSection '%s' has no data to dump.\n"),
3269 SECTION_NAME (section));
3273 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3275 addr = section->sh_addr;
3277 GET_DATA_ALLOC (section->sh_offset, bytes, start, char *,
3288 lbytes = (bytes > 16 ? 16 : bytes);
3290 printf (" 0x%8.8x ", addr);
3292 switch (elf_header.e_ident [EI_DATA])
3295 for (j = 15; j >= 0; j --)
3298 printf ("%2.2x", data [j]);
3308 for (j = 0; j < 16; j++)
3311 printf ("%2.2x", data [j]);
3321 for (j = 0; j < lbytes; j++)
3324 if (k >= ' ' && k < 0x80)
3343 static unsigned long int
3344 read_leb128 (data, length_return, sign)
3345 unsigned char * data;
3346 int * length_return;
3349 unsigned long int result = 0;
3350 unsigned int num_read = 0;
3359 result |= (byte & 0x7f) << shift;
3364 while (byte & 0x80);
3366 * length_return = num_read;
3368 if (sign && (shift < 32) && (byte & 0x40))
3369 result |= -1 << shift;
3376 process_extended_line_op (data, address)
3377 unsigned char * data;
3380 unsigned char op_code;
3383 unsigned char * orig_data = data;
3385 length = read_leb128 (data, & bytes_read, 0);
3387 length += bytes_read;
3389 op_code = * data ++;
3393 case DW_LNE_end_sequence:
3394 printf (_(" End Sequence\n\n"));
3397 case DW_LNE_set_address:
3398 /* XXX - assumption here that address size is 4! */
3399 * address = byte_get (data, 4);
3400 printf (_(" Set Address to %lx\n"), * address);
3403 case DW_LNE_define_file:
3404 printf (_(" Define File: %s"), data);
3405 data += strlen (data) + 1;
3406 printf (_(" Dir: %d"), read_leb128 (data, & bytes_read, 0));
3408 printf (_(" Time: %d"), read_leb128 (data, & bytes_read, 0));
3410 printf (_(" Size: %d"), read_leb128 (data, & bytes_read, 0));
3414 warn (_("Unknown extended line op: %d of length %d\n"),
3415 op_code, length - bytes_read);
3424 display_debug_lines (section, start, file)
3425 Elf32_Internal_Shdr * section;
3426 unsigned char * start;
3429 DWARF2_External_LineInfo * external;
3430 DWARF2_Internal_LineInfo info;
3431 unsigned char * standard_opcodes;
3433 unsigned char * data = start;
3434 unsigned char * end = start + section->sh_size;
3435 unsigned long address;
3440 printf (_("\nDump of debug contents of section %s:\n\n"),
3441 SECTION_NAME (section));
3443 external = (DWARF2_External_LineInfo *) start;
3445 /* Check the length of the block. */
3446 info.li_length = BYTE_GET (external->li_length);
3447 if (info.li_length > section->sh_size)
3450 (_("The line info appears to be corrupt - the section is too small\n"));
3454 /* Check its version number. */
3455 info.li_version = BYTE_GET (external->li_version);
3456 if (info.li_version != 2)
3458 warn (_("Only DWARF version 2 line info is currently supported.\n"));
3462 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
3463 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
3464 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
3465 info.li_line_base = BYTE_GET (external->li_line_base);
3466 info.li_line_range = BYTE_GET (external->li_line_range);
3467 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
3469 /* Sign extend the line base field. */
3470 info.li_line_base <<= 24;
3471 info.li_line_base >>= 24;
3473 printf (_(" Length: %d\n"), info.li_length);
3474 printf (_(" DWARF Version: %d\n"), info.li_version);
3475 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
3476 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
3477 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
3478 printf (_(" Line Base: %d\n"), info.li_line_base);
3479 printf (_(" Line Range: %d\n"), info.li_line_range);
3480 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
3482 /* Display the contents of the Opcodes table. */
3483 standard_opcodes = start + sizeof (* external);
3485 printf (_("\n Opcodes:\n"));
3487 for (i = 1; i < info.li_opcode_base; i++)
3488 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
3491 /* Display the contents of the Directory table. */
3492 data = standard_opcodes + info.li_opcode_base - 1;
3495 printf (_("\n The Directory Table is empty\n"));
3498 printf (_("\n The Directory Table:\n"));
3502 printf (_(" %s\n"), data);
3504 data += strlen (data) + 1;
3508 /* Skip the NUL at the end of the table. */
3511 /* Display the contents of the File Name table. */
3513 printf (_("\n The File Name Table is empty\n"));
3516 printf (_("\n The File Name Table:\n"));
3517 printf (_(" Name\t\tDir\tTime\tSize\n"));
3523 printf (_(" %s"), data);
3525 data += strlen (data) + 1;
3527 printf (_("\t%lu"), read_leb128 (data, & bytes_read, 0));
3529 printf (_("\t%lu"), read_leb128 (data, & bytes_read, 0));
3531 printf (_("\t%lu\n"), read_leb128 (data, & bytes_read, 0));
3536 /* Skip the NUL at the end of the table. */
3539 /* Now display the statements: */
3540 printf (_("\n Line Number Statements:\n"));
3544 is_stmt = info.li_default_is_stmt;
3548 unsigned char op_code;
3552 op_code = * data ++;
3556 case DW_LNS_extended_op:
3557 data += process_extended_line_op (data, & address);
3561 printf (_(" Copy\n"));
3564 case DW_LNS_advance_pc:
3565 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
3568 printf (_(" Advance PC by %x to %x\n"), adv, address);
3571 case DW_LNS_advance_line:
3572 adv = read_leb128 (data, & bytes_read, 0);
3575 printf (_(" Advance Line by %d to %d\n"), adv, line);
3578 case DW_LNS_set_file:
3579 adv = read_leb128 (data, & bytes_read, 0);
3581 printf (_(" Set File Name to entry %d in the File Name Table\n"),
3585 case DW_LNS_set_column:
3586 adv = read_leb128 (data, & bytes_read, 0);
3588 printf (_(" Set column to %d\n"), adv);
3591 case DW_LNS_negate_stmt:
3592 printf (_(" Set is_stmt to %d\n"), is_stmt);
3595 case DW_LNS_set_basic_block:
3596 printf (_(" Set basic block\n"));
3599 case DW_LNS_const_add_pc:
3600 adv = (255 - info.li_opcode_base) / info.li_line_range;
3602 printf (_(" Advance PC by constant %d to %x\n"), adv, address);
3605 case DW_LNS_fixed_advance_pc:
3606 adv = byte_get (data, 2);
3609 printf (_(" Advance PC by fixed size amount %d to %x\n"),
3614 op_code -= info.li_opcode_base;
3615 address += (op_code / info.li_line_range) * info.li_min_insn_length,
3616 line += (op_code % info.li_line_range) + info.li_line_base;
3618 (_(" Increase by %d, setting address to %lx and line to %d:\n"),
3619 op_code, address, line);
3628 display_debug_pubnames (section, start, file)
3629 Elf32_Internal_Shdr * section;
3630 unsigned char * start;
3633 DWARF2_External_PubNames * external;
3634 DWARF2_Internal_PubNames pubnames;
3635 unsigned char * end;
3637 end = start + section->sh_size;
3639 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
3643 unsigned char * data;
3644 unsigned long offset;
3646 external = (DWARF2_External_PubNames *) start;
3648 pubnames.pn_length = BYTE_GET (external->pn_length);
3649 pubnames.pn_version = BYTE_GET (external->pn_version);
3650 pubnames.pn_offset = BYTE_GET (external->pn_offset);
3651 pubnames.pn_size = BYTE_GET (external->pn_size);
3653 data = start + sizeof (* external);
3654 start += pubnames.pn_length + sizeof (external->pn_length);
3656 if (pubnames.pn_version != 2)
3658 warn (_("Only DWARF 2 pubnames are currently supported"));
3662 printf (_(" Length: %d\n"),
3663 pubnames.pn_length);
3664 printf (_(" Version: %d\n"),
3665 pubnames.pn_version);
3666 printf (_(" Offset into .debug_info section: %d\n"),
3667 pubnames.pn_offset);
3668 printf (_(" Size of area in .debug_info section: %d\n"),
3671 printf (_("\n Offset\tName\n"));
3675 offset = byte_get (data, 4);
3680 printf (" %d\t\t%s\n", offset, data);
3681 data += strlen (data) + 1;
3684 while (offset != 0);
3696 case DW_TAG_padding: return "DW_TAG_padding";
3697 case DW_TAG_array_type: return "DW_TAG_array_type";
3698 case DW_TAG_class_type: return "DW_TAG_class_type";
3699 case DW_TAG_entry_point: return "DW_TAG_entry_point";
3700 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
3701 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
3702 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
3703 case DW_TAG_label: return "DW_TAG_label";
3704 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
3705 case DW_TAG_member: return "DW_TAG_member";
3706 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
3707 case DW_TAG_reference_type: return "DW_TAG_reference_type";
3708 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
3709 case DW_TAG_string_type: return "DW_TAG_string_type";
3710 case DW_TAG_structure_type: return "DW_TAG_structure_type";
3711 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
3712 case DW_TAG_typedef: return "DW_TAG_typedef";
3713 case DW_TAG_union_type: return "DW_TAG_union_type";
3714 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
3715 case DW_TAG_variant: return "DW_TAG_variant";
3716 case DW_TAG_common_block: return "DW_TAG_common_block";
3717 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
3718 case DW_TAG_inheritance: return "DW_TAG_inheritance";
3719 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
3720 case DW_TAG_module: return "DW_TAG_module";
3721 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
3722 case DW_TAG_set_type: return "DW_TAG_set_type";
3723 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
3724 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
3725 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
3726 case DW_TAG_base_type: return "DW_TAG_base_type";
3727 case DW_TAG_catch_block: return "DW_TAG_catch_block";
3728 case DW_TAG_const_type: return "DW_TAG_const_type";
3729 case DW_TAG_constant: return "DW_TAG_constant";
3730 case DW_TAG_enumerator: return "DW_TAG_enumerator";
3731 case DW_TAG_file_type: return "DW_TAG_file_type";
3732 case DW_TAG_friend: return "DW_TAG_friend";
3733 case DW_TAG_namelist: return "DW_TAG_namelist";
3734 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
3735 case DW_TAG_packed_type: return "DW_TAG_packed_type";
3736 case DW_TAG_subprogram: return "DW_TAG_subprogram";
3737 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
3738 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
3739 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
3740 case DW_TAG_try_block: return "DW_TAG_try_block";
3741 case DW_TAG_variant_part: return "DW_TAG_variant_part";
3742 case DW_TAG_variable: return "DW_TAG_variable";
3743 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
3744 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
3745 case DW_TAG_format_label: return "DW_TAG_format_label";
3746 case DW_TAG_function_template: return "DW_TAG_function_template";
3747 case DW_TAG_class_template: return "DW_TAG_class_template";
3750 static char buffer [100];
3752 sprintf (buffer, _("Unknown TAG value: %x"), tag);
3759 get_AT_name (attribute)
3760 unsigned long attribute;
3764 case DW_AT_sibling: return "DW_AT_sibling";
3765 case DW_AT_location: return "DW_AT_location";
3766 case DW_AT_name: return "DW_AT_name";
3767 case DW_AT_ordering: return "DW_AT_ordering";
3768 case DW_AT_subscr_data: return "DW_AT_subscr_data";
3769 case DW_AT_byte_size: return "DW_AT_byte_size";
3770 case DW_AT_bit_offset: return "DW_AT_bit_offset";
3771 case DW_AT_bit_size: return "DW_AT_bit_size";
3772 case DW_AT_element_list: return "DW_AT_element_list";
3773 case DW_AT_stmt_list: return "DW_AT_stmt_list";
3774 case DW_AT_low_pc: return "DW_AT_low_pc";
3775 case DW_AT_high_pc: return "DW_AT_high_pc";
3776 case DW_AT_language: return "DW_AT_language";
3777 case DW_AT_member: return "DW_AT_member";
3778 case DW_AT_discr: return "DW_AT_discr";
3779 case DW_AT_discr_value: return "DW_AT_discr_value";
3780 case DW_AT_visibility: return "DW_AT_visibility";
3781 case DW_AT_import: return "DW_AT_import";
3782 case DW_AT_string_length: return "DW_AT_string_length";
3783 case DW_AT_common_reference: return "DW_AT_common_reference";
3784 case DW_AT_comp_dir: return "DW_AT_comp_dir";
3785 case DW_AT_const_value: return "DW_AT_const_value";
3786 case DW_AT_containing_type: return "DW_AT_containing_type";
3787 case DW_AT_default_value: return "DW_AT_default_value";
3788 case DW_AT_inline: return "DW_AT_inline";
3789 case DW_AT_is_optional: return "DW_AT_is_optional";
3790 case DW_AT_lower_bound: return "DW_AT_lower_bound";
3791 case DW_AT_producer: return "DW_AT_producer";
3792 case DW_AT_prototyped: return "DW_AT_prototyped";
3793 case DW_AT_return_addr: return "DW_AT_return_addr";
3794 case DW_AT_start_scope: return "DW_AT_start_scope";
3795 case DW_AT_stride_size: return "DW_AT_stride_size";
3796 case DW_AT_upper_bound: return "DW_AT_upper_bound";
3797 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
3798 case DW_AT_accessibility: return "DW_AT_accessibility";
3799 case DW_AT_address_class: return "DW_AT_address_class";
3800 case DW_AT_artificial: return "DW_AT_artificial";
3801 case DW_AT_base_types: return "DW_AT_base_types";
3802 case DW_AT_calling_convention: return "DW_AT_calling_convention";
3803 case DW_AT_count: return "DW_AT_count";
3804 case DW_AT_data_member_location: return "DW_AT_data_member_location";
3805 case DW_AT_decl_column: return "DW_AT_decl_column";
3806 case DW_AT_decl_file: return "DW_AT_decl_file";
3807 case DW_AT_decl_line: return "DW_AT_decl_line";
3808 case DW_AT_declaration: return "DW_AT_declaration";
3809 case DW_AT_discr_list: return "DW_AT_discr_list";
3810 case DW_AT_encoding: return "DW_AT_encoding";
3811 case DW_AT_external: return "DW_AT_external";
3812 case DW_AT_frame_base: return "DW_AT_frame_base";
3813 case DW_AT_friend: return "DW_AT_friend";
3814 case DW_AT_identifier_case: return "DW_AT_identifier_case";
3815 case DW_AT_macro_info: return "DW_AT_macro_info";
3816 case DW_AT_namelist_items: return "DW_AT_namelist_items";
3817 case DW_AT_priority: return "DW_AT_priority";
3818 case DW_AT_segment: return "DW_AT_segment";
3819 case DW_AT_specification: return "DW_AT_specification";
3820 case DW_AT_static_link: return "DW_AT_static_link";
3821 case DW_AT_type: return "DW_AT_type";
3822 case DW_AT_use_location: return "DW_AT_use_location";
3823 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
3824 case DW_AT_virtuality: return "DW_AT_virtuality";
3825 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
3826 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
3827 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
3828 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
3829 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
3830 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
3831 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
3832 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
3833 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
3834 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
3835 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
3836 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
3837 case DW_AT_sf_names: return "DW_AT_sf_names";
3838 case DW_AT_src_info: return "DW_AT_src_info";
3839 case DW_AT_mac_info: return "DW_AT_mac_info";
3840 case DW_AT_src_coords: return "DW_AT_src_coords";
3841 case DW_AT_body_begin: return "DW_AT_body_begin";
3842 case DW_AT_body_end: return "DW_AT_body_end";
3845 static char buffer [100];
3847 sprintf (buffer, _("Unknown AT value: %x"), attribute);
3854 get_FORM_name (form)
3859 case DW_FORM_addr: return "DW_FORM_addr";
3860 case DW_FORM_block2: return "DW_FORM_block2";
3861 case DW_FORM_block4: return "DW_FORM_block4";
3862 case DW_FORM_data2: return "DW_FORM_data2";
3863 case DW_FORM_data4: return "DW_FORM_data4";
3864 case DW_FORM_data8: return "DW_FORM_data8";
3865 case DW_FORM_string: return "DW_FORM_string";
3866 case DW_FORM_block: return "DW_FORM_block";
3867 case DW_FORM_block1: return "DW_FORM_block1";
3868 case DW_FORM_data1: return "DW_FORM_data1";
3869 case DW_FORM_flag: return "DW_FORM_flag";
3870 case DW_FORM_sdata: return "DW_FORM_sdata";
3871 case DW_FORM_strp: return "DW_FORM_strp";
3872 case DW_FORM_udata: return "DW_FORM_udata";
3873 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
3874 case DW_FORM_ref1: return "DW_FORM_ref1";
3875 case DW_FORM_ref2: return "DW_FORM_ref2";
3876 case DW_FORM_ref4: return "DW_FORM_ref4";
3877 case DW_FORM_ref8: return "DW_FORM_ref8";
3878 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
3879 case DW_FORM_indirect: return "DW_FORM_indirect";
3882 static char buffer [100];
3884 sprintf (buffer, _("Unknown FORM value: %x"), form);
3890 /* FIXME: There are better and more effiecint ways to handle
3891 these structures. For now though, I just want something that
3892 is simple to implement. */
3893 typedef struct abbrev_attr
3895 unsigned long attribute;
3897 struct abbrev_attr * next;
3901 typedef struct abbrev_entry
3903 unsigned long entry;
3906 struct abbrev_attr * first_attr;
3907 struct abbrev_attr * last_attr;
3908 struct abbrev_entry * next;
3912 static abbrev_entry * first_abbrev = NULL;
3913 static abbrev_entry * last_abbrev = NULL;
3916 free_abbrevs PARAMS ((void))
3918 abbrev_entry * abbrev;
3920 for (abbrev = first_abbrev; abbrev;)
3922 abbrev_entry * next = abbrev->next;
3925 for (attr = abbrev->first_attr; attr;)
3927 abbrev_attr * next = attr->next;
3937 last_abbrev = first_abbrev = NULL;
3941 add_abbrev (number, tag, children)
3942 unsigned long number;
3946 abbrev_entry * entry;
3948 entry = (abbrev_entry *) malloc (sizeof (* entry));
3954 entry->entry = number;
3956 entry->children = children;
3957 entry->first_attr = NULL;
3958 entry->last_attr = NULL;
3961 if (first_abbrev == NULL)
3962 first_abbrev = entry;
3964 last_abbrev->next = entry;
3966 last_abbrev = entry;
3970 add_abbrev_attr (attribute, form)
3971 unsigned long attribute;
3976 attr = (abbrev_attr *) malloc (sizeof (* attr));
3982 attr->attribute = attribute;
3986 if (last_abbrev->first_attr == NULL)
3987 last_abbrev->first_attr = attr;
3989 last_abbrev->last_attr->next = attr;
3991 last_abbrev->last_attr = attr;
3994 /* Processes the (partial) contents of a .debug_abbrev section.
3995 Returns NULL if the end of the section was encountered.
3996 Returns the address after the last byte read if the end of
3997 an abbreviation set was found. */
3999 static unsigned char *
4000 process_abbrev_section (start, end)
4001 unsigned char * start;
4002 unsigned char * end;
4004 if (first_abbrev != NULL)
4010 unsigned long entry;
4012 unsigned long attribute;
4015 entry = read_leb128 (start, & bytes_read, 0);
4016 start += bytes_read;
4021 tag = read_leb128 (start, & bytes_read, 0);
4022 start += bytes_read;
4024 children = * start ++;
4026 add_abbrev (entry, tag, children);
4032 attribute = read_leb128 (start, & bytes_read, 0);
4033 start += bytes_read;
4035 form = read_leb128 (start, & bytes_read, 0);
4036 start += bytes_read;
4039 add_abbrev_attr (attribute, form);
4041 while (attribute != 0);
4049 display_debug_abbrev (section, start, file)
4050 Elf32_Internal_Shdr * section;
4051 unsigned char * start;
4054 abbrev_entry * entry;
4055 unsigned char * end = start + section->sh_size;
4057 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4061 start = process_abbrev_section (start, end);
4063 printf (_(" Number TAG\n"));
4065 for (entry = first_abbrev; entry; entry = entry->next)
4069 printf (_(" %d %s [%s]\n"),
4071 get_TAG_name (entry->tag),
4072 entry->children ? _("has children") : _("no children"));
4074 for (attr = entry->first_attr; attr; attr = attr->next)
4076 printf (_(" %-18s %s\n"),
4077 get_AT_name (attr->attribute),
4078 get_FORM_name (attr->form));
4090 static unsigned char *
4091 display_block (data, length)
4092 unsigned char * data;
4093 unsigned long length;
4095 printf (_(" %d byte block: "), length);
4098 printf ("%x ", byte_get (data ++, 1));
4103 static unsigned char *
4104 read_and_display_attr (attribute, form, data, pointer_size)
4105 unsigned long attribute;
4107 unsigned char * data;
4108 unsigned long pointer_size;
4110 unsigned long uvalue;
4113 printf (" %-18s:", get_AT_name (attribute));
4117 case DW_FORM_ref_addr:
4119 uvalue = byte_get (data, pointer_size);
4120 printf (" %x", uvalue);
4121 data += pointer_size;
4127 uvalue = byte_get (data ++, 1);
4128 printf (" %x", uvalue);
4133 uvalue = byte_get (data, 2);
4135 printf (" %x", uvalue);
4140 uvalue = byte_get (data, 4);
4142 printf (" %x", uvalue);
4147 uvalue = byte_get (data, 4);
4148 printf (" %x", uvalue);
4149 printf (" %x", byte_get (data + 4, 4));
4153 case DW_FORM_string:
4154 printf (" %s", data);
4155 data += strlen (data) + 1;
4159 uvalue = read_leb128 (data, & bytes_read, 1);
4161 printf (" %ld", (long) uvalue);
4164 case DW_FORM_ref_udata:
4166 uvalue = read_leb128 (data, & bytes_read, 0);
4168 printf (" %lx", uvalue);
4172 uvalue = read_leb128 (data, & bytes_read, 0);
4173 data = display_block (data + bytes_read, uvalue);
4174 uvalue = * (data - uvalue);
4177 case DW_FORM_block1:
4178 uvalue = byte_get (data ++, 1);
4179 data = display_block (data, uvalue);
4180 uvalue = * (data - uvalue);
4183 case DW_FORM_block2:
4184 uvalue = byte_get (data, 2);
4185 data = display_block (data + 2, uvalue);
4186 uvalue = * (data - uvalue);
4189 case DW_FORM_block4:
4190 uvalue = byte_get (data, 4);
4191 data = display_block (data + 4, uvalue);
4192 uvalue = * (data - uvalue);
4196 case DW_FORM_indirect:
4197 warn (_("Unable to handle FORM: %d"), form);
4201 warn (_("Unrecognised form: %d"), form);
4205 /* For some attributes we can display futher information. */
4214 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
4215 case DW_INL_inlined: printf (_("(inlined)")); break;
4216 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
4217 case DW_INL_declared_inlined: printf (_("(declared as inline and implemented)")); break;
4218 defailt: printf (_(" (Unknown inline attribute value: %x)"), uvalue); break;
4222 case DW_AT_frame_base:
4223 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
4224 printf ("(reg %d)", uvalue - DW_OP_reg0);
4227 case DW_AT_language:
4230 case DW_LANG_C: printf ("(non-ANSI C)"); break;
4231 case DW_LANG_C89: printf ("(ANSI C)"); break;
4232 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
4233 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
4234 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
4235 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
4236 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
4237 case DW_LANG_Ada83: printf ("(Ada)"); break;
4238 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
4239 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
4240 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
4241 default: printf ("(Unknown: %x)", uvalue); break;
4254 display_debug_info (section, start, file)
4255 Elf32_Internal_Shdr * section;
4256 unsigned char * start;
4259 unsigned char * end = start + section->sh_size;
4261 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4265 DWARF2_External_CompUnit * external;
4266 DWARF2_Internal_CompUnit compunit;
4267 unsigned char * tags;
4270 external = (DWARF2_External_CompUnit *) start;
4272 compunit.cu_length = BYTE_GET (external->cu_length);
4273 compunit.cu_version = BYTE_GET (external->cu_version);
4274 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
4275 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
4277 tags = start + sizeof (* external);
4278 start += compunit.cu_length + sizeof (external->cu_length);
4280 if (compunit.cu_version != 2)
4282 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
4286 printf (_(" Compilation Unit:\n"));
4287 printf (_(" Length: %d\n"), compunit.cu_length);
4288 printf (_(" Version: %d\n"), compunit.cu_version);
4289 printf (_(" Abbrev Offset: %d\n"), compunit.cu_abbrev_offset);
4290 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
4292 if (first_abbrev != NULL)
4295 /* Read in the abbrevs used by this compilation unit. */
4298 Elf32_Internal_Shdr * sec;
4299 unsigned char * begin;
4301 /* Locate the .debug_abbrev section and process it. */
4302 for (i = 0, sec = section_headers;
4303 i < elf_header.e_shnum;
4305 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
4308 if (i == -1 || sec->sh_size == 0)
4310 warn (_("Unable to locate .debug_abbrev section!\n"));
4314 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, char *,
4315 "debug_abbrev section data");
4317 process_abbrev_section (begin + compunit.cu_abbrev_offset,
4318 begin + sec->sh_size);
4323 while (tags < start)
4327 abbrev_entry * entry;
4330 abbrev_number = read_leb128 (tags, & bytes_read, 0);
4333 if (abbrev_number == 0)
4336 /* Scan through the abbreviation list until we reach the
4338 for (entry = first_abbrev;
4339 entry && entry->entry != abbrev_number;
4340 entry = entry->next)
4345 warn (_("Unable to locate entry %d in the abbreviation table\n"),
4350 printf (_(" Abbrev Number: %d (%s)\n"),
4352 get_TAG_name (entry->tag));
4354 for (attr = entry->first_attr; attr; attr = attr->next)
4355 tags = read_and_display_attr (attr->attribute,
4358 compunit.cu_pointer_size);
4366 display_debug_not_supported (section, start, file)
4367 Elf32_Internal_Shdr * section;
4368 unsigned char * start;
4371 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
4372 SECTION_NAME (section));
4377 /* A structure containing the name of a debug section and a pointer
4378 to a function that can decode it. */
4382 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
4386 { ".debug_info", display_debug_info },
4387 { ".debug_abbrev", display_debug_abbrev },
4388 { ".debug_line", display_debug_lines },
4389 { ".debug_aranges", display_debug_not_supported },
4390 { ".debug_pubnames", display_debug_pubnames },
4391 { ".debug_macinfo", display_debug_not_supported },
4392 { ".debug_frame", display_debug_not_supported },
4393 { ".debug_loc", display_debug_not_supported },
4394 { ".debug_str", display_debug_not_supported }
4398 display_debug_section (section, file)
4399 Elf32_Internal_Shdr * section;
4402 char * name = SECTION_NAME (section);
4403 bfd_size_type length;
4404 unsigned char * start;
4407 length = section->sh_size;
4410 printf (_("\nSection '%s' has no debugging data.\n"), name);
4414 GET_DATA_ALLOC (section->sh_offset, length, start, char *,
4415 "debug section data");
4417 /* See if we know how to display the contents of this section. */
4418 for (i = NUM_ELEM (debug_displays); i--;)
4419 if (strcmp (debug_displays[i].name, name) == 0)
4421 debug_displays[i].display (section, start, file);
4426 printf (_("Unrecognised debug section: %s\n"), name);
4430 /* If we loaded in the abbrev section at some point,
4431 we must release it here. */
4432 if (first_abbrev != NULL)
4439 process_section_contents (file)
4442 Elf32_Internal_Shdr * section;
4448 for (i = 0, section = section_headers;
4449 i < elf_header.e_shnum
4450 && i < NUM_DUMP_SECTS;
4453 #ifdef SUPPORT_DISASSEMBLY
4454 if (dump_sects[i] & DISASS_DUMP)
4455 disassemble_section (section, file);
4457 if (dump_sects[i] & HEX_DUMP)
4458 dump_section (section, file);
4460 if (dump_sects[i] & DEBUG_DUMP)
4461 display_debug_section (section, file);
4468 process_mips_fpe_exception (mask)
4474 if (mask & OEX_FPU_INEX)
4475 fputs ("INEX", stdout), first = 0;
4476 if (mask & OEX_FPU_UFLO)
4477 printf ("%sUFLO", first ? "" : "|"), first = 0;
4478 if (mask & OEX_FPU_OFLO)
4479 printf ("%sOFLO", first ? "" : "|"), first = 0;
4480 if (mask & OEX_FPU_DIV0)
4481 printf ("%sDIV0", first ? "" : "|"), first = 0;
4482 if (mask & OEX_FPU_INVAL)
4483 printf ("%sINVAL", first ? "" : "|");
4486 fputs ("0", stdout);
4490 process_mips_specific (file)
4493 Elf_Internal_Dyn *entry;
4494 size_t liblist_offset = 0;
4495 size_t liblistno = 0;
4496 size_t conflictsno = 0;
4497 size_t options_offset = 0;
4498 size_t conflicts_offset = 0;
4500 /* We have a lot of special sections. Thanks SGI! */
4501 if (dynamic_segment == NULL)
4502 /* No information available. */
4505 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
4506 switch (entry->d_tag)
4508 case DT_MIPS_LIBLIST:
4509 liblist_offset = entry->d_un.d_val - loadaddr;
4511 case DT_MIPS_LIBLISTNO:
4512 liblistno = entry->d_un.d_val;
4514 case DT_MIPS_OPTIONS:
4515 options_offset = entry->d_un.d_val - loadaddr;
4517 case DT_MIPS_CONFLICT:
4518 conflicts_offset = entry->d_un.d_val - loadaddr;
4520 case DT_MIPS_CONFLICTNO:
4521 conflictsno = entry->d_un.d_val;
4527 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
4529 Elf32_External_Lib *elib;
4532 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
4533 elib, Elf32_External_Lib *, "liblist");
4535 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
4536 fputs (" Library Time Stamp Checksum Version Flags\n",
4539 for (cnt = 0; cnt < liblistno; ++cnt)
4545 liblist.l_name = BYTE_GET (elib[cnt].l_name);
4546 time = BYTE_GET (elib[cnt].l_time_stamp);
4547 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
4548 liblist.l_version = BYTE_GET (elib[cnt].l_version);
4549 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
4551 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
4553 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
4554 dynamic_strings + liblist.l_name, timebuf,
4555 liblist.l_checksum, liblist.l_version);
4557 if (liblist.l_flags == 0)
4567 { " EXACT_MATCH", LL_EXACT_MATCH },
4568 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
4569 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
4570 { " EXPORTS", LL_EXPORTS },
4571 { " DELAY_LOAD", LL_DELAY_LOAD },
4572 { " DELTA", LL_DELTA }
4574 int flags = liblist.l_flags;
4578 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
4580 if ((flags & l_flags_vals[fcnt].bit) != 0)
4582 fputs (l_flags_vals[fcnt].name, stdout);
4583 flags ^= l_flags_vals[fcnt].bit;
4586 printf (" %#lx", flags);
4595 if (options_offset != 0)
4597 Elf_External_Options *eopt;
4598 Elf_Internal_Shdr *sect = section_headers;
4599 Elf_Internal_Options *iopt;
4600 Elf_Internal_Options *option;
4604 /* Find the section header so that we get the size. */
4605 while (sect->sh_type != SHT_MIPS_OPTIONS)
4608 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
4609 Elf_External_Options *, "options");
4611 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
4615 error (_("Out of memory"));
4621 while (offset < sect->sh_size)
4623 Elf_External_Options *eoption;
4625 eoption = (Elf_External_Options *) ((char *) eopt + offset);
4627 option->kind = BYTE_GET (eoption->kind);
4628 option->size = BYTE_GET (eoption->size);
4629 option->section = BYTE_GET (eoption->section);
4630 option->info = BYTE_GET (eoption->info);
4632 offset += option->size;
4637 printf (_("\nSection '%s' contains %d entries:\n"),
4638 string_table + sect->sh_name, cnt);
4645 switch (option->kind)
4648 /* This shouldn't happen. */
4649 printf (" NULL %d %x", option->section, option->info);
4652 printf (" REGINFO ");
4653 if (elf_header.e_machine == EM_MIPS)
4656 Elf32_External_RegInfo *ereg;
4657 Elf32_RegInfo reginfo;
4659 ereg = (Elf32_External_RegInfo *) (option + 1);
4660 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
4661 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
4662 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
4663 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
4664 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
4665 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
4667 printf ("GPR %08lx GP %ld\n",
4668 reginfo.ri_gprmask, reginfo.ri_gp_value);
4669 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
4670 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
4671 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
4676 Elf64_External_RegInfo *ereg;
4677 Elf64_Internal_RegInfo reginfo;
4679 ereg = (Elf64_External_RegInfo *) (option + 1);
4680 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
4681 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
4682 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
4683 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
4684 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
4685 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
4687 printf ("GPR %08lx GP %ld\n",
4688 reginfo.ri_gprmask, reginfo.ri_gp_value);
4689 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
4690 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
4691 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
4695 case ODK_EXCEPTIONS:
4696 fputs (" EXCEPTIONS fpe_min(", stdout);
4697 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
4698 fputs (") fpe_max(", stdout);
4699 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
4700 fputs (")", stdout);
4702 if (option->info & OEX_PAGE0)
4703 fputs (" PAGE0", stdout);
4704 if (option->info & OEX_SMM)
4705 fputs (" SMM", stdout);
4706 if (option->info & OEX_FPDBUG)
4707 fputs (" FPDBUG", stdout);
4708 if (option->info & OEX_DISMISS)
4709 fputs (" DISMISS", stdout);
4712 fputs (" PAD ", stdout);
4713 if (option->info & OPAD_PREFIX)
4714 fputs (" PREFIX", stdout);
4715 if (option->info & OPAD_POSTFIX)
4716 fputs (" POSTFIX", stdout);
4717 if (option->info & OPAD_SYMBOL)
4718 fputs (" SYMBOL", stdout);
4721 fputs (" HWPATCH ", stdout);
4722 if (option->info & OHW_R4KEOP)
4723 fputs (" R4KEOP", stdout);
4724 if (option->info & OHW_R8KPFETCH)
4725 fputs (" R8KPFETCH", stdout);
4726 if (option->info & OHW_R5KEOP)
4727 fputs (" R5KEOP", stdout);
4728 if (option->info & OHW_R5KCVTL)
4729 fputs (" R5KCVTL", stdout);
4732 fputs (" FILL ", stdout);
4733 /* XXX Print content of info word? */
4736 fputs (" TAGS ", stdout);
4737 /* XXX Print content of info word? */
4740 fputs (" HWAND ", stdout);
4741 if (option->info & OHWA0_R4KEOP_CHECKED)
4742 fputs (" R4KEOP_CHECKED", stdout);
4743 if (option->info & OHWA0_R4KEOP_CLEAN)
4744 fputs (" R4KEOP_CLEAN", stdout);
4747 fputs (" HWOR ", stdout);
4748 if (option->info & OHWA0_R4KEOP_CHECKED)
4749 fputs (" R4KEOP_CHECKED", stdout);
4750 if (option->info & OHWA0_R4KEOP_CLEAN)
4751 fputs (" R4KEOP_CLEAN", stdout);
4754 printf (" GP_GROUP %#06x self-contained %#06x",
4755 option->info & OGP_GROUP,
4756 (option->info & OGP_SELF) >> 16);
4759 printf (" IDENT %#06x self-contained %#06x",
4760 option->info & OGP_GROUP,
4761 (option->info & OGP_SELF) >> 16);
4764 /* This shouldn't happen. */
4765 printf (" %3d ??? %d %x",
4766 option->kind, option->section, option->info);
4770 len = sizeof (*eopt);
4771 while (len < option->size)
4772 if (((char *) option)[len] >= ' '
4773 && ((char *) option)[len] < 0x7f)
4774 printf ("%c", ((char *) option)[len++]);
4776 printf ("\\%03o", ((char *) option)[len++]);
4778 fputs ("\n", stdout);
4785 if (conflicts_offset != 0 && conflictsno != 0)
4787 Elf32_External_Conflict *econf32;
4788 Elf64_External_Conflict *econf64;
4789 Elf32_Conflict *iconf;
4792 if (dynamic_symbols == NULL)
4794 error (_("conflict list with without table"));
4798 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
4801 error (_("Out of memory"));
4805 if (binary_class == ELFCLASS32)
4807 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
4808 econf32, Elf32_External_Conflict *, "conflict");
4810 for (cnt = 0; cnt < conflictsno; ++cnt)
4811 iconf[cnt] = BYTE_GET (econf32[cnt]);
4815 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
4816 econf64, Elf64_External_Conflict *, "conflict");
4818 for (cnt = 0; cnt < conflictsno; ++cnt)
4819 iconf[cnt] = BYTE_GET (econf64[cnt]);
4822 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
4823 puts (_(" Num: Index Value Name"));
4825 for (cnt = 0; cnt < conflictsno; ++cnt)
4827 Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
4829 printf ("%5u: %8u %#10x %s\n",
4830 cnt, iconf[cnt], (unsigned long) psym->st_value,
4831 dynamic_strings + psym->st_name);
4842 process_arch_specific (file)
4845 switch (elf_header.e_machine)
4848 case EM_MIPS_RS4_BE:
4849 return process_mips_specific (file);
4858 get_file_header (file)
4861 Elf32_External_Ehdr ehdr;
4863 if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
4866 memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
4868 if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
4869 byte_get = byte_get_little_endian;
4871 byte_get = byte_get_big_endian;
4873 elf_header.e_entry = BYTE_GET (ehdr.e_entry);
4874 elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
4875 elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
4876 elf_header.e_version = BYTE_GET (ehdr.e_version);
4877 elf_header.e_flags = BYTE_GET (ehdr.e_flags);
4878 elf_header.e_type = BYTE_GET (ehdr.e_type);
4879 elf_header.e_machine = BYTE_GET (ehdr.e_machine);
4880 elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
4881 elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
4882 elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
4883 elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
4884 elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
4885 elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
4891 process_file (file_name)
4895 struct stat statbuf;
4898 if (stat (file_name, & statbuf) < 0)
4900 error (_("Cannot stat input file %s.\n"), file_name);
4904 file = fopen (file_name, "rb");
4907 error (_("Input file %s not found.\n"), file_name);
4911 if (! get_file_header (file))
4913 error (_("%s: Failed to read file header\n"), file_name);
4918 /* Initialise per file variables. */
4919 for (i = NUM_ELEM (version_info); i--;)
4920 version_info[i] = 0;
4922 for (i = NUM_ELEM (dynamic_info); i--;)
4923 dynamic_info[i] = 0;
4925 /* Process the file. */
4927 printf (_("\nFile: %s\n"), file_name);
4929 if (! process_file_header ())
4935 process_section_headers (file);
4937 process_program_headers (file);
4939 process_dynamic_segment (file);
4941 process_relocs (file);
4943 process_symbol_table (file);
4945 process_syminfo (file);
4947 process_version_sections (file);
4949 process_section_contents (file);
4951 process_arch_specific (file);
4955 if (section_headers)
4957 free (section_headers);
4958 section_headers = NULL;
4963 free (string_table);
4964 string_table = NULL;
4967 if (dynamic_strings)
4969 free (dynamic_strings);
4970 dynamic_strings = NULL;
4973 if (dynamic_symbols)
4975 free (dynamic_symbols);
4976 dynamic_symbols = NULL;
4979 if (dynamic_syminfo)
4981 free (dynamic_syminfo);
4982 dynamic_syminfo = NULL;
4986 #ifdef SUPPORT_DISASSEMBLY
4987 /* Needed by the i386 disassembler. For extra credit, someone could
4988 fix this so that we insert symbolic addresses here, esp for GOT/PLT
4992 print_address (unsigned int addr, FILE * outfile)
4994 fprintf (outfile,"0x%8.8x", addr);
4997 /* Needed by the i386 disassembler. */
4999 db_task_printsym (unsigned int addr)
5001 print_address (addr, stderr);
5010 parse_args (argc, argv);
5012 if (optind < (argc - 1))
5015 while (optind < argc)
5016 process_file (argv [optind ++]);