summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2015-09-29 13:47:38 -0700
committerChih-Hung Hsieh <chh@google.com>2015-09-29 14:35:52 -0700
commitb67d33c44ca7c0d8709b9d729fb238f51008c50c (patch)
treead9113b82797fac924a0e474bcd6669dba47fcb8 /libelf
parent56e6b652fa71abee20fe70c83829928df57d40b2 (diff)
parentd8698e55cbe95e56c3a4cbd67c320048ea4f087a (diff)
downloadandroid_external_elfutils-b67d33c44ca7c0d8709b9d729fb238f51008c50c.tar.gz
android_external_elfutils-b67d33c44ca7c0d8709b9d729fb238f51008c50c.tar.bz2
android_external_elfutils-b67d33c44ca7c0d8709b9d729fb238f51008c50c.zip
Merge in latest aosp/upstream-master d8698e55.
git merge d8698e55cbe95e56c3a4cbd67c320048ea4f087a Include upstream changes up to Wed Sep 23 20:44:06 2015. Update generated files: ./config.h ./libdw/known-dwarf.h ./version.h Change-Id: Ica2510edda846659a0c89703aeafe85bd62abab8
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog190
-rw-r--r--libelf/dl-hash.h75
-rw-r--r--libelf/elf.h190
-rw-r--r--libelf/elf32_checksum.c5
-rw-r--r--libelf/elf32_fsize.c7
-rw-r--r--libelf/elf32_getehdr.c13
-rw-r--r--libelf/elf32_getphdr.c26
-rw-r--r--libelf/elf32_getshdr.c31
-rw-r--r--libelf/elf32_newehdr.c5
-rw-r--r--libelf/elf32_newphdr.c18
-rw-r--r--libelf/elf32_offscn.c6
-rw-r--r--libelf/elf32_updatefile.c74
-rw-r--r--libelf/elf32_updatenull.c22
-rw-r--r--libelf/elf32_xlatetof.c8
-rw-r--r--libelf/elf32_xlatetom.c8
-rw-r--r--libelf/elf_begin.c172
-rw-r--r--libelf/elf_cntl.c6
-rw-r--r--libelf/elf_end.c5
-rw-r--r--libelf/elf_error.c9
-rw-r--r--libelf/elf_fill.c5
-rw-r--r--libelf/elf_flagdata.c7
-rw-r--r--libelf/elf_flagehdr.c7
-rw-r--r--libelf/elf_flagelf.c7
-rw-r--r--libelf/elf_flagphdr.c7
-rw-r--r--libelf/elf_flagscn.c7
-rw-r--r--libelf/elf_flagshdr.c7
-rw-r--r--libelf/elf_getarhdr.c5
-rw-r--r--libelf/elf_getaroff.c5
-rw-r--r--libelf/elf_getarsym.c28
-rw-r--r--libelf/elf_getbase.c5
-rw-r--r--libelf/elf_getdata.c133
-rw-r--r--libelf/elf_getdata_rawchunk.c28
-rw-r--r--libelf/elf_getident.c6
-rw-r--r--libelf/elf_getphdrnum.c54
-rw-r--r--libelf/elf_getscn.c6
-rw-r--r--libelf/elf_getshdrnum.c11
-rw-r--r--libelf/elf_getshdrstrndx.c6
-rw-r--r--libelf/elf_gnu_hash.c5
-rw-r--r--libelf/elf_hash.c5
-rw-r--r--libelf/elf_kind.c5
-rw-r--r--libelf/elf_memory.c6
-rw-r--r--libelf/elf_ndxscn.c5
-rw-r--r--libelf/elf_newdata.c39
-rw-r--r--libelf/elf_newscn.c5
-rw-r--r--libelf/elf_next.c5
-rw-r--r--libelf/elf_nextscn.c6
-rw-r--r--libelf/elf_rand.c6
-rw-r--r--libelf/elf_rawdata.c6
-rw-r--r--libelf/elf_rawfile.c6
-rw-r--r--libelf/elf_readall.c6
-rw-r--r--libelf/elf_strptr.c56
-rw-r--r--libelf/elf_update.c23
-rw-r--r--libelf/elf_version.c5
-rw-r--r--libelf/gelf_checksum.c5
-rw-r--r--libelf/gelf_fsize.c8
-rw-r--r--libelf/gelf_getauxv.c7
-rw-r--r--libelf/gelf_getclass.c5
-rw-r--r--libelf/gelf_getdyn.c7
-rw-r--r--libelf/gelf_getehdr.c11
-rw-r--r--libelf/gelf_getlib.c7
-rw-r--r--libelf/gelf_getmove.c7
-rw-r--r--libelf/gelf_getnote.c10
-rw-r--r--libelf/gelf_getphdr.c19
-rw-r--r--libelf/gelf_getrel.c7
-rw-r--r--libelf/gelf_getrela.c7
-rw-r--r--libelf/gelf_getshdr.c6
-rw-r--r--libelf/gelf_getsym.c7
-rw-r--r--libelf/gelf_getsyminfo.c7
-rw-r--r--libelf/gelf_getsymshndx.c10
-rw-r--r--libelf/gelf_getverdaux.c7
-rw-r--r--libelf/gelf_getverdef.c7
-rw-r--r--libelf/gelf_getvernaux.c7
-rw-r--r--libelf/gelf_getverneed.c7
-rw-r--r--libelf/gelf_getversym.c7
-rw-r--r--libelf/gelf_newehdr.c6
-rw-r--r--libelf/gelf_newphdr.c6
-rw-r--r--libelf/gelf_offscn.c6
-rw-r--r--libelf/gelf_update_auxv.c7
-rw-r--r--libelf/gelf_update_dyn.c7
-rw-r--r--libelf/gelf_update_lib.c7
-rw-r--r--libelf/gelf_update_move.c7
-rw-r--r--libelf/gelf_update_sym.c7
-rw-r--r--libelf/gelf_update_syminfo.c7
-rw-r--r--libelf/gelf_update_symshndx.c10
-rw-r--r--libelf/gelf_update_verdaux.c7
-rw-r--r--libelf/gelf_update_verdef.c7
-rw-r--r--libelf/gelf_update_vernaux.c7
-rw-r--r--libelf/gelf_update_verneed.c7
-rw-r--r--libelf/gelf_update_versym.c7
-rw-r--r--libelf/gelf_xlate.c5
-rw-r--r--libelf/gelf_xlatetof.c9
-rw-r--r--libelf/gelf_xlatetom.c9
-rw-r--r--libelf/libelfP.h8
-rw-r--r--libelf/nlist.c10
-rw-r--r--libelf/version_xlate.h12
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;