#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-#define BYTE_GET(field) byte_get (field, sizeof (field))
+#define BYTE_GET(field) byte_get (field, sizeof (field))
+#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field))
#define GET_ELF_SYMBOLS(file, section) \
(is_32bit_elf ? get_32bit_elf_symbols (file, section) \
{
relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
relas[i].r_info = BYTE_GET (erelas[i].r_info);
- relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+ relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
}
free (erelas);
{
relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
relas[i].r_info = BYTE_GET (erelas[i].r_info);
- relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+ relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
/* The #ifdef BFD64 below is to prevent a compile time
warning. We know that if we do not have a 64 bit data
case EM_CR16_OLD:
rtype = elf_cr16_reloc_type (type);
break;
-
+
case EM_MICROBLAZE:
case EM_MICROBLAZE_OLD:
rtype = elf_microblaze_reloc_type (type);
if (is_rela)
{
- long off = (long) (bfd_signed_vma) rels[i].r_addend;
+ bfd_signed_vma off = rels[i].r_addend;
if (off < 0)
- printf (" - %lx", - off);
+ printf (" - %" BFD_VMA_FMT "x", - off);
else
- printf (" + %lx", off);
+ printf (" + %" BFD_VMA_FMT "x", off);
}
}
}
decode_ARM_machine_flags (e_flags, buf);
break;
+ case EM_BLACKFIN:
+ if (e_flags & EF_BFIN_PIC)
+ strcat (buf, ", PIC");
+
+ if (e_flags & EF_BFIN_FDPIC)
+ strcat (buf, ", FDPIC");
+
+ if (e_flags & EF_BFIN_CODE_IN_L1)
+ strcat (buf, ", code in L1");
+
+ if (e_flags & EF_BFIN_DATA_IN_L1)
+ strcat (buf, ", data in L1");
+
+ break;
+
case EM_CYGNUS_FRV:
switch (e_flags & EF_FRV_CPU_MASK)
{
case EF_M68K_CF_ISA_B:
isa = "B";
break;
+ case EF_M68K_CF_ISA_C:
+ isa = "C";
+ break;
+ case EF_M68K_CF_ISA_C_NODIV:
+ isa = "C";
+ additional = ", nodiv";
+ break;
}
strcat (buf, ", cf, isa ");
strcat (buf, isa);
case EF_M68K_CF_EMAC:
mac = "emac";
break;
+ case EF_M68K_CF_EMAC_B:
+ mac = "emac_b";
+ break;
}
if (mac)
{
case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
+ case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
strcat (buf, ", 64-bit doubles");
if (e_flags & E_FLAG_RX_DSP)
- strcat (buf, ", dsp");
+ strcat (buf, ", dsp");
case EM_S390:
if (e_flags & EF_S390_HIGH_GPRS)
get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
{
unsigned long number;
- Elf32_External_Sym * esyms;
+ Elf32_External_Sym * esyms = NULL;
Elf_External_Sym_Shndx * shndx;
- Elf_Internal_Sym * isyms;
+ Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
unsigned int j;
+ /* Run some sanity checks first. */
+ if (section->sh_entsize == 0)
+ {
+ error (_("sh_entsize is zero\n"));
+ return NULL;
+ }
+
+ number = section->sh_size / section->sh_entsize;
+
+ if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
+ {
+ error (_("Invalid sh_entsize\n"));
+ return NULL;
+ }
+
esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
section->sh_size, _("symbols"));
- if (!esyms)
+ if (esyms == NULL)
return NULL;
shndx = NULL;
symtab_shndx_hdr->sh_offset,
1, symtab_shndx_hdr->sh_size,
_("symtab shndx"));
- if (!shndx)
- {
- free (esyms);
- return NULL;
- }
+ if (shndx == NULL)
+ goto exit_point;
}
- number = section->sh_size / section->sh_entsize;
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_value = BYTE_GET (esyms[j].st_value);
psym->st_other = BYTE_GET (esyms[j].st_other);
}
+ exit_point:
if (shndx)
free (shndx);
- free (esyms);
+ if (esyms)
+ free (esyms);
return isyms;
}
Elf_Internal_Sym * psym;
unsigned int j;
+ /* Run some sanity checks first. */
+ if (section->sh_entsize == 0)
+ {
+ error (_("sh_entsize is zero\n"));
+ return NULL;
+ }
+
+ number = section->sh_size / section->sh_entsize;
+
+ if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
+ {
+ error (_("Invalid sh_entsize\n"));
+ return NULL;
+ }
+
esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
section->sh_size, _("symbols"));
if (!esyms)
}
}
- number = section->sh_size / section->sh_entsize;
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
}
if (!do_section_details)
- printf (_("Key to Flags:\n\
+ {
+ if (elf_header.e_machine == EM_X86_64
+ || elf_header.e_machine == EM_L1OM)
+ printf (_("Key to Flags:\n\
+ W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
+ I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
+ O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+ else
+ printf (_("Key to Flags:\n\
W (write), A (alloc), X (execute), M (merge), S (strings)\n\
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+ }
return 1;
}
symtab = GET_ELF_SYMBOLS (file, symtab_sec);
}
+ if (symtab == NULL)
+ {
+ error (_("Corrupt header in group section `%s'\n"), name);
+ continue;
+ }
+
sym = symtab + section->sh_info;
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
}
else
{
-
per_index = (word >> 24) & 0x7f;
if (per_index != 0 && per_index != 1 && per_index != 2)
{
int j;
int isum;
+ /* Check for negative or very large indicies. */
+ if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
+ break;
+
vstart = ((char *) edefs) + idx;
if (vstart + sizeof (*edef) > endbuf)
break;
printf (_(" Index: %d Cnt: %d "),
ent.vd_ndx, ent.vd_cnt);
+ /* Check for overflow. */
+ if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
+ || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
+ break;
+
vstart += ent.vd_aux;
eaux = (Elf_External_Verdaux *) vstart;
for (j = 1; j < ent.vd_cnt; j++)
{
+ /* Check for overflow. */
+ if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
+ || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
+ break;
+
isum += aux.vda_next;
vstart += aux.vda_next;
printf (_(" %#06x: Parent %d, name index: %ld\n"),
isum, j, aux.vda_name);
}
+
if (j < ent.vd_cnt)
printf (_(" Version def aux past end of section\n"));
idx += ent.vd_next;
}
+
if (cnt < section->sh_info)
printf (_(" Version definition past end of section\n"));
int isum;
char * vstart;
+ if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
+ break;
+
vstart = ((char *) eneed) + idx;
if (vstart + sizeof (*entry) > endbuf)
break;
printf (_(" Cnt: %d\n"), ent.vn_cnt);
+ /* Check for overflow. */
+ if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
+ || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
+ break;
+
vstart += ent.vn_aux;
for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
printf (_(" Flags: %s Version: %d\n"),
get_ver_flags (aux.vna_flags), aux.vna_other);
+ /* Check for overflow. */
+ if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
+ || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
+ break;
+
isum += aux.vna_next;
vstart += aux.vna_next;
}
found = 1;
symbols = GET_ELF_SYMBOLS (file, link_section);
+ if (symbols == NULL)
+ break;
string_sec = section_headers + link_section->sh_link;
nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
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))
+ {
+ warn (_("invalid index into symbol array\n"));
+ break;
+ }
+
check_def = 1;
check_need = 1;
if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
&& section->sh_type == SHT_SYMTAB))
continue;
+ if (section->sh_entsize == 0)
+ {
+ printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
+ SECTION_NAME (section));
+ continue;
+ }
+
printf (_("\nSymbol table '%s' contains %lu entries:\n"),
SECTION_NAME (section),
(unsigned long) (section->sh_size / section->sh_entsize));
+
if (is_32bit_elf)
printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
else
return reloc_type == 1; /* R_68K_32. */
case EM_860:
return reloc_type == 1; /* R_860_32. */
+ case EM_960:
+ return reloc_type == 2; /* R_960_32. */
case EM_ALPHA:
- return reloc_type == 1; /* XXX Is this right ? */
+ return reloc_type == 1; /* R_ALPHA_REFLONG. */
case EM_ARC:
return reloc_type == 1; /* R_ARC_32. */
case EM_ARM:
return reloc_type == 1; /* R_MCORE_ADDR32. */
case EM_CYGNUS_MEP:
return reloc_type == 4; /* R_MEP_32. */
+ case EM_MICROBLAZE:
+ return reloc_type == 1; /* R_MICROBLAZE_32. */
case EM_MIPS:
return reloc_type == 2; /* R_MIPS_32. */
case EM_MMIX:
return reloc_type == 10; /* R_ALPHA_SREL32. */
case EM_ARM:
return reloc_type == 3; /* R_ARM_REL32 */
+ case EM_MICROBLAZE:
+ return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
case EM_PARISC:
return reloc_type == 9; /* R_PARISC_PCREL32. */
case EM_PPC:
_("section contents"));
}
-
+
static void
dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
{
putchar ('\n');
}
-/* Uncompresses a section that was compressed using zlib, in place.
- This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
+/* Uncompresses a section that was compressed using zlib, in place. */
static int
uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
fail:
free (uncompressed_buffer);
+ /* Indicate decompression failure. */
+ *buffer = NULL;
return 0;
#endif /* HAVE_ZLIB_H */
}
{
struct dwarf_section * section = &debug_displays [debug].section;
char buf [64];
- int section_is_compressed;
/* If it is already loaded, do nothing. */
if (section->start != NULL)
return 1;
- section_is_compressed = section->name == section->compressed_name;
-
snprintf (buf, sizeof (buf), _("%s section data"), section->name);
section->address = sec->sh_addr;
section->size = sec->sh_size;
section->start = (unsigned char *) get_data (NULL, (FILE *) file,
sec->sh_offset, 1,
sec->sh_size, buf);
+ if (uncompress_section_contents (§ion->start, §ion->size))
+ sec->sh_size = section->size;
+
if (section->start == NULL)
return 0;
- if (section_is_compressed)
- {
- if (! uncompress_section_contents (§ion->start, §ion->size))
- return 0;
- sec->sh_size = section->size;
- }
-
if (debug_displays [debug].relocate)
apply_relocations ((FILE *) file, sec, section->start);
static const char * arm_attr_tag_FP_arch[] =
{"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
-static const char * arm_attr_tag_Advanced_SIMD_arch[] =
+static const char * arm_attr_tag_Advanced_SIMD_arch[] =
{"No", "NEONv1", "NEONv1 with Fused-MAC"};
static const char * arm_attr_tag_PCS_config[] =
{"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
{"Not Allowed", "Allowed"};
static const char * arm_attr_tag_ABI_FP_16bit_format[] =
{"None", "IEEE 754", "Alternative Format"};
-static const char * arm_attr_tag_MPextension_use[] =
+static const char * arm_attr_tag_MPextension_use[] =
{"Not Allowed", "Allowed"};
static const char * arm_attr_tag_DIV_use[] =
- {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
+ {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
"Allowed in v7-A with integer division extension"};
static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
static const char * arm_attr_tag_Virtualization_use[] =
- {"Not Allowed", "TrustZone", "Virtualization Extensions",
+ {"Not Allowed", "TrustZone", "Virtualization Extensions",
"TrustZone and Virtualization Extensions"};
-static const char * arm_attr_tag_MPextension_use_legacy[] =
+static const char * arm_attr_tag_MPextension_use_legacy[] =
{"Not Allowed", "Allowed"};
#define LOOKUP(id, name) \
case 3: printf ("??? 3\n"); break;
default:
if (val <= 12)
- printf (_("8-byte and up to %d-byte extended\n"),
+ printf (_("8-byte and up to %d-byte extended\n"),
1 << val);
else
printf ("??? (%d)\n", val);
case 3: printf ("??? 3\n"); break;
default:
if (val <= 12)
- printf (_("8-byte and up to %d-byte extended\n"),
+ printf (_("8-byte and up to %d-byte extended\n"),
1 << val);
else
printf ("??? (%d)\n", val);
printf (_("Soft float\n"));
break;
case 4:
- printf (_("64-bit float (-mips32r2 -mfp64)\n"));
+ printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
break;
default:
printf ("??? (%d)\n", val);
switch (tag)
{
- case Tag_C6XABI_Tag_CPU_arch:
+ case Tag_ISA:
val = read_uleb128 (p, &len);
p += len;
- printf (" Tag_C6XABI_Tag_CPU_arch: ");
+ printf (" Tag_ISA: ");
switch (val)
{
- case C6XABI_Tag_CPU_arch_none:
+ case C6XABI_Tag_ISA_none:
printf (_("None\n"));
break;
- case C6XABI_Tag_CPU_arch_C62X:
+ case C6XABI_Tag_ISA_C62X:
printf ("C62x\n");
break;
- case C6XABI_Tag_CPU_arch_C67X:
+ case C6XABI_Tag_ISA_C67X:
printf ("C67x\n");
break;
- case C6XABI_Tag_CPU_arch_C67XP:
+ case C6XABI_Tag_ISA_C67XP:
printf ("C67x+\n");
break;
- case C6XABI_Tag_CPU_arch_C64X:
+ case C6XABI_Tag_ISA_C64X:
printf ("C64x\n");
break;
- case C6XABI_Tag_CPU_arch_C64XP:
+ case C6XABI_Tag_ISA_C64XP:
printf ("C64x+\n");
break;
- case C6XABI_Tag_CPU_arch_C674X:
+ case C6XABI_Tag_ISA_C674X:
printf ("C674x\n");
break;
default:
}
return p;
- case 32:
- /* Tag_compatibility - treated as generic by binutils for now
- although not currently specified for C6X. */
+ case Tag_ABI_wchar_t:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_wchar_t: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("Not used\n"));
+ break;
+ case 1:
+ printf (_("2 bytes\n"));
+ break;
+ case 2:
+ printf (_("4 bytes\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_stack_align_needed:
val = read_uleb128 (p, &len);
p += len;
+ printf (" Tag_ABI_stack_align_needed: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("8-byte\n"));
+ break;
+ case 1:
+ printf (_("16-byte\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_stack_align_preserved:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_stack_align_preserved: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("8-byte\n"));
+ break;
+ case 1:
+ printf (_("16-byte\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_DSBT:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_DSBT: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("DSBT addressing not used\n"));
+ break;
+ case 1:
+ printf (_("DSBT addressing used\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_PID:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_PID: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("Data addressing position-dependent\n"));
+ break;
+ case 1:
+ printf (_("Data addressing position-independent, GOT near DP\n"));
+ break;
+ case 2:
+ printf (_("Data addressing position-independent, GOT far from DP\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_PIC:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_PIC: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("Code addressing position-dependent\n"));
+ break;
+ case 1:
+ printf (_("Code addressing position-independent\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_array_object_alignment:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_array_object_alignment: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("8-byte\n"));
+ break;
+ case 1:
+ printf (_("4-byte\n"));
+ break;
+ case 2:
+ printf (_("16-byte\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_array_object_align_expected:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_array_object_align_expected: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("8-byte\n"));
+ break;
+ case 1:
+ printf (_("4-byte\n"));
+ break;
+ case 2:
+ printf (_("16-byte\n"));
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+
+ case Tag_ABI_compatibility:
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_ABI_compatibility: ");
printf (_("flag = %d, vendor = %s\n"), val, p);
p += strlen ((char *) p) + 1;
return p;
+
+ case Tag_ABI_conformance:
+ printf (" Tag_ABI_conformance: ");
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ return p;
}
printf (" Tag_unknown_%d: ", tag);
- /* No general documentation of handling unknown attributes, treat as
- ULEB128 for now. */
- val = read_uleb128 (p, &len);
- p += len;
- printf ("%d (0x%x)\n", val, val);
+ if (tag & 1)
+ {
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ }
+ else
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf ("%d (0x%x)\n", val, val);
+ }
return p;
}
pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
_("notes"));
- if (!pnotes)
+ if (pnotes == NULL)
return 0;
external = pnotes;
next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
- if (((char *) next) > (((char *) pnotes) + length))
+ if ( ((char *) next > ((char *) pnotes) + length)
+ || ((char *) next < (char *) pnotes))
{
warn (_("corrupt note found at offset %lx into core notes\n"),
(unsigned long) ((char *) external - (char *) pnotes));
external = next;
+ /* Prevent out-of-bounds indexing. */
+ 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"),
+ (unsigned long) ((char *) external - (char *) pnotes));
+ warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
+ inote.type, inote.namesz, inote.descsz);
+ break;
+ }
+
/* Verify that name is null terminated. It appears that at least
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