#include "elf/d10v.h"
#include "elf/d30v.h"
#include "elf/dlx.h"
+#include "elf/bpf.h"
#include "elf/epiphany.h"
#include "elf/fr30.h"
#include "elf/frv.h"
return NULL;
}
- /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
+ /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
attempting to allocate memory when the read is bound to fail. */
- if (amt > filedata->file_size
- || offset + archive_file_offset + amt > filedata->file_size)
+ if (archive_file_offset > filedata->file_size
+ || offset > filedata->file_size - archive_file_offset
+ || amt > filedata->file_size - archive_file_offset - offset)
{
if (reason)
error (_("Reading %s bytes extends past end of file for %s\n"),
case EM_SCORE:
case EM_XGATE:
case EM_NFP:
+ case EM_BPF:
return FALSE;
/* Targets that use RELA relocations. */
rtype = elf_visium_reloc_type (type);
break;
+ case EM_BPF:
+ rtype = elf_bpf_reloc_type (type);
+ break;
+
case EM_ADAPTEVA_EPIPHANY:
rtype = elf_epiphany_reloc_type (type);
break;
return res;
}
+static const char *
+get_aarch64_dynamic_type (unsigned long type)
+{
+ switch (type)
+ {
+ case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
+ case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
+ default:
+ return NULL;
+ }
+}
+
static const char *
get_mips_dynamic_type (unsigned long type)
{
switch (filedata->file_header.e_machine)
{
+ case EM_AARCH64:
+ result = get_aarch64_dynamic_type (type);
+ break;
case EM_MIPS:
case EM_MIPS_RS3_LE:
result = get_mips_dynamic_type (type);
segment. Check this after matching against the section headers
so we don't warn on debuginfo file (which have NOBITS .dynamic
sections). */
- if (dynamic_addr + dynamic_size >= filedata->file_size)
+ if (dynamic_addr > filedata->file_size
+ || dynamic_size > filedata->file_size - dynamic_addr)
{
error (_("the dynamic segment offset + size exceeds the size of the file\n"));
dynamic_addr = dynamic_size = 0;
}
printf (_("pop frame {"));
- reg = nregs - 1;
- for (i = i * 2; i > 0; i--)
+ if (nregs == 0)
{
- if (regpos[reg].offset == i - 1)
+ printf (_("*corrupt* - no registers specified"));
+ }
+ else
+ {
+ reg = nregs - 1;
+ for (i = i * 2; i > 0; i--)
{
- name = tic6x_unwind_regnames[regpos[reg].reg];
- if (reg > 0)
- reg--;
- }
- else
- name = _("[pad]");
+ if (regpos[reg].offset == i - 1)
+ {
+ name = tic6x_unwind_regnames[regpos[reg].reg];
+ if (reg > 0)
+ reg--;
+ }
+ else
+ name = _("[pad]");
- fputs (name, stdout);
- if (i > 1)
- printf (", ");
+ fputs (name, stdout);
+ if (i > 1)
+ printf (", ");
+ }
}
printf ("}");
return TRUE;
}
+static void
+dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
+{
+ switch (entry->d_tag)
+ {
+ case DT_AARCH64_BTI_PLT:
+ case DT_AARCH64_PAC_PLT:
+ break;
+ default:
+ print_vma (entry->d_un.d_ptr, PREFIX_HEX);
+ break;
+ }
+ putchar ('\n');
+}
+
static void
dynamic_section_mips_val (Elf_Internal_Dyn * entry)
{
{
switch (filedata->file_header.e_machine)
{
+ case EM_AARCH64:
+ dynamic_section_aarch64_val (entry);
+ break;
case EM_MIPS:
case EM_MIPS_RS3_LE:
dynamic_section_mips_val (entry);
case EM_AARCH64:
return (reloc_type == 258
|| reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
+ case EM_BPF:
+ return reloc_type == 11; /* R_BPF_DATA_32 */
case EM_ADAPTEVA_EPIPHANY:
return reloc_type == 3;
case EM_ALPHA:
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", "v8", "v8-R", "v8-M.baseline",
- "v8-M.mainline"};
+ "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
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", "Yes"};
static const char * arm_attr_tag_MPextension_use_legacy[] =
{"Not Allowed", "Allowed"};
+static const char * arm_attr_tag_MVE_arch[] =
+ {"No MVE", "MVE Integer only", "MVE Integer and FP"};
+
#define LOOKUP(id, name) \
{id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
static arm_attr_public_tag arm_attr_public_tags[] =
LOOKUP(42, MPextension_use),
LOOKUP(44, DIV_use),
LOOKUP(46, DSP_extension),
+ LOOKUP(48, MVE_arch),
{64, "nodefaults", 0, NULL},
{65, "also_compatible_with", 0, NULL},
LOOKUP(66, T2EE_use),
error (_("No MIPS_OPTIONS header found\n"));
return FALSE;
}
+ /* PR 24243 */
+ if (sect->sh_size < sizeof (* eopt))
+ {
+ error (_("The MIPS options section is too small.\n"));
+ return FALSE;
+ }
eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
sect->sh_size, _("options"));
case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
printf ("AVX512_VNNI");
break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
+ printf ("AVX512_BF16");
+ break;
default:
printf (_("<unknown: %x>"), bit);
break;
}
}
+static void
+decode_aarch64_feature_1_and (unsigned int bitmask)
+{
+ while (bitmask)
+ {
+ unsigned int bit = bitmask & (- bitmask);
+
+ bitmask &= ~ bit;
+ switch (bit)
+ {
+ case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
+ printf ("BTI");
+ break;
+
+ case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
+ printf ("PAC");
+ break;
+
+ default:
+ printf (_("<unknown: %x>"), bit);
+ break;
+ }
+ if (bitmask)
+ printf (", ");
+ }
+}
+
static void
print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
{
break;
}
}
+ else if (filedata->file_header.e_machine == EM_AARCH64)
+ {
+ if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
+ {
+ printf ("AArch64 feature: ");
+ if (datasz != 4)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ decode_aarch64_feature_1_and (byte_get (ptr, 4));
+ goto next;
+ }
+ }
}
else
{
static bfd_boolean
print_stapsdt_note (Elf_Internal_Note *pnote)
{
- int addr_size = is_32bit_elf ? 4 : 8;
+ size_t len, maxlen;
+ unsigned long addr_size = is_32bit_elf ? 4 : 8;
char *data = pnote->descdata;
char *data_end = pnote->descdata + pnote->descsz;
bfd_vma pc, base_addr, semaphore;
char *provider, *probe, *arg_fmt;
+ if (pnote->descsz < (addr_size * 3))
+ goto stapdt_note_too_small;
+
pc = byte_get ((unsigned char *) data, addr_size);
data += addr_size;
+
base_addr = byte_get ((unsigned char *) data, addr_size);
data += addr_size;
+
semaphore = byte_get ((unsigned char *) data, addr_size);
data += addr_size;
- provider = data;
- data += strlen (data) + 1;
- probe = data;
- data += strlen (data) + 1;
- arg_fmt = data;
- data += strlen (data) + 1;
+ if (data >= data_end)
+ goto stapdt_note_too_small;
+ maxlen = data_end - data;
+ len = strnlen (data, maxlen);
+ if (len < maxlen)
+ {
+ provider = data;
+ data += len + 1;
+ }
+ else
+ goto stapdt_note_too_small;
+
+ if (data >= data_end)
+ goto stapdt_note_too_small;
+ maxlen = data_end - data;
+ len = strnlen (data, maxlen);
+ if (len < maxlen)
+ {
+ probe = data;
+ data += len + 1;
+ }
+ else
+ goto stapdt_note_too_small;
+
+ if (data >= data_end)
+ goto stapdt_note_too_small;
+ maxlen = data_end - data;
+ len = strnlen (data, maxlen);
+ if (len < maxlen)
+ {
+ arg_fmt = data;
+ data += len + 1;
+ }
+ else
+ goto stapdt_note_too_small;
printf (_(" Provider: %s\n"), provider);
printf (_(" Name: %s\n"), probe);
printf (_(" Arguments: %s\n"), arg_fmt);
return data == data_end;
+
+ stapdt_note_too_small:
+ printf (_(" <corrupt - note is too small>\n"));
+ error (_("corrupt stapdt note - the data size is too small\n"));
+ return FALSE;
}
static const char *
static bfd_boolean
print_ia64_vms_note (Elf_Internal_Note * pnote)
{
+ int maxlen = pnote->descsz;
+
+ if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
+ goto desc_size_fail;
+
switch (pnote->type)
{
case NT_VMS_MHD:
- if (pnote->descsz > 36)
- {
- size_t l = strlen (pnote->descdata + 34);
- printf (_(" Creation date : %.17s\n"), pnote->descdata);
- printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
- printf (_(" Module name : %s\n"), pnote->descdata + 34);
- printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
- }
+ if (maxlen <= 36)
+ goto desc_size_fail;
+
+ int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
+
+ printf (_(" Creation date : %.17s\n"), pnote->descdata);
+ printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
+ if (l + 34 < maxlen)
+ {
+ printf (_(" Module name : %s\n"), pnote->descdata + 34);
+ if (l + 35 < maxlen)
+ printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
+ else
+ printf (_(" Module version : <missing>\n"));
+ }
else
- printf (_(" Invalid size\n"));
+ {
+ printf (_(" Module name : <missing>\n"));
+ printf (_(" Module version : <missing>\n"));
+ }
break;
+
case NT_VMS_LNM:
- printf (_(" Language: %s\n"), pnote->descdata);
+ printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
break;
+
#ifdef BFD64
case NT_VMS_FPMODE:
printf (_(" Floating Point mode: "));
+ if (maxlen < 8)
+ goto desc_size_fail;
+ /* FIXME: Generate an error if descsz > 8 ? */
+
printf ("0x%016" BFD_VMA_FMT "x\n",
- (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
+ (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
break;
+
case NT_VMS_LINKTIME:
printf (_(" Link time: "));
+ if (maxlen < 8)
+ goto desc_size_fail;
+ /* FIXME: Generate an error if descsz > 8 ? */
+
print_vms_time
- ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
+ ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
printf ("\n");
break;
+
case NT_VMS_PATCHTIME:
printf (_(" Patch time: "));
+ if (maxlen < 8)
+ goto desc_size_fail;
+ /* FIXME: Generate an error if descsz > 8 ? */
+
print_vms_time
- ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
+ ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
printf ("\n");
break;
+
case NT_VMS_ORIG_DYN:
+ if (maxlen < 34)
+ goto desc_size_fail;
+
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));
(bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
printf (_(" Header flags: 0x%08x\n"),
(unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
- printf (_(" Image id : %s\n"), pnote->descdata + 32);
+ printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
break;
#endif
+
case NT_VMS_IMGNAM:
- printf (_(" Image name: %s\n"), pnote->descdata);
+ printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
break;
+
case NT_VMS_GSTNAM:
- printf (_(" Global symbol table name: %s\n"), pnote->descdata);
+ printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
break;
+
case NT_VMS_IMGID:
- printf (_(" Image id: %s\n"), pnote->descdata);
+ printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
break;
+
case NT_VMS_LINKID:
- printf (_(" Linker id: %s\n"), pnote->descdata);
+ printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
break;
+
default:
return FALSE;
}
+
return TRUE;
+
+ desc_size_fail:
+ printf (_(" <corrupt - data size is too small>\n"));
+ error (_("corrupt IA64 note: data size is too small\n"));
+ return FALSE;
}
/* Find the symbol associated with a build attribute that is attached
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 - 1] != '\0')
+ if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
{
if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
{
static bfd_boolean
process_object (Filedata * filedata)
{
- Filedata * separates;
+ bfd_boolean have_separate_files;
unsigned int i;
bfd_boolean res = TRUE;
res = FALSE;
if (filedata->file_header.e_shstrndx != SHN_UNDEF)
- separates = load_separate_debug_file (filedata, filedata->file_name);
+ have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
else
- separates = NULL;
+ have_separate_files = FALSE;
if (! process_section_contents (filedata))
res = FALSE;
- if (separates)
+ if (have_separate_files)
{
- if (! process_section_headers (separates))
- res = FALSE;
- else if (! process_section_contents (separates))
- res = FALSE;
+ separate_info * d;
+
+ for (d = first_separate_info; d != NULL; d = d->next)
+ {
+ if (! process_section_headers (d->handle))
+ res = FALSE;
+ else if (! process_section_contents (d->handle))
+ res = FALSE;
+ }
+
+ /* The file handles are closed by the call to free_debug_memory() below. */
}
if (! process_notes (filedata))