diff options
Diffstat (limited to 'libelf')
95 files changed, 1067 insertions, 649 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 3b88d031..1916877c 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,193 @@ +2015-09-23 Mark Wielaard <mjw@redhat.com> + + * elf32_getehdr.c (getehdr_wrlock): Mark as internal_function. + * elf32_getshdr.c (getshdr_rdlock): Likewise. + (getshdr_wrlock): Likewise. + * elf_error.c (__libelf_seterrno): Likewise. + * elf_getphdrnum.c (__elf_getphdrnum_rdlock): Likewise. + (__elf_getphdrnum_chk_rdlock): Likewise. + * elf_getshdrnum.c (__elf_getphdrnum_rdlock): Likewise. + (__elf_getphdrnum_chk_rdlock): Likewise. + * elf_getshdrnum.c (__elf_getshdrnum_rdlock): Likewise. + * elf_readall.c (__libelf_readall): Likewise. + * gelf_getehdr.c (__gelf_getehdr_rdlock): Likewise. + +2015-09-22 Mark Wielaard <mjw@redhat.com> + + * *.c: Remove old-style function definitions. + +2015-06-22 Mark Wielaard <mjw@redhat.com> + + * dl-hash.h: Update from glibc. + +2015-06-18 Mark Wielaard <mjw@redhat.com> + + * elf32_updatefile.c (updatefile): Always free shdr_data and scns + when allocated on failure paths. + +2015-06-18 Mark Wielaard <mjw@redhat.com> + + * nlist.c (nlist): Check symscn shdr exists before use. + +2015-06-16 Mark Wielaard <mjw@redhat.com> + + * elf_update.c (write_file): Always also use ftruncate before + posix_fallocate to make sure file has the right size. + +2015-06-04 Mark Wielaard <mjw@redhat.com> + + * elf_getdata.c (__libelf_type_aligns): Add entries for ELF_T_EHDR, + ELF_T_OFF, ELF_T_PHDR, ELF_T_SHDR, ELF_T_SWORD, ELF_T_XWORD, + ELF_T_SXWORD, ELF_T_GNUHASH, ELF_T_AUXV. + * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Check alignment + of rawdata against requested type. + +2015-06-02 Mark Wielaard <mjw@redhat.com> + + * elf_getdata.c (convert_data): Make sure source data is properly + aligned for type before calling actual conversion function. + +2015-06-04 Mark Wielaard <mjw@redhat.com> + + * elf_begin.c (get_shnum): Check alignment of Shdr, not Ehdr before + direct access. + +2015-06-02 Mark Wielaard <mjw@redhat.com> + + * elf_begin.c (file_read_elf): Split checks for ehdr and shdr + alignment, drop phdr alignment check. + +2015-05-31 Mark Wielaard <mjw@redhat.com> + + * elf32_getshdr.c (load_shdr_wrlock): Allocate shdrs with malloc, + not alloca and free after conversion when a copy needs to be made. + +2015-05-31 Mark Wielaard <mjw@redhat.com> + + * elf32_getphdr.c (getphdr_wrlock): Allocate phdrs with malloc, not + alloca and free after conversion when a copy needs to be made. + +2015-05-31 Mark Wielaard <mjw@redhat.com> + + * elf_getarsym.c (elf_getarsym): Allocate temporary file_date with + malloc, not alloca also in !ALLOW_UNALIGNED case. + +2015-05-30 Mark Wielaard <mjw@redhat.com> + + * gelf_xlate.c (elf_cvt_Byte): Only call memmove with non-zero size. + +2015-05-30 Mark Wielaard <mjw@redhat.com> + + * elf32_updatefile.c (updatemmap): Only call mempcpy and update + last_position when d_size is non-zero. + +2015-05-17 Mark Wielaard <mjw@redhat.com> + + * elf32_updatefile.c (updatefile): Allocate shdr_data and scns + with malloc, not alloca. Free after writing section headers. + +2015-05-16 Mark Wielaard <mjw@redhat.com> + + * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage + with malloc, not alloca. Free after writing section header. + +2015-05-16 Mark Wielaard <mjw@redhat.com> + + * elf_getarsym.c (elf_getarsym): Allocate temporary file_date with + malloc, not alloca. Call free after out. + +2015-05-14 Mark Wielaard <mjw@redhat.com> + + * elf_update.c (write_file): Use posix_fallocate instead of + ftruncate to extend file if necessary. + +2015-05-13 Mark Wielaard <mjw@redhat.com> + + * elf32_updatenull.c (default_ehdr): If e_phnum is zero then set + e_phoff also to zero. + +2015-05-12 Mark Wielaard <mjw@redhat.com> + + * elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign + is a powerof2. + * elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns + to the elf image offset. + +2015-05-12 Mark Wielaard <mjw@redhat.com> + + * elf32_newphdr.c (newphdr): Call __libelf_seterrno with + ELF_E_INVALID_INDEX before failing. Check whether section zero shdr + actually exists if we need to put extended phnum in section zero. + +2015-05-08 Mark Wielaard <mjw@redhat.com> + + * nlist.c (nlist): Call gelf_fsize with EV_CURRENT. + +2015-01-03 Mark Wielaard <mjw@redhat.com> + + * version_xlate.h (elf_cvt_Verdef): Use memmove to copy src to dest. + (elf_cvt_Verneed): Likewise. + +2015-03-28 Mark Wielaard <mjw@redhat.com> + + * elf.h: Update from glibc. + +2015-03-23 Mark Wielaard <mjw@redhat.com> + + * elf32_updatenull.c (updatenull_wrlock): Don't extend size with + SHT_NOBITS sh_offset. + +2015-02-18 Mark Wielaard <mjw@redhat.com> + + * libelfP.h (__libelf_set_data_list_rdlock): Make internal_function. + +2015-02-07 Jan Kratochvil <jan.kratochvil@redhat.com> + + * elf32_updatenull.c (__elfw2(LIBELFBITS,updatenull_wrlock)): Consider + sh_addralign 0 as 1. + +2015-01-22 Mark Wielaard <mjw@redhat.com> + + * elf_strptr (elf_strptr): Make sure returned string is NUL + terminated. + +2015-01-21 Mark Wielaard <mjw@redhat.com> + + * elf_strptr.c (elf_strptr): Check data_list_rear == NULL instead + of rawdata_base != NULL before using rawdata directly. + +2015-01-20 Mark Wielaard <mjw@redhat.com> + + * libelfP.h (__elf_strptr_internal): New function declaration. + * elf_getdata.c (__libelf_set_data_list_rdlock): New internal + function extracted from... + (__elf_getdata_rdlock): ... here. + * elf_newdata.c (elf_newdata): Check scn->rawdata_base and update + datalist if necessary. + +2015-01-20 Mark Wielaard <mjw@redhat.com> + + * elf_strptr.c (elf_strptr): Call __elf[32|64]_getshdr_rdlock if + necessary. + +2014-12-30 Mark Wielaard <mjw@redhat.com> + + * elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function. + (elf_getphdrnum): Call __elf_getphdrnum_chk_rdlock. + * gelf_getphdr (gelf_getphdr): Call __elf_getphdrnum_chk_rdlock + and always check ndx against phnum. + * libelfP.h (__elf_getphdrnum_chk_rdlock): New internal function. + +2014-12-25 Mark Wielaard <mjw@redhat.com> + + * elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be + negative. Include start_offset in maxsize. + +2014-12-28 Alexander Cherepanov <cherepan@mccme.ru> + + * elf_begin.c (read_long_names): Don't miss '/' right after + another '/'. Fixes a dir traversal vuln in ar extraction. + 2014-12-18 Ulrich Drepper <drepper@gmail.com> * Makefile.am: Suppress output of textrel_check command. diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h index e286d2e8..6ee5d1a6 100644 --- a/libelf/dl-hash.h +++ b/libelf/dl-hash.h @@ -1,31 +1,20 @@ /* Compute hash value for given string according to ELF standard. - Copyright (C) 2006 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <drepper@redhat.com>, 1995. + Copyright (C) 1995-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This file is free software; you can redistribute it and/or modify - it under the terms of either + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _DL_HASH_H #define _DL_HASH_H 1 @@ -34,44 +23,48 @@ /* This is the hashing function specified by the ELF ABI. In the first five operations no overflow is possible so we optimized it a bit. */ -static inline unsigned int -__attribute__ ((__pure__)) -_dl_elf_hash (const char *name) +static unsigned int +__attribute__ ((unused)) +_dl_elf_hash (const char *name_arg) { - const unsigned char *iname = (const unsigned char *) name; - unsigned int hash = (unsigned int) *iname++; - if (*iname != '\0') + const unsigned char *name = (const unsigned char *) name_arg; + unsigned long int hash = *name; + if (hash != 0 && name[1] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[1]; + if (name[2] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[2]; + if (name[3] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[3]; + if (name[4] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - while (*iname != '\0') + hash = (hash << 4) + name[4]; + name += 5; + while (*name != '\0') { - unsigned int hi; - hash = (hash << 4) + (unsigned int) *iname++; + unsigned long int hi; + hash = (hash << 4) + *name++; hi = hash & 0xf0000000; /* The algorithm specified in the ELF ABI is as follows: if (hi != 0) - hash ^= hi >> 24; + hash ^= hi >> 24; hash &= ~hi; But the following is equivalent and a lot faster, especially on modern processors. */ - hash ^= hi; hash ^= hi >> 24; } + + /* Second part of the modified formula. This + operation can be lifted outside the loop. */ + hash &= 0x0fffffff; } } } diff --git a/libelf/elf.h b/libelf/elf.h index 40e87b21..39bafc22 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-2014 Free Software Foundation, Inc. + Copyright (C) 1995-2015 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 @@ -249,6 +249,7 @@ typedef struct #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ #define EM_AARCH64 183 /* ARM AARCH64 */ #define EM_TILEPRO 188 /* Tilera TILEPro */ #define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ @@ -370,7 +371,7 @@ typedef struct #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ #define SHF_ORDERED (1 << 30) /* Special ordering requirement (Solaris). */ -#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless +#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless referenced or allocated (Solaris).*/ /* Section group handling. */ @@ -1383,6 +1384,7 @@ typedef struct #define EF_MIPS_64BIT_WHIRL 16 #define EF_MIPS_ABI2 32 #define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ #define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ #define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ @@ -1631,9 +1633,10 @@ typedef struct /* Legal values for p_type field of Elf32_Phdr. */ -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -#define PT_MIPS_OPTIONS 0x70000002 +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information. */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 +#define PT_MIPS_ABIFLAGS 0x70000003 /* FP mode requirement. */ /* Special program header types. */ @@ -1755,6 +1758,101 @@ typedef struct typedef Elf32_Addr Elf32_Conflict; +typedef struct +{ + /* Version of flags structure. */ + Elf32_Half version; + /* The level of the ISA: 1-5, 32, 64. */ + unsigned char isa_level; + /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise. */ + unsigned char isa_rev; + /* The size of general purpose registers. */ + unsigned char gpr_size; + /* The size of co-processor 1 registers. */ + unsigned char cpr1_size; + /* The size of co-processor 2 registers. */ + unsigned char cpr2_size; + /* The floating-point ABI. */ + unsigned char fp_abi; + /* Processor-specific extension. */ + Elf32_Word isa_ext; + /* Mask of ASEs used. */ + Elf32_Word ases; + /* Mask of general flags. */ + Elf32_Word flags1; + Elf32_Word flags2; +} Elf_MIPS_ABIFlags_v0; + +/* Values for the register size bytes of an abi flags structure. */ + +#define MIPS_AFL_REG_NONE 0x00 /* No registers. */ +#define MIPS_AFL_REG_32 0x01 /* 32-bit registers. */ +#define MIPS_AFL_REG_64 0x02 /* 64-bit registers. */ +#define MIPS_AFL_REG_128 0x03 /* 128-bit registers. */ + +/* Masks for the ases word of an ABI flags structure. */ + +#define MIPS_AFL_ASE_DSP 0x00000001 /* DSP ASE. */ +#define MIPS_AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */ +#define MIPS_AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ +#define MIPS_AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ +#define MIPS_AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */ +#define MIPS_AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */ +#define MIPS_AFL_ASE_MT 0x00000040 /* MT ASE. */ +#define MIPS_AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */ +#define MIPS_AFL_ASE_VIRT 0x00000100 /* VZ ASE. */ +#define MIPS_AFL_ASE_MSA 0x00000200 /* MSA ASE. */ +#define MIPS_AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */ +#define MIPS_AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */ +#define MIPS_AFL_ASE_XPA 0x00001000 /* XPA ASE. */ +#define MIPS_AFL_ASE_MASK 0x00001fff /* All ASEs. */ + +/* Values for the isa_ext word of an ABI flags structure. */ + +#define MIPS_AFL_EXT_XLR 1 /* RMI Xlr instruction. */ +#define MIPS_AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */ +#define MIPS_AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */ +#define MIPS_AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */ +#define MIPS_AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */ +#define MIPS_AFL_EXT_5900 6 /* MIPS R5900 instruction. */ +#define MIPS_AFL_EXT_4650 7 /* MIPS R4650 instruction. */ +#define MIPS_AFL_EXT_4010 8 /* LSI R4010 instruction. */ +#define MIPS_AFL_EXT_4100 9 /* NEC VR4100 instruction. */ +#define MIPS_AFL_EXT_3900 10 /* Toshiba R3900 instruction. */ +#define MIPS_AFL_EXT_10000 11 /* MIPS R10000 instruction. */ +#define MIPS_AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */ +#define MIPS_AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */ +#define MIPS_AFL_EXT_4120 14 /* NEC VR4120 instruction. */ +#define MIPS_AFL_EXT_5400 15 /* NEC VR5400 instruction. */ +#define MIPS_AFL_EXT_5500 16 /* NEC VR5500 instruction. */ +#define MIPS_AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */ +#define MIPS_AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */ + +/* Masks for the flags1 word of an ABI flags structure. */ +#define MIPS_AFL_FLAGS1_ODDSPREG 1 /* Uses odd single-precision registers. */ + +/* Object attribute values. */ +enum +{ + /* Not tagged or not using any ABIs affected by the differences. */ + Val_GNU_MIPS_ABI_FP_ANY = 0, + /* Using hard-float -mdouble-float. */ + Val_GNU_MIPS_ABI_FP_DOUBLE = 1, + /* Using hard-float -msingle-float. */ + Val_GNU_MIPS_ABI_FP_SINGLE = 2, + /* Using soft-float. */ + Val_GNU_MIPS_ABI_FP_SOFT = 3, + /* Using -mips32r2 -mfp64. */ + Val_GNU_MIPS_ABI_FP_OLD_64 = 4, + /* Using -mfpxx. */ + Val_GNU_MIPS_ABI_FP_XX = 5, + /* Using -mips32r2 -mfp64. */ + Val_GNU_MIPS_ABI_FP_64 = 6, + /* Using -mips32r2 -mfp64 -mno-odd-spreg. */ + Val_GNU_MIPS_ABI_FP_64A = 7, + /* Maximum allocated FP ABI value. */ + Val_GNU_MIPS_ABI_FP_MAX = 7 +}; /* HPPA specific definitions. */ @@ -2096,6 +2194,8 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ #define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ #define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ +#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */ +#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */ /* The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. */ @@ -2139,7 +2239,11 @@ typedef Elf32_Addr Elf32_Conflict; /* PowerPC specific values for the Dyn d_tag field. */ #define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_NUM 1 +#define DT_PPC_OPT (DT_LOPROC + 1) +#define DT_PPC_NUM 2 + +/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */ +#define PPC_OPT_TLS 1 /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE @@ -2283,7 +2387,7 @@ typedef Elf32_Addr Elf32_Conflict; #define DT_PPC64_OPD (DT_LOPROC + 1) #define DT_PPC64_OPDSZ (DT_LOPROC + 2) #define DT_PPC64_OPT (DT_LOPROC + 3) -#define DT_PPC64_NUM 3 +#define DT_PPC64_NUM 4 /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ #define PPC64_OPT_TLS 1 @@ -2362,6 +2466,20 @@ typedef Elf32_Addr Elf32_Conflict; /* AArch64 relocs. */ #define R_AARCH64_NONE 0 /* No relocation. */ + +/* ILP32 AArch64 relocs. */ +#define R_AARCH64_P32_ABS32 1 /* Direct 32 bit. */ +#define R_AARCH64_P32_COPY 180 /* Copy symbol at runtime. */ +#define R_AARCH64_P32_GLOB_DAT 181 /* Create GOT entry. */ +#define R_AARCH64_P32_JUMP_SLOT 182 /* Create PLT entry. */ +#define R_AARCH64_P32_RELATIVE 183 /* Adjust by program base. */ +#define R_AARCH64_P32_TLS_DTPMOD 184 /* Module number, 32 bit. */ +#define R_AARCH64_P32_TLS_DTPREL 185 /* Module-relative offset, 32 bit. */ +#define R_AARCH64_P32_TLS_TPREL 186 /* TP-relative offset, 32 bit. */ +#define R_AARCH64_P32_TLSDESC 187 /* TLS Descriptor. */ +#define R_AARCH64_P32_IRELATIVE 188 /* STT_GNU_IFUNC relocation. */ + +/* LP64 AArch64 relocs. */ #define R_AARCH64_ABS64 257 /* Direct 64 bit. */ #define R_AARCH64_ABS32 258 /* Direct 32 bit. */ #define R_AARCH64_ABS16 259 /* Direct 16-bit. */ @@ -2479,9 +2597,9 @@ typedef Elf32_Addr Elf32_Conflict; #define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ #define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ #define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */ -#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ -#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ +#define R_AARCH64_TLS_DTPMOD 1028 /* Module number, 64 bit. */ +#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset, 64 bit. */ +#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset, 64 bit. */ #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ #define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ @@ -3132,6 +3250,58 @@ typedef Elf32_Addr Elf32_Conflict; #define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */ #define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */ +/* Legal values for d_tag (dynamic entry type). */ +#define DT_NIOS2_GP 0x70000002 /* Address of _gp. */ + +/* Nios II relocations. */ +#define R_NIOS2_NONE 0 /* No reloc. */ +#define R_NIOS2_S16 1 /* Direct signed 16 bit. */ +#define R_NIOS2_U16 2 /* Direct unsigned 16 bit. */ +#define R_NIOS2_PCREL16 3 /* PC relative 16 bit. */ +#define R_NIOS2_CALL26 4 /* Direct call. */ +#define R_NIOS2_IMM5 5 /* 5 bit constant expression. */ +#define R_NIOS2_CACHE_OPX 6 /* 5 bit expression, shift 22. */ +#define R_NIOS2_IMM6 7 /* 6 bit constant expression. */ +#define R_NIOS2_IMM8 8 /* 8 bit constant expression. */ +#define R_NIOS2_HI16 9 /* High 16 bit. */ +#define R_NIOS2_LO16 10 /* Low 16 bit. */ +#define R_NIOS2_HIADJ16 11 /* High 16 bit, adjusted. */ +#define R_NIOS2_BFD_RELOC_32 12 /* 32 bit symbol value + addend. */ +#define R_NIOS2_BFD_RELOC_16 13 /* 16 bit symbol value + addend. */ +#define R_NIOS2_BFD_RELOC_8 14 /* 8 bit symbol value + addend. */ +#define R_NIOS2_GPREL 15 /* 16 bit GP pointer offset. */ +#define R_NIOS2_GNU_VTINHERIT 16 /* GNU C++ vtable hierarchy. */ +#define R_NIOS2_GNU_VTENTRY 17 /* GNU C++ vtable member usage. */ +#define R_NIOS2_UJMP 18 /* Unconditional branch. */ +#define R_NIOS2_CJMP 19 /* Conditional branch. */ +#define R_NIOS2_CALLR 20 /* Indirect call through register. */ +#define R_NIOS2_ALIGN 21 /* Alignment requirement for + linker relaxation. */ +#define R_NIOS2_GOT16 22 /* 16 bit GOT entry. */ +#define R_NIOS2_CALL16 23 /* 16 bit GOT entry for function. */ +#define R_NIOS2_GOTOFF_LO 24 /* %lo of offset to GOT pointer. */ +#define R_NIOS2_GOTOFF_HA 25 /* %hiadj of offset to GOT pointer. */ +#define R_NIOS2_PCREL_LO 26 /* %lo of PC relative offset. */ +#define R_NIOS2_PCREL_HA 27 /* %hiadj of PC relative offset. */ +#define R_NIOS2_TLS_GD16 28 /* 16 bit GOT offset for TLS GD. */ +#define R_NIOS2_TLS_LDM16 29 /* 16 bit GOT offset for TLS LDM. */ +#define R_NIOS2_TLS_LDO16 30 /* 16 bit module relative offset. */ +#define R_NIOS2_TLS_IE16 31 /* 16 bit GOT offset for TLS IE. */ +#define R_NIOS2_TLS_LE16 32 /* 16 bit LE TP-relative offset. */ +#define R_NIOS2_TLS_DTPMOD 33 /* Module number. */ +#define R_NIOS2_TLS_DTPREL 34 /* Module-relative offset. */ +#define R_NIOS2_TLS_TPREL 35 /* TP-relative offset. */ +#define R_NIOS2_COPY 36 /* Copy symbol at runtime. */ +#define R_NIOS2_GLOB_DAT 37 /* Create GOT entry. */ +#define R_NIOS2_JUMP_SLOT 38 /* Create PLT entry. */ +#define R_NIOS2_RELATIVE 39 /* Adjust by program base. */ +#define R_NIOS2_GOTOFF 40 /* 16 bit offset to GOT pointer. */ +#define R_NIOS2_CALL26_NOAT 41 /* Direct call in .noat section. */ +#define R_NIOS2_GOT_LO 42 /* %lo() of GOT entry. */ +#define R_NIOS2_GOT_HA 43 /* %hiadj() of GOT entry. */ +#define R_NIOS2_CALL_LO 44 /* %lo() of function GOT entry. */ +#define R_NIOS2_CALL_HA 45 /* %hiadj() of function GOT entry. */ + /* TILEPro relocations. */ #define R_TILEPRO_NONE 0 /* No reloc */ #define R_TILEPRO_32 1 /* Direct 32 bit */ diff --git a/libelf/elf32_checksum.c b/libelf/elf32_checksum.c index 4c598563..f9dfccb2 100644 --- a/libelf/elf32_checksum.c +++ b/libelf/elf32_checksum.c @@ -1,5 +1,5 @@ /* Compute simple checksum from permanent parts of the ELF file. - Copyright (C) 2002, 2003, 2004, 2005, 2009 Red Hat, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2009, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -51,8 +51,7 @@ long int -elfw2(LIBELFBITS,checksum) (elf) - Elf *elf; +elfw2(LIBELFBITS,checksum) (Elf *elf) { size_t shstrndx; Elf_Scn *scn; diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c index d7496fa3..fddae91e 100644 --- a/libelf/elf32_fsize.c +++ b/libelf/elf32_fsize.c @@ -1,5 +1,5 @@ /* Return the size of an object file type. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -40,10 +40,7 @@ size_t -elfw2(LIBELFBITS, fsize) (type, count, version) - Elf_Type type; - size_t count; - unsigned int version; +elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count, unsigned int version) { /* We do not have differences between file and memory sizes. Better not since otherwise `mmap' would not work. */ diff --git a/libelf/elf32_getehdr.c b/libelf/elf32_getehdr.c index ee0a2e0f..89e3c402 100644 --- a/libelf/elf32_getehdr.c +++ b/libelf/elf32_getehdr.c @@ -1,5 +1,5 @@ /* Get ELF header. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -42,9 +42,7 @@ static ElfW2(LIBELFBITS,Ehdr) * -getehdr_impl (elf, wrlock) - Elf *elf; - int wrlock; +getehdr_impl (Elf *elf, int wrlock) { if (elf == NULL) return NULL; @@ -77,15 +75,14 @@ getehdr_impl (elf, wrlock) } ElfW2(LIBELFBITS,Ehdr) * -__elfw2(LIBELFBITS,getehdr_wrlock) (elf) - Elf *elf; +internal_function +__elfw2(LIBELFBITS,getehdr_wrlock) (Elf *elf) { return getehdr_impl (elf, 1); } ElfW2(LIBELFBITS,Ehdr) * -elfw2(LIBELFBITS,getehdr) (elf) - Elf *elf; +elfw2(LIBELFBITS,getehdr) (Elf *elf) { ElfW2(LIBELFBITS,Ehdr) *result; if (elf == NULL) diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c index 1b82a480..99b4ac09 100644 --- a/libelf/elf32_getphdr.c +++ b/libelf/elf32_getphdr.c @@ -1,5 +1,5 @@ /* Get ELF program header table. - Copyright (C) 1998-2010, 2014 Red Hat, Inc. + Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -46,8 +46,7 @@ #endif ElfW2(LIBELFBITS,Phdr) * -__elfw2(LIBELFBITS,getphdr_wrlock) (elf) - Elf *elf; +__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf) { ElfW2(LIBELFBITS,Phdr) *result; @@ -141,13 +140,20 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf) } else { - if (ALLOW_UNALIGNED - || ((uintptr_t) file_phdr - & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0) + bool copy = ! (ALLOW_UNALIGNED + || ((uintptr_t) file_phdr + & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) + - 1)) == 0); + if (! copy) notcvt = file_phdr; else { - notcvt = (ElfW2(LIBELFBITS,Phdr) *) alloca (size); + notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size); + if (unlikely (notcvt == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } memcpy (notcvt, file_phdr, size); } @@ -162,6 +168,9 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf) CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags); CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align); } + + if (copy) + free (notcvt); } } } @@ -227,8 +236,7 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf) } ElfW2(LIBELFBITS,Phdr) * -elfw2(LIBELFBITS,getphdr) (elf) - Elf *elf; +elfw2(LIBELFBITS,getphdr) (Elf *elf) { ElfW2(LIBELFBITS,Phdr) *result; diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c index 74170473..3a6375c1 100644 --- a/libelf/elf32_getshdr.c +++ b/libelf/elf32_getshdr.c @@ -1,5 +1,5 @@ /* Return section header. - Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014 Red Hat, Inc. + Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -111,15 +111,22 @@ load_shdr_wrlock (Elf_Scn *scn) } else { - if (ALLOW_UNALIGNED - || ((uintptr_t) file_shdr - & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) + bool copy = ! (ALLOW_UNALIGNED + || ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) + == 0); + if (! copy) notcvt = (ElfW2(LIBELFBITS,Shdr) *) ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff); else { - notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size); + notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size); + if (unlikely (notcvt == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } memcpy (notcvt, ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff), size); @@ -153,6 +160,9 @@ load_shdr_wrlock (Elf_Scn *scn) elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index = -1; } + + if (copy) + free (notcvt); } } else if (likely (elf->fildes != -1)) @@ -233,8 +243,8 @@ scn_valid (Elf_Scn *scn) } ElfW2(LIBELFBITS,Shdr) * -__elfw2(LIBELFBITS,getshdr_rdlock) (scn) - Elf_Scn *scn; +internal_function +__elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn) { ElfW2(LIBELFBITS,Shdr) *result; @@ -255,8 +265,8 @@ __elfw2(LIBELFBITS,getshdr_rdlock) (scn) } ElfW2(LIBELFBITS,Shdr) * -__elfw2(LIBELFBITS,getshdr_wrlock) (scn) - Elf_Scn *scn; +internal_function +__elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn) { ElfW2(LIBELFBITS,Shdr) *result; @@ -271,8 +281,7 @@ __elfw2(LIBELFBITS,getshdr_wrlock) (scn) } ElfW2(LIBELFBITS,Shdr) * -elfw2(LIBELFBITS,getshdr) (scn) - Elf_Scn *scn; +elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn) { ElfW2(LIBELFBITS,Shdr) *result; diff --git a/libelf/elf32_newehdr.c b/libelf/elf32_newehdr.c index 4b547bcc..775d1157 100644 --- a/libelf/elf32_newehdr.c +++ b/libelf/elf32_newehdr.c @@ -1,5 +1,5 @@ /* Create new ELF header. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -42,8 +42,7 @@ ElfW2(LIBELFBITS,Ehdr) * -elfw2(LIBELFBITS,newehdr) (elf) - Elf *elf; +elfw2(LIBELFBITS,newehdr) (Elf *elf) { ElfW2(LIBELFBITS,Ehdr) *result; diff --git a/libelf/elf32_newphdr.c b/libelf/elf32_newphdr.c index 01038e73..4aa72137 100644 --- a/libelf/elf32_newphdr.c +++ b/libelf/elf32_newphdr.c @@ -1,5 +1,5 @@ /* Create new ELF program header table. - Copyright (C) 1999-2010, 2014 Red Hat, Inc. + Copyright (C) 1999-2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -43,9 +43,7 @@ ElfW2(LIBELFBITS,Phdr) * -elfw2(LIBELFBITS,newphdr) (elf, count) - Elf *elf; - size_t count; +elfw2(LIBELFBITS,newphdr) (Elf *elf, size_t count) { ElfW2(LIBELFBITS,Phdr) *result; @@ -116,6 +114,17 @@ elfw2(LIBELFBITS,newphdr) (elf, count) { if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr)))) { + __libelf_seterrno (ELF_E_INVALID_INDEX); + result = NULL; + goto out; + } + + Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; + if (unlikely (count >= PN_XNUM && scn0->shdr.ELFW(e,LIBELFBITS) == NULL)) + { + /* Something is wrong with section zero, but we need it to write + the extended phdr count. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); result = NULL; goto out; } @@ -134,7 +143,6 @@ elfw2(LIBELFBITS,newphdr) (elf, count) if (count >= PN_XNUM) { /* We have to write COUNT into the zeroth section's sh_info. */ - Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0) { assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0); diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c index a1ff6d40..9e757c84 100644 --- a/libelf/elf32_offscn.c +++ b/libelf/elf32_offscn.c @@ -1,5 +1,5 @@ /* Get section at specific index. - Copyright (C) 2005, 2008 Red Hat, Inc. + Copyright (C) 2005, 2008, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. @@ -43,9 +43,7 @@ Elf_Scn * -elfw2(LIBELFBITS,offscn) (elf, offset) - Elf *elf; - ElfW2(LIBELFBITS,Off) offset; +elfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset) { if (elf == NULL) return NULL; diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index 153e377f..832f852d 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -1,5 +1,5 @@ /* Write changed data structures. - Copyright (C) 2000-2010, 2014 Red Hat, Inc. + Copyright (C) 2000-2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -206,7 +206,12 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) return 1; Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; - Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); + Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *)); + if (unlikely (scns == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } char *const shdr_start = ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff); char *const shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize; @@ -238,7 +243,12 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) < ((char *) elf->map_address + elf->start_offset + elf->maximum_size)); - void *p = alloca (sizeof (ElfW2(LIBELFBITS,Shdr))); + void *p = malloc (sizeof (ElfW2(LIBELFBITS,Shdr))); + if (unlikely (p == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } scn->shdr.ELFW(e,LIBELFBITS) = memcpy (p, scn->shdr.ELFW(e,LIBELFBITS), sizeof (ElfW2(LIBELFBITS,Shdr))); @@ -260,7 +270,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) > (char *) scn->data_list.data.d.d_buf)) { void *p = malloc (scn->data_list.data.d.d_size); - if (p == NULL) + if (unlikely (p == NULL)) { __libelf_seterrno (ELF_E_NOMEM); return -1; @@ -357,7 +367,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) last_position += dl->data.d.d_size; } - else + else if (dl->data.d.d_size != 0) last_position = mempcpy (last_position, dl->data.d.d_buf, dl->data.d.d_size); @@ -421,12 +431,17 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) entry we now have to adjust the pointer again so point to new place in the mapping. */ if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced - && (scn->shdr_flags & ELF_F_MALLOCED) == 0) - scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + && (scn->shdr_flags & ELF_F_MALLOCED) == 0 + && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index]) + { + free (scn->shdr.ELFW(e,LIBELFBITS)); + scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + } scn->shdr_flags &= ~ELF_F_DIRTY; } } + free (scns); } /* That was the last part. Clear the overall flag. */ @@ -582,7 +597,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) /* Allocate sufficient memory. */ tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *) malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); - if (tmp_phdr == NULL) + if (unlikely (tmp_phdr == NULL)) { __libelf_seterrno (ELF_E_NOMEM); return 1; @@ -640,17 +655,32 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) #endif ElfW2(LIBELFBITS,Shdr) *shdr_data; + ElfW2(LIBELFBITS,Shdr) *shdr_data_mem = NULL; if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL || (elf->flags & ELF_F_DIRTY)) - shdr_data = (ElfW2(LIBELFBITS,Shdr) *) - alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + { + shdr_data_mem = (ElfW2(LIBELFBITS,Shdr) *) + malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + if (unlikely (shdr_data_mem == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + shdr_data = shdr_data_mem; + } else shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr; int shdr_flags = elf->flags; /* Get all sections into the array and sort them. */ Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; - Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); + Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *)); + if (unlikely (scns == NULL)) + { + free (shdr_data_mem); + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } sort_sections (scns, list); for (size_t cnt = 0; cnt < shnum; ++cnt) @@ -685,7 +715,12 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) (scn_start + dl->data.d.d_off) - last_offset, fillbuf, &filled) != 0)) - return 1; + { + fail_free: + free (shdr_data_mem); + free (scns); + return 1; + } } if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY) @@ -714,10 +749,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) if (dl->data.d.d_size > MAX_TMPBUF) { buf = malloc (dl->data.d.d_size); - if (buf == NULL) + if (unlikely (buf == NULL)) { __libelf_seterrno (ELF_E_NOMEM); - return 1; + goto fail_free; } } @@ -734,7 +769,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) free (buf); __libelf_seterrno (ELF_E_WRITE_ERROR); - return 1; + goto fail_free; } if (buf != dl->data.d.d_buf && buf != tmpbuf) @@ -759,7 +794,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) if (unlikely (fill (elf->fildes, last_offset, scn_start - last_offset, fillbuf, &filled) != 0)) - return 1; + goto fail_free; } last_offset = scn_start + shdr->sh_size; @@ -787,7 +822,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) && unlikely (fill (elf->fildes, last_offset, shdr_offset - last_offset, fillbuf, &filled) != 0)) - return 1; + goto fail_free; /* Write out the section header table. */ if (shdr_flags & ELF_F_DIRTY @@ -797,8 +832,11 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum)) { __libelf_seterrno (ELF_E_WRITE_ERROR); - return 1; + goto fail_free; } + + free (shdr_data_mem); + free (scns); } /* That was the last part. Clear the overall flag. */ diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c index be4cea03..c59ffcbd 100644 --- a/libelf/elf32_updatenull.c +++ b/libelf/elf32_updatenull.c @@ -1,5 +1,5 @@ /* Update data structures for changes. - Copyright (C) 2000-2010 Red Hat, Inc. + Copyright (C) 2000-2010, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -106,6 +106,14 @@ ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr, elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; } + /* If phnum is zero make sure e_phoff is also zero and not some random + value. That would cause trouble in update_file. */ + if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0) + { + ehdr->e_phoff = 0; + elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; + } + return 0; } @@ -202,6 +210,11 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) assert (shdr != NULL); ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize; ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1; + if (unlikely (! powerof2 (sh_align))) + { + __libelf_seterrno (ELF_E_INVALID_ALIGN); + return -1; + } /* Set the sh_entsize value if we can reliably detect it. */ switch (shdr->sh_type) @@ -318,9 +331,8 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) if (elf->flags & ELF_F_LAYOUT) { size = MAX ((GElf_Word) size, - shdr->sh_offset - + (shdr->sh_type != SHT_NOBITS - ? shdr->sh_size : 0)); + (shdr->sh_type != SHT_NOBITS + ? shdr->sh_offset + shdr->sh_size : 0)); /* The alignment must be a power of two. This is a requirement from the ELF specification. Additionally @@ -328,7 +340,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) enough for the largest alignment required by a data block. */ if (unlikely (! powerof2 (shdr->sh_addralign)) - || unlikely (shdr->sh_addralign < sh_align)) + || unlikely ((shdr->sh_addralign ?: 1) < sh_align)) { __libelf_seterrno (ELF_E_INVALID_ALIGN); return -1; diff --git a/libelf/elf32_xlatetof.c b/libelf/elf32_xlatetof.c index 27a973ec..ac4eaf40 100644 --- a/libelf/elf32_xlatetof.c +++ b/libelf/elf32_xlatetof.c @@ -1,5 +1,5 @@ /* Convert from memory to file representation. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -43,10 +43,8 @@ Elf_Data * -elfw2(LIBELFBITS, xlatetof) (dest, src, encode) - Elf_Data *dest; - const Elf_Data *src; - unsigned int encode; +elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src, + unsigned int encode) { /* First test whether the input data is really suitable for this type. This means, whether there is an integer number of records. diff --git a/libelf/elf32_xlatetom.c b/libelf/elf32_xlatetom.c index 368df078..13cd485d 100644 --- a/libelf/elf32_xlatetom.c +++ b/libelf/elf32_xlatetom.c @@ -1,5 +1,5 @@ /* Convert from file to memory representation. - Copyright (C) 1998, 1999, 2000, 2002, 2012 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2012, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -43,10 +43,8 @@ Elf_Data * -elfw2(LIBELFBITS, xlatetom) (dest, src, encode) - Elf_Data *dest; - const Elf_Data *src; - unsigned int encode; +elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src, + unsigned int encode) { /* First test whether the input data is really suitable for this type. This means, whether there is an integer number of records. diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 30abe0bf..213b5c0b 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -1,5 +1,5 @@ /* Create descriptor for processing file. - Copyright (C) 1998-2010, 2012, 2014 Red Hat, Inc. + Copyright (C) 1998-2010, 2012, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -151,8 +151,8 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA && (ALLOW_UNALIGNED - || (((size_t) ((char *) map_address + offset)) - & (__alignof__ (Elf32_Ehdr) - 1)) == 0)) + || (((size_t) ((char *) map_address + ehdr.e32->e_shoff)) + & (__alignof__ (Elf32_Shdr) - 1)) == 0)) /* We can directly access the memory. */ result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff + offset))->sh_size; @@ -201,8 +201,8 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset, Elf64_Xword size; if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA && (ALLOW_UNALIGNED - || (((size_t) ((char *) map_address + offset)) - & (__alignof__ (Elf64_Ehdr) - 1)) == 0)) + || (((size_t) ((char *) map_address + ehdr.e64->e_shoff)) + & (__alignof__ (Elf64_Shdr) - 1)) == 0)) /* We can directly access the memory. */ size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff + offset))->sh_size; @@ -306,17 +306,46 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, /* This is a 32-bit binary. */ if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA && (ALLOW_UNALIGNED - || ((((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0 - && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) - & (__alignof__ (Elf32_Shdr) - 1)) == 0 - && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) - & (__alignof__ (Elf32_Phdr) - 1)) == 0))) + || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0)) { /* We can use the mmapped memory. */ elf->state.elf32.ehdr = ehdr; + } + else + { + /* Copy the ELF header. */ + elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident, + sizeof (Elf32_Ehdr)); - if (unlikely (ehdr->e_shoff >= maxsize) - || unlikely (maxsize - ehdr->e_shoff + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf32.ehdr_mem.e_type); + CONVERT (elf->state.elf32.ehdr_mem.e_machine); + CONVERT (elf->state.elf32.ehdr_mem.e_version); + CONVERT (elf->state.elf32.ehdr_mem.e_entry); + CONVERT (elf->state.elf32.ehdr_mem.e_phoff); + CONVERT (elf->state.elf32.ehdr_mem.e_shoff); + CONVERT (elf->state.elf32.ehdr_mem.e_flags); + CONVERT (elf->state.elf32.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_phnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf32.ehdr_mem.e_shnum); + CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx); + } + } + + /* Don't precache the phdr pointer here. + elf32_getphdr will validate it against the size when asked. */ + + Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff; + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((uintptr_t) ((char *) ehdr + e_shoff) + & (__alignof__ (Elf32_Shdr) - 1)) == 0))) + { + if (unlikely (e_shoff >= maxsize) + || unlikely (maxsize - e_shoff < scncnt * sizeof (Elf32_Shdr))) { free_and_out: @@ -325,10 +354,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, return NULL; } elf->state.elf32.shdr - = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); - - /* Don't precache the phdr pointer here. - elf32_getphdr will validate it against the size when asked. */ + = (Elf32_Shdr *) ((char *) ehdr + e_shoff); for (size_t cnt = 0; cnt < scncnt; ++cnt) { @@ -361,27 +387,6 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, } else { - /* Copy the ELF header. */ - elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident, - sizeof (Elf32_Ehdr)); - - if (e_ident[EI_DATA] != MY_ELFDATA) - { - CONVERT (elf->state.elf32.ehdr_mem.e_type); - CONVERT (elf->state.elf32.ehdr_mem.e_machine); - CONVERT (elf->state.elf32.ehdr_mem.e_version); - CONVERT (elf->state.elf32.ehdr_mem.e_entry); - CONVERT (elf->state.elf32.ehdr_mem.e_phoff); - CONVERT (elf->state.elf32.ehdr_mem.e_shoff); - CONVERT (elf->state.elf32.ehdr_mem.e_flags); - CONVERT (elf->state.elf32.ehdr_mem.e_ehsize); - CONVERT (elf->state.elf32.ehdr_mem.e_phentsize); - CONVERT (elf->state.elf32.ehdr_mem.e_phnum); - CONVERT (elf->state.elf32.ehdr_mem.e_shentsize); - CONVERT (elf->state.elf32.ehdr_mem.e_shnum); - CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx); - } - for (size_t cnt = 0; cnt < scncnt; ++cnt) { elf->state.elf32.scns.data[cnt].index = cnt; @@ -402,24 +407,50 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, /* This is a 64-bit binary. */ if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA && (ALLOW_UNALIGNED - || ((((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0 - && ((uintptr_t) ((char *) ehdr + ehdr->e_shoff) - & (__alignof__ (Elf64_Shdr) - 1)) == 0 - && ((uintptr_t) ((char *) ehdr + ehdr->e_phoff) - & (__alignof__ (Elf64_Phdr) - 1)) == 0))) + || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0)) { /* We can use the mmapped memory. */ elf->state.elf64.ehdr = ehdr; + } + else + { + /* Copy the ELF header. */ + elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident, + sizeof (Elf64_Ehdr)); - if (unlikely (ehdr->e_shoff >= maxsize) - || unlikely (maxsize - ehdr->e_shoff + if (e_ident[EI_DATA] != MY_ELFDATA) + { + CONVERT (elf->state.elf64.ehdr_mem.e_type); + CONVERT (elf->state.elf64.ehdr_mem.e_machine); + CONVERT (elf->state.elf64.ehdr_mem.e_version); + CONVERT (elf->state.elf64.ehdr_mem.e_entry); + CONVERT (elf->state.elf64.ehdr_mem.e_phoff); + CONVERT (elf->state.elf64.ehdr_mem.e_shoff); + CONVERT (elf->state.elf64.ehdr_mem.e_flags); + CONVERT (elf->state.elf64.ehdr_mem.e_ehsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_phnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shentsize); + CONVERT (elf->state.elf64.ehdr_mem.e_shnum); + CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx); + } + } + + /* Don't precache the phdr pointer here. + elf64_getphdr will validate it against the size when asked. */ + + Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff; + if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA + && (ALLOW_UNALIGNED + || (((uintptr_t) ((char *) ehdr + e_shoff) + & (__alignof__ (Elf64_Shdr) - 1)) == 0))) + { + if (unlikely (e_shoff >= maxsize) + || unlikely (maxsize - e_shoff < scncnt * sizeof (Elf64_Shdr))) goto free_and_out; elf->state.elf64.shdr - = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff); - - /* Don't precache the phdr pointer here. - elf64_getphdr will validate it against the size when asked. */ + = (Elf64_Shdr *) ((char *) ehdr + e_shoff); for (size_t cnt = 0; cnt < scncnt; ++cnt) { @@ -452,27 +483,6 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident, } else { - /* Copy the ELF header. */ - elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident, - sizeof (Elf64_Ehdr)); - - if (e_ident[EI_DATA] != MY_ELFDATA) - { - CONVERT (elf->state.elf64.ehdr_mem.e_type); - CONVERT (elf->state.elf64.ehdr_mem.e_machine); - CONVERT (elf->state.elf64.ehdr_mem.e_version); - CONVERT (elf->state.elf64.ehdr_mem.e_entry); - CONVERT (elf->state.elf64.ehdr_mem.e_phoff); - CONVERT (elf->state.elf64.ehdr_mem.e_shoff); - CONVERT (elf->state.elf64.ehdr_mem.e_flags); - CONVERT (elf->state.elf64.ehdr_mem.e_ehsize); - CONVERT (elf->state.elf64.ehdr_mem.e_phentsize); - CONVERT (elf->state.elf64.ehdr_mem.e_phnum); - CONVERT (elf->state.elf64.ehdr_mem.e_shentsize); - CONVERT (elf->state.elf64.ehdr_mem.e_shnum); - CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx); - } - for (size_t cnt = 0; cnt < scncnt; ++cnt) { elf->state.elf64.scns.data[cnt].index = cnt; @@ -749,10 +759,7 @@ read_long_names (Elf *elf) } /* NUL-terminate the string. */ - *runp = '\0'; - - /* Skip the NUL byte and the \012. */ - runp += 2; + *runp++ = '\0'; /* A sanity check. Somebody might have generated invalid archive. */ @@ -768,8 +775,7 @@ read_long_names (Elf *elf) /* Read the next archive header. */ int internal_function -__libelf_next_arhdr_wrlock (elf) - Elf *elf; +__libelf_next_arhdr_wrlock (Elf *elf) { struct ar_hdr *ar_hdr; Elf_Arhdr *elf_ar_hdr; @@ -924,9 +930,16 @@ __libelf_next_arhdr_wrlock (elf) INT_FIELD (ar_mode); INT_FIELD (ar_size); + if (elf_ar_hdr->ar_size < 0) + { + __libelf_seterrno (ELF_E_INVALID_ARCHIVE); + return -1; + } + /* Truncated file? */ size_t maxsize; - maxsize = elf->maximum_size - elf->state.ar.offset - sizeof (struct ar_hdr); + maxsize = (elf->start_offset + elf->maximum_size + - elf->state.ar.offset - sizeof (struct ar_hdr)); if ((size_t) elf_ar_hdr->ar_size > maxsize) elf_ar_hdr->ar_size = maxsize; @@ -1029,10 +1042,7 @@ write_file (int fd, Elf_Cmd cmd) /* Return a descriptor for the file belonging to FILDES. */ Elf * -elf_begin (fildes, cmd, ref) - int fildes; - Elf_Cmd cmd; - Elf *ref; +elf_begin (int fildes, Elf_Cmd cmd, Elf *ref) { Elf *retval; @@ -1053,7 +1063,7 @@ elf_begin (fildes, cmd, ref) return NULL; } - Elf *lock_dup_elf () + Elf *lock_dup_elf (void) { /* We need wrlock to dup an archive. */ if (ref->kind == ELF_K_AR) diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c index a3c58051..ab13ffb6 100644 --- a/libelf/elf_cntl.c +++ b/libelf/elf_cntl.c @@ -1,5 +1,5 @@ /* Control an ELF file desrciptor. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -37,9 +37,7 @@ int -elf_cntl (elf, cmd) - Elf *elf; - Elf_Cmd cmd; +elf_cntl (Elf *elf, Elf_Cmd cmd) { int result = 0; diff --git a/libelf/elf_end.c b/libelf/elf_end.c index d4ae0517..7ea876c3 100644 --- a/libelf/elf_end.c +++ b/libelf/elf_end.c @@ -1,5 +1,5 @@ /* Free resources associated with Elf descriptor. - Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007 Red Hat, Inc. + Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -40,8 +40,7 @@ int -elf_end (elf) - Elf *elf; +elf_end (Elf *elf) { Elf *parent; diff --git a/libelf/elf_error.c b/libelf/elf_error.c index aa7f9173..d6bdaab0 100644 --- a/libelf/elf_error.c +++ b/libelf/elf_error.c @@ -1,5 +1,5 @@ /* Error handling in libelf. - Copyright (C) 1998-2010 Red Hat, Inc. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -283,16 +283,15 @@ static const uint_fast16_t msgidx[ELF_E_NUM] = void -__libelf_seterrno (value) - int value; +internal_function +__libelf_seterrno (int value) { global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR; } const char * -elf_errmsg (error) - int error; +elf_errmsg (int error) { int last_error = global_error; diff --git a/libelf/elf_fill.c b/libelf/elf_fill.c index 174ab45c..6ebdf63a 100644 --- a/libelf/elf_fill.c +++ b/libelf/elf_fill.c @@ -1,5 +1,5 @@ /* Set fill byte used when constructing ELF objects. - Copyright (C) 1998, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -40,8 +40,7 @@ int __libelf_fill_byte; void -elf_fill (fill) - int fill; +elf_fill (int fill) { __libelf_fill_byte = fill; } diff --git a/libelf/elf_flagdata.c b/libelf/elf_flagdata.c index ace8cc52..cd2b1237 100644 --- a/libelf/elf_flagdata.c +++ b/libelf/elf_flagdata.c @@ -1,5 +1,5 @@ /* Manipulate ELF data flag. - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,10 +38,7 @@ unsigned int -elf_flagdata (data, cmd, flags) - Elf_Data *data; - Elf_Cmd cmd; - unsigned int flags; +elf_flagdata (Elf_Data *data, Elf_Cmd cmd, unsigned int flags) { Elf_Data_Scn *data_scn; unsigned int result; diff --git a/libelf/elf_flagehdr.c b/libelf/elf_flagehdr.c index d3a320b9..a98276d5 100644 --- a/libelf/elf_flagehdr.c +++ b/libelf/elf_flagehdr.c @@ -1,5 +1,5 @@ /* Manipulate ELF header flags. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,10 +38,7 @@ unsigned int -elf_flagehdr (elf, cmd, flags) - Elf *elf; - Elf_Cmd cmd; - unsigned int flags; +elf_flagehdr (Elf *elf, Elf_Cmd cmd, unsigned int flags) { unsigned int result; diff --git a/libelf/elf_flagelf.c b/libelf/elf_flagelf.c index b34bd4f8..bd90a21f 100644 --- a/libelf/elf_flagelf.c +++ b/libelf/elf_flagelf.c @@ -1,5 +1,5 @@ /* Manipulate ELF file flags. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,10 +38,7 @@ unsigned int -elf_flagelf (elf, cmd, flags) - Elf *elf; - Elf_Cmd cmd; - unsigned int flags; +elf_flagelf (Elf *elf, Elf_Cmd cmd, unsigned int flags) { unsigned int result; diff --git a/libelf/elf_flagphdr.c b/libelf/elf_flagphdr.c index 2a589cc9..0682d1f4 100644 --- a/libelf/elf_flagphdr.c +++ b/libelf/elf_flagphdr.c @@ -1,5 +1,5 @@ /* Manipulate ELF program header flags. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,10 +38,7 @@ unsigned int -elf_flagphdr (elf, cmd, flags) - Elf *elf; - Elf_Cmd cmd; - unsigned int flags; +elf_flagphdr (Elf *elf, Elf_Cmd cmd, unsigned int flags) { unsigned int result; diff --git a/libelf/elf_flagscn.c b/libelf/elf_flagscn.c index 3ff826c6..2164a8c9 100644 --- a/libelf/elf_flagscn.c +++ b/libelf/elf_flagscn.c @@ -1,5 +1,5 @@ /* Manipulate ELF section flags. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,10 +38,7 @@ unsigned int -elf_flagscn (scn, cmd, flags) - Elf_Scn *scn; - Elf_Cmd cmd; - unsigned int flags; +elf_flagscn (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags) { unsigned int result; diff --git a/libelf/elf_flagshdr.c b/libelf/elf_flagshdr.c index 8d797af6..febf4abf 100644 --- a/libelf/elf_flagshdr.c +++ b/libelf/elf_flagshdr.c @@ -1,5 +1,5 @@ /* Manipulate ELF section header flags. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,10 +38,7 @@ unsigned int -elf_flagshdr (scn, cmd, flags) - Elf_Scn *scn; - Elf_Cmd cmd; - unsigned int flags; +elf_flagshdr (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags) { unsigned int result; diff --git a/libelf/elf_getarhdr.c b/libelf/elf_getarhdr.c index f8b36b8b..509f1da5 100644 --- a/libelf/elf_getarhdr.c +++ b/libelf/elf_getarhdr.c @@ -1,5 +1,5 @@ /* Read header of next archive member. - Copyright (C) 1998, 1999, 2000, 2002, 2008 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2008, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -39,8 +39,7 @@ Elf_Arhdr * -elf_getarhdr (elf) - Elf *elf; +elf_getarhdr (Elf *elf) { if (elf == NULL) return NULL; diff --git a/libelf/elf_getaroff.c b/libelf/elf_getaroff.c index 62da34df..5b59203f 100644 --- a/libelf/elf_getaroff.c +++ b/libelf/elf_getaroff.c @@ -1,5 +1,5 @@ /* Return offset in archive for current file ELF. - Copyright (C) 2005, 2008 Red Hat, Inc. + Copyright (C) 2005, 2008, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. @@ -39,8 +39,7 @@ off_t -elf_getaroff (elf) - Elf *elf; +elf_getaroff (Elf *elf) { /* Be gratious, the specs demand it. */ if (elf == NULL || elf->parent == NULL) diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c index 40633aa8..1ab94ca8 100644 --- a/libelf/elf_getarsym.c +++ b/libelf/elf_getarsym.c @@ -1,5 +1,5 @@ /* Return symbol table of archive. - Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014 Red Hat, Inc. + Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -74,9 +74,7 @@ read_number_entries (uint64_t *nump, Elf *elf, size_t *offp, bool index64_p) } Elf_Arsym * -elf_getarsym (elf, ptr) - Elf *elf; - size_t *ptr; +elf_getarsym (Elf *elf, size_t *ptr) { if (elf->kind != ELF_K_AR) { @@ -106,6 +104,9 @@ elf_getarsym (elf, ptr) /* In case we find no index remember this for the next call. */ elf->state.ar.ar_sym = (Elf_Arsym *) -1l; + /* We might have to allocate some temporary data for reading. */ + void *temp_data = NULL; + struct ar_hdr *index_hdr; if (elf->map_address == NULL) { @@ -210,7 +211,13 @@ elf_getarsym (elf, ptr) if (elf->map_address == NULL) { - file_data = alloca (sz); + temp_data = malloc (sz); + if (unlikely (temp_data == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + file_data = temp_data; ar_sym_len += index_size - n * w; Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym, @@ -246,7 +253,15 @@ elf_getarsym (elf, ptr) file_data = (void *) (elf->map_address + off); if (!ALLOW_UNALIGNED && ((uintptr_t) file_data & -(uintptr_t) n) != 0) - file_data = memcpy (alloca (sz), elf->map_address + off, sz); + { + temp_data = malloc (sz); + if (unlikely (temp_data == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + file_data = memcpy (temp_data, elf->map_address + off, sz); + } str_data = (char *) (elf->map_address + off + sz); } @@ -299,6 +314,7 @@ elf_getarsym (elf, ptr) result = elf->state.ar.ar_sym; out: + free (temp_data); rwlock_unlock (elf->lock); } diff --git a/libelf/elf_getbase.c b/libelf/elf_getbase.c index ff0feb40..8ec5f87e 100644 --- a/libelf/elf_getbase.c +++ b/libelf/elf_getbase.c @@ -1,5 +1,5 @@ /* Return offset of first byte for the object. - Copyright (C) 1998, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,8 +38,7 @@ off_t -elf_getbase (elf) - Elf *elf; +elf_getbase (Elf *elf) { return elf == NULL ? (off_t) -1 : elf->start_offset; } diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c index 0aeb9972..9a567e51 100644 --- a/libelf/elf_getdata.c +++ b/libelf/elf_getdata.c @@ -1,5 +1,5 @@ /* Return the next data element from the section after possibly converting it. - Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc. + Copyright (C) 1998-2005, 2006, 2007, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -83,8 +83,15 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] # define TYPE_ALIGNS(Bits) \ { \ [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \ + [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)), \ [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \ + [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)), \ + [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)), \ + [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)), \ + [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)), \ [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \ + [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)), \ + [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)), \ [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \ [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \ [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \ @@ -97,6 +104,8 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \ [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \ [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \ + [ELF_T_GNUHASH] = __alignof__ (Elf32_Word), \ + [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \ } [EV_CURRENT - 1] = { @@ -144,6 +153,25 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass, return; } + /* 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) + rawdata_source = scn->rawdata_base; + else + { + rawdata_source = (char *) malloc (size); + if (rawdata_source == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return; + } + + /* The copy will be appropriately aligned for direct access. */ + memcpy (rawdata_source, scn->rawdata_base, size); + } + /* Get the conversion function. */ #if EV_NUM != 2 fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type]; @@ -151,7 +179,10 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass, fp = __elf_xfctstom[0][0][eclass - 1][type]; #endif - fp (scn->data_base, scn->rawdata_base, size, 0); + fp (scn->data_base, rawdata_source, size, 0); + + if (rawdata_source != scn->rawdata_base) + free (rawdata_source); } scn->data_list.data.d.d_buf = scn->data_base; @@ -301,6 +332,20 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) else scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)]; scn->rawdata.d.d_off = 0; + + /* Make sure the alignment makes sense. d_align should be aligned both + in the section (trivially true since d_off is zero) and in the file. + Unfortunately we cannot be too strict because there are ELF files + out there that fail this requirement. We will try to fix those up + in elf_update when writing out the image. But for very large + alignment values this can bloat the image considerably. So here + just check and clamp the alignment value to not be bigger than the + actual offset of the data in the file. Given that there is always + at least an ehdr this will only trigger for alignment values > 64 + which should be uncommon. */ + align = align ?: 1; + if (align > offset) + align = offset; scn->rawdata.d.d_align = align; if (elf->class == ELFCLASS32 || (offsetof (struct Elf, state.elf32.ehdr) @@ -337,11 +382,47 @@ __libelf_set_rawdata (Elf_Scn *scn) return result; } +void +internal_function +__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked) +{ + if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0) + { + Elf *elf = scn->elf; + + /* Upgrade the lock to a write lock if necessary and check + nobody else already did the work. */ + if (!wrlocked) + { + rwlock_unlock (elf->lock); + rwlock_wrlock (elf->lock); + if (scn->data_list_rear != NULL) + return; + } + + /* Convert according to the version and the type. */ + convert_data (scn, __libelf_version, elf->class, + (elf->class == ELFCLASS32 + || (offsetof (struct Elf, state.elf32.ehdr) + == offsetof (struct Elf, state.elf64.ehdr)) + ? elf->state.elf32.ehdr->e_ident[EI_DATA] + : elf->state.elf64.ehdr->e_ident[EI_DATA]), + scn->rawdata.d.d_size, scn->rawdata.d.d_type); + } + else + { + /* This is an empty or NOBITS section. There is no buffer but + the size information etc is important. */ + scn->data_list.data.d = scn->rawdata.d; + scn->data_list.data.s = scn; + } + + scn->data_list_rear = &scn->data_list; +} + Elf_Data * internal_function -__elf_getdata_rdlock (scn, data) - Elf_Scn *scn; - Elf_Data *data; +__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data) { Elf_Data *result = NULL; Elf *elf; @@ -427,51 +508,17 @@ __elf_getdata_rdlock (scn, data) empty in case the section has size zero (for whatever reason). Now create the converted data in case this is necessary. */ if (scn->data_list_rear == NULL) - { - if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0) - { - if (!locked) - { - rwlock_unlock (elf->lock); - rwlock_wrlock (elf->lock); - if (scn->data_list_rear != NULL) - goto pass; - } - - /* Convert according to the version and the type. */ - convert_data (scn, __libelf_version, elf->class, - (elf->class == ELFCLASS32 - || (offsetof (struct Elf, state.elf32.ehdr) - == offsetof (struct Elf, state.elf64.ehdr)) - ? elf->state.elf32.ehdr->e_ident[EI_DATA] - : elf->state.elf64.ehdr->e_ident[EI_DATA]), - scn->rawdata.d.d_size, scn->rawdata.d.d_type); - } - else - { - /* This is an empty or NOBITS section. There is no buffer but - the size information etc is important. */ - scn->data_list.data.d = scn->rawdata.d; - scn->data_list.data.s = scn; - } - - scn->data_list_rear = &scn->data_list; - } + __libelf_set_data_list_rdlock (scn, locked); - /* If no data is present we cannot return any. */ - if (scn->data_list_rear != NULL) - pass: - /* Return the first data element in the list. */ - result = &scn->data_list.data.d; + /* Return the first data element in the list. */ + result = &scn->data_list.data.d; out: return result; } Elf_Data * -elf_getdata (scn, data) - Elf_Scn *scn; - Elf_Data *data; +elf_getdata (Elf_Scn *scn, Elf_Data *data) { Elf_Data *result; diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c index 63a9914f..51b3e3e7 100644 --- a/libelf/elf_getdata_rawchunk.c +++ b/libelf/elf_getdata_rawchunk.c @@ -1,5 +1,5 @@ /* Return converted data from raw chunk of ELF file. - Copyright (C) 2007, 2014 Red Hat, Inc. + Copyright (C) 2007, 2014, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -41,11 +41,7 @@ #include "common.h" Elf_Data * -elf_getdata_rawchunk (elf, offset, size, type) - Elf *elf; - off64_t offset; - size_t size; - Elf_Type type; +elf_getdata_rawchunk (Elf *elf, off64_t offset, size_t size, Elf_Type type) { if (unlikely (elf == NULL)) return NULL; @@ -79,9 +75,24 @@ elf_getdata_rawchunk (elf, offset, size, type) rwlock_rdlock (elf->lock); - /* If the file is mmap'ed we can use it directly. */ + size_t align = __libelf_type_align (elf->class, type); if (elf->map_address != NULL) - rawchunk = elf->map_address + elf->start_offset + offset; + { + /* 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) + rawchunk = rawdata; + else + { + /* We allocate the memory and memcpy it to get aligned data. */ + rawchunk = malloc (size); + if (rawchunk == NULL) + goto nomem; + memcpy (rawchunk, rawdata, size); + flags = ELF_F_MALLOCED; + } + } else { /* We allocate the memory and read the data from the file. */ @@ -108,7 +119,6 @@ elf_getdata_rawchunk (elf, offset, size, type) } /* Copy and/or convert the data as needed for aligned native-order access. */ - size_t align = __libelf_type_align (elf->class, type); void *buffer; if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA) { diff --git a/libelf/elf_getident.c b/libelf/elf_getident.c index 10beeafd..5abf8c94 100644 --- a/libelf/elf_getident.c +++ b/libelf/elf_getident.c @@ -1,5 +1,5 @@ /* Retrieve file identification data. - Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2004, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -37,9 +37,7 @@ char * -elf_getident (elf, ptr) - Elf *elf; - size_t *ptr; +elf_getident (Elf *elf, size_t *ptr) { /* In case this is no ELF file, the handle is invalid and we return NULL. */ diff --git a/libelf/elf_getphdrnum.c b/libelf/elf_getphdrnum.c index 63c27fb1..061183bb 100644 --- a/libelf/elf_getphdrnum.c +++ b/libelf/elf_getphdrnum.c @@ -1,5 +1,5 @@ /* Return number of program headers in the ELF file. - Copyright (C) 2010, 2014 Red Hat, Inc. + Copyright (C) 2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -38,9 +38,8 @@ int -__elf_getphdrnum_rdlock (elf, dst) - Elf *elf; - size_t *dst; +internal_function +__elf_getphdrnum_rdlock (Elf *elf, size_t *dst) { if (unlikely (elf->state.elf64.ehdr == NULL)) { @@ -80,23 +79,10 @@ __elf_getphdrnum_rdlock (elf, dst) } int -elf_getphdrnum (elf, dst) - Elf *elf; - size_t *dst; +internal_function +__elf_getphdrnum_chk_rdlock (Elf *elf, size_t *dst) { - int result; - - if (elf == NULL) - return -1; - - if (unlikely (elf->kind != ELF_K_ELF)) - { - __libelf_seterrno (ELF_E_INVALID_HANDLE); - return -1; - } - - rwlock_rdlock (elf->lock); - result = __elf_getphdrnum_rdlock (elf, dst); + int result = __elf_getphdrnum_rdlock (elf, dst); /* Do some sanity checking to make sure phnum and phoff are consistent. */ Elf64_Off off = (elf->class == ELFCLASS32 @@ -105,14 +91,13 @@ elf_getphdrnum (elf, dst) if (unlikely (off == 0)) { *dst = 0; - goto out; + return result; } if (unlikely (off >= elf->maximum_size)) { __libelf_seterrno (ELF_E_INVALID_DATA); - result = -1; - goto out; + return -1; } /* Check for too many sections. */ @@ -121,15 +106,32 @@ elf_getphdrnum (elf, dst) if (unlikely (*dst > SIZE_MAX / phdr_size)) { __libelf_seterrno (ELF_E_INVALID_DATA); - result = -1; - goto out; + return -1; } /* Truncated file? Don't return more than can be indexed. */ if (unlikely (elf->maximum_size - off < *dst * phdr_size)) *dst = (elf->maximum_size - off) / phdr_size; -out: + return result; +} + +int +elf_getphdrnum (Elf *elf, size_t *dst) +{ + int result; + + if (elf == NULL) + return -1; + + if (unlikely (elf->kind != ELF_K_ELF)) + { + __libelf_seterrno (ELF_E_INVALID_HANDLE); + return -1; + } + + rwlock_rdlock (elf->lock); + result = __elf_getphdrnum_chk_rdlock (elf, dst); rwlock_unlock (elf->lock); return result; diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c index 7c6b7dee..9f7213b4 100644 --- a/libelf/elf_getscn.c +++ b/libelf/elf_getscn.c @@ -1,5 +1,5 @@ /* Get section at specific index. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -39,9 +39,7 @@ Elf_Scn * -elf_getscn (elf, idx) - Elf *elf; - size_t idx; +elf_getscn (Elf *elf, size_t idx) { if (elf == NULL) return NULL; diff --git a/libelf/elf_getshdrnum.c b/libelf/elf_getshdrnum.c index 73a3300d..18e5d14a 100644 --- a/libelf/elf_getshdrnum.c +++ b/libelf/elf_getshdrnum.c @@ -1,5 +1,5 @@ /* Return number of sections in the ELF file. - Copyright (C) 2002, 2009 Red Hat, Inc. + Copyright (C) 2002, 2009, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -39,9 +39,8 @@ int -__elf_getshdrnum_rdlock (elf, dst) - Elf *elf; - size_t *dst; +internal_function +__elf_getshdrnum_rdlock (Elf *elf, size_t *dst) { int result = 0; int idx; @@ -71,9 +70,7 @@ __elf_getshdrnum_rdlock (elf, dst) } int -elf_getshdrnum (elf, dst) - Elf *elf; - size_t *dst; +elf_getshdrnum (Elf *elf, size_t *dst) { int result; diff --git a/libelf/elf_getshdrstrndx.c b/libelf/elf_getshdrstrndx.c index 6f8d66e8..aead2fe5 100644 --- a/libelf/elf_getshdrstrndx.c +++ b/libelf/elf_getshdrstrndx.c @@ -1,5 +1,5 @@ /* Return section index of section header string table. - Copyright (C) 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -43,9 +43,7 @@ int -elf_getshdrstrndx (elf, dst) - Elf *elf; - size_t *dst; +elf_getshdrstrndx (Elf *elf, size_t *dst) { int result = 0; diff --git a/libelf/elf_gnu_hash.c b/libelf/elf_gnu_hash.c index 4c21857f..5a1b8523 100644 --- a/libelf/elf_gnu_hash.c +++ b/libelf/elf_gnu_hash.c @@ -1,5 +1,5 @@ /* GNU-style Hash function used in ELF implementations. - Copyright (C) 2006 Red Hat, Inc. + Copyright (C) 2006, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 2006. @@ -37,8 +37,7 @@ #include <dl-hash.h> unsigned long int -elf_gnu_hash (string) - const char *string; +elf_gnu_hash (const char *string) { uint_fast32_t h = 5381; for (unsigned char c = *string; c != '\0'; c = *++string) diff --git a/libelf/elf_hash.c b/libelf/elf_hash.c index 306ebc2c..345697e1 100644 --- a/libelf/elf_hash.c +++ b/libelf/elf_hash.c @@ -1,5 +1,5 @@ /* Hash function used in ELF implementations. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -37,8 +37,7 @@ #include <dl-hash.h> unsigned long int -elf_hash (string) - const char *string; +elf_hash (const char *string) { return _dl_elf_hash (string); } diff --git a/libelf/elf_kind.c b/libelf/elf_kind.c index d8ab2fdd..0fb3f0c2 100644 --- a/libelf/elf_kind.c +++ b/libelf/elf_kind.c @@ -1,5 +1,5 @@ /* Return the kind of file associated with the descriptor. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,8 +38,7 @@ Elf_Kind -elf_kind (elf) - Elf *elf; +elf_kind (Elf *elf) { return elf == NULL ? ELF_K_NONE : elf->kind; } diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c index 08f85a12..a47f1d24 100644 --- a/libelf/elf_memory.c +++ b/libelf/elf_memory.c @@ -1,5 +1,5 @@ /* Create descriptor for memory region. - Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,9 +38,7 @@ Elf * -elf_memory (image, size) - char *image; - size_t size; +elf_memory (char *image, size_t size) { if (image == NULL) { diff --git a/libelf/elf_ndxscn.c b/libelf/elf_ndxscn.c index bd4bfbfd..488c4e5f 100644 --- a/libelf/elf_ndxscn.c +++ b/libelf/elf_ndxscn.c @@ -1,5 +1,5 @@ /* Get index of section. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,8 +38,7 @@ size_t -elf_ndxscn (scn) - Elf_Scn *scn; +elf_ndxscn (Elf_Scn *scn) { if (scn == NULL) return SHN_UNDEF; diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c index 90d18133..f6609a80 100644 --- a/libelf/elf_newdata.c +++ b/libelf/elf_newdata.c @@ -1,5 +1,5 @@ /* Create new, empty section data. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -64,6 +64,25 @@ elf_newdata (Elf_Scn *scn) rwlock_wrlock (scn->elf->lock); + /* data_read is set when data has been read from the ELF image or + when a new section has been created by elf_newscn. If data has + been read from the ELF image, then rawdata_base will point to raw + data. If data_read has been set by elf_newscn, then rawdata_base + will be NULL. data_list_rear will be set by elf_getdata if the + data has been converted, or by this function, elf_newdata, when + new data has been added. + + Currently elf_getdata and elf_update rely on the fact that when + data_list_read is not NULL all they have to do is walk the data + list. They will ignore any (unread) raw data in that case. + + So we need to make sure the data list is setup if there is + already data available. */ + if (scn->data_read + && scn->rawdata_base != NULL + && scn->data_list_rear == NULL) + __libelf_set_data_list_rdlock (scn, 1); + if (scn->data_read && scn->data_list_rear == NULL) { /* This means the section was created by the user and this is the @@ -73,6 +92,19 @@ elf_newdata (Elf_Scn *scn) } else { + /* It would be more efficient to create new data without + reading/converting the data from the file. But then we + have to remember this. Currently elf_getdata and + elf_update rely on the fact that they don't have to + load/convert any data if data_list_rear is set. */ + if (scn->data_read == 0) + { + if (__libelf_set_rawdata_wrlock (scn) != 0) + /* Something went wrong. The error value is already set. */ + goto out; + __libelf_set_data_list_rdlock (scn, 1); + } + /* Create a new, empty data descriptor. */ result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List)); if (result == NULL) @@ -82,11 +114,6 @@ elf_newdata (Elf_Scn *scn) } result->flags = ELF_F_DIRTY | ELF_F_MALLOCED; - - if (scn->data_list_rear == NULL) - /* We create new data without reading/converting the data from the - file. That is fine but we have to remember this. */ - scn->data_list_rear = &scn->data_list; } /* Set the predefined values. */ diff --git a/libelf/elf_newscn.c b/libelf/elf_newscn.c index 6e0029ed..d15a642e 100644 --- a/libelf/elf_newscn.c +++ b/libelf/elf_newscn.c @@ -1,5 +1,5 @@ /* Append new section. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 1998,1999,2000,2001,2002,2005,2009,2014,2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -41,8 +41,7 @@ Elf_Scn * -elf_newscn (elf) - Elf *elf; +elf_newscn (Elf *elf) { Elf_Scn *result = NULL; bool first = false; diff --git a/libelf/elf_next.c b/libelf/elf_next.c index 1f5c03c1..6edafd2e 100644 --- a/libelf/elf_next.c +++ b/libelf/elf_next.c @@ -1,5 +1,5 @@ /* Advance in archive to next element. - Copyright (C) 1998-2009 Red Hat, Inc. + Copyright (C) 1998-2009, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -39,8 +39,7 @@ Elf_Cmd -elf_next (elf) - Elf *elf; +elf_next (Elf *elf) { Elf *parent; Elf_Cmd ret; diff --git a/libelf/elf_nextscn.c b/libelf/elf_nextscn.c index 0d2bd666..62cb8914 100644 --- a/libelf/elf_nextscn.c +++ b/libelf/elf_nextscn.c @@ -1,5 +1,5 @@ /* Get next section. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -39,9 +39,7 @@ Elf_Scn * -elf_nextscn (elf, scn) - Elf *elf; - Elf_Scn *scn; +elf_nextscn (Elf *elf, Elf_Scn *scn) { Elf_Scn *result = NULL; diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c index cef4e448..f1850e7b 100644 --- a/libelf/elf_rand.c +++ b/libelf/elf_rand.c @@ -1,5 +1,5 @@ /* Select specific element in archive. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,9 +38,7 @@ size_t -elf_rand (elf, offset) - Elf *elf; - size_t offset; +elf_rand (Elf *elf, size_t offset) { /* Be gratious, the specs demand it. */ if (elf == NULL || elf->kind != ELF_K_AR) diff --git a/libelf/elf_rawdata.c b/libelf/elf_rawdata.c index 9672652c..db28f5dc 100644 --- a/libelf/elf_rawdata.c +++ b/libelf/elf_rawdata.c @@ -1,5 +1,5 @@ /* Return raw section content. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -37,9 +37,7 @@ Elf_Data * -elf_rawdata (scn, data) - Elf_Scn *scn; - Elf_Data *data; +elf_rawdata (Elf_Scn *scn, Elf_Data *data) { if (scn == NULL || scn->elf->kind != ELF_K_ELF) { diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c index dd71b88b..b3837f4f 100644 --- a/libelf/elf_rawfile.c +++ b/libelf/elf_rawfile.c @@ -1,5 +1,5 @@ /* Retrieve uninterpreted file contents. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,9 +38,7 @@ char * -elf_rawfile (elf, ptr) - Elf *elf; - size_t *ptr; +elf_rawfile (Elf *elf, size_t *ptr) { char *result; diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c index 01016188..384d2512 100644 --- a/libelf/elf_readall.c +++ b/libelf/elf_readall.c @@ -1,5 +1,5 @@ /* Read all of the file associated with the descriptor. - Copyright (C) 1998-2009 Red Hat, Inc. + Copyright (C) 1998-2009, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -66,8 +66,8 @@ set_address (Elf *elf, size_t offset) char * -__libelf_readall (elf) - Elf *elf; +internal_function +__libelf_readall (Elf *elf) { /* Get the file. */ rwlock_wrlock (elf->lock); diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c index 1f404292..c5138dc6 100644 --- a/libelf/elf_strptr.c +++ b/libelf/elf_strptr.c @@ -1,5 +1,5 @@ /* Return string pointer from string section. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2008, 2009 Red Hat, Inc. + Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,10 +38,7 @@ char * -elf_strptr (elf, idx, offset) - Elf *elf; - size_t idx; - size_t offset; +elf_strptr (Elf *elf, size_t idx, size_t offset) { if (elf == NULL) return NULL; @@ -86,16 +83,19 @@ elf_strptr (elf, idx, offset) } } + size_t sh_size = 0; if (elf->class == ELFCLASS32) { - if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB)) + Elf32_Shdr *shdr = strscn->shdr.e32 ?: __elf32_getshdr_rdlock (strscn); + if (unlikely (shdr->sh_type != SHT_STRTAB)) { /* This is no string section. */ __libelf_seterrno (ELF_E_INVALID_SECTION); goto out; } - if (unlikely (offset >= strscn->shdr.e32->sh_size)) + sh_size = shdr->sh_size; + if (unlikely (offset >= shdr->sh_size)) { /* The given offset is too big, it is beyond this section. */ __libelf_seterrno (ELF_E_OFFSET_RANGE); @@ -104,14 +104,16 @@ elf_strptr (elf, idx, offset) } else { - if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB)) + Elf64_Shdr *shdr = strscn->shdr.e64 ?: __elf64_getshdr_rdlock (strscn); + if (unlikely (shdr->sh_type != SHT_STRTAB)) { /* This is no string section. */ __libelf_seterrno (ELF_E_INVALID_SECTION); goto out; } - if (unlikely (offset >= strscn->shdr.e64->sh_size)) + sh_size = shdr->sh_size; + if (unlikely (offset >= shdr->sh_size)) { /* The given offset is too big, it is beyond this section. */ __libelf_seterrno (ELF_E_OFFSET_RANGE); @@ -129,12 +131,25 @@ elf_strptr (elf, idx, offset) goto out; } - if (likely (strscn->rawdata_base != NULL)) - // XXX Is this correct if a file is read and then new data is added - // XXX to the string section? Likely needs to check offset against - // XXX size of rawdata_base buffer and then iterate over rest of the - // XXX list. - result = &strscn->rawdata_base[offset]; + if (likely (strscn->data_list_rear == NULL)) + { + // XXX The above is currently correct since elf_newdata will + // make sure to convert the rawdata into the datalist if + // necessary. But it would be more efficient to keep the rawdata + // unconverted and only then iterate over the rest of the (newly + // added data) list. Note that when the ELF file is mmapped + // rawdata_base can be set while rawdata.d hasn't been + // initialized yet (when data_read is zero). So we cannot just + // look at the rawdata.d.d_size. + + /* Make sure the string is NUL terminated. Start from the end, + which very likely is a NUL char. */ + if (likely (memrchr (&strscn->rawdata_base[offset], + '\0', sh_size - offset) != NULL)) + result = &strscn->rawdata_base[offset]; + else + __libelf_seterrno (ELF_E_INVALID_INDEX); + } else { /* This is a file which is currently created. Use the list of @@ -145,7 +160,16 @@ elf_strptr (elf, idx, offset) if (offset >= (size_t) dl->data.d.d_off && offset < dl->data.d.d_off + dl->data.d.d_size) { - result = (char *) dl->data.d.d_buf + (offset - dl->data.d.d_off); + /* Make sure the string is NUL terminated. Start from + the end, which very likely is a NUL char. */ + if (likely (memrchr ((char *) dl->data.d.d_buf + + (offset - dl->data.d.d_off), '\0', + (dl->data.d.d_size + - (offset - dl->data.d.d_off))) != NULL)) + result = ((char *) dl->data.d.d_buf + + (offset - dl->data.d.d_off)); + else + __libelf_seterrno (ELF_E_INVALID_INDEX); break; } diff --git a/libelf/elf_update.c b/libelf/elf_update.c index 54c20f50..00f7a010 100644 --- a/libelf/elf_update.c +++ b/libelf/elf_update.c @@ -1,5 +1,5 @@ /* Update data structures for changes and write them out. - Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -32,6 +32,7 @@ #endif #include <libelf.h> +#include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> @@ -56,11 +57,22 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) We cannot do this if this file is in an archive. We also don't do it *now* if we are shortening the file since this would prevent programs to use the data of the file in generating the - new file. We truncate the file later in this case. */ + new file. We truncate the file later in this case. + + Note we use posix_fallocate to make sure the file content is really + there. Only using ftruncate might mean the file is extended, but space + isn't allocated yet. This might cause a SIGBUS once we write into + the mmapped space and the disk is full. Using fallocate might fail + on some file systems. posix_fallocate is required to extend the file + and allocate enough space even if the underlying filesystem would + normally return EOPNOTSUPP. Note that we do also need to ftruncate + in case the maximum_size isn't known and the file needs to be shorter + because posix_fallocate can only extend. */ if (elf->parent == NULL && (elf->maximum_size == ~((size_t) 0) || (size_t) size > elf->maximum_size) - && unlikely (ftruncate (elf->fildes, size) != 0)) + && unlikely (ftruncate (elf->fildes, size) != 0) + && unlikely (posix_fallocate (elf->fildes, 0, size) != 0)) { __libelf_seterrno (ELF_E_WRITE_ERROR); return -1; @@ -94,6 +106,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) size = -1; } + /* Reduce the file size if necessary. */ if (size != -1 && elf->parent == NULL && elf->maximum_size != ~((size_t) 0) @@ -124,9 +137,7 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) off_t -elf_update (elf, cmd) - Elf *elf; - Elf_Cmd cmd; +elf_update (Elf *elf, Elf_Cmd cmd) { size_t shnum; off_t size; diff --git a/libelf/elf_version.c b/libelf/elf_version.c index dcb67580..7c336ff9 100644 --- a/libelf/elf_version.c +++ b/libelf/elf_version.c @@ -1,5 +1,5 @@ /* Coordinate ELF library and application versions. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -42,8 +42,7 @@ unsigned int __libelf_version = EV_CURRENT; unsigned int -elf_version (version) - unsigned int version; +elf_version (unsigned int version) { if (version == EV_NONE) return __libelf_version; diff --git a/libelf/gelf_checksum.c b/libelf/gelf_checksum.c index 49067829..831c54cb 100644 --- a/libelf/gelf_checksum.c +++ b/libelf/gelf_checksum.c @@ -1,5 +1,5 @@ /* Convert from file to memory representation. Generic ELF version. - Copyright (C) 2002 Red Hat, Inc. + Copyright (C) 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -38,8 +38,7 @@ long int -gelf_checksum (elf) - Elf *elf; +gelf_checksum (Elf *elf) { if (elf == NULL) return -1l; diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c index a9d2288d..a124fa84 100644 --- a/libelf/gelf_fsize.c +++ b/libelf/gelf_fsize.c @@ -1,5 +1,5 @@ /* Return the size of an object file type. - Copyright (C) 1998-2010 Red Hat, Inc. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -79,11 +79,7 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] = size_t -gelf_fsize (elf, type, count, version) - Elf *elf; - Elf_Type type; - size_t count; - unsigned int version; +gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version) { /* We do not have differences between file and memory sizes. Better not since otherwise `mmap' would not work. */ diff --git a/libelf/gelf_getauxv.c b/libelf/gelf_getauxv.c index a2f04e7f..1591be2a 100644 --- a/libelf/gelf_getauxv.c +++ b/libelf/gelf_getauxv.c @@ -1,5 +1,5 @@ /* Get information from auxiliary vector at the given index. - Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -38,10 +38,7 @@ GElf_auxv_t * -gelf_getauxv (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_auxv_t *dst; +gelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; GElf_auxv_t *result = NULL; diff --git a/libelf/gelf_getclass.c b/libelf/gelf_getclass.c index 53759dc3..7d0924bd 100644 --- a/libelf/gelf_getclass.c +++ b/libelf/gelf_getclass.c @@ -1,5 +1,5 @@ /* Return the class of file associated with the descriptor. - Copyright (C) 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -38,8 +38,7 @@ int -gelf_getclass (elf) - Elf *elf; +gelf_getclass (Elf *elf) { return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class; } diff --git a/libelf/gelf_getdyn.c b/libelf/gelf_getdyn.c index c366fd5d..a0090e14 100644 --- a/libelf/gelf_getdyn.c +++ b/libelf/gelf_getdyn.c @@ -1,5 +1,5 @@ /* Get information from dynamic table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ GElf_Dyn * -gelf_getdyn (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Dyn *dst; +gelf_getdyn (Elf_Data *data, int ndx, GElf_Dyn *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; GElf_Dyn *result = NULL; diff --git a/libelf/gelf_getehdr.c b/libelf/gelf_getehdr.c index ea83fc04..abeb70c4 100644 --- a/libelf/gelf_getehdr.c +++ b/libelf/gelf_getehdr.c @@ -1,5 +1,5 @@ /* Get ELF header. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -40,9 +40,8 @@ GElf_Ehdr * -__gelf_getehdr_rdlock (elf, dest) - Elf *elf; - GElf_Ehdr *dest; +internal_function +__gelf_getehdr_rdlock (Elf *elf, GElf_Ehdr *dest) { GElf_Ehdr *result = NULL; @@ -95,9 +94,7 @@ __gelf_getehdr_rdlock (elf, dest) } GElf_Ehdr * -gelf_getehdr (elf, dest) - Elf *elf; - GElf_Ehdr *dest; +gelf_getehdr (Elf *elf, GElf_Ehdr *dest) { GElf_Ehdr *result; if (elf == NULL) diff --git a/libelf/gelf_getlib.c b/libelf/gelf_getlib.c index 880817e6..a8ac4785 100644 --- a/libelf/gelf_getlib.c +++ b/libelf/gelf_getlib.c @@ -1,5 +1,5 @@ /* Get library from table at the given index. - Copyright (C) 2004, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -39,10 +39,7 @@ GElf_Lib * -gelf_getlib (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Lib *dst; +gelf_getlib (Elf_Data *data, int ndx, GElf_Lib *dst) { if (data == NULL) return NULL; diff --git a/libelf/gelf_getmove.c b/libelf/gelf_getmove.c index b81d61f4..18efedcc 100644 --- a/libelf/gelf_getmove.c +++ b/libelf/gelf_getmove.c @@ -1,5 +1,5 @@ /* Get move structure at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ GElf_Move * -gelf_getmove (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Move *dst; +gelf_getmove (Elf_Data *data, int ndx, GElf_Move *dst) { GElf_Move *result = NULL; Elf *elf; diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c index 7dc82156..c75eddab 100644 --- a/libelf/gelf_getnote.c +++ b/libelf/gelf_getnote.c @@ -1,5 +1,5 @@ /* Get note information at the supplied offset. - Copyright (C) 2007, 2014 Red Hat, Inc. + Copyright (C) 2007, 2014, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -37,12 +37,8 @@ #include "libelfP.h" size_t -gelf_getnote (data, offset, result, name_offset, desc_offset) - Elf_Data *data; - size_t offset; - GElf_Nhdr *result; - size_t *name_offset; - size_t *desc_offset; +gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result, + size_t *name_offset, size_t *desc_offset) { if (data == NULL) return 0; diff --git a/libelf/gelf_getphdr.c b/libelf/gelf_getphdr.c index 3bf7123f..c719e4be 100644 --- a/libelf/gelf_getphdr.c +++ b/libelf/gelf_getphdr.c @@ -1,5 +1,5 @@ /* Return program header table entry. - Copyright (C) 1998-2010 Red Hat, Inc. + Copyright (C) 1998-2010, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -39,10 +39,7 @@ GElf_Phdr * -gelf_getphdr (elf, ndx, dst) - Elf *elf; - int ndx; - GElf_Phdr *dst; +gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst) { GElf_Phdr *result = NULL; @@ -80,10 +77,8 @@ gelf_getphdr (elf, ndx, dst) /* Test whether the index is ok. */ size_t phnum; - if (ndx >= elf->state.elf32.ehdr->e_phnum - && (elf->state.elf32.ehdr->e_phnum != PN_XNUM - || __elf_getphdrnum_rdlock (elf, &phnum) != 0 - || (size_t) ndx >= phnum)) + if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum) { __libelf_seterrno (ELF_E_INVALID_INDEX); goto out; @@ -122,10 +117,8 @@ gelf_getphdr (elf, ndx, dst) /* Test whether the index is ok. */ size_t phnum; - if (ndx >= elf->state.elf64.ehdr->e_phnum - && (elf->state.elf64.ehdr->e_phnum != PN_XNUM - || __elf_getphdrnum_rdlock (elf, &phnum) != 0 - || (size_t) ndx >= phnum)) + if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0 + || (size_t) ndx >= phnum) { __libelf_seterrno (ELF_E_INVALID_INDEX); goto out; diff --git a/libelf/gelf_getrel.c b/libelf/gelf_getrel.c index 1f786ff5..309e3d37 100644 --- a/libelf/gelf_getrel.c +++ b/libelf/gelf_getrel.c @@ -1,5 +1,5 @@ /* Get REL relocation information at given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -38,10 +38,7 @@ GElf_Rel * -gelf_getrel (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Rel *dst; +gelf_getrel (Elf_Data *data, int ndx, GElf_Rel *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_getrela.c b/libelf/gelf_getrela.c index cead7eee..d695f659 100644 --- a/libelf/gelf_getrela.c +++ b/libelf/gelf_getrela.c @@ -1,5 +1,5 @@ /* Get RELA relocation information at given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -38,10 +38,7 @@ GElf_Rela * -gelf_getrela (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Rela *dst; +gelf_getrela (Elf_Data *data, int ndx, GElf_Rela *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_getshdr.c b/libelf/gelf_getshdr.c index 4a48cb6c..3858c8e1 100644 --- a/libelf/gelf_getshdr.c +++ b/libelf/gelf_getshdr.c @@ -1,5 +1,5 @@ /* Return section header. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,9 +38,7 @@ GElf_Shdr * -gelf_getshdr (scn, dst) - Elf_Scn *scn; - GElf_Shdr *dst; +gelf_getshdr (Elf_Scn *scn, GElf_Shdr *dst) { GElf_Shdr *result = NULL; diff --git a/libelf/gelf_getsym.c b/libelf/gelf_getsym.c index a141c2d5..01534d2c 100644 --- a/libelf/gelf_getsym.c +++ b/libelf/gelf_getsym.c @@ -1,5 +1,5 @@ /* Get symbol information from symbol table at the given index. - Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Sym * -gelf_getsym (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Sym *dst; +gelf_getsym (Elf_Data *data, int ndx, GElf_Sym *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; GElf_Sym *result = NULL; diff --git a/libelf/gelf_getsyminfo.c b/libelf/gelf_getsyminfo.c index 8d7da7f2..8360ed38 100644 --- a/libelf/gelf_getsyminfo.c +++ b/libelf/gelf_getsyminfo.c @@ -1,5 +1,5 @@ /* Get additional symbol information from symbol table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ GElf_Syminfo * -gelf_getsyminfo (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Syminfo *dst; +gelf_getsyminfo (Elf_Data *data, int ndx, GElf_Syminfo *dst) { GElf_Syminfo *result = NULL; diff --git a/libelf/gelf_getsymshndx.c b/libelf/gelf_getsymshndx.c index c19e8761..17c90fc6 100644 --- a/libelf/gelf_getsymshndx.c +++ b/libelf/gelf_getsymshndx.c @@ -1,6 +1,6 @@ /* Get symbol information and separate section index from symbol table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -40,12 +40,8 @@ GElf_Sym * -gelf_getsymshndx (symdata, shndxdata, ndx, dst, dstshndx) - Elf_Data *symdata; - Elf_Data *shndxdata; - int ndx; - GElf_Sym *dst; - Elf32_Word *dstshndx; +gelf_getsymshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx, + GElf_Sym *dst, Elf32_Word *dstshndx) { Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; diff --git a/libelf/gelf_getverdaux.c b/libelf/gelf_getverdaux.c index d125d9ea..739a7657 100644 --- a/libelf/gelf_getverdaux.c +++ b/libelf/gelf_getverdaux.c @@ -1,5 +1,5 @@ /* Get additional symbol version definition information at the given offset. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Verdaux * -gelf_getverdaux (data, offset, dst) - Elf_Data *data; - int offset; - GElf_Verdaux *dst; +gelf_getverdaux (Elf_Data *data, int offset, GElf_Verdaux *dst) { GElf_Verdaux *result; diff --git a/libelf/gelf_getverdef.c b/libelf/gelf_getverdef.c index 59a32142..651f4fad 100644 --- a/libelf/gelf_getverdef.c +++ b/libelf/gelf_getverdef.c @@ -1,5 +1,5 @@ /* Get symbol version definition information at the given offset. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Verdef * -gelf_getverdef (data, offset, dst) - Elf_Data *data; - int offset; - GElf_Verdef *dst; +gelf_getverdef (Elf_Data *data, int offset, GElf_Verdef *dst) { GElf_Verdef *result; diff --git a/libelf/gelf_getvernaux.c b/libelf/gelf_getvernaux.c index 8ebf56ab..e47fb0a2 100644 --- a/libelf/gelf_getvernaux.c +++ b/libelf/gelf_getvernaux.c @@ -1,5 +1,5 @@ /* Get additional required symbol version information at the given offset. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Vernaux * -gelf_getvernaux (data, offset, dst) - Elf_Data *data; - int offset; - GElf_Vernaux *dst; +gelf_getvernaux (Elf_Data *data, int offset, GElf_Vernaux *dst) { GElf_Vernaux *result; diff --git a/libelf/gelf_getverneed.c b/libelf/gelf_getverneed.c index 95fd11fb..c1f5d340 100644 --- a/libelf/gelf_getverneed.c +++ b/libelf/gelf_getverneed.c @@ -1,5 +1,5 @@ /* Get required symbol version information at the given offset. - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Verneed * -gelf_getverneed (data, offset, dst) - Elf_Data *data; - int offset; - GElf_Verneed *dst; +gelf_getverneed (Elf_Data *data, int offset, GElf_Verneed *dst) { GElf_Verneed *result; diff --git a/libelf/gelf_getversym.c b/libelf/gelf_getversym.c index fe8dc62b..68d23c72 100644 --- a/libelf/gelf_getversym.c +++ b/libelf/gelf_getversym.c @@ -1,5 +1,5 @@ /* Get symbol version information at the given index. - Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -39,10 +39,7 @@ GElf_Versym * -gelf_getversym (data, ndx, dst) - Elf_Data *data; - int ndx; - GElf_Versym *dst; +gelf_getversym (Elf_Data *data, int ndx, GElf_Versym *dst) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_newehdr.c b/libelf/gelf_newehdr.c index e9f7a58f..cfa80e1b 100644 --- a/libelf/gelf_newehdr.c +++ b/libelf/gelf_newehdr.c @@ -1,5 +1,5 @@ /* Create new ELF header. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,9 +38,7 @@ unsigned long int -gelf_newehdr (elf, class) - Elf *elf; - int class; +gelf_newehdr (Elf *elf, int class) { return (class == ELFCLASS32 ? (unsigned long int) INTUSE(elf32_newehdr) (elf) diff --git a/libelf/gelf_newphdr.c b/libelf/gelf_newphdr.c index b6340377..4e95474e 100644 --- a/libelf/gelf_newphdr.c +++ b/libelf/gelf_newphdr.c @@ -1,5 +1,5 @@ /* Create new ELF program header. - Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -38,9 +38,7 @@ unsigned long int -gelf_newphdr (elf, phnum) - Elf *elf; - size_t phnum; +gelf_newphdr ( Elf *elf, size_t phnum) { return (elf->class == ELFCLASS32 ? (unsigned long int) INTUSE(elf32_newphdr) (elf, phnum) diff --git a/libelf/gelf_offscn.c b/libelf/gelf_offscn.c index 62d12e41..cf206f5b 100644 --- a/libelf/gelf_offscn.c +++ b/libelf/gelf_offscn.c @@ -1,5 +1,5 @@ /* Create new ELF header. - Copyright (C) 2005 Red Hat, Inc. + Copyright (C) 2005, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2005. @@ -38,9 +38,7 @@ Elf_Scn * -gelf_offscn (elf, offset) - Elf *elf; - GElf_Off offset; +gelf_offscn (Elf *elf, GElf_Off offset) { if (elf->class == ELFCLASS32) { diff --git a/libelf/gelf_update_auxv.c b/libelf/gelf_update_auxv.c index dd8f4726..e4e5229c 100644 --- a/libelf/gelf_update_auxv.c +++ b/libelf/gelf_update_auxv.c @@ -1,5 +1,5 @@ /* Update information in dynamic table at the given index. - Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2007, 2015 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -37,10 +37,7 @@ int -gelf_update_auxv (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_auxv_t *src; +gelf_update_auxv (Elf_Data *data, int ndx, GElf_auxv_t *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_update_dyn.c b/libelf/gelf_update_dyn.c index 2eb526ec..5c515d26 100644 --- a/libelf/gelf_update_dyn.c +++ b/libelf/gelf_update_dyn.c @@ -1,5 +1,5 @@ /* Update information in dynamic table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -38,10 +38,7 @@ int -gelf_update_dyn (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Dyn *src; +gelf_update_dyn (Elf_Data *data, int ndx, GElf_Dyn *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_update_lib.c b/libelf/gelf_update_lib.c index 1c8c23da..d0f235e8 100644 --- a/libelf/gelf_update_lib.c +++ b/libelf/gelf_update_lib.c @@ -1,5 +1,5 @@ /* Update library in table at the given index. - Copyright (C) 2004, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -39,10 +39,7 @@ int -gelf_update_lib (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Lib *src; +gelf_update_lib (Elf_Data *data, int ndx, GElf_Lib *src) { if (data == NULL) return 0; diff --git a/libelf/gelf_update_move.c b/libelf/gelf_update_move.c index ad2ca6ab..4190ee30 100644 --- a/libelf/gelf_update_move.c +++ b/libelf/gelf_update_move.c @@ -1,5 +1,5 @@ /* Update move structure at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ int -gelf_update_move (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Move *src; +gelf_update_move (Elf_Data *data, int ndx, GElf_Move *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_update_sym.c b/libelf/gelf_update_sym.c index 278129cf..0f478857 100644 --- a/libelf/gelf_update_sym.c +++ b/libelf/gelf_update_sym.c @@ -1,5 +1,5 @@ /* Update symbol information in symbol table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ int -gelf_update_sym (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Sym *src; +gelf_update_sym (Elf_Data *data, int ndx, GElf_Sym *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_update_syminfo.c b/libelf/gelf_update_syminfo.c index 640a1ed2..6f7f3025 100644 --- a/libelf/gelf_update_syminfo.c +++ b/libelf/gelf_update_syminfo.c @@ -1,5 +1,5 @@ /* Update additional symbol information in symbol table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -39,10 +39,7 @@ int -gelf_update_syminfo (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Syminfo *src; +gelf_update_syminfo (Elf_Data *data, int ndx, GElf_Syminfo *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; Elf_Scn *scn; diff --git a/libelf/gelf_update_symshndx.c b/libelf/gelf_update_symshndx.c index 5e2c7f70..eb80afac 100644 --- a/libelf/gelf_update_symshndx.c +++ b/libelf/gelf_update_symshndx.c @@ -1,6 +1,6 @@ /* Update symbol information and section index in symbol table at the given index. - Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -40,12 +40,8 @@ int -gelf_update_symshndx (symdata, shndxdata, ndx, src, srcshndx) - Elf_Data *symdata; - Elf_Data *shndxdata; - int ndx; - GElf_Sym *src; - Elf32_Word srcshndx; +gelf_update_symshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx, + GElf_Sym *src, Elf32_Word srcshndx) { Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata; Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata; diff --git a/libelf/gelf_update_verdaux.c b/libelf/gelf_update_verdaux.c index b377d40a..f3554fdc 100644 --- a/libelf/gelf_update_verdaux.c +++ b/libelf/gelf_update_verdaux.c @@ -1,5 +1,5 @@ /* Update additional symbol version definition information. - Copyright (C) 2001, 2002 Red Hat, Inc. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -39,10 +39,7 @@ int -gelf_update_verdaux (data, offset, src) - Elf_Data *data; - int offset; - GElf_Verdaux *src; +gelf_update_verdaux (Elf_Data *data, int offset, GElf_Verdaux *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_update_verdef.c b/libelf/gelf_update_verdef.c index d591a4f1..adb5db14 100644 --- a/libelf/gelf_update_verdef.c +++ b/libelf/gelf_update_verdef.c @@ -1,5 +1,5 @@ /* Update symbol version definition information. - Copyright (C) 2001, 2002 Red Hat, Inc. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -39,10 +39,7 @@ int -gelf_update_verdef (data, offset, src) - Elf_Data *data; - int offset; - GElf_Verdef *src; +gelf_update_verdef (Elf_Data *data, int offset, GElf_Verdef *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_update_vernaux.c b/libelf/gelf_update_vernaux.c index 1f691b0e..854afabb 100644 --- a/libelf/gelf_update_vernaux.c +++ b/libelf/gelf_update_vernaux.c @@ -1,5 +1,5 @@ /* Update additional required symbol version information. - Copyright (C) 2001, 2002 Red Hat, Inc. + Copyright (C) 2001, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -39,10 +39,7 @@ int -gelf_update_vernaux (data, offset, src) - Elf_Data *data; - int offset; - GElf_Vernaux *src; +gelf_update_vernaux (Elf_Data *data, int offset, GElf_Vernaux *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_update_verneed.c b/libelf/gelf_update_verneed.c index 713c0171..bf5af5a3 100644 --- a/libelf/gelf_update_verneed.c +++ b/libelf/gelf_update_verneed.c @@ -1,5 +1,5 @@ /* Update required symbol version information. - Copyright (C) 2001, 2002 Red Hat, Inc. + Copyright (C) 2001, 2002, 201r Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -39,10 +39,7 @@ int -gelf_update_verneed (data, offset, src) - Elf_Data *data; - int offset; - GElf_Verneed *src; +gelf_update_verneed (Elf_Data *data, int offset, GElf_Verneed *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_update_versym.c b/libelf/gelf_update_versym.c index 03a3c5a1..9949dffb 100644 --- a/libelf/gelf_update_versym.c +++ b/libelf/gelf_update_versym.c @@ -1,5 +1,5 @@ /* Update symbol version information. - Copyright (C) 2001, 2002, 2005, 2009, 2014 Red Hat, Inc. + Copyright (C) 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -39,10 +39,7 @@ int -gelf_update_versym (data, ndx, src) - Elf_Data *data; - int ndx; - GElf_Versym *src; +gelf_update_versym (Elf_Data *data, int ndx, GElf_Versym *src) { Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c index c417051a..c5805e73 100644 --- a/libelf/gelf_xlate.c +++ b/libelf/gelf_xlate.c @@ -1,5 +1,5 @@ /* Transformation functions for ELF data types. - Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007 Red Hat, Inc. + Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -52,7 +52,8 @@ static void (elf_cvt_Byte) (void *dest, const void *src, size_t n, int encode __attribute__ ((unused))) { - memmove (dest, src, n); + if (n != 0) + memmove (dest, src, n); } diff --git a/libelf/gelf_xlatetof.c b/libelf/gelf_xlatetof.c index 3366bdcd..e2661805 100644 --- a/libelf/gelf_xlatetof.c +++ b/libelf/gelf_xlatetof.c @@ -1,5 +1,5 @@ /* Convert from memory to file representation. Generic ELF version. - Copyright (C) 2000, 2002 Red Hat, Inc. + Copyright (C) 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -38,11 +38,8 @@ Elf_Data * -gelf_xlatetof (elf, dest, src, encode) - Elf *elf; - Elf_Data *dest; - const Elf_Data * src; - unsigned int encode; +gelf_xlatetof (Elf *elf, Elf_Data *dest, const Elf_Data * src, + unsigned int encode) { if (elf == NULL) return NULL; diff --git a/libelf/gelf_xlatetom.c b/libelf/gelf_xlatetom.c index c3e812f0..8499c711 100644 --- a/libelf/gelf_xlatetom.c +++ b/libelf/gelf_xlatetom.c @@ -1,5 +1,5 @@ /* Convert from file to memory representation. Generic ELF version. - Copyright (C) 2000, 2002 Red Hat, Inc. + Copyright (C) 2000, 2002, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -38,11 +38,8 @@ Elf_Data * -gelf_xlatetom (elf, dest, src, encode) - Elf *elf; - Elf_Data *dest; - const Elf_Data * src; - unsigned int encode; +gelf_xlatetom (Elf *elf, Elf_Data *dest, const Elf_Data * src, + unsigned int encode) { if (elf == NULL) return NULL; diff --git a/libelf/libelfP.h b/libelf/libelfP.h index 52cf7457..3f4d654b 100644 --- a/libelf/libelfP.h +++ b/libelf/libelfP.h @@ -511,6 +511,8 @@ extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset) attribute_hidden; extern int __elf_getphdrnum_rdlock (Elf *__elf, size_t *__dst) internal_function; +extern int __elf_getphdrnum_chk_rdlock (Elf *__elf, size_t *__dst) + internal_function; extern int __elf_getshdrnum_rdlock (Elf *__elf, size_t *__dst) internal_function; extern int __elf_getshdrstrndx_internal (Elf *__elf, size_t *__dst) @@ -530,6 +532,12 @@ extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data) internal_function; extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data) attribute_hidden; +/* Should be called to setup first section data element if + data_list_rear is NULL and we know data_read is set and there is + raw data available. Might upgrade the ELF lock from a read to a + write lock. If the lock is already a write lock set wrlocked. */ +extern void __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked) + internal_function; extern char *__elf_strptr_internal (Elf *__elf, size_t __index, size_t __offset) attribute_hidden; extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest, diff --git a/libelf/nlist.c b/libelf/nlist.c index 41e5ff64..c7b32fdb 100644 --- a/libelf/nlist.c +++ b/libelf/nlist.c @@ -1,5 +1,5 @@ /* Extract symbol list from binary. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -116,7 +116,11 @@ nlist (const char *filename, struct nlist *nl) /* Re-get the section header in case we found only the dynamic symbol table. */ if (scn == NULL) - shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem); + { + shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem); + if (unlikely (shdr == NULL)) + goto fail_close; + } /* SHDR->SH_LINK now contains the index of the string section. */ /* Get the data for the symbol section. */ @@ -126,7 +130,7 @@ nlist (const char *filename, struct nlist *nl) /* How many symbols are there? */ nsyms = (shdr->sh_size - / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, data->d_version)); + / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, EV_CURRENT)); /* Create the hash table. */ table = nlist_fshash_init (nsyms); diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h index 16eaa19c..9fe01c64 100644 --- a/libelf/version_xlate.h +++ b/libelf/version_xlate.h @@ -1,5 +1,5 @@ /* Conversion functions for versioning information. - Copyright (C) 1998, 1999, 2000, 2002, 2003 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 1998. @@ -55,6 +55,11 @@ elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode) if (len == 0) return; + /* Below we rely on the next field offsets to be correct, start by + copying over all data as is in case some data isn't translated. + We don't want to leave (undefined) garbage in the dest buffer. */ + memmove (dest, src, len); + do { size_t aux_offset; @@ -149,6 +154,11 @@ elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode) if (len == 0) return; + /* Below we rely on the next field offsets to be correct, start by + copying over all data as is in case some data isn't translated. + We don't want to leave (undefined) garbage in the dest buffer. */ + memmove (dest, src, len); + do { size_t aux_offset; |