/* readelf.c -- display contents of an ELF format file
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011
+ 2008, 2009, 2010, 2011, 2012, 2013
Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
ELF file than is provided by objdump. In particular it can display DWARF
debugging information which (at the moment) objdump cannot. */
\f
-#include "config.h"
#include "sysdep.h"
#include <assert.h>
-#include <sys/stat.h>
#include <time.h>
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
#if __GNUC__ >= 2
/* Define BFD64 here, even if our default architecture is 32 bit ELF
#define RELOC_MACROS_GEN_FUNC
+#include "elf/aarch64.h"
#include "elf/alpha.h"
#include "elf/arc.h"
#include "elf/arm.h"
#include "elf/d10v.h"
#include "elf/d30v.h"
#include "elf/dlx.h"
+#include "elf/epiphany.h"
#include "elf/fr30.h"
#include "elf/frv.h"
#include "elf/h8.h"
#include "elf/m68hc11.h"
#include "elf/mcore.h"
#include "elf/mep.h"
+#include "elf/metag.h"
#include "elf/microblaze.h"
#include "elf/mips.h"
#include "elf/mmix.h"
#include "elf/pj.h"
#include "elf/ppc.h"
#include "elf/ppc64.h"
+#include "elf/rl78.h"
#include "elf/rx.h"
#include "elf/s390.h"
#include "elf/score.h"
#include "elf/vax.h"
#include "elf/x86-64.h"
#include "elf/xc16x.h"
+#include "elf/xgate.h"
#include "elf/xstormy16.h"
#include "elf/xtensa.h"
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-#define GET_ELF_SYMBOLS(file, section) \
- (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
- : get_64bit_elf_symbols (file, section))
+#define GET_ELF_SYMBOLS(file, section, sym_count) \
+ (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
+ : get_64bit_elf_symbols (file, section, sym_count))
#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
return 0;
}
-/* Display a symbol on stdout. Handles the display of non-printing characters.
+/* Display a symbol on stdout. Handles the display of control characters and
+ multibye characters (assuming the host environment supports them).
+
+ Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
- If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
- truncating as necessary. If WIDTH is negative then format the string to be
- exactly - WIDTH characters, truncating or padding as necessary.
+ If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
+ padding as necessary.
Returns the number of emitted characters. */
static unsigned int
print_symbol (int width, const char *symbol)
{
- const char *c;
bfd_boolean extra_padding = FALSE;
- unsigned int num_printed = 0;
+ int num_printed = 0;
+#ifdef HAVE_MBSTATE_T
+ mbstate_t state;
+#endif
+ int width_remaining;
- if (do_wide)
- {
- /* Set the width to a very large value. This simplifies the
- code below. */
- width = INT_MAX;
- }
- else if (width < 0)
+ if (width < 0)
{
/* Keep the width positive. This also helps. */
width = - width;
extra_padding = TRUE;
- }
-
- while (width)
- {
- int len;
-
- c = symbol;
-
- /* Look for non-printing symbols inside the symbol's name.
- This test is triggered in particular by the names generated
- by the assembler for local labels. */
- while (ISPRINT (*c))
- c++;
-
- len = c - symbol;
+ }
- if (len)
- {
- if (len > width)
- len = width;
+ if (do_wide)
+ /* Set the remaining width to a very large value.
+ This simplifies the code below. */
+ width_remaining = INT_MAX;
+ else
+ width_remaining = width;
- printf ("%.*s", len, symbol);
+#ifdef HAVE_MBSTATE_T
+ /* Initialise the multibyte conversion state. */
+ memset (& state, 0, sizeof (state));
+#endif
- width -= len;
- num_printed += len;
- }
+ while (width_remaining)
+ {
+ size_t n;
+ const char c = *symbol++;
- if (*c == 0 || width == 0)
+ if (c == 0)
break;
- /* Now display the non-printing character, if
- there is room left in which to dipslay it. */
- if ((unsigned char) *c < 32)
+ /* Do not print control characters directly as they can affect terminal
+ settings. Such characters usually appear in the names generated
+ by the assembler for local labels. */
+ if (ISCNTRL (c))
{
- if (width < 2)
+ if (width_remaining < 2)
break;
- printf ("^%c", *c + 0x40);
-
- width -= 2;
+ printf ("^%c", c + 0x40);
+ width_remaining -= 2;
num_printed += 2;
}
+ else if (ISPRINT (c))
+ {
+ putchar (c);
+ width_remaining --;
+ num_printed ++;
+ }
else
{
- if (width < 6)
- break;
-
- printf ("<0x%.2x>", (unsigned char) *c);
-
- width -= 6;
- num_printed += 6;
+#ifdef HAVE_MBSTATE_T
+ wchar_t w;
+#endif
+ /* Let printf do the hard work of displaying multibyte characters. */
+ printf ("%.1s", symbol - 1);
+ width_remaining --;
+ num_printed ++;
+
+#ifdef HAVE_MBSTATE_T
+ /* Try to find out how many bytes made up the character that was
+ just printed. Advance the symbol pointer past the bytes that
+ were displayed. */
+ n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
+#else
+ n = 1;
+#endif
+ if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
+ symbol += (n - 1);
}
-
- symbol = c + 1;
}
- if (extra_padding && width > 0)
+ if (extra_padding && num_printed < width)
{
/* Fill in the remaining spaces. */
- printf ("%-*s", width, " ");
- num_printed += 2;
+ printf ("%-*s", width - num_printed, " ");
+ num_printed = width;
}
return num_printed;
return NULL;
}
+/* Return a pointer to section NAME, or NULL if no such section exists,
+ restricted to the list of sections given in SET. */
+
+static Elf_Internal_Shdr *
+find_section_in_set (const char * name, unsigned int * set)
+{
+ unsigned int i;
+
+ if (set != NULL)
+ {
+ while ((i = *set++) > 0)
+ if (streq (SECTION_NAME (section_headers + i), name))
+ return section_headers + i;
+ }
+
+ return find_section (name);
+}
+
/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
bytes read. */
case EM_OPENRISC:
case EM_OR32:
case EM_SCORE:
+ case EM_XGATE:
return FALSE;
/* Targets that use RELA relocations. */
case EM_68K:
case EM_860:
+ case EM_AARCH64:
+ case EM_ADAPTEVA_EPIPHANY:
case EM_ALPHA:
case EM_ALTERA_NIOS2:
case EM_AVR:
case EM_AVR_OLD:
case EM_BLACKFIN:
case EM_CR16:
- case EM_CR16_OLD:
case EM_CRIS:
case EM_CRX:
case EM_D30V:
case EM_M32R:
case EM_MCORE:
case EM_CYGNUS_MEP:
+ case EM_METAG:
case EM_MMIX:
case EM_MN10200:
case EM_CYGNUS_MN10200:
case EM_NIOS32:
case EM_PPC64:
case EM_PPC:
+ case EM_RL78:
case EM_RX:
case EM_S390:
case EM_S390_OLD:
case EM_TI_C6000:
case EM_TILEGX:
case EM_TILEPRO:
+ case EM_V800:
case EM_V850:
case EM_CYGNUS_V850:
case EM_VAX:
Elf32_External_Rela * erelas;
erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
- rel_size, _("relocs"));
+ rel_size, _("32-bit relocation data"));
if (!erelas)
return 0;
Elf64_External_Rela * erelas;
erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
- rel_size, _("relocs"));
+ rel_size, _("64-bit relocation data"));
if (!erelas)
return 0;
Elf32_External_Rel * erels;
erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
- rel_size, _("relocs"));
+ rel_size, _("32-bit relocation data"));
if (!erels)
return 0;
Elf64_External_Rel * erels;
erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
- rel_size, _("relocs"));
+ rel_size, _("64-bit relocation data"));
if (!erels)
return 0;
rtype = NULL;
break;
+ case EM_AARCH64:
+ rtype = elf_aarch64_reloc_type (type);
+ break;
+
case EM_M32R:
case EM_CYGNUS_M32R:
rtype = elf_m32r_reloc_type (type);
rtype = elf_spu_reloc_type (type);
break;
+ case EM_V800:
+ rtype = v800_reloc_type (type);
+ break;
case EM_V850:
case EM_CYGNUS_V850:
rtype = v850_reloc_type (type);
rtype = elf_vax_reloc_type (type);
break;
+ case EM_ADAPTEVA_EPIPHANY:
+ rtype = elf_epiphany_reloc_type (type);
+ break;
+
case EM_IP2K:
case EM_IP2K_OLD:
rtype = elf_ip2k_reloc_type (type);
break;
case EM_CR16:
- case EM_CR16_OLD:
rtype = elf_cr16_reloc_type (type);
break;
rtype = elf_microblaze_reloc_type (type);
break;
+ case EM_RL78:
+ rtype = elf_rl78_reloc_type (type);
+ break;
+
case EM_RX:
rtype = elf_rx_reloc_type (type);
break;
+ case EM_METAG:
+ rtype = elf_metag_reloc_type (type);
+ break;
+
case EM_XC16X:
case EM_C166:
rtype = elf_xc16x_reloc_type (type);
case EM_TILEPRO:
rtype = elf_tilepro_reloc_type (type);
break;
+
+ case EM_XGATE:
+ rtype = elf_xgate_reloc_type (type);
+ break;
}
if (rtype == NULL)
}
else if (is_rela)
{
- printf ("%*c", is_32bit_elf ?
- (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
- print_vma (rels[i].r_addend, LONG_HEX);
+ bfd_signed_vma off = rels[i].r_addend;
+
+ printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
+ if (off < 0)
+ printf ("-%" BFD_VMA_FMT "x", - off);
+ else
+ printf ("%" BFD_VMA_FMT "x", off);
}
if (elf_header.e_machine == EM_SPARCV9
switch (e_machine)
{
case EM_NONE: return _("None");
+ case EM_AARCH64: return "AArch64";
case EM_M32: return "WE32100";
case EM_SPARC: return "Sparc";
case EM_SPU: return "SPU";
case EM_960: return "Intel 90860";
case EM_PPC: return "PowerPC";
case EM_PPC64: return "PowerPC64";
- case EM_V800: return "NEC V800";
case EM_FR20: return "Fujitsu FR20";
case EM_RH32: return "TRW RH32";
case EM_MCORE: return "MCORE";
case EM_IA_64: return "Intel IA-64";
case EM_MIPS_X: return "Stanford MIPS-X";
case EM_COLDFIRE: return "Motorola Coldfire";
- case EM_68HC12: return "Motorola M68HC12";
case EM_ALPHA: return "Alpha";
case EM_CYGNUS_D10V:
case EM_D10V: return "d10v";
case EM_CYGNUS_M32R:
case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
case EM_CYGNUS_V850:
- case EM_V850: return "Renesas v850";
+ case EM_V800: return "Renesas V850 (using RH850 ABI)";
+ case EM_V850: return "Renesas V850";
case EM_CYGNUS_MN10300:
case EM_MN10300: return "mn10300";
case EM_CYGNUS_MN10200:
case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
+ case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
case EM_OR32: return "OpenRISC";
case EM_ARC_A5: return "ARC International ARCompact processor";
case EM_CRX: return "National Semiconductor CRX microprocessor";
+ case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
case EM_DLX: return "OpenDLX";
case EM_IP2K_OLD:
case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
case EM_CR16:
- case EM_CR16_OLD: return "National Semiconductor's CR16";
- case EM_MICROBLAZE: return "Xilinx MicroBlaze";
+ case EM_MICROBLAZE:
case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
+ case EM_RL78: return "Renesas RL78";
case EM_RX: return "Renesas RX";
- case EM_METAG: return "Imagination Technologies META processor architecture";
+ case EM_METAG: return "Imagination Technologies Meta processor architecture";
case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
case EM_ECOG16: return "Cyan Technology eCOG16 family";
case EM_ETPU: return "Freescale Extended Time Processing Unit";
case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
case EM_CUDA: return "NVIDIA CUDA architecture";
+ case EM_XGATE: return "Motorola XGATE embedded processor";
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
return buff;
case EF_ARM_EABI_VER4:
strcat (buf, ", Version4 EABI");
- goto eabi;
+ while (e_flags)
+ {
+ unsigned flag;
+
+ /* Process flags one bit at a time. */
+ flag = e_flags & - e_flags;
+ e_flags &= ~ flag;
+
+ switch (flag)
+ {
+ case EF_ARM_BE8:
+ strcat (buf, ", BE8");
+ break;
+
+ case EF_ARM_LE8:
+ strcat (buf, ", LE8");
+ break;
+
+ default:
+ unknown = 1;
+ break;
+ }
+ break;
+ }
+ break;
case EF_ARM_EABI_VER5:
strcat (buf, ", Version5 EABI");
- eabi:
while (e_flags)
{
unsigned flag;
strcat (buf, ", LE8");
break;
+ case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
+ strcat (buf, ", soft-float ABI");
+ break;
+
+ case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
+ strcat (buf, ", hard-float ABI");
+ break;
+
default:
unknown = 1;
break;
strcat (buf, _(", relocatable-lib"));
break;
+ case EM_V800:
+ if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
+ strcat (buf, ", RH850 ABI");
+
+ if (e_flags & EF_V800_850E3)
+ strcat (buf, ", V3 architecture");
+
+ if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
+ strcat (buf, ", FPU not used");
+
+ if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
+ strcat (buf, ", regmode: COMMON");
+
+ if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
+ strcat (buf, ", r4 not used");
+
+ if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
+ strcat (buf, ", r30 not used");
+
+ if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
+ strcat (buf, ", r5 not used");
+
+ if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
+ strcat (buf, ", r2 not used");
+
+ for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
+ {
+ switch (e_flags & - e_flags)
+ {
+ case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
+ case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
+ case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
+ case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
+ case EF_RH850_MMU: strcat (buf, ", MMU"); break;
+ case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
+ case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
+ case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
+ case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
+ case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
+ case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
+ case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
+ case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
+ case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
+ case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
+ case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
+ default: break;
+ }
+ }
+ break;
+
case EM_V850:
case EM_CYGNUS_V850:
switch (e_flags & EF_V850_ARCH)
case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
default: strcat (buf, _(", unknown ISA")); break;
}
-
- if (e_flags & EF_SH_PIC)
- strcat (buf, ", pic");
-
- if (e_flags & EF_SH_FDPIC)
- strcat (buf, ", fdpic");
break;
case EM_SH:
default: strcat (buf, _(", unknown ISA")); break;
}
+ if (e_flags & EF_SH_PIC)
+ strcat (buf, ", pic");
+
+ if (e_flags & EF_SH_FDPIC)
+ strcat (buf, ", fdpic");
break;
case EM_SPARCV9:
strcat (buf, ", dsp");
if (e_flags & E_FLAG_RX_PID)
strcat (buf, ", pid");
+ if (e_flags & E_FLAG_RX_ABI)
+ strcat (buf, ", RX ABI");
break;
case EM_S390:
}
}
+static const char *
+get_aarch64_segment_type (unsigned long type)
+{
+ switch (type)
+ {
+ case PT_AARCH64_ARCHEXT:
+ return "AARCH64_ARCHEXT";
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
static const char *
get_arm_segment_type (unsigned long type)
{
switch (elf_header.e_machine)
{
+ case EM_AARCH64:
+ result = get_aarch64_segment_type (p_type);
+ break;
case EM_ARM:
result = get_arm_segment_type (p_type);
break;
return NULL;
}
+static const char *
+get_aarch64_section_type_name (unsigned int sh_type)
+{
+ switch (sh_type)
+ {
+ case SHT_AARCH64_ATTRIBUTES:
+ return "AARCH64_ATTRIBUTES";
+ default:
+ break;
+ }
+ return NULL;
+}
+
static const char *
get_arm_section_type_name (unsigned int sh_type)
{
case EM_K1OM:
result = get_x86_64_section_type_name (sh_type);
break;
+ case EM_AARCH64:
+ result = get_aarch64_section_type_name (sh_type);
+ break;
case EM_ARM:
result = get_arm_section_type_name (sh_type);
break;
#define OPTION_DYN_SYMS 513
#define OPTION_DWARF_DEPTH 514
#define OPTION_DWARF_START 515
+#define OPTION_DWARF_CHECK 516
static struct option options[] =
{
{"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
{"dwarf-start", required_argument, 0, OPTION_DWARF_START},
+ {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
{"version", no_argument, 0, 'v'},
{"wide", no_argument, 0, 'W'},
-u --unwind Display the unwind info (if present)\n\
-d --dynamic Display the dynamic section (if present)\n\
-V --version-info Display the version sections (if present)\n\
- -A --arch-specific Display architecture specific information (if any).\n\
+ -A --arch-specific Display architecture specific information (if any)\n\
-c --archive-index Display the symbol/file index in an archive\n\
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
-x --hex-dump=<number|name>\n\
-w[lLiaprmfFsoRt] or\n\
--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
=frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
- =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
+ =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
+ =addr,=cu_index]\n\
Display the contents of DWARF2 debug sections\n"));
fprintf (stream, _("\
--dwarf-depth=N Do not display DIEs at depth N or greater\n\
dwarf_start_die = strtoul (optarg, & cp, 0);
}
break;
+ case OPTION_DWARF_CHECK:
+ dwarf_check = 1;
+ break;
case OPTION_DYN_SYMS:
do_dyn_syms++;
break;
printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
else
{
- print_vma (segment->p_offset, FULL_HEX);
+ print_vma (segment->p_memsz, FULL_HEX);
}
printf (" %c%c%c ",
}
static Elf_Internal_Sym *
-get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
+get_32bit_elf_symbols (FILE * file,
+ Elf_Internal_Shdr * section,
+ unsigned long * num_syms_return)
{
- unsigned long number;
+ unsigned long number = 0;
Elf32_External_Sym * esyms = NULL;
- Elf_External_Sym_Shndx * shndx;
+ Elf_External_Sym_Shndx * shndx = NULL;
Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
unsigned int j;
if (section->sh_entsize == 0)
{
error (_("sh_entsize is zero\n"));
- return NULL;
+ goto exit_point;
}
number = section->sh_size / section->sh_entsize;
if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
{
error (_("Invalid sh_entsize\n"));
- return NULL;
+ goto exit_point;
}
esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
section->sh_size, _("symbols"));
if (esyms == NULL)
- return NULL;
+ goto exit_point;
shndx = NULL;
if (symtab_shndx_hdr != NULL
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
symtab_shndx_hdr->sh_offset,
1, symtab_shndx_hdr->sh_size,
- _("symtab shndx"));
+ _("symbol table section indicies"));
if (shndx == NULL)
goto exit_point;
}
}
exit_point:
- if (shndx)
+ if (shndx != NULL)
free (shndx);
- if (esyms)
+ if (esyms != NULL)
free (esyms);
+ if (num_syms_return != NULL)
+ * num_syms_return = isyms == NULL ? 0 : number;
+
return isyms;
}
static Elf_Internal_Sym *
-get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
+get_64bit_elf_symbols (FILE * file,
+ Elf_Internal_Shdr * section,
+ unsigned long * num_syms_return)
{
- unsigned long number;
- Elf64_External_Sym * esyms;
- Elf_External_Sym_Shndx * shndx;
- Elf_Internal_Sym * isyms;
+ unsigned long number = 0;
+ Elf64_External_Sym * esyms = NULL;
+ Elf_External_Sym_Shndx * shndx = NULL;
+ Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
unsigned int j;
if (section->sh_entsize == 0)
{
error (_("sh_entsize is zero\n"));
- return NULL;
+ goto exit_point;
}
number = section->sh_size / section->sh_entsize;
if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
{
error (_("Invalid sh_entsize\n"));
- return NULL;
+ goto exit_point;
}
esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
section->sh_size, _("symbols"));
if (!esyms)
- return NULL;
+ goto exit_point;
- shndx = NULL;
if (symtab_shndx_hdr != NULL
&& (symtab_shndx_hdr->sh_link
== (unsigned long) (section - section_headers)))
shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
symtab_shndx_hdr->sh_offset,
1, symtab_shndx_hdr->sh_size,
- _("symtab shndx"));
- if (!shndx)
- {
- free (esyms);
- return NULL;
- }
+ _("symbol table section indicies"));
+ if (shndx == NULL)
+ goto exit_point;
}
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
{
error (_("Out of memory\n"));
- if (shndx)
- free (shndx);
- free (esyms);
- return NULL;
+ goto exit_point;
}
- for (j = 0, psym = isyms;
- j < number;
- j++, psym++)
+ for (j = 0, psym = isyms; j < number; j++, psym++)
{
psym->st_name = BYTE_GET (esyms[j].st_name);
psym->st_info = BYTE_GET (esyms[j].st_info);
psym->st_other = BYTE_GET (esyms[j].st_other);
psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
+
if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
psym->st_shndx
= byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
+
psym->st_value = BYTE_GET (esyms[j].st_value);
psym->st_size = BYTE_GET (esyms[j].st_size);
}
- if (shndx)
+ exit_point:
+ if (shndx != NULL)
free (shndx);
- free (esyms);
+ if (esyms != NULL)
+ free (esyms);
+
+ if (num_syms_return != NULL)
+ * num_syms_return = isyms == NULL ? 0 : number;
return isyms;
}
}
CHECK_ENTSIZE (section, i, Sym);
- num_dynamic_syms = section->sh_size / section->sh_entsize;
- dynamic_symbols = GET_ELF_SYMBOLS (file, section);
+ dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
}
else if (section->sh_type == SHT_STRTAB
&& streq (name, ".dynstr"))
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|| do_debug_lines || do_debug_pubnames || do_debug_pubtypes
|| do_debug_aranges || do_debug_frames || do_debug_macinfo
- || do_debug_str || do_debug_loc || do_debug_ranges)
+ || do_debug_str || do_debug_loc || do_debug_ranges
+ || do_debug_addr || do_debug_cu_index)
&& (const_strneq (name, ".debug_")
|| const_strneq (name, ".zdebug_")))
{
name += sizeof (".debug_") - 1;
if (do_debugging
- || (do_debug_info && streq (name, "info"))
- || (do_debug_info && streq (name, "types"))
- || (do_debug_abbrevs && streq (name, "abbrev"))
- || (do_debug_lines && streq (name, "line"))
- || (do_debug_pubnames && streq (name, "pubnames"))
- || (do_debug_pubtypes && streq (name, "pubtypes"))
- || (do_debug_aranges && streq (name, "aranges"))
- || (do_debug_ranges && streq (name, "ranges"))
- || (do_debug_frames && streq (name, "frame"))
- || (do_debug_macinfo && streq (name, "macinfo"))
- || (do_debug_macinfo && streq (name, "macro"))
- || (do_debug_str && streq (name, "str"))
- || (do_debug_loc && streq (name, "loc"))
+ || (do_debug_info && const_strneq (name, "info"))
+ || (do_debug_info && const_strneq (name, "types"))
+ || (do_debug_abbrevs && const_strneq (name, "abbrev"))
+ || (do_debug_lines && const_strneq (name, "line"))
+ || (do_debug_pubnames && const_strneq (name, "pubnames"))
+ || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
+ || (do_debug_aranges && const_strneq (name, "aranges"))
+ || (do_debug_ranges && const_strneq (name, "ranges"))
+ || (do_debug_frames && const_strneq (name, "frame"))
+ || (do_debug_macinfo && const_strneq (name, "macinfo"))
+ || (do_debug_macinfo && const_strneq (name, "macro"))
+ || (do_debug_str && const_strneq (name, "str"))
+ || (do_debug_loc && const_strneq (name, "loc"))
+ || (do_debug_addr && const_strneq (name, "addr"))
+ || (do_debug_cu_index && const_strneq (name, "cu_index"))
+ || (do_debug_cu_index && const_strneq (name, "tu_index"))
)
request_dump_bynumber (i, DEBUG_DUMP);
}
i < elf_header.e_shnum;
i++, section++)
{
+ printf (" [%2u] ", i);
if (do_section_details)
{
- printf (" [%2u] %s\n",
- i,
- SECTION_NAME (section));
- if (is_32bit_elf || do_wide)
- printf (" %-15.15s ",
- get_section_type_name (section->sh_type));
+ print_symbol (INT_MAX, SECTION_NAME (section));
+ printf ("\n ");
}
else
- printf ((do_wide ? " [%2u] %-17s %-15s "
- : " [%2u] %-17.17s %-15.15s "),
- i,
- SECTION_NAME (section),
- get_section_type_name (section->sh_type));
-
+ {
+ print_symbol (-17, SECTION_NAME (section));
+ }
+
+ printf (do_wide ? " %-15s " : " %-15.15s ",
+ get_section_type_name (section->sh_type));
+
if (is_32bit_elf)
{
const char * link_too_big = NULL;
Elf_Internal_Shdr * symtab_sec;
Elf_Internal_Shdr * strtab_sec;
Elf_Internal_Sym * symtab;
+ unsigned long num_syms;
char * strtab;
size_t strtab_size;
if (section_headers == NULL)
{
error (_("Section headers are not available!\n"));
- abort ();
+ /* PR 13622: This can happen with a corrupt ELF header. */
+ return 0;
}
section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
symtab_sec = NULL;
strtab_sec = NULL;
symtab = NULL;
+ num_syms = 0;
strtab = NULL;
strtab_size = 0;
for (i = 0, section = section_headers, group = section_groups;
symtab_sec = sec;
if (symtab)
free (symtab);
- symtab = GET_ELF_SYMBOLS (file, symtab_sec);
+ symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
}
if (symtab == NULL)
continue;
}
+ if (section->sh_info >= num_syms)
+ {
+ error (_("Bad sh_info in group section `%s'\n"), name);
+ continue;
+ }
+
sym = symtab + section->sh_info;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
1, imgrela->img_rela_cnt * sizeof (*imrs),
- _("dynamic section image relas"));
+ _("dynamic section image relocations"));
if (!imrs)
return;
if (string_table == NULL)
printf ("%d", section->sh_name);
else
- printf (_("'%s'"), SECTION_NAME (section));
+ printf ("'%s'", SECTION_NAME (section));
printf (_(" at offset 0x%lx contains %lu entries:\n"),
rel_offset, (unsigned long) (rel_size / section->sh_entsize));
&& symsec->sh_type != SHT_DYNSYM)
continue;
- nsyms = symsec->sh_size / symsec->sh_entsize;
- symtab = GET_ELF_SYMBOLS (file, symsec);
+ symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
if (symtab == NULL)
continue;
break;
}
}
+
if (best)
{
*symname = (best->st_name >= strtab_size
*offset = dist;
return;
}
+
*symname = NULL;
*offset = addr.offset;
}
return 1;
}
-static int
+static void
ia64_process_unwind (FILE * file)
{
Elf_Internal_Shdr * sec;
if (sec->sh_type == SHT_SYMTAB
&& sec->sh_link < elf_header.e_shnum)
{
- aux.nsyms = sec->sh_size / sec->sh_entsize;
- aux.symtab = GET_ELF_SYMBOLS (file, sec);
+ aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
assert (aux.strtab == NULL);
free (aux.symtab);
if (aux.strtab)
free ((char *) aux.strtab);
-
- return 1;
}
struct hppa_unw_table_entry
return 1;
}
-static int
+static void
hppa_process_unwind (FILE * file)
{
struct hppa_unw_aux_info aux;
Elf_Internal_Shdr * sec;
unsigned long i;
- memset (& aux, 0, sizeof (aux));
-
if (string_table == NULL)
- return 1;
+ return;
+
+ memset (& aux, 0, sizeof (aux));
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
if (sec->sh_type == SHT_SYMTAB
&& sec->sh_link < elf_header.e_shnum)
{
- aux.nsyms = sec->sh_size / sec->sh_entsize;
- aux.symtab = GET_ELF_SYMBOLS (file, sec);
+ aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
assert (aux.strtab == NULL);
free (aux.symtab);
if (aux.strtab)
free ((char *) aux.strtab);
-
- return 1;
}
struct arm_section
{
- unsigned char *data;
-
- Elf_Internal_Shdr *sec;
- Elf_Internal_Rela *rela;
- unsigned long nrelas;
- unsigned int rel_type;
-
- Elf_Internal_Rela *next_rela;
+ unsigned char * data; /* The unwind data. */
+ Elf_Internal_Shdr * sec; /* The cached unwind section header. */
+ Elf_Internal_Rela * rela; /* The cached relocations for this section. */
+ unsigned long nrelas; /* The number of relocations. */
+ unsigned int rel_type; /* REL or RELA ? */
+ Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
};
struct arm_unw_aux_info
{
- FILE *file;
-
- Elf_Internal_Sym *symtab; /* The symbol table. */
- unsigned long nsyms; /* Number of symbols. */
- char *strtab; /* The string table. */
- unsigned long strtab_size; /* Size of string table. */
+ FILE * file; /* The file containing the unwind sections. */
+ Elf_Internal_Sym * symtab; /* The file's symbol table. */
+ unsigned long nsyms; /* Number of symbols. */
+ char * strtab; /* The file's string table. */
+ unsigned long strtab_size; /* Size of string table. */
};
static const char *
free (arm_sec->rela);
}
-static int
-arm_section_get_word (struct arm_unw_aux_info *aux,
- struct arm_section *arm_sec,
- Elf_Internal_Shdr *sec, bfd_vma word_offset,
- unsigned int *wordp, struct absaddr *addr)
+/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
+ cached section and install SEC instead.
+ 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
+ and return its valued in * WORDP, relocating if necessary.
+ 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
+ relocation's offset in ADDR.
+ 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
+ into the string table of the symbol associated with the reloc. If no
+ reloc was applied store -1 there.
+ 5) Return TRUE upon success, FALSE otherwise. */
+
+static bfd_boolean
+get_unwind_section_word (struct arm_unw_aux_info * aux,
+ struct arm_section * arm_sec,
+ Elf_Internal_Shdr * sec,
+ bfd_vma word_offset,
+ unsigned int * wordp,
+ struct absaddr * addr,
+ bfd_vma * sym_name)
{
Elf_Internal_Rela *rp;
Elf_Internal_Sym *sym;
addr->section = SHN_UNDEF;
addr->offset = 0;
+ if (sym_name != NULL)
+ *sym_name = (bfd_vma) -1;
+
+ /* If necessary, update the section cache. */
if (sec != arm_sec->sec)
{
Elf_Internal_Shdr *relsec;
|| section_headers + relsec->sh_info != sec)
continue;
+ arm_sec->rel_type = relsec->sh_type;
if (relsec->sh_type == SHT_REL)
{
if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
relsec->sh_size,
& arm_sec->rela, & arm_sec->nrelas))
- return 0;
+ return FALSE;
break;
}
else if (relsec->sh_type == SHT_RELA)
if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
relsec->sh_size,
& arm_sec->rela, & arm_sec->nrelas))
- return 0;
+ return FALSE;
break;
}
+ else
+ warn (_("unexpected relocation type (%d) for section %d"),
+ relsec->sh_type, relsec->sh_info);
}
arm_sec->next_rela = arm_sec->rela;
}
+ /* If there is no unwind data we can do nothing. */
if (arm_sec->data == NULL)
- return 0;
+ return FALSE;
+ /* Get the word at the required offset. */
word = byte_get (arm_sec->data + word_offset, 4);
+ /* Look through the relocs to find the one that applies to the provided offset. */
wrapped = FALSE;
for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
{
if (rp->r_offset < word_offset)
continue;
- switch (elf_header.e_machine)
- {
- case EM_ARM:
- relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
- break;
-
- case EM_TI_C6000:
- relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
- break;
-
- default:
- abort();
- }
-
- if (streq (relname, "R_ARM_NONE")
- || streq (relname, "R_C6000_NONE"))
- continue;
-
- if (!(streq (relname, "R_ARM_PREL31")
- || streq (relname, "R_C6000_PREL31")))
- {
- warn (_("Skipping unexpected relocation type %s\n"), relname);
- continue;
- }
-
sym = aux->symtab + ELF32_R_SYM (rp->r_info);
if (arm_sec->rel_type == SHT_REL)
if (offset & 0x40000000)
offset |= ~ (bfd_vma) 0x7fffffff;
}
- else
+ else if (arm_sec->rel_type == SHT_RELA)
offset = rp->r_addend;
+ else
+ abort ();
offset += sym->st_value;
prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
- if (streq (relname, "R_C6000_PREL31"))
- prelval >>= 1;
+ /* Check that we are processing the expected reloc type. */
+ if (elf_header.e_machine == EM_ARM)
+ {
+ relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
+
+ if (streq (relname, "R_ARM_NONE"))
+ continue;
+
+ if (! streq (relname, "R_ARM_PREL31"))
+ {
+ warn (_("Skipping unexpected relocation type %s\n"), relname);
+ continue;
+ }
+ }
+ else if (elf_header.e_machine == EM_TI_C6000)
+ {
+ relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
+
+ if (streq (relname, "R_C6000_NONE"))
+ continue;
+
+ if (! streq (relname, "R_C6000_PREL31"))
+ {
+ warn (_("Skipping unexpected relocation type %s\n"), relname);
+ continue;
+ }
+
+ prelval >>= 1;
+ }
+ else
+ /* This function currently only supports ARM and TI unwinders. */
+ abort ();
word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
addr->section = sym->st_shndx;
addr->offset = offset;
+ if (sym_name)
+ * sym_name = sym->st_name;
break;
}
*wordp = word;
arm_sec->next_rela = rp;
- return 1;
+ return TRUE;
}
-static const char *tic6x_unwind_regnames[16] = {
- "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
- "A14", "A13", "A12", "A11", "A10",
- "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
+static const char *tic6x_unwind_regnames[16] =
+{
+ "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
+ "A14", "A13", "A12", "A11", "A10",
+ "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
+};
static void
decode_tic6x_unwind_regmask (unsigned int mask)
if (remaining == 0 && more_words) \
{ \
data_offset += 4; \
- if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
- data_offset, &word, &addr)) \
+ if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
+ data_offset, & word, & addr, NULL)) \
return; \
remaining = 4; \
more_words--; \
}
if (op & 0x08)
{
- if (first)
+ if (!first)
printf (", ");
printf ("r14");
}
op = word >> 24;
word <<= 8;
- printf (_(" 0x%02x "), op);
+ printf (" 0x%02x ", op);
if ((op & 0xc0) == 0x00)
{
int offset = ((op & 0x3f) << 3) + 8;
- printf (_(" sp = sp + %d"), offset);
+ printf (" sp = sp + %d", offset);
}
else if ((op & 0xc0) == 0x80)
{
unsigned int nregs;
unsigned int i;
const char *name;
- struct {
+ struct
+ {
unsigned int offset;
unsigned int reg;
} regpos[16];
unsigned char buf[9];
unsigned int i, len;
unsigned long offset;
+
for (i = 0; i < sizeof (buf); i++)
{
GET_OP (buf[i]);
}
static bfd_vma
-expand_prel31 (bfd_vma word, bfd_vma where)
+arm_expand_prel31 (bfd_vma word, bfd_vma where)
{
bfd_vma offset;
}
static void
-decode_arm_unwind (struct arm_unw_aux_info *aux,
- unsigned int word, unsigned int remaining,
- bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
- struct arm_section *data_arm_sec)
+decode_arm_unwind (struct arm_unw_aux_info * aux,
+ unsigned int word,
+ unsigned int remaining,
+ bfd_vma data_offset,
+ Elf_Internal_Shdr * data_sec,
+ struct arm_section * data_arm_sec)
{
int per_index;
unsigned int more_words = 0;
struct absaddr addr;
+ bfd_vma sym_name = (bfd_vma) -1;
if (remaining == 0)
{
- /* Fetch the first word. */
- if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
- &word, &addr))
+ /* Fetch the first word.
+ Note - when decoding an object file the address extracted
+ here will always be 0. So we also pass in the sym_name
+ parameter so that we can find the symbol associated with
+ the personality routine. */
+ if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
+ & word, & addr, & sym_name))
return;
+
remaining = 4;
}
bfd_vma fn;
const char *procname;
- fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
+ fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
printf (_(" Personality routine: "));
- procname = arm_print_vma_and_name (aux, fn, addr);
+ if (fn == 0
+ && addr.section == SHN_UNDEF && addr.offset == 0
+ && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
+ {
+ procname = aux->strtab + sym_name;
+ print_vma (fn, PREFIX_HEX);
+ if (procname)
+ {
+ fputs (" <", stdout);
+ fputs (procname, stdout);
+ fputc ('>', stdout);
+ }
+ }
+ else
+ procname = arm_print_vma_and_name (aux, fn, addr);
fputc ('\n', stdout);
/* The GCC personality routines use the standard compact
}
else
{
-
+ /* ARM EHABI Section 6.3:
+
+ An exception-handling table entry for the compact model looks like:
+
+ 31 30-28 27-24 23-0
+ -- ----- ----- ----
+ 1 0 index Data for personalityRoutine[index] */
+
+ if (elf_header.e_machine == EM_ARM
+ && (word & 0x70000000))
+ warn (_("Corrupt ARM compact model table entry: %x \n"), word);
+
per_index = (word >> 24) & 0x7f;
- printf (_(" Compact model %d\n"), per_index);
+ printf (_(" Compact model index: %d\n"), per_index);
if (per_index == 0)
{
more_words = 0;
data_offset, data_sec, data_arm_sec);
}
else
- printf (" [reserved]\n");
+ {
+ warn (_("Unknown ARM compact model index encountered\n"));
+ printf (_(" [reserved]\n"));
+ }
break;
case EM_TI_C6000:
if (per_index < 3)
{
decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
- data_offset, data_sec, data_arm_sec);
+ data_offset, data_sec, data_arm_sec);
}
else if (per_index < 5)
{
tic6x_unwind_regnames[word & 0xf]);
}
else
- printf (" [reserved]\n");
+ printf (_(" [reserved (%d)]\n"), per_index);
break;
default:
- abort ();
+ error (_("Unsupported architecture type %d encountered when decoding unwind table"),
+ elf_header.e_machine);
}
/* Decode the descriptors. Not implemented. */
fputc ('\n', stdout);
- if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
- 8 * i, &exidx_fn, &fn_addr)
- || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
- 8 * i + 4, &exidx_entry, &entry_addr))
+ if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
+ 8 * i, & exidx_fn, & fn_addr, NULL)
+ || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
+ 8 * i + 4, & exidx_entry, & entry_addr, NULL))
{
- arm_free_section (&exidx_arm_sec);
- arm_free_section (&extab_arm_sec);
+ arm_free_section (& exidx_arm_sec);
+ arm_free_section (& extab_arm_sec);
return;
}
- fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
+ /* ARM EHABI, Section 5:
+ An index table entry consists of 2 words.
+ The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
+ if (exidx_fn & 0x80000000)
+ warn (_("corrupt index table entry: %x\n"), exidx_fn);
+
+ fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
- arm_print_vma_and_name (aux, fn, entry_addr);
+ arm_print_vma_and_name (aux, fn, fn_addr);
fputs (": ", stdout);
if (exidx_entry == 1)
Elf_Internal_Shdr *table_sec;
fputs ("@", stdout);
- table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
+ table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
print_vma (table, PREFIX_HEX);
printf ("\n");
}
/* Used for both ARM and C6X unwinding tables. */
-static int
+
+static void
arm_process_unwind (FILE *file)
{
struct arm_unw_aux_info aux;
unsigned long i;
unsigned int sec_type;
- memset (& aux, 0, sizeof (aux));
- aux.file = file;
-
switch (elf_header.e_machine)
{
case EM_ARM:
sec_type = SHT_C6000_UNWIND;
break;
- default:
- abort();
+ default:
+ error (_("Unsupported architecture type %d encountered when processing unwind table"),
+ elf_header.e_machine);
+ return;
}
if (string_table == NULL)
- return 1;
+ return;
+
+ memset (& aux, 0, sizeof (aux));
+ aux.file = file;
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
{
- aux.nsyms = sec->sh_size / sec->sh_entsize;
- aux.symtab = GET_ELF_SYMBOLS (file, sec);
+ aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
assert (aux.strtab == NULL);
unwsec = sec;
}
- if (!unwsec)
+ if (unwsec == NULL)
printf (_("\nThere are no unwind sections in this file.\n"));
+ else
+ for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
+ {
+ if (sec->sh_type == sec_type)
+ {
+ printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
+ SECTION_NAME (sec),
+ (unsigned long) sec->sh_offset,
+ (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
- for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
- {
- if (sec->sh_type == sec_type)
- {
- printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
- SECTION_NAME (sec),
- (unsigned long) sec->sh_offset,
- (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
-
- dump_arm_unwind (&aux, sec);
- }
- }
+ dump_arm_unwind (&aux, sec);
+ }
+ }
if (aux.symtab)
free (aux.symtab);
if (aux.strtab)
free ((char *) aux.strtab);
-
- return 1;
}
-static int
+static void
process_unwind (FILE * file)
{
struct unwind_handler
{
int machtype;
- int (* handler)(FILE *);
+ void (* handler)(FILE *);
} handlers[] =
{
{ EM_ARM, arm_process_unwind },
int i;
if (!do_unwind)
- return 1;
+ return;
for (i = 0; handlers[i].handler != NULL; i++)
if (elf_header.e_machine == handlers[i].machtype)
return handlers[i].handler (file);
- printf (_("\nThere are no unwind sections in this file.\n"));
- return 1;
+ printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
+ get_machine_name (elf_header.e_machine));
}
static void
{
case DT_MIPS_FLAGS:
if (entry->d_un.d_val == 0)
- printf (_("NONE\n"));
+ printf (_("NONE"));
else
{
static const char * opts[] =
printf ("%s%s", first ? "" : " ", opts[cnt]);
first = 0;
}
- puts ("");
}
break;
case DT_MIPS_IVERSION:
if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
- printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
+ printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
else
- printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
+ printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
break;
case DT_MIPS_TIME_STAMP:
snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
- printf (_("Time Stamp: %s\n"), timebuf);
+ printf (_("Time Stamp: %s"), timebuf);
}
break;
case DT_MIPS_DELTA_SYM_NO:
case DT_MIPS_DELTA_CLASSSYM_NO:
case DT_MIPS_COMPACT_SIZE:
- printf ("%ld\n", (long) entry->d_un.d_ptr);
+ print_vma (entry->d_un.d_ptr, DEC);
break;
default:
- printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
+ print_vma (entry->d_un.d_ptr, PREFIX_HEX);
}
+ putchar ('\n');
}
static void
else
section.sh_entsize = sizeof (Elf64_External_Sym);
- num_dynamic_syms = section.sh_size / section.sh_entsize;
+ dynamic_symbols = GET_ELF_SYMBOLS (file, §ion, & num_dynamic_syms);
if (num_dynamic_syms < 1)
{
error (_("Unable to determine the number of symbols to load\n"));
continue;
}
-
- dynamic_symbols = GET_ELF_SYMBOLS (file, §ion);
}
}
printf (" NODUMP");
val ^= DF_1_NODUMP;
}
- if (val & DF_1_CONLFAT)
+ if (val & DF_1_CONFALT)
+ {
+ printf (" CONFALT");
+ val ^= DF_1_CONFALT;
+ }
+ if (val & DF_1_ENDFILTEE)
+ {
+ printf (" ENDFILTEE");
+ val ^= DF_1_ENDFILTEE;
+ }
+ if (val & DF_1_DISPRELDNE)
+ {
+ printf (" DISPRELDNE");
+ val ^= DF_1_DISPRELDNE;
+ }
+ if (val & DF_1_DISPRELPND)
+ {
+ printf (" DISPRELPND");
+ val ^= DF_1_DISPRELPND;
+ }
+ if (val & DF_1_NODIRECT)
+ {
+ printf (" NODIRECT");
+ val ^= DF_1_NODIRECT;
+ }
+ if (val & DF_1_IGNMULDEF)
+ {
+ printf (" IGNMULDEF");
+ val ^= DF_1_IGNMULDEF;
+ }
+ if (val & DF_1_NOKSYMS)
{
- printf (" CONLFAT");
- val ^= DF_1_CONLFAT;
+ printf (" NOKSYMS");
+ val ^= DF_1_NOKSYMS;
+ }
+ if (val & DF_1_NOHDR)
+ {
+ printf (" NOHDR");
+ val ^= DF_1_NOHDR;
+ }
+ if (val & DF_1_EDITED)
+ {
+ printf (" EDITED");
+ val ^= DF_1_EDITED;
+ }
+ if (val & DF_1_NORELOC)
+ {
+ printf (" NORELOC");
+ val ^= DF_1_NORELOC;
+ }
+ if (val & DF_1_SYMINTPOSE)
+ {
+ printf (" SYMINTPOSE");
+ val ^= DF_1_SYMINTPOSE;
+ }
+ if (val & DF_1_GLOBAUDIT)
+ {
+ printf (" GLOBAUDIT");
+ val ^= DF_1_GLOBAUDIT;
+ }
+ if (val & DF_1_SINGLETON)
+ {
+ printf (" SINGLETON");
+ val ^= DF_1_SINGLETON;
}
if (val != 0)
printf (" %lx", val);
eneed = (Elf_External_Verneed *) get_data (NULL, file,
section->sh_offset, 1,
section->sh_size,
- _("version need section"));
+ _("Version Needs section"));
if (!eneed)
break;
endbuf = (char *) eneed + section->sh_size;
isum += aux.vna_next;
vstart += aux.vna_next;
}
+
if (j < ent.vn_cnt)
- printf (_(" Version need aux past end of section\n"));
+ warn (_("Missing Version Needs auxillary information\n"));
idx += ent.vn_next;
}
+
if (cnt < section->sh_info)
- printf (_(" Version need past end of section\n"));
+ warn (_("Missing Version Needs information\n"));
free (eneed);
}
char * strtab;
Elf_Internal_Sym * symbols;
Elf_Internal_Shdr * string_sec;
+ unsigned long num_syms;
long off;
if (section->sh_link >= elf_header.e_shnum)
found = 1;
- symbols = GET_ELF_SYMBOLS (file, link_section);
+ symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
if (symbols == NULL)
break;
data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
/* If this index value is greater than the size of the symbols
- array, break to avoid an out-of-bounds read, */
- if ((unsigned long)(cnt + j) >=
- ((unsigned long)link_section->sh_size /
- (unsigned long)link_section->sh_entsize))
+ array, break to avoid an out-of-bounds read. */
+ if ((unsigned long)(cnt + j) >= num_syms)
{
warn (_("invalid index into symbol array\n"));
break;
if (type == STT_GNU_IFUNC
&& (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
+ || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
/* GNU is still using the default value 0. */
|| elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
return "IFUNC";
sprintf (buff, "OS [0x%04x]", type & 0xffff);
else if (type >= SHN_LORESERVE)
sprintf (buff, "RSV[0x%04x]", type & 0xffff);
+ else if (type >= elf_header.e_shnum)
+ sprintf (buff, "bad section index[%3d]", type);
else
sprintf (buff, "%3d", type);
break;
unsigned long int strtab_size = 0;
Elf_Internal_Sym * symtab;
Elf_Internal_Sym * psym;
+ unsigned long num_syms;
if ((section->sh_type != SHT_SYMTAB
&& section->sh_type != SHT_DYNSYM)
else
printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
- symtab = GET_ELF_SYMBOLS (file, section);
+ symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
if (symtab == NULL)
continue;
strtab_size = strtab != NULL ? string_sec->sh_size : 0;
}
- for (si = 0, psym = symtab;
- si < section->sh_size / section->sh_entsize;
- si++, psym++)
+ for (si = 0, psym = symtab; si < num_syms; si++, psym++)
{
printf ("%6d: ", si);
print_vma (psym->st_value, LONG_HEX);
return reloc_type == 1; /* R_860_32. */
case EM_960:
return reloc_type == 2; /* R_960_32. */
+ case EM_AARCH64:
+ return reloc_type == 258; /* R_AARCH64_ABS32 */
case EM_ALPHA:
return reloc_type == 1; /* R_ALPHA_REFLONG. */
case EM_ARC:
case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 1;
+ case EM_ADAPTEVA_EPIPHANY:
+ return reloc_type == 3;
case EM_BLACKFIN:
return reloc_type == 0x12; /* R_byte4_data. */
case EM_CRIS:
return reloc_type == 3; /* R_CRIS_32. */
case EM_CR16:
- case EM_CR16_OLD:
return reloc_type == 3; /* R_CR16_NUM32. */
case EM_CRX:
return reloc_type == 15; /* R_CRX_NUM32. */
return reloc_type == 1; /* R_MCORE_ADDR32. */
case EM_CYGNUS_MEP:
return reloc_type == 4; /* R_MEP_32. */
+ case EM_METAG:
+ return reloc_type == 2; /* R_METAG_ADDR32. */
case EM_MICROBLAZE:
return reloc_type == 1; /* R_MICROBLAZE_32. */
case EM_MIPS:
return reloc_type == 1; /* R_PPC64_ADDR32. */
case EM_PPC:
return reloc_type == 1; /* R_PPC_ADDR32. */
+ case EM_RL78:
+ return reloc_type == 1; /* R_RL78_DIR32. */
case EM_RX:
return reloc_type == 1; /* R_RX_DIR32. */
case EM_S370:
case EM_CYGNUS_V850:
case EM_V850:
return reloc_type == 6; /* R_V850_ABS32. */
+ case EM_V800:
+ return reloc_type == 0x33; /* R_V810_WORD. */
case EM_VAX:
return reloc_type == 1; /* R_VAX_32. */
case EM_X86_64:
case EM_XC16X:
case EM_C166:
return reloc_type == 3; /* R_XC16C_ABS_32. */
+ case EM_XGATE:
+ return reloc_type == 4; /* R_XGATE_32. */
case EM_XSTORMY16:
return reloc_type == 1; /* R_XSTROMY16_32. */
case EM_XTENSA_OLD:
return reloc_type == 2; /* R_386_PC32. */
case EM_68K:
return reloc_type == 4; /* R_68K_PC32. */
+ case EM_AARCH64:
+ return reloc_type == 261; /* R_AARCH64_PREL32 */
+ case EM_ADAPTEVA_EPIPHANY:
+ return reloc_type == 6;
case EM_ALPHA:
return reloc_type == 10; /* R_ALPHA_SREL32. */
case EM_ARM:
{
switch (elf_header.e_machine)
{
+ case EM_AARCH64:
+ return reloc_type == 257; /* R_AARCH64_ABS64. */
case EM_ALPHA:
return reloc_type == 2; /* R_ALPHA_REFQUAD. */
case EM_IA_64:
{
switch (elf_header.e_machine)
{
+ case EM_AARCH64:
+ return reloc_type == 260; /* R_AARCH64_PREL64. */
case EM_ALPHA:
return reloc_type == 11; /* R_ALPHA_SREL64. */
case EM_IA_64:
case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 4; /* R_AVR_16. */
+ case EM_ADAPTEVA_EPIPHANY:
+ return reloc_type == 5;
case EM_CYGNUS_D10V:
case EM_D10V:
return reloc_type == 3; /* R_D10V_16. */
case EM_XC16X:
case EM_C166:
return reloc_type == 2; /* R_XC16C_ABS_16. */
+ case EM_CYGNUS_MN10200:
+ case EM_MN10200:
+ return reloc_type == 2; /* R_MN10200_16. */
+ case EM_CYGNUS_MN10300:
+ case EM_MN10300:
+ return reloc_type == 2; /* R_MN10300_16. */
+ case EM_XGATE:
+ return reloc_type == 3; /* R_XGATE_16. */
default:
return FALSE;
}
case EM_MIPS: /* R_MIPS_NONE. */
case EM_PARISC: /* R_PARISC_NONE. */
case EM_ALPHA: /* R_ALPHA_NONE. */
+ case EM_ADAPTEVA_EPIPHANY:
case EM_PPC: /* R_PPC_NONE. */
case EM_PPC64: /* R_PPC64_NONE. */
case EM_ARM: /* R_ARM_NONE. */
case EM_XC16X:
case EM_C166: /* R_XC16X_NONE. */
return reloc_type == 0;
+ case EM_AARCH64:
+ return reloc_type == 0 || reloc_type == 256;
case EM_XTENSA_OLD:
case EM_XTENSA:
return (reloc_type == 0 /* R_XTENSA_NONE. */
|| reloc_type == 17 /* R_XTENSA_DIFF8. */
|| reloc_type == 18 /* R_XTENSA_DIFF16. */
|| reloc_type == 19 /* R_XTENSA_DIFF32. */);
+ case EM_METAG:
+ return reloc_type == 3; /* R_METAG_NONE. */
}
return FALSE;
}
Elf_Internal_Rela * rp;
Elf_Internal_Shdr * symsec;
Elf_Internal_Sym * symtab;
+ unsigned long num_syms;
Elf_Internal_Sym * sym;
if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
is_rela = FALSE;
symsec = section_headers + relsec->sh_link;
- symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
+ symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
for (rp = relocs; rp < relocs + num_relocs; ++rp)
{
unsigned int reloc_type;
unsigned int reloc_size;
unsigned char * rloc;
+ unsigned long sym_index;
reloc_type = get_reloc_type (rp->r_info);
continue;
}
- sym = symtab + get_reloc_symindex (rp->r_info);
+ sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
+ if (sym_index >= num_syms)
+ {
+ warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
+ sym_index, SECTION_NAME (section));
+ continue;
+ }
+ sym = symtab + sym_index;
/* If the reloc has a symbol associated with it,
make sure that it is of an appropriate type.
return 1;
}
+/* If this is not NULL, load_debug_section will only look for sections
+ within the list of sections given here. */
+unsigned int *section_subset = NULL;
+
int
load_debug_section (enum dwarf_section_display_enum debug, void * file)
{
Elf_Internal_Shdr * sec;
/* Locate the debug section. */
- sec = find_section (section->uncompressed_name);
+ sec = find_section_in_set (section->uncompressed_name, section_subset);
if (sec != NULL)
section->name = section->uncompressed_name;
else
{
- sec = find_section (section->compressed_name);
+ sec = find_section_in_set (section->compressed_name, section_subset);
if (sec != NULL)
section->name = section->compressed_name;
}
if (sec == NULL)
return 0;
+ /* If we're loading from a subset of sections, and we've loaded
+ a section matching this name before, it's likely that it's a
+ different one. */
+ if (section_subset != NULL)
+ free_debug_section (debug);
+
return load_specific_debug_section (debug, sec, (FILE *) file);
}
}
static int
-display_debug_section (Elf_Internal_Shdr * section, FILE * file)
+display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
{
char * name = SECTION_NAME (section);
bfd_size_type length;
if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
section, file))
{
+ /* If this debug section is part of a CU/TU set in a .dwp file,
+ restrict load_debug_section to the sections in that set. */
+ section_subset = find_cu_tu_set (file, shndx);
+
result &= debug_displays[i].display (sec, file);
+ section_subset = NULL;
+
if (secondary || (i != info && i != abbrev))
free_debug_section ((enum dwarf_section_display_enum) i);
}
dump_section_as_strings (section, file);
if (dump_sects[i] & DEBUG_DUMP)
- display_debug_section (section, file);
+ display_debug_section (i, section, file);
}
/* Check to see if the user requested a
static const char * arm_attr_tag_CPU_arch[] =
{"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
- "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
+ "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
static const char * arm_attr_tag_THUMB_ISA_use[] =
{"No", "Thumb-1", "Thumb-2"};
static const char * arm_attr_tag_FP_arch[] =
- {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
+ {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
+ "FP for ARMv8"};
static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
static const char * arm_attr_tag_Advanced_SIMD_arch[] =
- {"No", "NEONv1", "NEONv1 with Fused-MAC"};
+ {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
static const char * arm_attr_tag_PCS_config[] =
{"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
"PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
liblistno,
sizeof (Elf32_External_Lib),
- _("liblist"));
+ _("liblist section data"));
if (elib)
{
printf (_("\nSection '.liblist' contains %lu entries:\n"),
offset = offset_from_vma (file, pltgot, global_end - pltgot);
data = (unsigned char *) get_data (NULL, file, offset,
- global_end - pltgot, 1, _("GOT"));
+ global_end - pltgot, 1,
+ _("Global Offset Table data"));
if (data == NULL)
return 0;
printf (_(" Global entries:\n"));
printf (" %*s %10s %*s %*s %-7s %3s %s\n",
- addr_size * 2, _("Address"), _("Access"),
+ addr_size * 2, _("Address"),
+ _("Access"),
addr_size * 2, _("Initial"),
- addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
+ addr_size * 2, _("Sym.Val."),
+ _("Type"),
+ /* Note for translators: "Ndx" = abbreviated form of "Index". */
+ _("Ndx"), _("Name"));
+
sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
for (i = gotsym; i < symtabno; i++)
{
offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
- 1, _("PLT GOT"));
+ 1, _("Procedure Linkage Table data"));
if (data == NULL)
return 0;
- printf (_("\nPLT GOT:\n\n"));
+ printf ("\nPLT GOT:\n\n");
printf (_(" Reserved entries:\n"));
printf (_(" %*s %*s Purpose\n"),
addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
elib = (Elf32_External_Lib *)
get_data (NULL, file, section->sh_offset, 1, section->sh_size,
- _("liblist"));
+ _("liblist section data"));
if (elib == NULL)
break;
return _("NT_PPC_VMX (ppc Altivec registers)");
case NT_PPC_VSX:
return _("NT_PPC_VSX (ppc VSX registers)");
+ case NT_386_TLS:
+ return _("NT_386_TLS (x86 TLS information)");
+ case NT_386_IOPERM:
+ return _("NT_386_IOPERM (x86 I/O permissions)");
case NT_X86_XSTATE:
return _("NT_X86_XSTATE (x86 XSAVE extended state)");
case NT_S390_HIGH_GPRS:
return _("NT_S390_PREFIX (s390 prefix register)");
case NT_ARM_VFP:
return _("NT_ARM_VFP (arm VFP registers)");
+ case NT_ARM_TLS:
+ return _("NT_ARM_TLS (AArch TLS registers)");
+ case NT_ARM_HW_BREAK:
+ return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
+ case NT_ARM_HW_WATCH:
+ return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
case NT_PSTATUS:
return _("NT_PSTATUS (pstatus structure)");
case NT_FPREGS:
return _("NT_LWPSINFO (lwpsinfo_t structure)");
case NT_WIN32PSTATUS:
return _("NT_WIN32PSTATUS (win32_pstatus structure)");
+ case NT_SIGINFO:
+ return _("NT_SIGINFO (siginfo_t data)");
+ case NT_FILE:
+ return _("NT_FILE (mapped files)");
default:
break;
}
return buff;
}
+static int
+print_core_note (Elf_Internal_Note *pnote)
+{
+ unsigned int addr_size = is_32bit_elf ? 4 : 8;
+ bfd_vma count, page_size;
+ unsigned char *descdata, *filenames, *descend;
+
+ if (pnote->type != NT_FILE)
+ return 1;
+
+#ifndef BFD64
+ if (!is_32bit_elf)
+ {
+ printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
+ /* Still "successful". */
+ return 1;
+ }
+#endif
+
+ if (pnote->descsz < 2 * addr_size)
+ {
+ printf (_(" Malformed note - too short for header\n"));
+ return 0;
+ }
+
+ descdata = (unsigned char *) pnote->descdata;
+ descend = descdata + pnote->descsz;
+
+ if (descdata[pnote->descsz - 1] != '\0')
+ {
+ printf (_(" Malformed note - does not end with \\0\n"));
+ return 0;
+ }
+
+ count = byte_get (descdata, addr_size);
+ descdata += addr_size;
+
+ page_size = byte_get (descdata, addr_size);
+ descdata += addr_size;
+
+ if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
+ {
+ printf (_(" Malformed note - too short for supplied file count\n"));
+ return 0;
+ }
+
+ printf (_(" Page size: "));
+ print_vma (page_size, DEC);
+ printf ("\n");
+
+ printf (_(" %*s%*s%*s\n"),
+ (int) (2 + 2 * addr_size), _("Start"),
+ (int) (4 + 2 * addr_size), _("End"),
+ (int) (4 + 2 * addr_size), _("Page Offset"));
+ filenames = descdata + count * 3 * addr_size;
+ while (--count > 0)
+ {
+ bfd_vma start, end, file_ofs;
+
+ if (filenames == descend)
+ {
+ printf (_(" Malformed note - filenames end too early\n"));
+ return 0;
+ }
+
+ start = byte_get (descdata, addr_size);
+ descdata += addr_size;
+ end = byte_get (descdata, addr_size);
+ descdata += addr_size;
+ file_ofs = byte_get (descdata, addr_size);
+ descdata += addr_size;
+
+ printf (" ");
+ print_vma (start, FULL_HEX);
+ printf (" ");
+ print_vma (end, FULL_HEX);
+ printf (" ");
+ print_vma (file_ofs, FULL_HEX);
+ printf ("\n %s\n", filenames);
+
+ filenames += 1 + strlen ((char *) filenames);
+ }
+
+ return 1;
+}
+
static const char *
get_gnu_elf_note_type (unsigned e_type)
{
printf (_(" Build ID: "));
for (i = 0; i < pnote->descsz; ++i)
printf ("%02x", pnote->descdata[i] & 0xff);
- printf (_("\n"));
+ printf ("\n");
}
break;
}
}
- snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
+ snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e_type - NT_NETBSDCORE_FIRSTMACH);
return buff;
}
print_vma (base_addr, FULL_HEX);
printf (_(", Semaphore: "));
print_vma (semaphore, FULL_HEX);
- printf (_("\n"));
+ printf ("\n");
printf (_(" Arguments: %s\n"), arg_fmt);
return data == data_end;
case NT_VMS_SRC:
return _("NT_VMS_SRC (source files)");
case NT_VMS_TITLE:
- return _("NT_VMS_TITLE");
+ return "NT_VMS_TITLE";
case NT_VMS_EIDC:
return _("NT_VMS_EIDC (consistency check)");
case NT_VMS_FPMODE:
return _("NT_VMS_FPMODE (FP mode)");
case NT_VMS_LINKTIME:
- return _("NT_VMS_LINKTIME");
+ return "NT_VMS_LINKTIME";
case NT_VMS_IMGNAM:
return _("NT_VMS_IMGNAM (image name)");
case NT_VMS_IMGID:
case NT_VMS_GSTNAM:
return _("NT_VMS_GSTNAM (sym table name)");
case NT_VMS_ORIG_DYN:
- return _("NT_VMS_ORIG_DYN");
+ return "NT_VMS_ORIG_DYN";
case NT_VMS_PATCHTIME:
- return _("NT_VMS_PATCHTIME");
+ return "NT_VMS_PATCHTIME";
default:
snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
return buff;
break;
#ifdef BFD64
case NT_VMS_FPMODE:
- printf (_(" FP mode: "));
+ printf (_(" Floating Point mode: "));
printf ("0x%016" BFD_VMA_FMT "x\n",
(bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
break;
printf (_(" Major id: %u, minor id: %u\n"),
(unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
(unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
- printf (_(" Manip date : "));
+ printf (_(" Last modified : "));
print_vms_time
((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
- printf (_("\n"
- " Link flags : "));
+ printf (_("\n Link flags : "));
printf ("0x%016" BFD_VMA_FMT "x\n",
(bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
printf (_(" Header flags: 0x%08x\n"),
return print_gnu_note (pnote);
else if (const_strneq (pnote->namedata, "stapsdt"))
return print_stapsdt_note (pnote);
+ else if (const_strneq (pnote->namedata, "CORE"))
+ return print_core_note (pnote);
else
return 1;
}
external = next;
/* Prevent out-of-bounds indexing. */
- if (inote.namedata + inote.namesz >= (char *) pnotes + length
+ if (inote.namedata + inote.namesz > (char *) pnotes + length
|| inote.namedata + inote.namesz < inote.namedata)
{
warn (_("corrupt note found at offset %lx into core notes\n"),
one version of Linux (RedHat 6.0) generates corefiles that don't
comply with the ELF spec by failing to include the null byte in
namesz. */
- if (inote.namedata[inote.namesz] != '\0')
+ if (inote.namedata[inote.namesz - 1] != '\0')
{
temp = (char *) malloc (inote.namesz + 1);
int res = 1;
for (i = 0, section = section_headers;
- i < elf_header.e_shnum;
+ i < elf_header.e_shnum && section != NULL;
i++, section++)
if (section->sh_type == SHT_NOTE)
res &= process_corefile_note_segment (file,
unsigned long current_pos;
printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
- file_name, arch.index_num, arch.sym_size);
+ file_name, (long) arch.index_num, arch.sym_size);
current_pos = ftell (file);
for (i = l = 0; i < arch.index_num; i++)
if (qualified_name != NULL)
{
- printf (_("Binary %s contains:\n"), qualified_name);
+ printf (_("Contents of binary %s at offset "), qualified_name);
+ (void) print_vma (arch.index_array[i], PREFIX_HEX);
+ putchar ('\n');
free (qualified_name);
}
}
l += strlen (arch.sym_table + l) + 1;
}
- if (l & 01)
- ++l;
+ if (arch.uses_64bit_indicies)
+ l = (l + 7) & ~ 7;
+ else
+ l += l & 1;
+
if (l < arch.sym_size)
- error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
- file_name);
+ error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
+ file_name, arch.sym_size - l);
if (fseek (file, current_pos, SEEK_SET) != 0)
{