diff options
| author | Ulf Hermann <[email protected]> | 2018-07-13 18:32:53 +0200 |
|---|---|---|
| committer | Ulf Hermann <[email protected]> | 2018-07-13 18:32:53 +0200 |
| commit | 731aa2b1b0f73b443c8ed7538c134849935d0ba1 (patch) | |
| tree | 9179c5a58889c4725751856bf75d6a91810d5bf8 /libelf | |
| parent | d9483eb79086970df1dd875f6914bd0a442e8566 (diff) | |
| parent | aa36de0335e3ce12898954985a208f6336731289 (diff) | |
Merge tag 'elfutils-0.173'
elfutils 0.173 release
Change-Id: I83dc56dd15c26fe7acf4ce73c29df65b8b65e757
Diffstat (limited to 'libelf')
| -rw-r--r-- | libelf/ChangeLog | 64 | ||||
| -rw-r--r-- | libelf/elf.h | 242 | ||||
| -rw-r--r-- | libelf/elf32_updatenull.c | 2 | ||||
| -rw-r--r-- | libelf/elf_begin.c | 69 | ||||
| -rw-r--r-- | libelf/elf_cntl.c | 2 | ||||
| -rw-r--r-- | libelf/elf_error.c | 7 | ||||
| -rw-r--r-- | libelf/elf_getdata.c | 5 | ||||
| -rw-r--r-- | libelf/elf_getdata_rawchunk.c | 3 | ||||
| -rw-r--r-- | libelf/elf_getshdrstrndx.c | 20 | ||||
| -rw-r--r-- | libelf/libelfP.h | 5 |
10 files changed, 369 insertions, 50 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index f83f68dd..bc9ea954 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -14,20 +14,72 @@ 2017-04-27 Ulf Hermann <[email protected]> - * libelfP.h: Use attribute_hidden. + * elf_getarsym.c: Don't replace rawmemchr. + * elf_strptr.c: Don't replace memrchr. + +2017-04-21 Ulf Hermann <[email protected]> + + * Makefile.am: Link libelf agaist libgnu.a if requested. + +2018-06-19 Mark Wielaard <[email protected]> + + * libelfP.h (__libelf_type_align): Remove !ALLOW_UNALIGNED guard. + * elf_getdata.c (__libelf_type_aligns): Likewise. + (convert_data): Remove ALLOW_UNALIGNED check. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise. + +2018-06-21 Mark Wielaard <[email protected]> + + * elf.h: Update from glibc. + +2018-04-19 Andreas Schwab <[email protected]> + + * elf.h: Update from glibc. + +2018-02-16 Mark Wielaard <[email protected]> + + * elf.h: Update from glibc. + +2018-02-09 Joshua Watt <[email protected]> + + * elf32_updatenull.c (updatenull_wrlock): Use FALLTHROUGH macro + instead of comment. + * elf_begin.c (read_unmmaped_file): Likewise. + (elf_begin): Likewise. + * elf_cntl.c (elf_cntl): Likewise. + +2017-10-04 Mark Wielaard <[email protected]> + + * elf_begin.c (file_read_elf): Skip sanity checking e_shoff if scncnt + is zero, we won't use it then. + +2017-10-04 Mark Wielaard <[email protected]> + + * libelfP.h: Add ELF_E_INVALID_ELF to error values enum. + * elf_error.c (ELF_E_INVALID_ELF_IDX): New define. Use it as value + for ELF_E_INVALID_ELF in msgidx. + * elf_getshdrstrndx.c (elf_getshdrstrndx): Distinquish between pread + failing and not having enough data. + * elf_begin.c (get_shnum): Likewise. Explicitly set libelf errno on + too large value. + (file_read_elf): Make sure to always set libelf errno when returning + NULL. Distinquish between i/o file and elf data errors. + +2017-08-18 Ulf Hermann <[email protected]> + + * gelf_xlate.c: Use attribute_packed. 2017-04-27 Ulf Hermann <[email protected]> - * Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS. + * libelfP.h: Use attribute_hidden. 2017-04-27 Ulf Hermann <[email protected]> - * elf_getarsym.c: Don't replace rawmemchr. - * elf_strptr.c: Don't replace memrchr. + * Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS. -2017-04-21 Ulf Hermann <[email protected]> +2017-08-15 Mark Wielaard <[email protected]> - * Makefile.am: Link libelf agaist libgnu.a if requested. + * elf.h: Update from glibc. Add new powerpc note descriptors. 2017-07-19 Gustavo Romero <[email protected]> diff --git a/libelf/elf.h b/libelf/elf.h index 1c331b44..a1e07264 100644 --- a/libelf/elf.h +++ b/libelf/elf.h @@ -1,5 +1,5 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2016 Free Software Foundation, Inc. + Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -741,6 +741,8 @@ typedef struct /* Legal values for note segment descriptor types for core files. */ #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_PRFPREG 2 /* Contains copy of fpregset + struct. */ #define NT_FPREGSET 2 /* Contains copy of fpregset struct */ #define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ #define NT_PRXREG 4 /* Contains copy of prxregset struct */ @@ -764,8 +766,25 @@ typedef struct #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_PPC_TAR 0x103 /* Target Address Register */ +#define NT_PPC_PPR 0x104 /* Program Priority Register */ +#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ +#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ +#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ +#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ +#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ +#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ +#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ +#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ +#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address + Register */ +#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority + Register */ +#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control + Register */ +#define NT_PPC_PKEY 0x110 /* Memory Protection Keys + registers. */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -#define NT_PPC_TM_SPR 0x10c /* PowerPC HW Transactional Memory SPRs */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ #define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ @@ -777,11 +796,20 @@ typedef struct #define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ #define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ #define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ +#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 + upper half. */ +#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */ +#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */ +#define NT_S390_GS_BC 0x30c /* s390 guarded storage + broadcast control block. */ +#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */ #define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ #define NT_ARM_TLS 0x401 /* ARM TLS register */ #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ +#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension + registers */ /* Legal values for the note segment descriptor types for object files. */ @@ -846,7 +874,8 @@ typedef struct #define DT_ENCODING 32 /* Start of encoded range */ #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -#define DT_NUM 34 /* Number used */ +#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ +#define DT_NUM 35 /* Number used */ #define DT_LOOS 0x6000000d /* Start of OS-specific */ #define DT_HIOS 0x6ffff000 /* End of OS-specific */ #define DT_LOPROC 0x70000000 /* Start of processor-specific */ @@ -954,6 +983,8 @@ typedef struct #define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ #define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ #define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ +#define DF_1_STUB 0x04000000 +#define DF_1_PIE 0x08000000 /* Flags for the feature selection in DT_FEATURE_1. */ #define DTF_1_PARINIT 0x00000001 @@ -1173,6 +1204,18 @@ typedef struct #define AT_L2_CACHESHAPE 36 #define AT_L3_CACHESHAPE 37 +/* Shapes of the caches, with more room to describe them. + *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits + and the cache associativity in the next 16 bits. */ +#define AT_L1I_CACHESIZE 40 +#define AT_L1I_CACHEGEOMETRY 41 +#define AT_L1D_CACHESIZE 42 +#define AT_L1D_CACHEGEOMETRY 43 +#define AT_L2_CACHESIZE 44 +#define AT_L2_CACHEGEOMETRY 45 +#define AT_L3_CACHESIZE 46 +#define AT_L3_CACHEGEOMETRY 47 + /* Note section contents. Each entry in the note section begins with a header of a fixed form. */ @@ -1238,6 +1281,62 @@ typedef struct /* Version note generated by GNU gold containing a version string. */ #define NT_GNU_GOLD_VERSION 4 +/* Program property. */ +#define NT_GNU_PROPERTY_TYPE_0 5 + +/* Note section name of program property. */ +#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property" + +/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ + +/* Stack size. */ +#define GNU_PROPERTY_STACK_SIZE 1 +/* No copy relocation on protected data symbol. */ +#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 + +/* Processor-specific semantics, lo */ +#define GNU_PROPERTY_LOPROC 0xc0000000 +/* Processor-specific semantics, hi */ +#define GNU_PROPERTY_HIPROC 0xdfffffff +/* Application-specific semantics, lo */ +#define GNU_PROPERTY_LOUSER 0xe0000000 +/* Application-specific semantics, hi */ +#define GNU_PROPERTY_HIUSER 0xffffffff + +/* The x86 instruction sets indicated by the corresponding bits are + used in program. Their support in the hardware is optional. */ +#define GNU_PROPERTY_X86_ISA_1_USED 0xc0000000 +/* The x86 instruction sets indicated by the corresponding bits are + used in program and they must be supported by the hardware. */ +#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0000001 +/* X86 processor-specific features used in program. */ +#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 + +#define GNU_PROPERTY_X86_ISA_1_486 (1U << 0) +#define GNU_PROPERTY_X86_ISA_1_586 (1U << 1) +#define GNU_PROPERTY_X86_ISA_1_686 (1U << 2) +#define GNU_PROPERTY_X86_ISA_1_SSE (1U << 3) +#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4) +#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5) +#define GNU_PROPERTY_X86_ISA_1_SSSE3 (1U << 6) +#define GNU_PROPERTY_X86_ISA_1_SSE4_1 (1U << 7) +#define GNU_PROPERTY_X86_ISA_1_SSE4_2 (1U << 8) +#define GNU_PROPERTY_X86_ISA_1_AVX (1U << 9) +#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10) +#define GNU_PROPERTY_X86_ISA_1_AVX512F (1U << 11) +#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12) +#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13) +#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14) +#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15) +#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16) +#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17) + +/* This indicates that all executable sections are compatible with + IBT. */ +#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) +/* This indicates that all executable sections are compatible with + SHSTK. */ +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) /* Move records. */ typedef struct @@ -2535,9 +2634,10 @@ enum #define DT_PPC64_OPT (DT_LOPROC + 3) #define DT_PPC64_NUM 4 -/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ +/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry. */ #define PPC64_OPT_TLS 1 #define PPC64_OPT_MULTI_TOC 2 +#define PPC64_OPT_LOCALENTRY 4 /* PowerPC64 specific values for the Elf64_Sym st_other field. */ #define STO_PPC64_LOCAL_BIT 5 @@ -3271,6 +3371,9 @@ enum relaxable. */ #define R_X86_64_NUM 43 +/* x86-64 sh_type values. */ +#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */ + /* AM33 relocations. */ #define R_MN10300_NONE 0 /* No reloc. */ @@ -3680,10 +3783,139 @@ enum #define R_TILEGX_NUM 130 +/* RISC-V ELF Flags */ +#define EF_RISCV_RVC 0x0001 +#define EF_RISCV_FLOAT_ABI 0x0006 +#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 +#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 +#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 + +/* RISC-V relocations. */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 + +#define R_RISCV_NUM 58 + /* BPF specific declarations. */ #define R_BPF_NONE 0 /* No reloc */ -#define R_BPF_MAP_FD 1 /* Map fd to pointer */ +#define R_BPF_64_64 1 +#define R_BPF_64_32 10 + +/* Imagination Meta specific relocations. */ + +#define R_METAG_HIADDR16 0 +#define R_METAG_LOADDR16 1 +#define R_METAG_ADDR32 2 /* 32bit absolute address */ +#define R_METAG_NONE 3 /* No reloc */ +#define R_METAG_RELBRANCH 4 +#define R_METAG_GETSETOFF 5 + +/* Backward compatability */ +#define R_METAG_REG32OP1 6 +#define R_METAG_REG32OP2 7 +#define R_METAG_REG32OP3 8 +#define R_METAG_REG16OP1 9 +#define R_METAG_REG16OP2 10 +#define R_METAG_REG16OP3 11 +#define R_METAG_REG32OP4 12 + +#define R_METAG_HIOG 13 +#define R_METAG_LOOG 14 + +#define R_METAG_REL8 15 +#define R_METAG_REL16 16 + +/* GNU */ +#define R_METAG_GNU_VTINHERIT 30 +#define R_METAG_GNU_VTENTRY 31 + +/* PIC relocations */ +#define R_METAG_HI16_GOTOFF 32 +#define R_METAG_LO16_GOTOFF 33 +#define R_METAG_GETSET_GOTOFF 34 +#define R_METAG_GETSET_GOT 35 +#define R_METAG_HI16_GOTPC 36 +#define R_METAG_LO16_GOTPC 37 +#define R_METAG_HI16_PLT 38 +#define R_METAG_LO16_PLT 39 +#define R_METAG_RELBRANCH_PLT 40 +#define R_METAG_GOTOFF 41 +#define R_METAG_PLT 42 +#define R_METAG_COPY 43 +#define R_METAG_JMP_SLOT 44 +#define R_METAG_RELATIVE 45 +#define R_METAG_GLOB_DAT 46 + +/* TLS relocations */ +#define R_METAG_TLS_GD 47 +#define R_METAG_TLS_LDM 48 +#define R_METAG_TLS_LDO_HI16 49 +#define R_METAG_TLS_LDO_LO16 50 +#define R_METAG_TLS_LDO 51 +#define R_METAG_TLS_IE 52 +#define R_METAG_TLS_IENONPIC 53 +#define R_METAG_TLS_IENONPIC_HI16 54 +#define R_METAG_TLS_IENONPIC_LO16 55 +#define R_METAG_TLS_TPOFF 56 +#define R_METAG_TLS_DTPMOD 57 +#define R_METAG_TLS_DTPOFF 58 +#define R_METAG_TLS_LE 59 +#define R_METAG_TLS_LE_HI16 60 +#define R_METAG_TLS_LE_LO16 61 #ifdef __cplusplus } diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c index d83c0b3f..3e9ef61b 100644 --- a/libelf/elf32_updatenull.c +++ b/libelf/elf32_updatenull.c @@ -232,7 +232,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) __libelf_seterrno (ELF_E_GROUP_NOT_REL); return -1; } - /* FALLTHROUGH */ + FALLTHROUGH; case SHT_SYMTAB_SHNDX: sh_entsize = elf_typesize (32, ELF_T_WORD, 1); break; diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 6f850382..b20ab4f3 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -158,6 +158,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, else { Elf32_Word size; + ssize_t r; if (likely (map_address != NULL)) /* gcc will optimize the memcpy to a simple memory @@ -167,11 +168,19 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, + offset))->sh_size, sizeof (Elf32_Word)); else - if (unlikely (pread_retry (fildes, &size, sizeof (Elf32_Word), - offset + ehdr.e32->e_shoff - + offsetof (Elf32_Shdr, sh_size)) + if (unlikely ((r = pread_retry (fildes, &size, + sizeof (Elf32_Word), + offset + ehdr.e32->e_shoff + + offsetof (Elf32_Shdr, + sh_size))) != sizeof (Elf32_Word))) - return (size_t) -1l; + { + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } if (e_ident[EI_DATA] != MY_ELFDATA) CONVERT (size); @@ -207,6 +216,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, + offset))->sh_size; else { + ssize_t r; if (likely (map_address != NULL)) /* gcc will optimize the memcpy to a simple memory access while taking care of alignment issues. */ @@ -215,19 +225,30 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, + offset))->sh_size, sizeof (Elf64_Xword)); else - if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Xword), - offset + ehdr.e64->e_shoff - + offsetof (Elf64_Shdr, sh_size)) + if (unlikely ((r = pread_retry (fildes, &size, + sizeof (Elf64_Xword), + offset + ehdr.e64->e_shoff + + offsetof (Elf64_Shdr, + sh_size))) != sizeof (Elf64_Xword))) - return (size_t) -1l; + { + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } if (e_ident[EI_DATA] != MY_ELFDATA) CONVERT (size); } if (size > ~((GElf_Word) 0)) - /* Invalid value, it is too large. */ - return (size_t) -1l; + { + /* Invalid value, it is too large. */ + __libelf_seterrno (ELF_E_INVALID_ELF); + return (size_t) -1l; + } result = size; } @@ -255,11 +276,13 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, && e_ident[EI_DATA] != ELFDATA2MSB))) { /* Cannot handle this. */ - __libelf_seterrno (ELF_E_INVALID_FILE); + __libelf_seterrno (ELF_E_INVALID_ELF); return NULL; } - /* Determine the number of sections. */ + /* Determine the number of sections. Returns -1 and sets libelf errno + if the file handle or elf file is invalid. Returns zero if there + are no section headers (or they cannot be read). */ size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize); if (scncnt == (size_t) -1l) /* Could not determine the number of sections. */ @@ -269,10 +292,16 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, if (e_ident[EI_CLASS] == ELFCLASS32) { if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr))) - return NULL; + { + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } } else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr))) - return NULL; + { + __libelf_seterrno (ELF_E_INVALID_ELF); + return NULL; + } /* We can now allocate the memory. Even if there are no section headers, we allocate space for a zeroth section in case we need it later. */ @@ -281,7 +310,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent, ELF_K_ELF, scnmax * sizeof (Elf_Scn)); if (elf == NULL) - /* Not enough memory. */ + /* Not enough memory. allocate_elf will have set libelf errno. */ return NULL; assert ((unsigned int) scncnt == scncnt); @@ -344,13 +373,13 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, || (((uintptr_t) ((char *) ehdr + e_shoff) & (__alignof__ (Elf32_Shdr) - 1)) == 0))) { - if (unlikely (e_shoff >= maxsize) + if (unlikely (scncnt > 0 && e_shoff >= maxsize) || unlikely (maxsize - e_shoff < scncnt * sizeof (Elf32_Shdr))) { free_and_out: free (elf); - __libelf_seterrno (ELF_E_INVALID_FILE); + __libelf_seterrno (ELF_E_INVALID_ELF); return NULL; } elf->state.elf32.shdr @@ -446,7 +475,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, || (((uintptr_t) ((char *) ehdr + e_shoff) & (__alignof__ (Elf64_Shdr) - 1)) == 0))) { - if (unlikely (e_shoff >= maxsize) + if (unlikely (scncnt > 0 && e_shoff >= maxsize) || unlikely (maxsize - e_shoff < scncnt * sizeof (Elf64_Shdr))) goto free_and_out; @@ -582,7 +611,7 @@ read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd, ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))) return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd, parent); - /* FALLTHROUGH */ + FALLTHROUGH; default: break; @@ -1097,7 +1126,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) retval = NULL; break; } - /* FALLTHROUGH */ + FALLTHROUGH; case ELF_C_READ: case ELF_C_READ_MMAP: diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c index ab13ffb6..fd681789 100644 --- a/libelf/elf_cntl.c +++ b/libelf/elf_cntl.c @@ -62,7 +62,7 @@ elf_cntl (Elf *elf, Elf_Cmd cmd) result = -1; break; } - /* FALLTHROUGH */ + FALLTHROUGH; case ELF_C_FDDONE: /* Mark the file descriptor as not usable. */ diff --git a/libelf/elf_error.c b/libelf/elf_error.c index 888b389a..5364e685 100644 --- a/libelf/elf_error.c +++ b/libelf/elf_error.c @@ -94,8 +94,12 @@ static const char msgstr[] = (ELF_E_NOMEM_IDX + sizeof "out of memory") N_("invalid file descriptor") "\0" -#define ELF_E_INVALID_OP_IDX \ +#define ELF_E_INVALID_ELF_IDX \ (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor") + N_("invalid ELF file data") + "\0" +#define ELF_E_INVALID_OP_IDX \ + (ELF_E_INVALID_ELF_IDX + sizeof "invalid ELF file data") N_("invalid operation") "\0" #define ELF_E_NO_VERSION_IDX \ @@ -280,6 +284,7 @@ static const uint_fast16_t msgidx[ELF_E_NUM] = [ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX, [ELF_E_NOMEM] = ELF_E_NOMEM_IDX, [ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX, + [ELF_E_INVALID_ELF] = ELF_E_INVALID_ELF_IDX, [ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX, [ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX, [ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX, diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c index 97c503b5..278dfa8f 100644 --- a/libelf/elf_getdata.c +++ b/libelf/elf_getdata.c @@ -76,7 +76,6 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] = } }; -#if !ALLOW_UNALIGNED /* Associate libelf types with their internal alignment requirements. */ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = { @@ -115,7 +114,6 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] } # undef TYPE_ALIGNS }; -#endif Elf_Type @@ -173,8 +171,7 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass, /* Make sure the source is correctly aligned for the conversion function to directly access the data elements. */ char *rawdata_source; - if (ALLOW_UNALIGNED || - ((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) + if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) rawdata_source = scn->rawdata_base; else { diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c index 31b2fe7d..d0c0b75f 100644 --- a/libelf/elf_getdata_rawchunk.c +++ b/libelf/elf_getdata_rawchunk.c @@ -80,8 +80,7 @@ elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type) { /* If the file is mmap'ed we can use it directly, if aligned for type. */ char *rawdata = elf->map_address + elf->start_offset + offset; - if (ALLOW_UNALIGNED || - ((uintptr_t) rawdata & (align - 1)) == 0) + if (((uintptr_t) rawdata & (align - 1)) == 0) rawchunk = rawdata; else { diff --git a/libelf/elf_getshdrstrndx.c b/libelf/elf_getshdrstrndx.c index aead2fe5..ad884fd3 100644 --- a/libelf/elf_getshdrstrndx.c +++ b/libelf/elf_getshdrstrndx.c @@ -133,13 +133,17 @@ elf_getshdrstrndx (Elf *elf, size_t *dst) /* We avoid reading in all the section headers. Just read the first one. */ Elf32_Shdr shdr_mem; + ssize_t r; - if (unlikely (pread_retry (elf->fildes, &shdr_mem, - sizeof (Elf32_Shdr), offset) + if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf32_Shdr), offset)) != sizeof (Elf32_Shdr))) { /* We must be able to read this ELF section header. */ - __libelf_seterrno (ELF_E_INVALID_FILE); + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); result = -1; goto out; } @@ -194,13 +198,17 @@ elf_getshdrstrndx (Elf *elf, size_t *dst) /* We avoid reading in all the section headers. Just read the first one. */ Elf64_Shdr shdr_mem; + ssize_t r; - if (unlikely (pread_retry (elf->fildes, &shdr_mem, - sizeof (Elf64_Shdr), offset) + if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem, + sizeof (Elf64_Shdr), offset)) != sizeof (Elf64_Shdr))) { /* We must be able to read this ELF section header. */ - __libelf_seterrno (ELF_E_INVALID_FILE); + if (r < 0) + __libelf_seterrno (ELF_E_INVALID_FILE); + else + __libelf_seterrno (ELF_E_INVALID_ELF); result = -1; goto out; } diff --git a/libelf/libelfP.h b/libelf/libelfP.h index a4a0a3a9..ed216c8c 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -102,6 +102,7 @@ enum ELF_E_INVALID_ENCODING, ELF_E_NOMEM, ELF_E_INVALID_FILE, + ELF_E_INVALID_ELF, ELF_E_INVALID_OP, ELF_E_NO_VERSION, ELF_E_INVALID_CMD, @@ -442,15 +443,11 @@ extern int __libelf_version_initialized attribute_hidden; # define LIBELF_EV_IDX (__libelf_version - 1) #endif -#if !ALLOW_UNALIGNED /* Array with alignment requirements of the internal types indexed by ELF version, binary class, and type. */ extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden; # define __libelf_type_align(class, type) \ (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1) -#else -# define __libelf_type_align(class, type) 1 -#endif /* Given an Elf handle and a section type returns the Elf_Data d_type. Should not be called when SHF_COMPRESSED is set, the d_type should |
