/* readelf.c -- display contents of an ELF format file
- Copyright (C) 1998-2018 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
Modifications by Nick Clifton <nickc@redhat.com>
#include "bucomm.h"
#include "elfcomm.h"
#include "dwarf.h"
+#include "ctf-api.h"
#include "elf/common.h"
#include "elf/external.h"
#include "elf/cr16.h"
#include "elf/cris.h"
#include "elf/crx.h"
+#include "elf/csky.h"
#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"
#include "elf/m32r.h"
#include "elf/m68k.h"
#include "elf/m68hc11.h"
+#include "elf/s12z.h"
#include "elf/mcore.h"
#include "elf/mep.h"
#include "elf/metag.h"
#include "elf/mt.h"
#include "elf/msp430.h"
#include "elf/nds32.h"
+#include "elf/nfp.h"
#include "elf/nios2.h"
#include "elf/or1k.h"
#include "elf/pj.h"
#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
+#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
typedef unsigned char dump_type;
static bfd_boolean do_version = FALSE;
static bfd_boolean do_histogram = FALSE;
static bfd_boolean do_debugging = FALSE;
+static bfd_boolean do_ctf = FALSE;
static bfd_boolean do_arch = FALSE;
static bfd_boolean do_notes = FALSE;
static bfd_boolean do_archive_index = FALSE;
static bfd_boolean is_32bit_elf = FALSE;
static bfd_boolean decompress_dumps = FALSE;
+static char *dump_ctf_parent_name;
+static char *dump_ctf_symtab_name;
+static char *dump_ctf_strtab_name;
+
struct group_list
{
struct group_list * next;
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"),
width = - width;
extra_padding = TRUE;
}
- assert (width != 0);
+ else if (width == 0)
+ return 0;
if (do_wide)
/* Set the remaining width to a very large value.
{
unsigned int i;
- assert (filedata->section_headers != NULL);
+ if (filedata->section_headers == NULL)
+ return NULL;
for (i = 0; i < filedata->file_header.e_shnum; i++)
if (streq (SECTION_NAME (filedata->section_headers + i), name))
{
unsigned int i;
+ if (filedata->section_headers == NULL)
+ return NULL;
+
for (i = 0; i < filedata->file_header.e_shnum; i++)
{
Elf_Internal_Shdr *sec = filedata->section_headers + i;
{
unsigned int i;
+ if (filedata->section_headers == NULL)
+ return NULL;
+
for (i = 0; i < filedata->file_header.e_shnum; i++)
{
Elf_Internal_Shdr *sec = filedata->section_headers + i;
{
unsigned int i;
+ if (filedata->section_headers == NULL)
+ return NULL;
+
if (set != NULL)
{
while ((i = *set++) > 0)
case EM_CYGNUS_M32R:
case EM_SCORE:
case EM_XGATE:
+ case EM_NFP:
+ case EM_BPF:
return FALSE;
/* Targets that use RELA relocations. */
case EM_CR16:
case EM_CRIS:
case EM_CRX:
+ case EM_CSKY:
case EM_D30V:
case EM_CYGNUS_D30V:
case EM_FR30:
rtype = elf_m68hc11_reloc_type (type);
break;
+ case EM_S12Z:
+ rtype = elf_s12z_reloc_type (type);
+ break;
+
case EM_68K:
rtype = elf_m68k_reloc_type (type);
break;
rtype = elf_frv_reloc_type (type);
break;
+ case EM_CSKY:
+ rtype = elf_csky_reloc_type (type);
+ break;
+
case EM_FT32:
rtype = elf_ft32_reloc_type (type);
break;
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;
case EM_TI_PRU:
rtype = elf_pru_reloc_type (type);
break;
+
+ case EM_NFP:
+ if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
+ rtype = elf_nfp3200_reloc_type (type);
+ else
+ rtype = elf_nfp_reloc_type (type);
+ break;
}
if (rtype == NULL)
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";
+ case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
+ 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);
case EM_PARISC: return "HPPA";
case EM_VPP550: return "Fujitsu VPP500";
case EM_SPARC32PLUS: return "Sparc v8+" ;
- case EM_960: return "Intel 90860";
+ case EM_960: return "Intel 80960";
case EM_PPC: return "PowerPC";
/* 20 */
case EM_PPC64: return "PowerPC64";
case EM_RISCV: return "RISC-V";
case EM_LANAI: return "Lanai 32-bit processor";
case EM_BPF: return "Linux BPF";
+ case EM_NFP: return "Netronome Flow Processor";
/* Large numbers... */
case EM_MT: return "Morpho Techologies MT processor";
case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
case EM_CYGNUS_FRV: return "Fujitsu FR-V";
+ case EM_S12Z: return "Freescale S12Z";
+ case EM_CSKY: return "C-SKY";
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
e_flags &= ~ EF_ARM_RELEXEC;
}
+ if (e_flags & EF_ARM_PIC)
+ {
+ strcat (buf, ", position independent");
+ e_flags &= ~ EF_ARM_PIC;
+ }
+
/* Now handle EABI specific flags. */
switch (eabi)
{
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_GS464: strcat (buf, ", gs464"); break;
+ case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
+ case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
break;
+ case EM_NFP:
+ switch (EF_NFP_MACH (e_flags))
+ {
+ case E_NFP_MACH_3200:
+ strcat (buf, ", NFP-32xx");
+ break;
+ case E_NFP_MACH_6000:
+ strcat (buf, ", NFP-6xxx");
+ break;
+ }
+ break;
+
case EM_RISCV:
if (e_flags & EF_RISCV_RVC)
strcat (buf, ", RVC");
+ if (e_flags & EF_RISCV_RVE)
+ strcat (buf, ", RVE");
+
switch (e_flags & EF_RISCV_FLOAT_ABI)
{
case EF_RISCV_FLOAT_ABI_SOFT:
? ", uses String instructions" : ", bans String instructions");
if (e_flags & E_FLAG_RX_V2)
strcat (buf, ", V2");
+ if (e_flags & E_FLAG_RX_V3)
+ strcat (buf, ", V3");
break;
case EM_S390:
switch (osabi)
{
case ELFOSABI_ARM: return "ARM";
+ case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
default:
break;
}
case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
case PT_GNU_STACK: return "GNU_STACK";
case PT_GNU_RELRO: return "GNU_RELRO";
+ case PT_GNU_PROPERTY: return "GNU_PROPERTY";
default:
if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
}
}
+static const char *
+get_nfp_section_type_name (unsigned int sh_type)
+{
+ switch (sh_type)
+ {
+ case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
+ case SHT_NFP_INITREG: return "NFP_INITREG";
+ case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
+ default: return NULL;
+ }
+}
+
static const char *
get_v850_section_type_name (unsigned int sh_type)
{
}
}
+static const char *
+get_riscv_section_type_name (unsigned int sh_type)
+{
+ switch (sh_type)
+ {
+ case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
+ default: return NULL;
+ }
+}
+
static const char *
get_section_type_name (Filedata * filedata, unsigned int sh_type)
{
case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
case SHT_GNU_HASH: return "GNU_HASH";
case SHT_GROUP: return "GROUP";
- case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
+ case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
case SHT_GNU_verdef: return "VERDEF";
case SHT_GNU_verneed: return "VERNEED";
case SHT_GNU_versym: return "VERSYM";
case EM_MSP430:
result = get_msp430x_section_type_name (sh_type);
break;
+ case EM_NFP:
+ result = get_nfp_section_type_name (sh_type);
+ break;
case EM_V800:
case EM_V850:
case EM_CYGNUS_V850:
result = get_v850_section_type_name (sh_type);
break;
+ case EM_RISCV:
+ result = get_riscv_section_type_name (sh_type);
+ break;
default:
result = NULL;
break;
#define OPTION_DWARF_DEPTH 514
#define OPTION_DWARF_START 515
#define OPTION_DWARF_CHECK 516
+#define OPTION_CTF_DUMP 517
+#define OPTION_CTF_PARENT 518
+#define OPTION_CTF_SYMBOLS 519
+#define OPTION_CTF_STRINGS 520
static struct option options[] =
{
{"dwarf-start", required_argument, 0, OPTION_DWARF_START},
{"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
+ {"ctf", required_argument, 0, OPTION_CTF_DUMP},
+
+ {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
+ {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
+ {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
+
{"version", no_argument, 0, 'v'},
{"wide", no_argument, 0, 'W'},
{"help", no_argument, 0, 'H'},
--dwarf-depth=N Do not display DIEs at depth N or greater\n\
--dwarf-start=N Display DIEs starting with N, at the same depth\n\
or deeper\n"));
+ fprintf (stream, _("\
+ --ctf=<number|name> Display CTF info from section <number|name>\n\
+ --ctf-parent=<number|name>\n\
+ Use section <number|name> as the CTF parent\n\n\
+ --ctf-symbols=<number|name>\n\
+ Use section <number|name> as the CTF external symtab\n\n\
+ --ctf-strings=<number|name>\n\
+ Use section <number|name> as the CTF external strtab\n\n"));
+
#ifdef SUPPORT_DISASSEMBLY
fprintf (stream, _("\
-i --instruction-dump=<number|name>\n\
case OPTION_DWARF_CHECK:
dwarf_check = TRUE;
break;
+ case OPTION_CTF_DUMP:
+ do_ctf = TRUE;
+ request_dump (filedata, CTF_DUMP);
+ break;
+ case OPTION_CTF_SYMBOLS:
+ dump_ctf_symtab_name = strdup (optarg);
+ break;
+ case OPTION_CTF_STRINGS:
+ dump_ctf_strtab_name = strdup (optarg);
+ break;
+ case OPTION_CTF_PARENT:
+ dump_ctf_parent_name = strdup (optarg);
+ break;
case OPTION_DYN_SYMS:
do_dyn_syms = TRUE;
break;
get_elf_class (header->e_ident[EI_CLASS]));
printf (_(" Data: %s\n"),
get_data_encoding (header->e_ident[EI_DATA]));
- printf (_(" Version: %d %s\n"),
+ printf (_(" Version: %d%s\n"),
header->e_ident[EI_VERSION],
(header->e_ident[EI_VERSION] == EV_CURRENT
- ? "(current)"
+ ? _(" (current)")
: (header->e_ident[EI_VERSION] != EV_NONE
- ? _("<unknown: %lx>")
+ ? _(" <unknown>")
: "")));
printf (_(" OS/ABI: %s\n"),
get_osabi_name (filedata, header->e_ident[EI_OSABI]));
printf (_(" Machine: %s\n"),
get_machine_name (header->e_machine));
printf (_(" Version: 0x%lx\n"),
- (unsigned long) header->e_version);
+ header->e_version);
printf (_(" Entry point address: "));
- print_vma ((bfd_vma) header->e_entry, PREFIX_HEX);
+ print_vma (header->e_entry, PREFIX_HEX);
printf (_("\n Start of program headers: "));
- print_vma ((bfd_vma) header->e_phoff, DEC);
+ print_vma (header->e_phoff, DEC);
printf (_(" (bytes into file)\n Start of section headers: "));
- print_vma ((bfd_vma) header->e_shoff, DEC);
+ print_vma (header->e_shoff, DEC);
printf (_(" (bytes into file)\n"));
printf (_(" Flags: 0x%lx%s\n"),
- (unsigned long) header->e_flags,
+ header->e_flags,
get_machine_flags (filedata, header->e_flags, header->e_machine));
- printf (_(" Size of this header: %ld (bytes)\n"),
- (long) header->e_ehsize);
- printf (_(" Size of program headers: %ld (bytes)\n"),
- (long) header->e_phentsize);
- printf (_(" Number of program headers: %ld"),
- (long) header->e_phnum);
+ printf (_(" Size of this header: %u (bytes)\n"),
+ header->e_ehsize);
+ printf (_(" Size of program headers: %u (bytes)\n"),
+ header->e_phentsize);
+ printf (_(" Number of program headers: %u"),
+ header->e_phnum);
if (filedata->section_headers != NULL
&& header->e_phnum == PN_XNUM
&& filedata->section_headers[0].sh_info != 0)
- printf (" (%ld)", (long) filedata->section_headers[0].sh_info);
+ {
+ header->e_phnum = filedata->section_headers[0].sh_info;
+ printf (" (%u)", header->e_phnum);
+ }
putc ('\n', stdout);
- printf (_(" Size of section headers: %ld (bytes)\n"),
- (long) header->e_shentsize);
- printf (_(" Number of section headers: %ld"),
- (long) header->e_shnum);
+ printf (_(" Size of section headers: %u (bytes)\n"),
+ header->e_shentsize);
+ printf (_(" Number of section headers: %u"),
+ header->e_shnum);
if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
- printf (" (%ld)", (long) filedata->section_headers[0].sh_size);
+ {
+ header->e_shnum = filedata->section_headers[0].sh_size;
+ printf (" (%u)", header->e_shnum);
+ }
putc ('\n', stdout);
- printf (_(" Section header string table index: %ld"),
- (long) header->e_shstrndx);
+ printf (_(" Section header string table index: %u"),
+ header->e_shstrndx);
if (filedata->section_headers != NULL
&& header->e_shstrndx == (SHN_XINDEX & 0xffff))
- printf (" (%u)", filedata->section_headers[0].sh_link);
- else if (header->e_shstrndx != SHN_UNDEF
- && header->e_shstrndx >= header->e_shnum)
- printf (_(" <corrupt: out of range>"));
+ {
+ header->e_shstrndx = filedata->section_headers[0].sh_link;
+ printf (" (%u)", header->e_shstrndx);
+ }
+ if (header->e_shstrndx != SHN_UNDEF
+ && header->e_shstrndx >= header->e_shnum)
+ {
+ header->e_shstrndx = SHN_UNDEF;
+ printf (_(" <corrupt: out of range>"));
+ }
putc ('\n', stdout);
}
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;
{
if (!probe)
error (_("Out of memory reading %u section headers\n"), num);
+ free (shdrs);
return FALSE;
}
{
if (! probe)
error (_("Out of memory reading %u section headers\n"), num);
+ free (shdrs);
return FALSE;
}
Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
unsigned int j;
+ elf_section_list * entry;
if (section->sh_size == 0)
{
if (esyms == NULL)
goto exit_point;
- {
- elf_section_list * entry;
-
- shndx = NULL;
- for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
- if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
- {
- shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
- entry->hdr->sh_offset,
- 1, entry->hdr->sh_size,
- _("symbol table section indicies"));
- if (shndx == NULL)
- goto exit_point;
- /* PR17531: file: heap-buffer-overflow */
- else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
- {
- error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
- printable_section_name (filedata, entry->hdr),
- (unsigned long) entry->hdr->sh_size,
- (unsigned long) section->sh_size);
- goto exit_point;
- }
+ shndx = NULL;
+ for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
+ {
+ if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
+ continue;
+
+ if (shndx != NULL)
+ {
+ error (_("Multiple symbol table index sections associated with the same symbol section\n"));
+ free (shndx);
+ }
+
+ shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
+ entry->hdr->sh_offset,
+ 1, entry->hdr->sh_size,
+ _("symbol table section indices"));
+ if (shndx == NULL)
+ goto exit_point;
+
+ /* PR17531: file: heap-buffer-overflow */
+ if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+ {
+ error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+ printable_section_name (filedata, entry->hdr),
+ (unsigned long) entry->hdr->sh_size,
+ (unsigned long) section->sh_size);
+ goto exit_point;
}
- }
+ }
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
}
exit_point:
- if (shndx != NULL)
- free (shndx);
- if (esyms != NULL)
- free (esyms);
+ free (shndx);
+ free (esyms);
if (num_syms_return != NULL)
* num_syms_return = isyms == NULL ? 0 : number;
Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
unsigned int j;
+ elf_section_list * entry;
if (section->sh_size == 0)
{
if (!esyms)
goto exit_point;
- {
- elf_section_list * entry;
-
- shndx = NULL;
- for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
- if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
- {
- shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
- entry->hdr->sh_offset,
- 1, entry->hdr->sh_size,
- _("symbol table section indicies"));
- if (shndx == NULL)
- goto exit_point;
- /* PR17531: file: heap-buffer-overflow */
- else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
- {
- error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
- printable_section_name (filedata, entry->hdr),
- (unsigned long) entry->hdr->sh_size,
- (unsigned long) section->sh_size);
- goto exit_point;
- }
+ shndx = NULL;
+ for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
+ {
+ if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
+ continue;
+
+ if (shndx != NULL)
+ {
+ error (_("Multiple symbol table index sections associated with the same symbol section\n"));
+ free (shndx);
+ }
+
+ shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
+ entry->hdr->sh_offset,
+ 1, entry->hdr->sh_size,
+ _("symbol table section indices"));
+ if (shndx == NULL)
+ goto exit_point;
+
+ /* PR17531: file: heap-buffer-overflow */
+ if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+ {
+ error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+ printable_section_name (filedata, entry->hdr),
+ (unsigned long) entry->hdr->sh_size,
+ (unsigned long) section->sh_size);
+ goto exit_point;
}
- }
+ }
isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
}
exit_point:
- if (shndx != NULL)
- free (shndx);
- if (esyms != NULL)
- free (esyms);
+ free (shndx);
+ free (esyms);
if (num_syms_return != NULL)
* num_syms_return = isyms == NULL ? 0 : number;
/* Check the sh_link field. */
switch (section->sh_type)
{
+ case SHT_REL:
+ case SHT_RELA:
+ if (section->sh_link == 0
+ && (filedata->file_header.e_type == ET_EXEC
+ || filedata->file_header.e_type == ET_DYN))
+ /* A dynamic relocation section where all entries use a
+ zero symbol index need not specify a symtab section. */
+ break;
+ /* Fall through. */
case SHT_SYMTAB_SHNDX:
case SHT_GROUP:
case SHT_HASH:
case SHT_GNU_HASH:
case SHT_GNU_versym:
- case SHT_REL:
- case SHT_RELA:
- if (section->sh_link < 1
+ if (section->sh_link == 0
|| section->sh_link >= filedata->file_header.e_shnum
|| (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
&& filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
case SHT_GNU_verneed:
case SHT_GNU_verdef:
case SHT_GNU_LIBLIST:
- if (section->sh_link < 1
+ if (section->sh_link == 0
|| section->sh_link >= filedata->file_header.e_shnum
|| filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
warn (_("[%2u]: Link field (%u) should index a string section.\n"),
{
case SHT_REL:
case SHT_RELA:
- if (section->sh_info < 1
+ if (section->sh_info == 0
+ && (filedata->file_header.e_type == ET_EXEC
+ || filedata->file_header.e_type == ET_DYN))
+ /* Dynamic relocations apply to segments, so they do not
+ need to specify the section they relocate. */
+ break;
+ if (section->sh_info == 0
|| section->sh_info >= filedata->file_header.e_shnum
|| (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
&& filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
&& filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
&& filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
+ && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
+ && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
/* FIXME: Are other section types valid ? */
&& filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
- {
- if (section->sh_info == 0
- && (filedata->file_header.e_type == ET_EXEC
- || filedata->file_header.e_type == ET_DYN
- /* These next two tests may be redundant, but
- they have been left in for paranoia's sake. */
- || streq (SECTION_NAME (section), ".rel.dyn")
- || streq (SECTION_NAME (section), ".rela.dyn")))
- /* Dynamic relocations apply to segments, not sections, so
- they do not need an sh_info value. */
- ;
- else
- warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
- i, section->sh_info);
- }
+ warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
+ i, section->sh_info);
break;
case SHT_DYNAMIC:
}
else if (do_section_details)
{
- printf (" %-15.15s ",
- get_section_type_name (filedata, section->sh_type));
+ putchar (' ');
print_vma (section->sh_addr, LONG_HEX);
if ((long) section->sh_offset == section->sh_offset)
printf (" %16.16lx", (unsigned long) section->sh_offset);
printable_section_name (filedata, section),
(unsigned long) section->sh_entsize,
(unsigned long) section->sh_size);
- break;
+ continue;
}
start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
entry, i, filedata->file_header.e_shnum - 1);
if (num_group_errors == 10)
- warn (_("Further error messages about overlarge group section indicies suppressed\n"));
+ warn (_("Further error messages about overlarge group section indices suppressed\n"));
}
continue;
}
for (rp = rela; rp < rela + nrelas; ++rp)
{
- relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
- sym = aux->symtab + get_reloc_symindex (rp->r_info);
+ unsigned int sym_ndx;
+ unsigned int r_type = get_reloc_type (filedata, rp->r_info);
+ relname = elf_ia64_reloc_type (r_type);
/* PR 17531: file: 9fa67536. */
if (relname == NULL)
{
- warn (_("Skipping unknown relocation type: %u\n"),
- get_reloc_type (filedata, rp->r_info));
+ warn (_("Skipping unknown relocation type: %u\n"), r_type);
continue;
}
continue;
}
+ sym_ndx = get_reloc_symindex (rp->r_info);
+ if (sym_ndx >= aux->nsyms)
+ {
+ warn (_("Skipping reloc with invalid symbol index: %u\n"),
+ sym_ndx);
+ continue;
+ }
+ sym = aux->symtab + sym_ndx;
+
switch (rp->r_offset / eh_addr_size % 3)
{
case 0:
for (rp = rela; rp < rela + nrelas; ++rp)
{
- relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
- sym = aux->symtab + get_reloc_symindex (rp->r_info);
+ unsigned int sym_ndx;
+ unsigned int r_type = get_reloc_type (filedata, rp->r_info);
+ relname = elf_hppa_reloc_type (r_type);
+
+ if (relname == NULL)
+ {
+ warn (_("Skipping unknown relocation type: %u\n"), r_type);
+ continue;
+ }
/* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
if (! const_strneq (relname, "R_PARISC_SEGREL"))
{
- warn (_("Skipping unexpected relocation type %s\n"), relname);
+ warn (_("Skipping unexpected relocation type: %s\n"), relname);
continue;
}
i = rp->r_offset / unw_ent_size;
+ if (i >= aux->table_len)
+ {
+ warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
+ continue;
+ }
+
+ sym_ndx = get_reloc_symindex (rp->r_info);
+ if (sym_ndx >= aux->nsyms)
+ {
+ warn (_("Skipping reloc with invalid symbol index: %u\n"),
+ sym_ndx);
+ continue;
+ }
+ sym = aux->symtab + sym_ndx;
- switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
+ switch ((rp->r_offset % unw_ent_size) / 4)
{
case 0:
aux->table[i].start.section = sym->st_shndx;
{
if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
{
- unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
+ unsigned long num_unwind = sec->sh_size / 16;
printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
"contains %lu entry:\n",
if (! slurp_hppa_unwind_table (filedata, &aux, sec))
res = FALSE;
-
- if (aux.table_len > 0)
+
+ if (res && aux.table_len > 0)
{
if (! dump_hppa_unwind (filedata, &aux))
res = FALSE;
}
printf (_("pop frame {"));
- reg = nregs - 1;
- for (i = i * 2; i > 0; i--)
+ if (nregs == 0)
+ {
+ printf (_("*corrupt* - no registers specified"));
+ }
+ else
{
- if (regpos[reg].offset == i - 1)
+ 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)
{
section.sh_entsize = sizeof (Elf64_External_Sym);
section.sh_name = filedata->string_table_length;
+ if (dynamic_symbols != NULL)
+ {
+ error (_("Multiple dynamic symbol table sections found\n"));
+ free (dynamic_symbols);
+ }
dynamic_symbols = GET_ELF_SYMBOLS (filedata, §ion, & num_dynamic_syms);
if (num_dynamic_syms < 1)
{
if (archive_file_offset != 0)
str_tab_len = archive_file_size - offset;
else
- str_tab_len = filedata->file_size;
+ str_tab_len = filedata->file_size - offset;
if (str_tab_len < 1)
{
continue;
}
+ if (dynamic_strings != NULL)
+ {
+ error (_("Multiple dynamic string tables found\n"));
+ free (dynamic_strings);
+ }
+
dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
str_tab_len,
_("dynamic string table"));
dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
- break;
}
}
if (!extsyminfo)
return FALSE;
+ if (dynamic_syminfo != NULL)
+ {
+ error (_("Multiple dynamic symbol information sections found\n"));
+ free (dynamic_syminfo);
+ }
dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
if (dynamic_syminfo == NULL)
{
printf (" PIE");
val ^= DF_1_PIE;
}
+ if (val & DF_1_KMOD)
+ {
+ printf (" KMOD");
+ val ^= DF_1_KMOD;
+ }
+ if (val & DF_1_WEAKFILTER)
+ {
+ printf (" WEAKFILTER");
+ val ^= DF_1_WEAKFILTER;
+ }
+ if (val & DF_1_NOCOMMON)
+ {
+ printf (" NOCOMMON");
+ val ^= DF_1_NOCOMMON;
+ }
if (val != 0)
printf (" %lx", val);
puts ("");
{
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);
static char *
get_ver_flags (unsigned int flags)
{
- static char buff[32];
+ static char buff[128];
buff[0] = 0;
}
}
+static const char *
+get_aarch64_symbol_other (unsigned int other)
+{
+ static char buf[32];
+
+ if (other & STO_AARCH64_VARIANT_PCS)
+ {
+ other &= ~STO_AARCH64_VARIANT_PCS;
+ if (other == 0)
+ return "VARIANT_PCS";
+ snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
+ return buf;
+ }
+ return NULL;
+}
+
static const char *
get_mips_symbol_other (unsigned int other)
{
static const char *
get_ppc64_symbol_other (unsigned int other)
{
- if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
+ if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
+ return NULL;
+
+ other >>= STO_PPC64_LOCAL_BIT;
+ if (other <= 6)
{
static char buf[32];
- snprintf (buf, sizeof buf, _("<localentry>: %d"),
- PPC64_LOCAL_ENTRY_OFFSET (other));
+ if (other >= 2)
+ other = ppc64_decode_local_entry (other);
+ snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
return buf;
}
return NULL;
switch (filedata->file_header.e_machine)
{
+ case EM_AARCH64:
+ result = get_aarch64_symbol_other (other);
+ break;
case EM_MIPS:
result = get_mips_symbol_other (other);
break;
unsigned char data[2];
unsigned short vers_data;
unsigned long offset;
+ unsigned short max_vd_ndx;
if (!is_dynsym
|| version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
vers_data = byte_get (data, 2);
- if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
+ if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
return NULL;
+ max_vd_ndx = 0;
+
/* Usually we'd only see verdef for defined symbols, and verneed for
undefined symbols. However, symbols defined by the linker in
.dynbss for variables copied from a shared library in order to
ivd.vd_ndx = 0;
ivd.vd_aux = 0;
ivd.vd_next = 0;
+ ivd.vd_flags = 0;
}
else
{
ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
ivd.vd_aux = BYTE_GET (evd.vd_aux);
ivd.vd_next = BYTE_GET (evd.vd_next);
+ ivd.vd_flags = BYTE_GET (evd.vd_flags);
}
+ if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
+ max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
+
off += ivd.vd_next;
}
while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
{
+ if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
+ return NULL;
+
off -= ivd.vd_next;
off += ivd.vd_aux;
return (ivna.vna_name < strtab_size
? strtab + ivna.vna_name : _("<corrupt>"));
}
+ else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
+ && (vers_data & VERSYM_VERSION) > max_vd_ndx)
+ return _("<corrupt>");
}
return NULL;
}
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:
return reloc_type == 3; /* R_CR16_NUM32. */
case EM_CRX:
return reloc_type == 15; /* R_CRX_NUM32. */
+ case EM_CSKY:
+ return reloc_type == 1; /* R_CKCORE_ADDR32. */
case EM_CYGNUS_FRV:
return reloc_type == 1;
case EM_CYGNUS_D10V:
case EM_68HC11:
case EM_68HC12:
return reloc_type == 6; /* R_M68HC11_32. */
+ case EM_S12Z:
+ return reloc_type == 7 || /* R_S12Z_EXT32 */
+ reloc_type == 6; /* R_S12Z_CW32. */
case EM_MCORE:
return reloc_type == 1; /* R_MCORE_ADDR32. */
case EM_CYGNUS_MEP:
case EM_OR1K:
return reloc_type == 1; /* R_OR1K_32. */
case EM_PARISC:
- return (reloc_type == 1 /* R_PARISC_DIR32. */
+ return (reloc_type == 1 /* R_PARISC_DIR32. */
+ || reloc_type == 2 /* R_PARISC_DIR21L. */
|| reloc_type == 41); /* R_PARISC_SECREL32. */
case EM_PJ:
case EM_PJ_OLD:
return reloc_type == 26; /* R_PPC_REL32. */
case EM_PPC64:
return reloc_type == 26; /* R_PPC64_REL32. */
+ case EM_RISCV:
+ return reloc_type == 57; /* R_RISCV_32_PCREL. */
case EM_S390_OLD:
case EM_S390:
return reloc_type == 5; /* R_390_PC32. */
return reloc_type == 9; /* R_NIOS_16. */
case EM_OR1K:
return reloc_type == 2; /* R_OR1K_16. */
+ case EM_RISCV:
+ return reloc_type == 55; /* R_RISCV_SET16. */
case EM_TI_PRU:
return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
case EM_TI_C6000:
}
}
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 8-bit absolute RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 54; /* R_RISCV_SET8. */
+ default:
+ return FALSE;
+ }
+}
+
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 6-bit absolute RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 53; /* R_RISCV_SET6. */
+ default:
+ return FALSE;
+ }
+}
+
/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
a 32-bit inplace add RELA relocation used in DWARF debug sections. */
}
}
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 52; /* R_RISCV_SUB6. */
+ default:
+ return FALSE;
+ }
+}
+
/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
relocation entries (possibly formerly used for SHT_GROUP sections). */
{
Elf_Internal_Shdr * relsec;
unsigned char * end = start + size;
- bfd_boolean res = TRUE;
if (relocs_return != NULL)
{
reloc_size = 3;
else if (is_16bit_abs_reloc (filedata, reloc_type))
reloc_size = 2;
+ else if (is_8bit_abs_reloc (filedata, reloc_type)
+ || is_6bit_abs_reloc (filedata, reloc_type))
+ reloc_size = 1;
else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
reloc_type))
|| is_32bit_inplace_add_reloc (filedata, reloc_type))
reloc_size = 1;
reloc_inplace = TRUE;
}
+ else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
+ reloc_type)))
+ {
+ reloc_size = 1;
+ reloc_inplace = TRUE;
+ }
else
{
static unsigned int prev_reloc = 0;
warn (_("unable to apply unsupported reloc type %d to section %s\n"),
reloc_type, printable_section_name (filedata, section));
prev_reloc = reloc_type;
- res = FALSE;
continue;
}
warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
(unsigned long) rp->r_offset,
printable_section_name (filedata, section));
- res = FALSE;
continue;
}
{
warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
sym_index, printable_section_name (filedata, section));
- res = FALSE;
continue;
}
sym = symtab + sym_index;
get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
printable_section_name (filedata, relsec),
(long int)(rp - relocs));
- res = FALSE;
continue;
}
|| filedata->file_header.e_machine == EM_CYGNUS_D30V)
&& reloc_type == 12)
|| reloc_inplace)
- addend += byte_get (rloc, reloc_size);
+ {
+ if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
+ addend += byte_get (rloc, reloc_size) & 0x3f;
+ else
+ addend += byte_get (rloc, reloc_size);
+ }
if (is_32bit_pcrel_reloc (filedata, reloc_type)
|| is_64bit_pcrel_reloc (filedata, reloc_type))
byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
reloc_size);
}
+ else if (is_6bit_abs_reloc (filedata, reloc_type)
+ || is_6bit_inplace_sub_reloc (filedata, reloc_type))
+ {
+ if (reloc_subtract)
+ addend -= sym->st_value;
+ else
+ addend += sym->st_value;
+ addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
+ byte_put (rloc, addend, reloc_size);
+ }
else if (reloc_subtract)
byte_put (rloc, addend - sym->st_value, reloc_size);
else
break;
}
- return res;
+ return TRUE;
}
#ifdef SUPPORT_DISASSEMBLY
printable_section_name (filedata, section), chdr.ch_type);
return FALSE;
}
- else if (chdr.ch_addralign != section->sh_addralign)
- {
- warn (_("compressed section '%s' is corrupted\n"),
- printable_section_name (filedata, section));
- return FALSE;
- }
uncompressed_size = chdr.ch_size;
start += compression_header_size;
new_size -= compression_header_size;
printable_section_name (filedata, section), chdr.ch_type);
return FALSE;
}
- else if (chdr.ch_addralign != section->sh_addralign)
- {
- warn (_("compressed section '%s' is corrupted\n"),
- printable_section_name (filedata, section));
- return FALSE;
- }
uncompressed_size = chdr.ch_size;
start += compression_header_size;
new_size -= compression_header_size;
return TRUE;
}
+static ctf_sect_t *
+shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
+{
+ buf->cts_name = SECTION_NAME(shdr);
+ buf->cts_type = shdr->sh_type;
+ buf->cts_flags = shdr->sh_flags;
+ buf->cts_size = shdr->sh_size;
+ buf->cts_entsize = shdr->sh_entsize;
+ buf->cts_offset = (off64_t) shdr->sh_offset;
+
+ return buf;
+}
+
+/* Formatting callback function passed to ctf_dump. Returns either the pointer
+ it is passed, or a pointer to newly-allocated storage, in which case
+ dump_ctf() will free it when it no longer needs it. */
+
+static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
+ char *s, void *arg)
+{
+ char *spaces = arg;
+ char *new_s;
+
+ if (asprintf (&new_s, "%s%s", spaces, s) < 0)
+ return s;
+ return new_s;
+}
+
+static bfd_boolean
+dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
+{
+ Elf_Internal_Shdr * parent_sec = NULL;
+ Elf_Internal_Shdr * symtab_sec = NULL;
+ Elf_Internal_Shdr * strtab_sec = NULL;
+ void * data = NULL;
+ void * symdata = NULL;
+ void * strdata = NULL;
+ void * parentdata = NULL;
+ ctf_sect_t ctfsect, symsect, strsect, parentsect;
+ ctf_sect_t * symsectp = NULL;
+ ctf_sect_t * strsectp = NULL;
+ ctf_file_t * ctf = NULL;
+ ctf_file_t * parent = NULL;
+
+ const char *things[] = {"Labels", "Data objects", "Function objects",
+ "Variables", "Types", "Strings", ""};
+ const char **thing;
+ int err;
+ bfd_boolean ret = FALSE;
+ size_t i;
+
+ shdr_to_ctf_sect (&ctfsect, section, filedata);
+ data = get_section_contents (section, filedata);
+ ctfsect.cts_data = data;
+
+ if (dump_ctf_symtab_name)
+ {
+ if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
+ {
+ error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
+ goto fail;
+ }
+ if ((symdata = (void *) get_data (NULL, filedata,
+ symtab_sec->sh_offset, 1,
+ symtab_sec->sh_size,
+ _("symbols"))) == NULL)
+ goto fail;
+ symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
+ symsect.cts_data = symdata;
+ }
+ if (dump_ctf_strtab_name)
+ {
+ if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
+ {
+ error (_("No string table section named %s\n"),
+ dump_ctf_strtab_name);
+ goto fail;
+ }
+ if ((strdata = (void *) get_data (NULL, filedata,
+ strtab_sec->sh_offset, 1,
+ strtab_sec->sh_size,
+ _("strings"))) == NULL)
+ goto fail;
+ strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
+ strsect.cts_data = strdata;
+ }
+ if (dump_ctf_parent_name)
+ {
+ if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
+ {
+ error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
+ goto fail;
+ }
+ if ((parentdata = (void *) get_data (NULL, filedata,
+ parent_sec->sh_offset, 1,
+ parent_sec->sh_size,
+ _("CTF parent"))) == NULL)
+ goto fail;
+ shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
+ parentsect.cts_data = parentdata;
+ }
+
+ /* Load the CTF file and dump it. */
+
+ if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
+ {
+ error (_("CTF open failure: %s\n"), ctf_errmsg (err));
+ goto fail;
+ }
+
+ if (parentdata)
+ {
+ if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
+ {
+ error (_("CTF open failure: %s\n"), ctf_errmsg (err));
+ goto fail;
+ }
+
+ ctf_import (ctf, parent);
+ }
+
+ ret = TRUE;
+
+ printf (_("\nDump of CTF section '%s':\n"),
+ printable_section_name (filedata, section));
+
+ for (i = 1, thing = things; *thing[0]; thing++, i++)
+ {
+ ctf_dump_state_t *s = NULL;
+ char *item;
+
+ printf ("\n %s:\n", *thing);
+ while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
+ (void *) " ")) != NULL)
+ {
+ printf ("%s\n", item);
+ free (item);
+ }
+
+ if (ctf_errno (ctf))
+ {
+ error (_("Iteration failed: %s, %s\n"), *thing,
+ ctf_errmsg (ctf_errno (ctf)));
+ ret = FALSE;
+ }
+ }
+
+ fail:
+ ctf_file_close (ctf);
+ ctf_file_close (parent);
+ free (parentdata);
+ free (data);
+ free (symdata);
+ free (strdata);
+ return ret;
+}
+
static bfd_boolean
load_specific_debug_section (enum dwarf_section_display_enum debug,
const Elf_Internal_Shdr * sec,
section->name, chdr.ch_type);
return FALSE;
}
- else if (chdr.ch_addralign != sec->sh_addralign)
- {
- warn (_("compressed section '%s' is corrupted\n"),
- section->name);
- return FALSE;
- }
uncompressed_size = chdr.ch_size;
start += compression_header_size;
size -= compression_header_size;
if (! display_debug_section (i, section, filedata))
res = FALSE;
}
+
+ if (dump & CTF_DUMP)
+ {
+ if (! dump_section_as_ctf (section, filedata))
+ res = FALSE;
+ }
}
/* Check to see if the user requested a
printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
break;
+ case Tag_ARC_ATR_version:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ATR_version: %d\n", val);
+ break;
+
default:
return display_tag_value (tag & 1, p, end);
}
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),
unsigned long addr = 0;
size_t bytes = end - p;
- assert (end > p);
+ assert (end >= p);
while (bytes)
{
int j;
return p;
}
+struct riscv_attr_tag_t {
+ const char *name;
+ int tag;
+};
+
+static struct riscv_attr_tag_t riscv_attr_tag[] =
+{
+#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
+ T(arch),
+ T(priv_spec),
+ T(priv_spec_minor),
+ T(priv_spec_revision),
+ T(unaligned_access),
+ T(stack_align),
+#undef T
+};
+
+static unsigned char *
+display_riscv_attribute (unsigned char *p,
+ const unsigned char * const end)
+{
+ unsigned int len;
+ int val;
+ int tag;
+ struct riscv_attr_tag_t *attr = NULL;
+ unsigned i;
+
+ tag = read_uleb128 (p, &len, end);
+ p += len;
+
+ /* Find the name of attribute. */
+ for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
+ {
+ if (riscv_attr_tag[i].tag == tag)
+ {
+ attr = &riscv_attr_tag[i];
+ break;
+ }
+ }
+
+ if (attr)
+ printf (" %s: ", attr->name);
+ else
+ return display_tag_value (tag, p, end);
+
+ switch (tag)
+ {
+ case Tag_RISCV_priv_spec:
+ case Tag_RISCV_priv_spec_minor:
+ case Tag_RISCV_priv_spec_revision:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (_("%d\n"), val);
+ break;
+ case Tag_RISCV_unaligned_access:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ switch (val)
+ {
+ case 0:
+ printf (_("No unaligned access\n"));
+ break;
+ case 1:
+ printf (_("Unaligned access\n"));
+ break;
+ }
+ break;
+ case Tag_RISCV_stack_align:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (_("%d-bytes\n"), val);
+ break;
+ case Tag_RISCV_arch:
+ p = display_tag_value (-1, p, end);
+ break;
+ default:
+ return display_tag_value (tag, p, end);
+ }
+
+ return p;
+}
+
static bfd_boolean
process_attributes (Filedata * filedata,
const char * public_name,
fputs ("\n\tXPA ASE", stdout);
if (mask & AFL_ASE_MIPS16E2)
fputs ("\n\tMIPS16e2 ASE", stdout);
+ if (mask & AFL_ASE_CRC)
+ fputs ("\n\tCRC ASE", stdout);
+ if (mask & AFL_ASE_GINV)
+ fputs ("\n\tGINV ASE", stdout);
+ if (mask & AFL_ASE_LOONGSON_MMI)
+ fputs ("\n\tLoongson MMI ASE", stdout);
+ if (mask & AFL_ASE_LOONGSON_CAM)
+ fputs ("\n\tLoongson CAM ASE", stdout);
+ if (mask & AFL_ASE_LOONGSON_EXT)
+ fputs ("\n\tLoongson EXT ASE", stdout);
+ if (mask & AFL_ASE_LOONGSON_EXT2)
+ fputs ("\n\tLoongson EXT2 ASE", stdout);
if (mask == 0)
fprintf (stdout, "\n\t%s", _("None"));
else if ((mask & ~AFL_ASE_MASK) != 0)
case AFL_EXT_OCTEONP:
fputs ("Cavium Networks OcteonP", stdout);
break;
- case AFL_EXT_LOONGSON_3A:
- fputs ("Loongson 3A", stdout);
- break;
case AFL_EXT_OCTEON:
fputs ("Cavium Networks Octeon", stdout);
break;
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 NT_PPC_TM_CVMX:
return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
case NT_PPC_TM_CVSX:
- return _("NT_PPC_TM_VSX (ppc checkpointed VSX registers)");
+ return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
case NT_PPC_TM_SPR:
return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
case NT_PPC_TM_CTAR:
}
}
+static void
+decode_x86_compat_isa (unsigned int bitmask)
+{
+ while (bitmask)
+ {
+ unsigned int bit = bitmask & (- bitmask);
+
+ bitmask &= ~ bit;
+ switch (bit)
+ {
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
+ printf ("i486");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
+ printf ("586");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
+ printf ("686");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
+ printf ("SSE");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
+ printf ("SSE2");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
+ printf ("SSE3");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
+ printf ("SSSE3");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
+ printf ("SSE4_1");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
+ printf ("SSE4_2");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
+ printf ("AVX");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
+ printf ("AVX2");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
+ printf ("AVX512F");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
+ printf ("AVX512CD");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
+ printf ("AVX512ER");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
+ printf ("AVX512PF");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
+ printf ("AVX512VL");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
+ printf ("AVX512DQ");
+ break;
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
+ printf ("AVX512BW");
+ break;
+ default:
+ printf (_("<unknown: %x>"), bit);
+ break;
+ }
+ if (bitmask)
+ printf (", ");
+ }
+}
+
static void
decode_x86_isa (unsigned int bitmask)
{
+ if (!bitmask)
+ {
+ printf (_("<None>"));
+ return;
+ }
+
while (bitmask)
{
unsigned int bit = bitmask & (- bitmask);
bitmask &= ~ bit;
switch (bit)
{
- case GNU_PROPERTY_X86_ISA_1_486: printf ("i486"); break;
- case GNU_PROPERTY_X86_ISA_1_586: printf ("586"); break;
- case GNU_PROPERTY_X86_ISA_1_686: printf ("686"); break;
- case GNU_PROPERTY_X86_ISA_1_SSE: printf ("SSE"); break;
- case GNU_PROPERTY_X86_ISA_1_SSE2: printf ("SSE2"); break;
- case GNU_PROPERTY_X86_ISA_1_SSE3: printf ("SSE3"); break;
- case GNU_PROPERTY_X86_ISA_1_SSSE3: printf ("SSSE3"); break;
- case GNU_PROPERTY_X86_ISA_1_SSE4_1: printf ("SSE4_1"); break;
- case GNU_PROPERTY_X86_ISA_1_SSE4_2: printf ("SSE4_2"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX: printf ("AVX"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX2: printf ("AVX2"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512F: printf ("AVX512F"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512CD: printf ("AVX512CD"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512ER: printf ("AVX512ER"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512PF: printf ("AVX512PF"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512VL: printf ("AVX512VL"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512DQ: printf ("AVX512DQ"); break;
- case GNU_PROPERTY_X86_ISA_1_AVX512BW: printf ("AVX512BW"); break;
- default: printf (_("<unknown: %x>"), bit); break;
+ case GNU_PROPERTY_X86_ISA_1_CMOV:
+ printf ("CMOV");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSE:
+ printf ("SSE");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSE2:
+ printf ("SSE2");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSE3:
+ printf ("SSE3");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSSE3:
+ printf ("SSSE3");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSE4_1:
+ printf ("SSE4_1");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_SSE4_2:
+ printf ("SSE4_2");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX:
+ printf ("AVX");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX2:
+ printf ("AVX2");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_FMA:
+ printf ("FMA");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512F:
+ printf ("AVX512F");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512CD:
+ printf ("AVX512CD");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512ER:
+ printf ("AVX512ER");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512PF:
+ printf ("AVX512PF");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512VL:
+ printf ("AVX512VL");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
+ printf ("AVX512DQ");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512BW:
+ printf ("AVX512BW");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
+ printf ("AVX512_4FMAPS");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
+ printf ("AVX512_4VNNIW");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
+ printf ("AVX512_BITALG");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
+ printf ("AVX512_IFMA");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
+ printf ("AVX512_VBMI");
+ break;
+ case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
+ printf ("AVX512_VBMI2");
+ break;
+ 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;
}
if (bitmask)
printf (", ");
}
static void
-decode_x86_feature (unsigned int type, unsigned int bitmask)
+decode_x86_feature_1 (unsigned int bitmask)
{
+ if (!bitmask)
+ {
+ printf (_("<None>"));
+ return;
+ }
+
while (bitmask)
{
unsigned int bit = bitmask & (- bitmask);
switch (bit)
{
case GNU_PROPERTY_X86_FEATURE_1_IBT:
- switch (type)
- {
- case GNU_PROPERTY_X86_FEATURE_1_AND:
- printf ("IBT");
- break;
- default:
- /* This should never happen. */
- abort ();
- }
+ printf ("IBT");
break;
case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
- switch (type)
- {
- case GNU_PROPERTY_X86_FEATURE_1_AND:
- printf ("SHSTK");
- break;
- default:
- /* This should never happen. */
- abort ();
- }
+ printf ("SHSTK");
break;
default:
printf (_("<unknown: %x>"), bit);
}
}
+static void
+decode_x86_feature_2 (unsigned int bitmask)
+{
+ if (!bitmask)
+ {
+ printf (_("<None>"));
+ return;
+ }
+
+ while (bitmask)
+ {
+ unsigned int bit = bitmask & (- bitmask);
+
+ bitmask &= ~ bit;
+ switch (bit)
+ {
+ case GNU_PROPERTY_X86_FEATURE_2_X86:
+ printf ("x86");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_X87:
+ printf ("x87");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_MMX:
+ printf ("MMX");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_XMM:
+ printf ("XMM");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_YMM:
+ printf ("YMM");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_ZMM:
+ printf ("ZMM");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_FXSR:
+ printf ("FXSR");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
+ printf ("XSAVE");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
+ printf ("XSAVEOPT");
+ break;
+ case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
+ printf ("XSAVEC");
+ break;
+ default:
+ printf (_("<unknown: %x>"), bit);
+ break;
+ }
+ if (bitmask)
+ printf (", ");
+ }
+}
+
+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)
{
|| filedata->file_header.e_machine == EM_IAMCU
|| filedata->file_header.e_machine == EM_386)
{
+ unsigned int bitmask;
+
+ if (datasz == 4)
+ bitmask = byte_get (ptr, 4);
+ else
+ bitmask = 0;
+
switch (type)
{
case GNU_PROPERTY_X86_ISA_1_USED:
- printf ("x86 ISA used: ");
if (datasz != 4)
- printf (_("<corrupt length: %#x> "), datasz);
+ printf (_("x86 ISA used: <corrupt length: %#x> "),
+ datasz);
else
- decode_x86_isa (byte_get (ptr, 4));
+ {
+ printf ("x86 ISA used: ");
+ decode_x86_isa (bitmask);
+ }
goto next;
case GNU_PROPERTY_X86_ISA_1_NEEDED:
- printf ("x86 ISA needed: ");
if (datasz != 4)
- printf (_("<corrupt length: %#x> "), datasz);
+ printf (_("x86 ISA needed: <corrupt length: %#x> "),
+ datasz);
else
- decode_x86_isa (byte_get (ptr, 4));
+ {
+ printf ("x86 ISA needed: ");
+ decode_x86_isa (bitmask);
+ }
goto next;
case GNU_PROPERTY_X86_FEATURE_1_AND:
- printf ("x86 feature: ");
if (datasz != 4)
- printf (_("<corrupt length: %#x> "), datasz);
+ printf (_("x86 feature: <corrupt length: %#x> "),
+ datasz);
+ else
+ {
+ printf ("x86 feature: ");
+ decode_x86_feature_1 (bitmask);
+ }
+ goto next;
+
+ case GNU_PROPERTY_X86_FEATURE_2_USED:
+ if (datasz != 4)
+ printf (_("x86 feature used: <corrupt length: %#x> "),
+ datasz);
else
- decode_x86_feature (type, byte_get (ptr, 4));
+ {
+ printf ("x86 feature used: ");
+ decode_x86_feature_2 (bitmask);
+ }
+ goto next;
+
+ case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
+ if (datasz != 4)
+ printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
+ else
+ {
+ printf ("x86 feature needed: ");
+ decode_x86_feature_2 (bitmask);
+ }
+ goto next;
+
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
+ if (datasz != 4)
+ printf (_("x86 ISA used: <corrupt length: %#x> "),
+ datasz);
+ else
+ {
+ printf ("x86 ISA used: ");
+ decode_x86_compat_isa (bitmask);
+ }
+ goto next;
+
+ case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
+ if (datasz != 4)
+ printf (_("x86 ISA needed: <corrupt length: %#x> "),
+ datasz);
+ else
+ {
+ printf ("x86 ISA needed: ");
+ decode_x86_compat_isa (bitmask);
+ }
goto next;
default:
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
if (strtab[sym->st_name] == 0)
continue;
+ /* The AArch64 and ARM architectures define mapping symbols
+ (eg $d, $x, $t) which we want to ignore. */
+ if (strtab[sym->st_name] == '$'
+ && strtab[sym->st_name + 1] != 0
+ && strtab[sym->st_name + 2] == 0)
+ continue;
+
if (is_open_attr)
{
/* For OPEN attributes we prefer GLOBAL over LOCAL symbols
return saved_sym;
}
+/* Returns true iff addr1 and addr2 are in the same section. */
+
+static bfd_boolean
+same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
+{
+ Elf_Internal_Shdr * a1;
+ Elf_Internal_Shdr * a2;
+
+ a1 = find_section_by_address (filedata, addr1);
+ a2 = find_section_by_address (filedata, addr2);
+
+ return a1 == a2 && a1 != NULL;
+}
+
static bfd_boolean
print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
Filedata * filedata)
name = NULL;
sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
+ /* As of version 5 of the annobin plugin, filename symbols are biased by 2
+ in order to avoid them being confused with the start address of the
+ first function in the file... */
+ if (sym == NULL && is_open_attr)
+ sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
+ & name);
if (end == 0 && sym != NULL && sym->st_size > 0)
end = start + sym->st_size;
if (is_open_attr)
{
- /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
- if (global_end > 0 && start > BFD_ALIGN (global_end, 16))
+ /* FIXME: Need to properly allow for section alignment.
+ 16 is just the alignment used on x86_64. */
+ if (global_end > 0
+ && start > BFD_ALIGN (global_end, 16)
+ /* Build notes are not guaranteed to be organised in order of
+ increasing address, but we should find the all of the notes
+ for one section in the same place. */
+ && same_section (filedata, start, global_end))
warn (_("Gap in build notes detected from %#lx to %#lx\n"),
global_end + 1, start - 1);
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)
{
display_msp430x_attribute,
display_generic_attribute);
+ case EM_RISCV:
+ return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
+ display_riscv_attribute,
+ display_generic_attribute);
+
case EM_NDS32:
return process_nds32_specific (filedata);
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))
l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
}
- if (arch.uses_64bit_indicies)
+ if (arch.uses_64bit_indices)
l = (l + 7) & ~ 7;
else
l += l & 1;
/* Read the next archive header. */
if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
{
- error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
+ error (_("%s: failed to seek to next archive header\n"), arch.file_name);
return FALSE;
}
got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
{
if (got == 0)
break;
- error (_("%s: failed to read archive header\n"), filedata->file_name);
+ /* PR 24049 - we cannot use filedata->file_name as this will
+ have already been freed. */
+ error (_("%s: failed to read archive header\n"), arch.file_name);
+
ret = FALSE;
break;
}
name = get_archive_member_name (&arch, &nested_arch);
if (name == NULL)
{
- error (_("%s: bad archive file name\n"), filedata->file_name);
+ error (_("%s: bad archive file name\n"), arch.file_name);
ret = FALSE;
break;
}
qualified_name = make_qualified_name (&arch, &nested_arch, name);
if (qualified_name == NULL)
{
- error (_("%s: bad archive file name\n"), filedata->file_name);
+ error (_("%s: bad archive file name\n"), arch.file_name);
ret = FALSE;
break;
}
if (nested_arch.file == NULL)
{
error (_("%s: contains corrupt thin archive: %s\n"),
- filedata->file_name, name);
+ qualified_name, name);
ret = FALSE;
break;
}
if (cmdline.dump_sects != NULL)
free (cmdline.dump_sects);
+ free (dump_ctf_symtab_name);
+ free (dump_ctf_strtab_name);
+ free (dump_ctf_parent_name);
+
return err ? EXIT_FAILURE : EXIT_SUCCESS;
}