#include "elf/v850.h"
#include "elf/vax.h"
#include "elf/visium.h"
+#include "elf/wasm32.h"
#include "elf/x86-64.h"
#include "elf/xc16x.h"
#include "elf/xgate.h"
} \
while (0)
\f
+/* Print a BFD_VMA to an internal buffer, for use in error messages.
+ BFD_FMA_FMT can't be used in translated strings. */
+
+static const char *
+bfd_vmatoa (char *fmtch, bfd_vma value)
+{
+ /* bfd_vmatoa is used more then once in a printf call for output.
+ Cycle through an array of buffers. */
+ static int buf_pos = 0;
+ static struct bfd_vmatoa_buf
+ {
+ char place[64];
+ } buf[4];
+ char *ret;
+ char fmt[32];
+
+ ret = buf[buf_pos++].place;
+ buf_pos %= ARRAY_SIZE (buf);
+
+ sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
+ snprintf (ret, sizeof (buf[0].place), fmt, value);
+ return ret;
+}
+
/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
the offset of the current archive member, if we are examining an archive.
Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
|| (bfd_size_type) ((size_t) nmemb) != nmemb))
{
if (reason)
- error (_("Size truncation prevents reading 0x%" BFD_VMA_FMT "x"
- " elements of size 0x%" BFD_VMA_FMT "x for %s\n"),
- nmemb, size, reason);
+ error (_("Size truncation prevents reading %s"
+ " elements of size %s for %s\n"),
+ bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
return NULL;
}
if (amt < nmemb)
{
if (reason)
- error (_("Size overflow prevents reading 0x%" BFD_VMA_FMT "x"
- " elements of size 0x%" BFD_VMA_FMT "x for %s\n"),
- nmemb, size, reason);
+ error (_("Size overflow prevents reading %s"
+ " elements of size %s for %s\n"),
+ bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
return NULL;
}
|| offset + archive_file_offset + amt > current_file_size)
{
if (reason)
- error (_("Reading 0x%" BFD_VMA_FMT "x"
- " bytes extends past end of file for %s\n"),
- amt, reason);
+ error (_("Reading %s bytes extends past end of file for %s\n"),
+ bfd_vmatoa ("u", amt), reason);
return NULL;
}
if (mvar == NULL)
{
if (reason)
- error (_("Out of memory allocating 0x%" BFD_VMA_FMT "x"
- " bytes for %s\n"),
- amt, reason);
+ error (_("Out of memory allocating %s bytes for %s\n"),
+ bfd_vmatoa ("u", amt), reason);
return NULL;
}
if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
{
if (reason)
- error (_("Unable to read in 0x%" BFD_VMA_FMT "x bytes of %s\n"),
- amt, reason);
+ error (_("Unable to read in %s bytes of %s\n"),
+ bfd_vmatoa ("u", amt), reason);
if (mvar != var)
free (mvar);
return NULL;
if (width < 0)
{
- /* Keep the width positive. This also helps. */
+ /* Keep the width positive. This helps the code below. */
width = - width;
extra_padding = TRUE;
}
case EM_XTENSA_OLD:
case EM_MICROBLAZE:
case EM_MICROBLAZE_OLD:
+ case EM_WEBASSEMBLY:
return TRUE;
case EM_68HC05:
rtype = elf_tilepro_reloc_type (type);
break;
+ case EM_WEBASSEMBLY:
+ rtype = elf_wasm32_reloc_type (type);
+ break;
+
case EM_XGATE:
rtype = elf_xgate_reloc_type (type);
break;
if (rtype == NULL)
printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
else
- printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
+ printf (do_wide ? "%-22s" : "%-17.17s", rtype);
if (elf_header.e_machine == EM_ALPHA
&& rtype != NULL
switch (e_machine)
{
+ /* Please keep this switch table sorted by increasing EM_ value. */
+ /* 0 */
case EM_NONE: return _("None");
- case EM_AARCH64: return "AArch64";
case EM_M32: return "WE32100";
case EM_SPARC: return "Sparc";
- case EM_SPU: return "SPU";
case EM_386: return "Intel 80386";
case EM_68K: return "MC68000";
case EM_88K: return "MC88000";
case EM_860: return "Intel 80860";
case EM_MIPS: return "MIPS R3000";
case EM_S370: return "IBM System/370";
+ /* 10 */
case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
case EM_OLD_SPARCV9: return "Sparc v9 (old)";
case EM_PARISC: return "HPPA";
- case EM_PPC_OLD: return "Power PC (old)";
+ case EM_VPP550: return "Fujitsu VPP500";
case EM_SPARC32PLUS: return "Sparc v8+" ;
case EM_960: return "Intel 90860";
case EM_PPC: return "PowerPC";
+ /* 20 */
case EM_PPC64: return "PowerPC64";
+ case EM_S390_OLD:
+ case EM_S390: return "IBM S/390";
+ case EM_SPU: return "SPU";
+ /* 30 */
+ case EM_V800: return "Renesas V850 (using RH850 ABI)";
case EM_FR20: return "Fujitsu FR20";
- case EM_FT32: return "FTDI FT32";
case EM_RH32: return "TRW RH32";
case EM_MCORE: return "MCORE";
+ /* 40 */
case EM_ARM: return "ARM";
case EM_OLD_ALPHA: return "Digital Alpha (old)";
case EM_SH: return "Renesas / SuperH SH";
case EM_SPARCV9: return "Sparc v9";
case EM_TRICORE: return "Siemens Tricore";
case EM_ARC: return "ARC";
- case EM_ARC_COMPACT: return "ARCompact";
- case EM_ARC_COMPACT2: return "ARCv2";
case EM_H8_300: return "Renesas H8/300";
case EM_H8_300H: return "Renesas H8/300H";
case EM_H8S: return "Renesas H8S";
case EM_H8_500: return "Renesas H8/500";
+ /* 50 */
case EM_IA_64: return "Intel IA-64";
case EM_MIPS_X: return "Stanford MIPS-X";
case EM_COLDFIRE: return "Motorola Coldfire";
- case EM_ALPHA: return "Alpha";
- case EM_CYGNUS_D10V:
- case EM_D10V: return "d10v";
- case EM_CYGNUS_D30V:
- case EM_D30V: return "d30v";
- case EM_CYGNUS_M32R:
- case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
- case EM_CYGNUS_V850:
- case EM_V800: return "Renesas V850 (using RH850 ABI)";
- case EM_V850: return "Renesas V850";
- case EM_CYGNUS_MN10300:
- case EM_MN10300: return "mn10300";
- case EM_CYGNUS_MN10200:
- case EM_MN10200: return "mn10200";
- case EM_MOXIE: return "Moxie";
- case EM_CYGNUS_FR30:
- case EM_FR30: return "Fujitsu FR30";
- case EM_CYGNUS_FRV: return "Fujitsu FR-V";
- case EM_PJ_OLD:
- case EM_PJ: return "picoJava";
+ case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
case EM_MMA: return "Fujitsu Multimedia Accelerator";
case EM_PCP: return "Siemens PCP";
case EM_NCPU: return "Sony nCPU embedded RISC processor";
case EM_NDR1: return "Denso NDR1 microprocesspr";
case EM_STARCORE: return "Motorola Star*Core processor";
case EM_ME16: return "Toyota ME16 processor";
+ /* 60 */
case EM_ST100: return "STMicroelectronics ST100 processor";
case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
+ case EM_X86_64: return "Advanced Micro Devices X86-64";
case EM_PDSP: return "Sony DSP processor";
case EM_PDP10: return "Digital Equipment Corp. PDP-10";
case EM_PDP11: return "Digital Equipment Corp. PDP-11";
case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
- case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
+ /* 70 */
case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
case EM_SVX: return "Silicon Graphics SVx";
case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
case EM_VAX: return "Digital VAX";
- case EM_VISIUM: return "CDS VISIUMcore processor";
- case EM_AVR_OLD:
- case EM_AVR: return "Atmel AVR 8-bit microcontroller";
case EM_CRIS: return "Axis Communications 32-bit embedded processor";
case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
case EM_FIREPATH: return "Element 14 64-bit DSP processor";
case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
+ /* 80 */
case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
case EM_HUANY: return "Harvard Universitys's machine-independent object format";
case EM_PRISM: return "Vitesse Prism";
- case EM_X86_64: return "Advanced Micro Devices X86-64";
- case EM_L1OM: return "Intel L1OM";
- case EM_K1OM: return "Intel K1OM";
- case EM_S390_OLD:
- case EM_S390: return "IBM S/390";
- case EM_SCORE: return "SUNPLUS S+Core";
- case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
+ case EM_AVR_OLD:
+ case EM_AVR: return "Atmel AVR 8-bit microcontroller";
+ case EM_CYGNUS_FR30:
+ case EM_FR30: return "Fujitsu FR30";
+ case EM_CYGNUS_D10V:
+ case EM_D10V: return "d10v";
+ case EM_CYGNUS_D30V:
+ case EM_D30V: return "d30v";
+ case EM_CYGNUS_V850:
+ case EM_V850: return "Renesas V850";
+ case EM_CYGNUS_M32R:
+ case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
+ case EM_CYGNUS_MN10300:
+ case EM_MN10300: return "mn10300";
+ /* 90 */
+ case EM_CYGNUS_MN10200:
+ case EM_MN10200: return "mn10200";
+ case EM_PJ: return "picoJava";
case EM_OR1K: return "OpenRISC 1000";
- case EM_CRX: return "National Semiconductor CRX microprocessor";
- case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
- case EM_DLX: return "OpenDLX";
- case EM_IP2K_OLD:
- case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
- case EM_IQ2000: return "Vitesse IQ2000";
+ case EM_ARC_COMPACT: return "ARCompact";
case EM_XTENSA_OLD:
case EM_XTENSA: return "Tensilica Xtensa Processor";
case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
case EM_NS32K: return "National Semiconductor 32000 series";
case EM_TPC: return "Tenor Network TPC processor";
- case EM_ST200: return "STMicroelectronics ST200 microcontroller";
+ case EM_SNP1K: return "Trebia SNP 1000 processor";
+ /* 100 */
+ case EM_ST200: return "STMicroelectronics ST200 microcontroller";
+ case EM_IP2K_OLD:
+ case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
case EM_MAX: return "MAX Processor";
case EM_CR: return "National Semiconductor CompactRISC";
case EM_F2MC16: return "Fujitsu F2MC16";
case EM_MSP430: return "Texas Instruments msp430 microcontroller";
- case EM_LATTICEMICO32: return "Lattice Mico32";
- case EM_M32C_OLD:
- case EM_M32C: return "Renesas M32c";
- case EM_MT: return "Morpho Techologies MT processor";
case EM_BLACKFIN: return "Analog Devices Blackfin";
case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
case EM_SEP: return "Sharp embedded microprocessor";
case EM_ARCA: return "Arca RISC microprocessor";
+ /* 110 */
case EM_UNICORE: return "Unicore";
case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
- case EM_NIOS32: return "Altera Nios";
case EM_ALTERA_NIOS2: return "Altera Nios II";
+ case EM_CRX: return "National Semiconductor CRX microprocessor";
+ case EM_XGATE: return "Motorola XGATE embedded processor";
case EM_C166:
case EM_XC16X: return "Infineon Technologies xc16x";
case EM_M16C: return "Renesas M16C series microprocessors";
case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
case EM_CE: return "Freescale Communication Engine RISC core";
+ /* 120 */
+ case EM_M32C: return "Renesas M32c";
+ /* 130 */
case EM_TSK3000: return "Altium TSK3000 core";
case EM_RS08: return "Freescale RS08 embedded processor";
case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
+ case EM_SCORE: return "SUNPLUS S+Core";
case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
+ case EM_LATTICEMICO32: return "Lattice Mico32";
case EM_SE_C17: return "Seiko Epson C17 family";
+ /* 140 */
case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
+ case EM_TI_PRU: return "TI PRU I/O processor";
+ /* 160 */
case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
case EM_R32C: return "Renesas R32C series microprocessors";
case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
case EM_ECOG1X: return "Cyan Technology eCOG1X family";
case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
+ /* 170 */
case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
- case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
- case EM_CR16:
- case EM_MICROBLAZE:
- case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
- case EM_RISCV: return "RISC-V";
- case EM_RL78: return "Renesas RL78";
case EM_RX: return "Renesas RX";
case EM_METAG: return "Imagination Technologies Meta processor architecture";
case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
case EM_ECOG16: return "Cyan Technology eCOG16 family";
+ case EM_CR16:
+ case EM_MICROBLAZE:
+ case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
case EM_ETPU: return "Freescale Extended Time Processing Unit";
case EM_SLE9X: return "Infineon Technologies SLE9X core";
- case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
+ /* 180 */
+ case EM_L1OM: return "Intel L1OM";
+ case EM_K1OM: return "Intel K1OM";
+ case EM_INTEL182: return "Intel (reserved)";
+ case EM_AARCH64: return "AArch64";
+ case EM_ARM184: return "ARM (reserved)";
+ case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
case EM_TILE64: return "Tilera TILE64 multicore architecture family";
case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
- case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
+ /* 190 */
case EM_CUDA: return "NVIDIA CUDA architecture";
- case EM_XGATE: return "Motorola XGATE embedded processor";
+ case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
case EM_CLOUDSHIELD: return "CloudShield architecture family";
case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
+ case EM_ARC_COMPACT2: return "ARCv2";
case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
+ case EM_RL78: return "Renesas RL78";
case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
+ case EM_78K0R: return "Renesas 78K0R";
+ /* 200 */
case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
case EM_BA1: return "Beyond BA1 CPU architecture";
case EM_BA2: return "Beyond BA2 CPU architecture";
case EM_XCORE: return "XMOS xCORE processor family";
case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
+ /* 210 */
case EM_KM32: return "KM211 KM32 32-bit processor";
case EM_KMX32: return "KM211 KMX32 32-bit processor";
case EM_KMX16: return "KM211 KMX16 16-bit processor";
case EM_COOL: return "Bluechip Systems CoolEngine";
case EM_NORC: return "Nanoradio Optimized RISC";
case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
+ /* 220 */
case EM_Z80: return "Zilog Z80";
- case EM_AMDGPU: return "AMD GPU architecture";
- case EM_TI_PRU: return "TI PRU I/O processor";
+ case EM_VISIUM: return "CDS VISIUMcore processor";
+ case EM_FT32: return "FTDI Chip FT32";
+ case EM_MOXIE: return "Moxie";
+ case EM_AMDGPU: return "AMD GPU";
+ case EM_RISCV: return "RISC-V";
+ case EM_LANAI: return "Lanai 32-bit processor";
+ case EM_BPF: return "Linux BPF";
+
+ /* Large numbers... */
+ case EM_MT: return "Morpho Techologies MT processor";
+ case EM_ALPHA: return "Alpha";
+ case EM_WEBASSEMBLY: return "Web Assembly";
+ case EM_DLX: return "OpenDLX";
+ case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
+ case EM_IQ2000: return "Vitesse IQ2000";
+ case EM_M32C_OLD:
+ case EM_NIOS32: return "Altera Nios";
+ case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
+ case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
+ case EM_CYGNUS_FRV: return "Fujitsu FR-V";
+
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
return buff;
case E_ARC_OSABI_V3:
strcat (buf, ", v3 no-legacy-syscalls ABI");
break;
+ case E_ARC_OSABI_V4:
+ strcat (buf, ", v4 ABI");
+ break;
default:
strcat (buf, ", unrecognised ARC OSABI flag");
break;
case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
+ case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
+ case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
case 0:
/* We simply ignore the field in this case to avoid confusion:
MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
}
}
+static const char *
+get_s390_segment_type (unsigned long type)
+{
+ switch (type)
+ {
+ case PT_S390_PGSTE: return "S390_PGSTE";
+ default: return NULL;
+ }
+}
+
static const char *
get_mips_segment_type (unsigned long type)
{
case PT_GNU_RELRO: return "GNU_RELRO";
default:
- if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
+ if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
+ {
+ sprintf (buff, "GNU_MBIND+%#lx",
+ p_type - PT_GNU_MBIND_LO);
+ }
+ else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
{
const char * result;
case EM_TI_C6000:
result = get_tic6x_segment_type (p_type);
break;
+ case EM_S390:
+ case EM_S390_OLD:
+ result = get_s390_segment_type (p_type);
+ break;
default:
result = NULL;
break;
}
}
+static const char *
+get_arc_section_type_name (unsigned int sh_type)
+{
+ switch (sh_type)
+ {
+ case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
+ default:
+ break;
+ }
+ return NULL;
+}
+
static const char *
get_mips_section_type_name (unsigned int sh_type)
{
{
switch (elf_header.e_machine)
{
+ case EM_ARC:
+ case EM_ARC_COMPACT:
+ case EM_ARC_COMPACT2:
+ result = get_arc_section_type_name (sh_type);
+ break;
case EM_MIPS:
case EM_MIPS_RS3_LE:
result = get_mips_section_type_name (sh_type);
if (program_headers != NULL)
return TRUE;
- phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
- sizeof (Elf_Internal_Phdr));
+ /* Be kind to memory checkers by looking for
+ e_phnum values which we know must be invalid. */
+ if (elf_header.e_phnum
+ * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
+ >= current_file_size)
+ {
+ error (_("Too many program headers - %#x - the file is not that big\n"),
+ elf_header.e_phnum);
+ return FALSE;
+ }
+ phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
+ sizeof (Elf_Internal_Phdr));
if (phdrs == NULL)
{
error (_("Out of memory reading %u program headers\n"),
section in the DYNAMIC segment. */
dynamic_addr = segment->p_offset;
dynamic_size = segment->p_filesz;
- /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
- if (dynamic_addr + dynamic_size >= current_file_size)
- {
- error (_("the dynamic segment offset + size exceeds the size of the file\n"));
- dynamic_addr = dynamic_size = 0;
- }
/* Try to locate the .dynamic section. If there is
a section header table, we can easily locate it. */
warn (_("the .dynamic section is not the first section"
" in the dynamic segment.\n"));
}
+
+ /* PR binutils/17512: Avoid corrupt dynamic section info in the
+ 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 >= current_file_size)
+ {
+ error (_("the dynamic segment offset + size exceeds the size of the file\n"));
+ dynamic_addr = dynamic_size = 0;
+ }
break;
case PT_INTERP:
/* ARM specific. */
/* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
/* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
- /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
+ /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
+ /* GNU specific. */
+ /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
+ /* VLE specific. */
+ /* 25 */ { STRING_COMMA_LEN ("VLE") },
};
if (do_section_details)
case SHF_TLS: sindex = 9; break;
case SHF_EXCLUDE: sindex = 18; break;
case SHF_COMPRESSED: sindex = 20; break;
+ case SHF_GNU_MBIND: sindex = 24; break;
default:
sindex = -1;
default: break;
}
break;
+ case EM_PPC:
+ if (flag == SHF_PPC_VLE)
+ sindex = 25;
+ break;
default:
break;
case SHF_TLS: *p = 'T'; break;
case SHF_EXCLUDE: *p = 'E'; break;
case SHF_COMPRESSED: *p = 'C'; break;
+ case SHF_GNU_MBIND: *p = 'D'; break;
default:
if ((elf_header.e_machine == EM_X86_64
else if (elf_header.e_machine == EM_ARM
&& flag == SHF_ARM_PURECODE)
*p = 'y';
+ else if (elf_header.e_machine == EM_PPC
+ && flag == SHF_PPC_VLE)
+ *p = 'v';
else if (flag & SHF_MASKOS)
{
*p = 'o';
request_dump_bynumber (i, DEBUG_DUMP);
else if (do_debug_frames && streq (name, ".eh_frame"))
request_dump_bynumber (i, DEBUG_DUMP);
- else if (do_gdb_index && streq (name, ".gdb_index"))
+ else if (do_gdb_index && (streq (name, ".gdb_index")
+ || streq (name, ".debug_names")))
request_dump_bynumber (i, DEBUG_DUMP);
/* Trace sections for Itanium VMS. */
else if ((do_debugging || do_trace_info || do_trace_abbrevs
if (section->sh_info < 1 || section->sh_info >= elf_header.e_shnum)
warn (_("[%2u]: Expected link to another section in info field"), i);
}
- else if (section->sh_type < SHT_LOOS && section->sh_info != 0)
+ else if (section->sh_type < SHT_LOOS
+ && (section->sh_flags & SHF_GNU_MBIND) == 0
+ && section->sh_info != 0)
warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
i, section->sh_info);
break;
}
+ /* Check the sh_size field. */
+ if (section->sh_size > current_file_size
+ && section->sh_type != SHT_NOBITS
+ && section->sh_type != SHT_NULL
+ && section->sh_type < SHT_LOOS)
+ warn (_("Size of section %u is larger than the entire file!\n"), i);
+
printf (" [%2u] ", i);
if (do_section_details)
printf ("%s\n ", printable_section_name (section));
printf (_("l (large), "));
else if (elf_header.e_machine == EM_ARM)
printf (_("y (purecode), "));
+ else if (elf_header.e_machine == EM_PPC)
+ printf (_("v (VLE), "));
printf ("p (processor specific)\n");
}
error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
entry, i, elf_header.e_shnum - 1);
if (num_group_errors == 10)
- warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
+ warn (_("Further error messages about overlarge group section indicies suppressed\n"));
}
continue;
}
}
if (! found)
- printf (_("\nThere are no relocations in this file.\n"));
+ {
+ /* Users sometimes forget the -D option, so try to be helpful. */
+ for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
+ {
+ if (dynamic_info [dynamic_relocations [i].size])
+ {
+ printf (_("\nThere are no static relocations in this file."));
+ printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
+
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE (dynamic_relocations))
+ printf (_("\nThere are no relocations in this file.\n"));
+ }
}
return TRUE;
return FALSE;
/* If the offset is invalid then fail. */
- if (word_offset > (sec->sh_size - 4)
- /* PR 18879 */
- || (sec->sh_size < 5 && word_offset >= sec->sh_size)
+ if (/* PR 21343 *//* PR 18879 */
+ sec->sh_size < 4
+ || word_offset > (sec->sh_size - 4)
|| ((bfd_signed_vma) word_offset) < 0)
return FALSE;
unsigned int more_words = 0;
struct absaddr addr;
bfd_vma sym_name = (bfd_vma) -1;
- bfd_boolean res = FALSE;
+ bfd_boolean res = TRUE;
if (remaining == 0)
{
processing that. This is overkill, I know, but it
should work. */
section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
+ if ((bfd_size_type) section.sh_offset > current_file_size)
+ {
+ /* See PR 21379 for a reproducer. */
+ error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
+ return FALSE;
+ }
if (archive_file_offset != 0)
section.sh_size = archive_file_size - section.sh_offset;
case SHT_GNU_verdef:
{
Elf_External_Verdef * edefs;
- unsigned int idx;
- unsigned int cnt;
- unsigned int end;
+ unsigned long idx;
+ unsigned long cnt;
char * endbuf;
found = TRUE;
break;
endbuf = (char *) edefs + section->sh_size;
- /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
- end = (section->sh_info < section->sh_size
- ? section->sh_info : section->sh_size);
- for (idx = cnt = 0; cnt < end; ++cnt)
+ for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
{
char * vstart;
Elf_External_Verdef * edef;
Elf_Internal_Verdef ent;
Elf_External_Verdaux * eaux;
Elf_Internal_Verdaux aux;
- unsigned int isum;
+ unsigned long isum;
int j;
- /* Check for very large indices. */
- if (idx > (size_t) (endbuf - (char *) edefs))
- break;
-
vstart = ((char *) edefs) + idx;
if (vstart + sizeof (*edef) > endbuf)
break;
ent.vd_aux = BYTE_GET (edef->vd_aux);
ent.vd_next = BYTE_GET (edef->vd_next);
- printf (_(" %#06x: Rev: %d Flags: %s"),
+ printf (_(" %#06lx: Rev: %d Flags: %s"),
idx, ent.vd_version, get_ver_flags (ent.vd_flags));
printf (_(" Index: %d Cnt: %d "),
ent.vd_ndx, ent.vd_cnt);
/* Check for overflow. */
- if (ent.vd_aux + sizeof (* eaux) > (size_t) (endbuf - vstart))
+ if (ent.vd_aux > (size_t) (endbuf - vstart))
break;
vstart += ent.vd_aux;
+ if (vstart + sizeof (*eaux) > endbuf)
+ break;
eaux = (Elf_External_Verdaux *) vstart;
aux.vda_name = BYTE_GET (eaux->vda_name);
for (j = 1; j < ent.vd_cnt; j++)
{
+ if (aux.vda_next < sizeof (*eaux)
+ && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
+ {
+ warn (_("Invalid vda_next field of %lx\n"),
+ aux.vda_next);
+ j = ent.vd_cnt;
+ break;
+ }
/* Check for overflow. */
if (aux.vda_next > (size_t) (endbuf - vstart))
break;
isum += aux.vda_next;
vstart += aux.vda_next;
- eaux = (Elf_External_Verdaux *) vstart;
if (vstart + sizeof (*eaux) > endbuf)
break;
+ eaux = (Elf_External_Verdaux *) vstart;
aux.vda_name = BYTE_GET (eaux->vda_name);
aux.vda_next = BYTE_GET (eaux->vda_next);
if (VALID_DYNAMIC_NAME (aux.vda_name))
- printf (_(" %#06x: Parent %d: %s\n"),
+ printf (_(" %#06lx: Parent %d: %s\n"),
isum, j, GET_DYNAMIC_NAME (aux.vda_name));
else
- printf (_(" %#06x: Parent %d, name index: %ld\n"),
+ printf (_(" %#06lx: Parent %d, name index: %ld\n"),
isum, j, aux.vda_name);
}
/* PR 17531:
file: id:000001,src:000172+005151,op:splice,rep:2. */
- if (idx + ent.vd_next < idx)
+ if (ent.vd_next < sizeof (*edef)
+ && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
+ {
+ warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
+ cnt = section->sh_info;
+ break;
+ }
+ if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
break;
idx += ent.vd_next;
case SHT_GNU_verneed:
{
Elf_External_Verneed * eneed;
- unsigned int idx;
- unsigned int cnt;
+ unsigned long idx;
+ unsigned long cnt;
char * endbuf;
found = TRUE;
{
Elf_External_Verneed * entry;
Elf_Internal_Verneed ent;
- unsigned int isum;
+ unsigned long isum;
int j;
char * vstart;
- if (idx > (size_t) (endbuf - (char *) eneed))
- break;
-
vstart = ((char *) eneed) + idx;
if (vstart + sizeof (*entry) > endbuf)
break;
ent.vn_aux = BYTE_GET (entry->vn_aux);
ent.vn_next = BYTE_GET (entry->vn_next);
- printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
+ printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
if (VALID_DYNAMIC_NAME (ent.vn_file))
printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
aux.vna_next = BYTE_GET (eaux->vna_next);
if (VALID_DYNAMIC_NAME (aux.vna_name))
- printf (_(" %#06x: Name: %s"),
+ printf (_(" %#06lx: Name: %s"),
isum, GET_DYNAMIC_NAME (aux.vna_name));
else
- printf (_(" %#06x: Name index: %lx"),
+ printf (_(" %#06lx: Name index: %lx"),
isum, aux.vna_name);
printf (_(" Flags: %s Version: %d\n"),
get_ver_flags (aux.vna_flags), aux.vna_other);
- /* Check for overflow. */
- if (aux.vna_next > (size_t) (endbuf - vstart)
- || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
+ if (aux.vna_next < sizeof (*eaux)
+ && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
{
warn (_("Invalid vna_next field of %lx\n"),
aux.vna_next);
j = ent.vn_cnt;
break;
}
+ /* Check for overflow. */
+ if (aux.vna_next > (size_t) (endbuf - vstart))
+ break;
isum += aux.vna_next;
vstart += aux.vna_next;
}
if (j < ent.vn_cnt)
warn (_("Missing Version Needs auxillary information\n"));
- if (ent.vn_next == 0 && cnt < section->sh_info - 1)
+ if (ent.vn_next < sizeof (*entry)
+ && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
{
- warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
+ warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
cnt = section->sh_info;
break;
}
+ if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
+ break;
idx += ent.vn_next;
}
if (sizeof (size_t) < sizeof (bfd_size_type)
&& (bfd_size_type) ((size_t) number) != number)
{
- error (_("Size truncation prevents reading %" BFD_VMA_FMT "u"
- " elements of size %u\n"),
- number, ent_size);
+ error (_("Size truncation prevents reading %s elements of size %u\n"),
+ bfd_vmatoa ("u", number), ent_size);
return NULL;
}
attempting to allocate memory when the read is bound to fail. */
if (ent_size * number > current_file_size)
{
- error (_("Invalid number of dynamic entries: %" BFD_VMA_FMT "u\n"),
- number);
+ error (_("Invalid number of dynamic entries: %s\n"),
+ bfd_vmatoa ("u", number));
return NULL;
}
e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
if (e_data == NULL)
{
- error (_("Out of memory reading %" BFD_VMA_FMT "u dynamic entries\n"),
- number);
+ error (_("Out of memory reading %s dynamic entries\n"),
+ bfd_vmatoa ("u", number));
return NULL;
}
if (fread (e_data, ent_size, (size_t) number, file) != number)
{
- error (_("Unable to read in %" BFD_VMA_FMT "u bytes of dynamic data\n"),
- number * ent_size);
+ error (_("Unable to read in %s bytes of dynamic data\n"),
+ bfd_vmatoa ("u", number * ent_size));
free (e_data);
return NULL;
}
i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
if (i_data == NULL)
{
- error (_("Out of memory allocating space for %" BFD_VMA_FMT "u"
- " dynamic entries\n"),
- number);
+ error (_("Out of memory allocating space for %s dynamic entries\n"),
+ bfd_vmatoa ("u", number));
free (e_data);
return NULL;
}
if (dynamic_info[DT_HASH])
{
bfd_vma si;
+ char *visited;
printf (_("\nSymbol table for image:\n"));
if (is_32bit_elf)
else
printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
+ visited = xcmalloc (nchains, 1);
+ memset (visited, 0, nchains);
for (hn = 0; hn < nbuckets; hn++)
{
- if (! buckets[hn])
- continue;
-
- for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
- print_dynamic_symbol (si, hn);
+ for (si = buckets[hn]; si > 0; si = chains[si])
+ {
+ print_dynamic_symbol (si, hn);
+ if (si >= nchains || visited[si])
+ {
+ error (_("histogram chain is corrupt\n"));
+ break;
+ }
+ visited[si] = 1;
+ }
}
+ free (visited);
}
if (dynamic_info_DT_GNU_HASH)
unsigned long maxlength = 0;
unsigned long nzero_counts = 0;
unsigned long nsyms = 0;
- unsigned long chained;
+ char *visited;
printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
(unsigned long) nbuckets);
error (_("Out of memory allocating space for histogram buckets\n"));
return FALSE;
}
+ visited = xcmalloc (nchains, 1);
+ memset (visited, 0, nchains);
printf (_(" Length Number %% of total Coverage\n"));
for (hn = 0; hn < nbuckets; ++hn)
{
- for (si = buckets[hn], chained = 0;
- si > 0 && si < nchains && si < nbuckets && chained <= nchains;
- si = chains[si], ++chained)
+ for (si = buckets[hn]; si > 0; si = chains[si])
{
++nsyms;
if (maxlength < ++lengths[hn])
++maxlength;
+ if (si >= nchains || visited[si])
+ {
+ error (_("histogram chain is corrupt\n"));
+ break;
+ }
+ visited[si] = 1;
}
-
- /* PR binutils/17531: A corrupt binary could contain broken
- histogram data. Do not go into an infinite loop trying
- to process it. */
- if (chained > nchains)
- {
- error (_("histogram chain is corrupt\n"));
- break;
- }
}
+ free (visited);
counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
if (counts == NULL)
case EM_H8_300H:
return reloc_type == 1; /* R_H8_DIR32. */
case EM_IA_64:
- return reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
- || reloc_type == 0x25; /* R_IA64_DIR32LSB. */
+ return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
+ || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
+ || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
+ || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
case EM_IP2K_OLD:
case EM_IP2K:
return reloc_type == 2; /* R_IP2K_32. */
return reloc_type == 1; /* R_VAX_32. */
case EM_VISIUM:
return reloc_type == 3; /* R_VISIUM_32. */
+ case EM_WEBASSEMBLY:
+ return reloc_type == 1; /* R_WASM32_32. */
case EM_X86_64:
case EM_L1OM:
case EM_K1OM:
case EM_ALPHA:
return reloc_type == 2; /* R_ALPHA_REFQUAD. */
case EM_IA_64:
- return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
+ return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
+ || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
case EM_PARISC:
return reloc_type == 80; /* R_PARISC_DIR64. */
case EM_PPC64:
case EM_SPARC32PLUS:
case EM_SPARCV9:
case EM_SPARC:
- return reloc_type == 54; /* R_SPARC_UA64. */
+ return reloc_type == 32 /* R_SPARC_64. */
+ || reloc_type == 54; /* R_SPARC_UA64. */
case EM_X86_64:
case EM_L1OM:
case EM_K1OM:
case EM_ALPHA:
return reloc_type == 11; /* R_ALPHA_SREL64. */
case EM_IA_64:
- return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
+ return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
+ || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
case EM_PARISC:
return reloc_type == 72; /* R_PARISC_PCREL64. */
case EM_PPC64:
case EM_CYGNUS_D10V:
case EM_D10V:
return reloc_type == 3; /* R_D10V_16. */
+ case EM_FT32:
+ return reloc_type == 2; /* R_FT32_16. */
case EM_H8S:
case EM_H8_300:
case EM_H8_300H:
case EM_TI_C6000:/* R_C6000_NONE. */
case EM_X86_64: /* R_X86_64_NONE. */
case EM_XC16X:
+ case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
return reloc_type == 0;
case EM_AARCH64:
if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
{
- printf (_("\nSection '%s' has no data to dump.\n"),
+ printf (_("Section '%s' has no data to dump.\n"),
printable_section_name (section));
return NULL;
}
unsigned char * start;
bfd_boolean some_strings_shown;
- real_start = start = (unsigned char *) get_section_contents (section,
- file);
+ real_start = start = (unsigned char *) get_section_contents (section, file);
if (start == NULL)
- return FALSE;
+ /* PR 21820: Do not fail if the section was empty. */
+ return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
+
num_bytes = section->sh_size;
printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
real_start = start = (unsigned char *) get_section_contents (section, file);
if (start == NULL)
- return FALSE;
+ /* PR 21820: Do not fail if the section was empty. */
+ return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
section_size = section->sh_size;
return p;
}
-/* ARM EABI attributes section. */
-typedef struct
+/* ARC ABI attributes section. */
+
+static unsigned char *
+display_arc_attribute (unsigned char * p,
+ const unsigned char * const end)
{
unsigned int tag;
- const char * name;
- /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
- unsigned int type;
- const char ** table;
-} arm_attr_public_tag;
+ unsigned int len;
+ unsigned int val;
-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-M.baseline",
- "v8-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_FP_arch[] =
- {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
- "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
-static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
-static const char * arm_attr_tag_Advanced_SIMD_arch[] =
- {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
- "NEON for ARMv8.1"};
-static const char * arm_attr_tag_PCS_config[] =
- {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
- "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
-static const char * arm_attr_tag_ABI_PCS_R9_use[] =
- {"V6", "SB", "TLS", "Unused"};
-static const char * arm_attr_tag_ABI_PCS_RW_data[] =
- {"Absolute", "PC-relative", "SB-relative", "None"};
-static const char * arm_attr_tag_ABI_PCS_RO_data[] =
- {"Absolute", "PC-relative", "None"};
-static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
- {"None", "direct", "GOT-indirect"};
-static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
- {"None", "??? 1", "2", "??? 3", "4"};
-static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_denormal[] =
- {"Unused", "Needed", "Sign only"};
-static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_number_model[] =
- {"Unused", "Finite", "RTABI", "IEEE 754"};
-static const char * arm_attr_tag_ABI_enum_size[] =
- {"Unused", "small", "int", "forced to int"};
-static const char * arm_attr_tag_ABI_HardFP_use[] =
+ tag = read_uleb128 (p, &len, end);
+ p += len;
+
+ switch (tag)
+ {
+ case Tag_ARC_PCS_config:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_PCS_config: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("Absent/Non standard\n"));
+ break;
+ case 1:
+ printf (_("Bare metal/mwdt\n"));
+ break;
+ case 2:
+ printf (_("Bare metal/newlib\n"));
+ break;
+ case 3:
+ printf (_("Linux/uclibc\n"));
+ break;
+ case 4:
+ printf (_("Linux/glibc\n"));
+ break;
+ default:
+ printf (_("Unknown\n"));
+ break;
+ }
+ break;
+
+ case Tag_ARC_CPU_base:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_CPU_base: ");
+ switch (val)
+ {
+ default:
+ case TAG_CPU_NONE:
+ printf (_("Absent\n"));
+ break;
+ case TAG_CPU_ARC6xx:
+ printf ("ARC6xx\n");
+ break;
+ case TAG_CPU_ARC7xx:
+ printf ("ARC7xx\n");
+ break;
+ case TAG_CPU_ARCEM:
+ printf ("ARCEM\n");
+ break;
+ case TAG_CPU_ARCHS:
+ printf ("ARCHS\n");
+ break;
+ }
+ break;
+
+ case Tag_ARC_CPU_variation:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_CPU_variation: ");
+ switch (val)
+ {
+ default:
+ if (val > 0 && val < 16)
+ printf ("Core%d\n", val);
+ else
+ printf ("Unknown\n");
+ break;
+
+ case 0:
+ printf (_("Absent\n"));
+ break;
+ }
+ break;
+
+ case Tag_ARC_CPU_name:
+ printf (" Tag_ARC_CPU_name: ");
+ p = display_tag_value (-1, p, end);
+ break;
+
+ case Tag_ARC_ABI_rf16:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
+ break;
+
+ case Tag_ARC_ABI_osver:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_osver: v%d\n", val);
+ break;
+
+ case Tag_ARC_ABI_pic:
+ case Tag_ARC_ABI_sda:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
+ : " Tag_ARC_ABI_pic: ");
+ switch (val)
+ {
+ case 0:
+ printf (_("Absent\n"));
+ break;
+ case 1:
+ printf ("MWDT\n");
+ break;
+ case 2:
+ printf ("GNU\n");
+ break;
+ default:
+ printf (_("Unknown\n"));
+ break;
+ }
+ break;
+
+ case Tag_ARC_ABI_tls:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
+ break;
+
+ case Tag_ARC_ABI_enumsize:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
+ _("smallest"));
+ break;
+
+ case Tag_ARC_ABI_exceptions:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
+ : _("default"));
+ break;
+
+ case Tag_ARC_ABI_double_size:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ABI_double_size: %d\n", val);
+ break;
+
+ case Tag_ARC_ISA_config:
+ printf (" Tag_ARC_ISA_config: ");
+ p = display_tag_value (-1, p, end);
+ break;
+
+ case Tag_ARC_ISA_apex:
+ printf (" Tag_ARC_ISA_apex: ");
+ p = display_tag_value (-1, p, end);
+ break;
+
+ case Tag_ARC_ISA_mpy_option:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
+ break;
+
+ default:
+ return display_tag_value (tag & 1, p, end);
+ }
+
+ return p;
+}
+
+/* ARM EABI attributes section. */
+typedef struct
+{
+ unsigned int tag;
+ const char * name;
+ /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
+ unsigned int type;
+ const char ** table;
+} arm_attr_public_tag;
+
+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"};
+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_FP_arch[] =
+ {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
+ "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
+static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
+static const char * arm_attr_tag_Advanced_SIMD_arch[] =
+ {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
+ "NEON for ARMv8.1"};
+static const char * arm_attr_tag_PCS_config[] =
+ {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
+ "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
+static const char * arm_attr_tag_ABI_PCS_R9_use[] =
+ {"V6", "SB", "TLS", "Unused"};
+static const char * arm_attr_tag_ABI_PCS_RW_data[] =
+ {"Absolute", "PC-relative", "SB-relative", "None"};
+static const char * arm_attr_tag_ABI_PCS_RO_data[] =
+ {"Absolute", "PC-relative", "None"};
+static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
+ {"None", "direct", "GOT-indirect"};
+static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
+ {"None", "??? 1", "2", "??? 3", "4"};
+static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
+static const char * arm_attr_tag_ABI_FP_denormal[] =
+ {"Unused", "Needed", "Sign only"};
+static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
+static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
+static const char * arm_attr_tag_ABI_FP_number_model[] =
+ {"Unused", "Finite", "RTABI", "IEEE 754"};
+static const char * arm_attr_tag_ABI_enum_size[] =
+ {"Unused", "small", "int", "forced to int"};
+static const char * arm_attr_tag_ABI_HardFP_use[] =
{"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
static const char * arm_attr_tag_ABI_VFP_args[] =
{"AAPCS", "VFP registers", "custom", "compatible"};
fputs ("\n\tMICROMIPS ASE", stdout);
if (mask & AFL_ASE_XPA)
fputs ("\n\tXPA ASE", stdout);
+ if (mask & AFL_ASE_MIPS16E2)
+ fputs ("\n\tMIPS16e2 ASE", stdout);
if (mask == 0)
fprintf (stdout, "\n\t%s", _("None"));
else if ((mask & ~AFL_ASE_MASK) != 0)
case AFL_EXT_LOONGSON_2F:
fputs ("ST Microelectronics Loongson 2F", stdout);
break;
+ case AFL_EXT_INTERAPTIV_MR2:
+ fputs ("Imagination interAptiv MR2", stdout);
+ break;
default:
fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
}
/* We have a lot of special sections. Thanks SGI! */
if (dynamic_section == NULL)
- /* No information available. */
- return res;
+ {
+ /* No dynamic information available. See if there is static GOT. */
+ sect = find_section (".got");
+ if (sect != NULL)
+ {
+ unsigned char *data_end;
+ unsigned char *data;
+ bfd_vma ent, end;
+ int addr_size;
+
+ pltgot = sect->sh_addr;
+
+ ent = pltgot;
+ addr_size = (is_32bit_elf ? 4 : 8);
+ end = pltgot + sect->sh_size;
+
+ data = (unsigned char *) get_data (NULL, file, sect->sh_offset,
+ end - pltgot, 1,
+ _("Global Offset Table data"));
+ /* PR 12855: Null data is handled gracefully throughout. */
+ data_end = data + (end - pltgot);
+
+ printf (_("\nStatic GOT:\n"));
+ printf (_(" Canonical gp value: "));
+ print_vma (ent + 0x7ff0, LONG_HEX);
+ printf ("\n\n");
+
+ /* In a dynamic binary GOT[0] is reserved for the dynamic
+ loader to store the lazy resolver pointer, however in
+ a static binary it may well have been omitted and GOT
+ reduced to a table of addresses.
+ PR 21344: Check for the entry being fully available
+ before fetching it. */
+ if (data
+ && data + ent - pltgot + addr_size <= data_end
+ && byte_get (data + ent - pltgot, addr_size) == 0)
+ {
+ printf (_(" Reserved entries:\n"));
+ printf (_(" %*s %10s %*s\n"),
+ addr_size * 2, _("Address"), _("Access"),
+ addr_size * 2, _("Value"));
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+
+ /* Check for the MSB of GOT[1] being set, identifying a
+ GNU object. This entry will be used by some runtime
+ loaders, to store the module pointer. Otherwise this
+ is an ordinary local entry.
+ PR 21344: Check for the entry being fully available
+ before fetching it. */
+ if (data
+ && data + ent - pltgot + addr_size <= data_end
+ && (byte_get (data + ent - pltgot, addr_size)
+ >> (addr_size * 8 - 1)) != 0)
+ {
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+ }
+ printf ("\n");
+ }
+
+ if (data != NULL && ent < end)
+ {
+ printf (_(" Local entries:\n"));
+ printf (" %*s %10s %*s\n",
+ addr_size * 2, _("Address"), _("Access"),
+ addr_size * 2, _("Value"));
+ while (ent < end)
+ {
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+ }
+ printf ("\n");
+ }
+
+ sgot_print_fail:
+ if (data)
+ free (data);
+ }
+ return res;
+ }
for (entry = dynamic_section;
/* PR 17531 file: 012-50589-0.004. */
return FALSE;
}
+ /* PR 21345 - print a slightly more helpful error message
+ if we are sure that the cmalloc will fail. */
+ if (conflictsno * sizeof (* iconf) > current_file_size)
+ {
+ error (_("Overlarge number of conflicts detected: %lx\n"),
+ (long) conflictsno);
+ return FALSE;
+ }
+
iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
if (iconf == NULL)
{
data = (unsigned char *) get_data (NULL, file, offset,
global_end - pltgot, 1,
_("Global Offset Table data"));
- if (data == NULL)
- return FALSE;
+ /* PR 12855: Null data is handled gracefully throughout. */
data_end = data + (global_end - pltgot);
printf (_("\nPrimary GOT:\n"));
printf (_(" Lazy resolver\n"));
if (ent == (bfd_vma) -1)
goto got_print_fail;
+
+ /* Check for the MSB of GOT[1] being set, denoting a GNU object.
+ This entry will be used by some runtime loaders, to store the
+ module pointer. Otherwise this is an ordinary local entry.
+ PR 21344: Check for the entry being fully available before
+ fetching it. */
if (data
+ && data + ent - pltgot + addr_size <= data_end
&& (byte_get (data + ent - pltgot, addr_size)
>> (addr_size * 8 - 1)) != 0)
{
}
printf ("\n");
- if (ent < local_end)
+ if (data != NULL && ent < local_end)
{
printf (_(" Local entries:\n"));
printf (" %*s %10s %*s\n",
printf ("\n");
}
- if (gotsym < symtabno)
+ if (data != NULL && gotsym < symtabno)
{
int sym_width;
return _("NT_PPC_VMX (ppc Altivec registers)");
case NT_PPC_VSX:
return _("NT_PPC_VSX (ppc VSX registers)");
+ case NT_PPC_TAR:
+ return _("NT_PPC_TAR (ppc TAR register)");
+ case NT_PPC_PPR:
+ return _("NT_PPC_PPR (ppc PPR register)");
+ case NT_PPC_DSCR:
+ return _("NT_PPC_DSCR (ppc DSCR register)");
+ case NT_PPC_EBB:
+ return _("NT_PPC_EBB (ppc EBB registers)");
+ case NT_PPC_PMU:
+ return _("NT_PPC_PMU (ppc PMU registers)");
+ case NT_PPC_TM_CGPR:
+ return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
+ case NT_PPC_TM_CFPR:
+ return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
+ 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)");
+ case NT_PPC_TM_SPR:
+ return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
+ case NT_PPC_TM_CTAR:
+ return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
+ case NT_PPC_TM_CPPR:
+ return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
+ case NT_PPC_TM_CDSCR:
+ return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
case NT_386_TLS:
return _("NT_386_TLS (x86 TLS information)");
case NT_386_IOPERM:
return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
case NT_S390_VXRS_HIGH:
return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
+ case NT_S390_GS_CB:
+ return _("NT_S390_GS_CB (s390 guarded-storage registers)");
+ case NT_S390_GS_BC:
+ return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
case NT_ARM_VFP:
return _("NT_ARM_VFP (arm VFP registers)");
case NT_ARM_TLS:
unsigned char *descdata, *filenames, *descend;
if (pnote->type != NT_FILE)
- return TRUE;
+ {
+ if (do_wide)
+ printf ("\n");
+ return TRUE;
+ }
#ifndef BFD64
if (!is_32bit_elf)
page_size = byte_get (descdata, addr_size);
descdata += addr_size;
- if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
+ if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
+ || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
{
error (_(" Malformed note - too short for supplied file count\n"));
return FALSE;
}
static void
-decode_x86_isa (unsigned long bitmask)
+decode_x86_isa (unsigned int bitmask)
{
while (bitmask)
{
- unsigned long bit = bitmask & (- bitmask);
+ unsigned int bit = bitmask & (- bitmask);
bitmask &= ~ bit;
switch (bit)
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: %lx>"), bit); break;
+ default: printf (_("<unknown: %x>"), bit); break;
+ }
+ if (bitmask)
+ printf (", ");
+ }
+}
+
+static void
+decode_x86_feature (unsigned int type, unsigned int bitmask)
+{
+ while (bitmask)
+ {
+ unsigned int bit = bitmask & (- bitmask);
+
+ bitmask &= ~ bit;
+ 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 ();
+ }
+ 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 ();
+ }
+ break;
+ default:
+ printf (_("<unknown: %x>"), bit);
+ break;
}
if (bitmask)
printf (", ");
printf (_(" Properties: "));
- if (pnote->descsz % size)
+ if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
{
printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
return;
}
- while (ptr < (ptr_end - (size * 2)))
+ while (ptr < ptr_end)
{
- unsigned long j;
- unsigned long type = byte_get (ptr, size);
- unsigned long datasz = byte_get (ptr + size, size);
-
- ptr += 2 * size;
+ unsigned int j;
+ unsigned int type;
+ unsigned int datasz;
- switch (type)
+ if ((size_t) (ptr_end - ptr) < 8)
{
- case GNU_PROPERTY_STACK_SIZE:
- printf (_("stack size: "));
- if (datasz != size || (ptr + size > ptr_end))
- printf (_("<corrupt length: %#lx> "), datasz);
- else
- printf ("%#lx", (unsigned long) byte_get (ptr, size));
+ printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
break;
+ }
- case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
- printf ("no copy on protected ");
- if (datasz)
- printf (_("<corrupt length: %#lx> "), datasz);
- break;
+ type = byte_get (ptr, 4);
+ datasz = byte_get (ptr + 4, 4);
- case GNU_PROPERTY_X86_ISA_1_USED:
- printf ("x86 ISA used: ");
- if (datasz != size || (ptr + size > ptr_end))
- printf (_("<corrupt length: %#lx> "), datasz);
- else
- decode_x86_isa (byte_get (ptr, size));
- break;
+ ptr += 8;
- case GNU_PROPERTY_X86_ISA_1_NEEDED:
- printf ("x86 ISA needed: ");
- if (datasz != size || (ptr + size > ptr_end))
- printf (_("<corrupt length: %#lx> "), datasz);
- else
- decode_x86_isa (byte_get (ptr, size));
+ if (datasz > (size_t) (ptr_end - ptr))
+ {
+ printf (_("<corrupt type (%#x) datasz: %#x>\n"),
+ type, datasz);
break;
+ }
- default:
- printf (_("<unknown type %#lx data: "), type);
- if (ptr + datasz > ptr_end)
+ if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
+ {
+ if (elf_header.e_machine == EM_X86_64
+ || elf_header.e_machine == EM_IAMCU
+ || elf_header.e_machine == EM_386)
+ {
+ switch (type)
+ {
+ case GNU_PROPERTY_X86_ISA_1_USED:
+ printf ("x86 ISA used: ");
+ if (datasz != 4)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ decode_x86_isa (byte_get (ptr, 4));
+ goto next;
+
+ case GNU_PROPERTY_X86_ISA_1_NEEDED:
+ printf ("x86 ISA needed: ");
+ if (datasz != 4)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ decode_x86_isa (byte_get (ptr, 4));
+ goto next;
+
+ case GNU_PROPERTY_X86_FEATURE_1_AND:
+ printf ("x86 feature: ");
+ if (datasz != 4)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ decode_x86_feature (type, byte_get (ptr, 4));
+ goto next;
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch (type)
{
- printf (_("corrupt datasz: %#lx>\n"), datasz);
+ case GNU_PROPERTY_STACK_SIZE:
+ printf (_("stack size: "));
+ if (datasz != size)
+ printf (_("<corrupt length: %#x> "), datasz);
+ else
+ printf ("%#lx", (unsigned long) byte_get (ptr, size));
+ goto next;
+
+ case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+ printf ("no copy on protected ");
+ if (datasz)
+ printf (_("<corrupt length: %#x> "), datasz);
+ goto next;
+
+ default:
break;
}
- for (j = 0; j < datasz; ++j)
- printf ("%02x ", ptr[j] & 0xff);
- printf (">");
- break;
}
+ if (type < GNU_PROPERTY_LOPROC)
+ printf (_("<unknown type %#x data: "), type);
+ else if (type < GNU_PROPERTY_LOUSER)
+ printf (_("<procesor-specific type %#x data: "), type);
+ else
+ printf (_("<application-specific type %#x data: "), type);
+ for (j = 0; j < datasz; ++j)
+ printf ("%02x ", ptr[j] & 0xff);
+ printf (">");
+
+next:
ptr += ((datasz + (size - 1)) & ~ (size - 1));
- if (ptr < (ptr_end - (size * 2)))
- {
- if (do_wide)
- printf (", ");
- else
- printf ("\n\t");
- }
+ if (ptr == ptr_end)
+ break;
+
+ if (do_wide)
+ printf (", ");
+ else
+ printf ("\n\t");
}
printf ("\n");
return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
case NT_FREEBSD_PROCSTAT_AUXV:
return _("NT_PROCSTAT_AUXV (auxv data)");
+ case NT_FREEBSD_PTLWPINFO:
+ return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
}
return get_note_type (e_type);
}
return TRUE;
}
+/* Print the name of the symbol associated with a build attribute
+ that is attached to address OFFSET. */
+
static bfd_boolean
-print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
- FILE * file,
- Elf_Internal_Shdr * section ATTRIBUTE_UNUSED)
+print_symbol_for_build_attribute (FILE * file,
+ unsigned long offset,
+ bfd_boolean is_open_attr)
{
- static unsigned long global_offset = 0;
- unsigned long i;
- unsigned long strtab_size = 0;
- char * strtab = NULL;
- Elf_Internal_Sym * symtab = NULL;
- unsigned long nsyms = 0;
- Elf_Internal_Shdr * symsec = NULL;
- unsigned int desc_size = is_32bit_elf ? 4 : 8;
-
- if (pnote->descsz == 0)
- {
- printf (_(" Applies from offset %#lx\n"), global_offset);
- return TRUE;
- }
+ static FILE * saved_file = NULL;
+ static char * strtab;
+ static unsigned long strtablen;
+ static Elf_Internal_Sym * symtab;
+ static unsigned long nsyms;
+ Elf_Internal_Sym * saved_sym = NULL;
+ Elf_Internal_Sym * sym;
- if (pnote->descsz != desc_size)
+ if (section_headers != NULL
+ && (saved_file == NULL || file != saved_file))
{
- error (_(" <invalid description size: %lx>\n"), pnote->descsz);
- printf (_(" <invalid descsz>"));
- return FALSE;
- }
+ Elf_Internal_Shdr * symsec;
- /* Load the symbols. */
- for (symsec = section_headers;
- symsec < section_headers + elf_header.e_shnum;
- symsec ++)
- {
- if (symsec->sh_type == SHT_SYMTAB)
+ /* Load the symbol and string sections. */
+ for (symsec = section_headers;
+ symsec < section_headers + elf_header.e_shnum;
+ symsec ++)
{
- symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
-
- if (symsec->sh_link < elf_header.e_shnum)
+ if (symsec->sh_type == SHT_SYMTAB)
{
- Elf_Internal_Shdr * strtab_sec = section_headers + symsec->sh_link;
+ symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
+
+ if (symsec->sh_link < elf_header.e_shnum)
+ {
+ Elf_Internal_Shdr * strtab_sec = section_headers + symsec->sh_link;
- strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
- 1, strtab_sec->sh_size,
- _("string table"));
- strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
+ strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
+ 1, strtab_sec->sh_size,
+ _("string table"));
+ strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
+ }
}
}
+ saved_file = file;
}
- printf (_(" Applies from offset"));
-
- for (i = 0; i < pnote->descsz; i += desc_size)
+ if (symtab == NULL || strtab == NULL)
{
- Elf_Internal_Sym * saved_sym = NULL;
- Elf_Internal_Sym * sym;
- unsigned long offset;
+ printf ("\n");
+ return FALSE;
+ }
+
+ /* Find a symbol whose value matches offset. */
+ for (sym = symtab; sym < symtab + nsyms; sym ++)
+ if (sym->st_value == offset)
+ {
+ if (sym->st_name >= strtablen)
+ /* Huh ? This should not happen. */
+ continue;
- offset = byte_get ((unsigned char *) pnote->descdata + i, desc_size);
+ if (strtab[sym->st_name] == 0)
+ continue;
- if (i + desc_size == pnote->descsz)
- printf (_(" %#lx"), offset);
- else
- printf (_(" %#lx, "), offset);
+ if (is_open_attr)
+ {
+ /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
+ and FILE or OBJECT symbols over NOTYPE symbols. We skip
+ FUNC symbols entirely. */
+ switch (ELF_ST_TYPE (sym->st_info))
+ {
+ case STT_FILE:
+ saved_sym = sym;
+ /* We can stop searching now. */
+ sym = symtab + nsyms;
+ continue;
- if (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN)
- global_offset = offset;
+ case STT_OBJECT:
+ saved_sym = sym;
+ continue;
- if (symtab == NULL || strtab == NULL)
- continue;
+ case STT_FUNC:
+ /* Ignore function symbols. */
+ continue;
- /* Find a symbol whose value matches offset. */
- for (sym = symtab; sym < symtab + nsyms; sym ++)
- if (sym->st_value == offset)
- {
- if (sym->st_name < strtab_size)
+ default:
+ break;
+ }
+
+ switch (ELF_ST_BIND (sym->st_info))
{
- if (strtab[sym->st_name] == 0)
- continue;
+ case STB_GLOBAL:
+ if (saved_sym == NULL
+ || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
+ saved_sym = sym;
+ break;
- if (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN)
- {
- /* For OPEN attributes we prefer GLOBAL symbols, if there
- is one that matches. But keep a record of a matching
- LOCAL symbol, just in case that is all that we can find. */
- if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
- {
- saved_sym = sym;
- continue;
- }
- printf (_(" (file: %s)"), strtab + sym->st_name);
- }
- else if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
- continue;
- else
- printf (_(" (function: %s)"), strtab + sym->st_name);
+ case STB_LOCAL:
+ if (saved_sym == NULL)
+ saved_sym = sym;
+ break;
+
+ default:
break;
}
}
+ else
+ {
+ if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
+ continue;
+
+ saved_sym = sym;
+ break;
+ }
+ }
+
+ printf (" (%s: %s)\n",
+ is_open_attr ? _("file") : _("func"),
+ saved_sym ? strtab + saved_sym->st_name : _("<no symbol found>)"));
+ return TRUE;
+}
- if (sym == symtab + nsyms)
+static bfd_boolean
+print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
+ FILE * file)
+{
+ static unsigned long global_offset = 0;
+ unsigned long offset;
+ unsigned int desc_size = is_32bit_elf ? 4 : 8;
+ bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
+
+ if (pnote->descsz == 0)
+ {
+ if (is_open_attr)
{
- if (saved_sym)
- printf (_(" (file: %s)"), strtab + saved_sym->st_name);
- else
- printf (_(" (<symbol name unknown>)"));
+ printf (_(" Applies from offset %#lx\n"), global_offset);
+ return TRUE;
+ }
+ else
+ {
+ printf (_(" Applies to func at %#lx"), global_offset);
+ return print_symbol_for_build_attribute (file, global_offset, is_open_attr);
}
}
- printf ("\n");
- return TRUE;
+ if (pnote->descsz != desc_size)
+ {
+ error (_(" <invalid description size: %lx>\n"), pnote->descsz);
+ printf (_(" <invalid descsz>"));
+ return FALSE;
+ }
+
+ offset = byte_get ((unsigned char *) pnote->descdata, desc_size);
+
+ if (is_open_attr)
+ {
+ printf (_(" Applies from offset %#lx"), offset);
+ global_offset = offset;
+ }
+ else
+ {
+ printf (_(" Applies to func at %#lx"), offset);
+ }
+
+ return print_symbol_for_build_attribute (file, offset, is_open_attr);
}
static bfd_boolean
print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
{
+ static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
+ static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
+ static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
char name_type;
char name_attribute;
- char * expected_types;
+ const char * expected_types;
const char * name = pnote->namedata;
const char * text;
- int left;
+ signed int left;
if (name == NULL || pnote->namesz < 2)
{
error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
- print_symbol (-20, _(" <corrupt name field>"));
+ print_symbol (-20, _(" <corrupt name>"));
return FALSE;
}
+ left = 20;
+
+ /* Version 2 of the spec adds a "GA" prefix to the name field. */
+ if (name[0] == 'G' && name[1] == 'A')
+ {
+ printf ("GA");
+ name += 2;
+ left -= 2;
+ }
+
switch ((name_type = * name))
{
case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
printf ("%c", * name);
+ left --;
break;
default:
error (_("unrecognised attribute type in name field: %d\n"), name_type);
return FALSE;
}
- left = 19;
++ name;
text = NULL;
{
case GNU_BUILD_ATTRIBUTE_VERSION:
text = _("<version>");
- expected_types = "$";
+ expected_types = string_expected;
++ name;
break;
case GNU_BUILD_ATTRIBUTE_STACK_PROT:
text = _("<stack prot>");
- expected_types = "!+";
+ expected_types = "!+*";
++ name;
break;
case GNU_BUILD_ATTRIBUTE_RELRO:
text = _("<relro>");
- expected_types = "!+";
+ expected_types = bool_expected;
++ name;
break;
case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
text = _("<stack size>");
- expected_types = "*";
+ expected_types = number_expected;
++ name;
break;
case GNU_BUILD_ATTRIBUTE_TOOL:
text = _("<tool>");
- expected_types = "$";
+ expected_types = string_expected;
++ name;
break;
case GNU_BUILD_ATTRIBUTE_ABI:
break;
case GNU_BUILD_ATTRIBUTE_PIC:
text = _("<PIC>");
- expected_types = "*";
+ expected_types = number_expected;
+ ++ name;
+ break;
+ case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
+ text = _("<short enum>");
+ expected_types = bool_expected;
++ name;
break;
-
default:
if (ISPRINT (* name))
{
if (len > left && ! do_wide)
len = left;
- printf ("%.*s ", len, name);
+ printf ("%.*s:", len, name);
left -= len;
- name += len + 1;
+ name += len;
}
else
{
- error (_("unexpected character in name field\n"));
- print_symbol (- left, _("<unknown attribute>"));
- return 0;
+ static char tmpbuf [128];
+
+ error (_("unrecognised byte in name field: %d\n"), * name);
+ sprintf (tmpbuf, _("<unknown:_%d>"), * name);
+ text = tmpbuf;
+ name ++;
}
expected_types = "*$!+";
break;
}
if (text)
- {
- printf ("%s", text);
- left -= strlen (text);
- }
+ left -= printf ("%s", text);
if (strchr (expected_types, name_type) == NULL)
- warn (_("attribute does not have the expected type\n"));
+ warn (_("attribute does not have an expected type (%c)\n"), name_type);
if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
{
{
case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
{
- unsigned int bytes = pnote->namesz - (name - pnote->namedata);
- unsigned long val = 0;
- unsigned int shift = 0;
+ unsigned int bytes;
+ unsigned long long val = 0;
+ unsigned int shift = 0;
+ char * decoded = NULL;
+
+ bytes = pnote->namesz - (name - pnote->namedata);
+ if (bytes > 0)
+ /* The -1 is because the name field is always 0 terminated, and we
+ want to be able to ensure that the shift in the while loop below
+ will not overflow. */
+ -- bytes;
+
+ if (bytes > sizeof (val))
+ {
+ fprintf (stderr, "namesz %lx name %p namedata %p\n",
+ pnote->namesz, name, pnote->namedata);
+ error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
+ bytes);
+ bytes = sizeof (val);
+ }
+ /* We do not bother to warn if bytes == 0 as this can
+ happen with some early versions of the gcc plugin. */
while (bytes --)
{
shift += 8;
}
- if (name_attribute == GNU_BUILD_ATTRIBUTE_PIC)
+ switch (name_attribute)
{
- char * pic_type = NULL;
-
+ case GNU_BUILD_ATTRIBUTE_PIC:
switch (val)
{
- case 0: pic_type = "static"; break;
- case 1: pic_type = "pic"; break;
- case 2: pic_type = "PIC"; break;
- case 3: pic_type = "pie"; break;
- case 4: pic_type = "PIE"; break;
+ case 0: decoded = "static"; break;
+ case 1: decoded = "pic"; break;
+ case 2: decoded = "PIC"; break;
+ case 3: decoded = "pie"; break;
+ case 4: decoded = "PIE"; break;
+ default: break;
}
-
- if (pic_type != NULL)
+ break;
+ case GNU_BUILD_ATTRIBUTE_STACK_PROT:
+ switch (val)
{
- if (do_wide)
- left -= printf ("%s", pic_type);
- else
- left -= printf ("%-.*s", left, pic_type);
- break;
+ /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
+ case 0: decoded = "off"; break;
+ case 1: decoded = "on"; break;
+ case 2: decoded = "all"; break;
+ case 3: decoded = "strong"; break;
+ case 4: decoded = "explicit"; break;
+ default: break;
}
+ break;
+ default:
+ break;
}
- if (do_wide)
- left -= printf ("0x%lx", val);
+ if (decoded != NULL)
+ {
+ print_symbol (-left, decoded);
+ left = 0;
+ }
+ else if (val == 0)
+ {
+ printf ("0x0");
+ left -= 3;
+ }
else
- left -= printf ("0x%-.*lx", left, val);
+ {
+ if (do_wide)
+ left -= printf ("0x%llx", val);
+ else
+ left -= printf ("0x%-.*llx", left, val);
+ }
}
break;
case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
static bfd_boolean
process_note (Elf_Internal_Note * pnote,
- FILE * file,
- Elf_Internal_Shdr * section)
+ FILE * file)
{
const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
const char * nt;
printf (" ");
- if (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
- || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC)
+ if (((const_strneq (pnote->namedata, "GA")
+ && strchr ("*$!+", pnote->namedata[2]) != NULL)
+ || strchr ("*$!+", pnote->namedata[0]) != NULL)
+ && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
+ || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
print_gnu_build_attribute_name (pnote);
else
print_symbol (-20, name);
return print_stapsdt_note (pnote);
else if (const_strneq (pnote->namedata, "CORE"))
return print_core_note (pnote);
- else if (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
- || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC)
- return print_gnu_build_attribute_description (pnote, file, section);
+ else if (((const_strneq (pnote->namedata, "GA")
+ && strchr ("*$!+", pnote->namedata[2]) != NULL)
+ || strchr ("*$!+", pnote->namedata[0]) != NULL)
+ && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
+ || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
+ return print_gnu_build_attribute_description (pnote, file);
if (pnote->descsz)
{
printf (_(" description data: "));
for (i = 0; i < pnote->descsz; i++)
printf ("%02x ", pnote->descdata[i]);
+ if (!do_wide)
+ printf ("\n");
}
if (do_wide)
(int) data_remaining);
break;
}
+ data_remaining -= min_notesz;
+
inote.type = BYTE_GET (external->type);
inote.namesz = BYTE_GET (external->namesz);
inote.namedata = external->name;
inote.descsz = BYTE_GET (external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
- /* PR 17531: file: 3443835e. */
- if (inote.descdata < (char *) pnotes || inote.descdata > end)
- {
- warn (_("Corrupt note: name size is too big: (got: %lx, expected no more than: %lx)\n"),
- inote.namesz, (long)(end - inote.namedata));
- inote.descdata = inote.namedata;
- inote.namesz = 0;
- }
-
inote.descpos = offset + (inote.descdata - (char *) pnotes);
next = inote.descdata + align_power (inote.descsz, 2);
}
(int) data_remaining);
break;
}
+ data_remaining -= min_notesz;
vms_external = (Elf64_External_VMS_Note *) external;
inote.type = BYTE_GET (vms_external->type);
next = inote.descdata + align_power (inote.descsz, 3);
}
- if (inote.descdata < (char *) external + min_notesz
- || next < (char *) external + min_notesz
- /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
- || inote.namedata + inote.namesz < inote.namedata
- || inote.descdata + inote.descsz < inote.descdata
- || data_remaining < (size_t)(next - (char *) external))
+ /* PR 17531: file: 3443835e. */
+ /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
+ if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
+ || (size_t) (inote.descdata - inote.namedata) > data_remaining
+ || (size_t) (next - inote.descdata) < inote.descsz
+ || ((size_t) (next - inote.descdata)
+ > data_remaining - (size_t) (inote.descdata - inote.namedata)))
{
warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
(unsigned long) ((char *) external - (char *) pnotes));
namesz. */
if (inote.namedata[inote.namesz - 1] != '\0')
{
- temp = (char *) malloc (inote.namesz + 1);
- if (temp == NULL)
+ if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
{
- error (_("Out of memory allocating space for inote name\n"));
- res = FALSE;
- break;
- }
-
- memcpy (temp, inote.namedata, inote.namesz);
- temp[inote.namesz] = 0;
+ temp = (char *) malloc (inote.namesz + 1);
+ if (temp == NULL)
+ {
+ error (_("Out of memory allocating space for inote name\n"));
+ res = FALSE;
+ break;
+ }
- /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
- inote.namedata = temp;
+ memcpy (temp, inote.namedata, inote.namesz);
+ inote.namedata = temp;
+ }
+ inote.namedata[inote.namesz] = 0;
}
- if (! process_note (& inote, file, section))
+ if (! process_note (& inote, file))
res = FALSE;
if (temp != NULL)
switch (elf_header.e_machine)
{
+ case EM_ARC:
+ case EM_ARC_COMPACT:
+ case EM_ARC_COMPACT2:
+ return process_attributes (file, "ARC", SHT_ARC_ATTRIBUTES,
+ display_arc_attribute,
+ display_generic_attribute);
case EM_ARM:
return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
display_arm_attribute,
return process_mips_specific (file);
case EM_MSP430:
- return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
+ return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
display_msp430x_attribute,
display_generic_attribute);