summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2015-10-19 11:01:28 -0700
committerChih-Hung Hsieh <chh@google.com>2015-10-19 11:04:19 -0700
commitdc6526a51317dbaf812df26108da614703050770 (patch)
treef0e905a010727d290b5aa2498b7260922c65a6e0 /libelf
parent495820301403545dee86eadbc2198d63765d06a3 (diff)
parenta1e17a2551ddd1b2c4853e053dc1b254440211bd (diff)
downloadandroid_external_elfutils-dc6526a51317dbaf812df26108da614703050770.tar.gz
android_external_elfutils-dc6526a51317dbaf812df26108da614703050770.tar.bz2
android_external_elfutils-dc6526a51317dbaf812df26108da614703050770.zip
Merge upstream 'a1e17a2', version 0.164.
* git merge a1e17a2 * Android relevant upstream changes: version number changed to 0.164 handle ELF with merged strtab/shstrtab handle missing SHF_INFO_LINK section flags open64 -> open loff_t -> int64_t conditionally include <config.h> See all upstream changes since the previous merge: git diff 86ed7f7..a1e17a2 * Manual changes (of generated files) after git merge: * version.h: new version number 164. * config.h: new version number 0.164, still keep Android #if __LP64__ * libdw/known-dwarf.h: no change Change-Id: Ieb1bfed35e76ee3a641499897863679e6d4da096
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog14
-rw-r--r--libelf/elf_getdata_rawchunk.c2
-rw-r--r--libelf/elf_update.c36
-rw-r--r--libelf/libelf.h13
-rw-r--r--libelf/libelfP.h6
5 files changed, 48 insertions, 23 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 0b9ddf2b..d8651d75 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,17 @@
+2015-10-09 Josh Stone <jistone@redhat.com>
+
+ * libelf.h: Replace loff_t with int64_t throughout.
+
+2015-10-05 Mark Wielaard <mjw@redhat.com>
+
+ * elf_update.c (write_file): Only use posix_fallocate when using
+ mmap. Only report failure when errno is ENOSPC.
+
+2015-10-09 Josh Stone <jistone@redhat.com>
+
+ * libelfP.h (struct Elf): Replace off64_t with off_t.
+ * elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise.
+
2015-10-05 Chih-Hung Hsieh <chh@google.com>
* elf_getarsym.c (elf_getarsym): Do not use
diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
index 51b3e3e7..31b2fe7d 100644
--- a/libelf/elf_getdata_rawchunk.c
+++ b/libelf/elf_getdata_rawchunk.c
@@ -41,7 +41,7 @@
#include "common.h"
Elf_Data *
-elf_getdata_rawchunk (Elf *elf, off64_t offset, size_t size, Elf_Type type)
+elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
{
if (unlikely (elf == NULL))
return NULL;
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 00f7a010..c635eb32 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -57,22 +57,11 @@ 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.
-
- 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. */
+ new file. We truncate the file later in this case. */
if (elf->parent == NULL
&& (elf->maximum_size == ~((size_t) 0)
|| (size_t) size > elf->maximum_size)
- && unlikely (ftruncate (elf->fildes, size) != 0)
- && unlikely (posix_fallocate (elf->fildes, 0, size) != 0))
+ && unlikely (ftruncate (elf->fildes, size) != 0))
{
__libelf_seterrno (ELF_E_WRITE_ERROR);
return -1;
@@ -89,6 +78,27 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
if (elf->map_address != NULL)
{
+ /* When using mmap we want 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. In glibc posix_fallocate is required to extend the
+ file and allocate enough space even if the underlying
+ filesystem would normally return EOPNOTSUPP. But other
+ implementations might not work as expected. And the glibc
+ fallback case might fail (with unexpected errnos) in some cases.
+ So we only report an error when the call fails and errno is
+ ENOSPC. Otherwise we ignore the error and treat it as just hint. */
+ if (elf->parent == NULL
+ && (elf->maximum_size == ~((size_t) 0)
+ || (size_t) size > elf->maximum_size)
+ && unlikely (posix_fallocate (elf->fildes, 0, size) != 0))
+ if (errno == ENOSPC)
+ {
+ __libelf_seterrno (ELF_E_WRITE_ERROR);
+ return -1;
+ }
+
/* The file is mmaped. */
if ((class == ELFCLASS32
? __elf32_updatemmap (elf, change_bo, shnum)
diff --git a/libelf/libelf.h b/libelf/libelf.h
index 5a2b3af8..54f7c29b 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -29,6 +29,7 @@
#ifndef _LIBELF_H
#define _LIBELF_H 1
+#include <stdint.h>
#include <sys/types.h>
/* Get the ELF types. */
@@ -74,7 +75,7 @@ typedef struct
Elf_Type d_type; /* Type of this piece of data. */
unsigned int d_version; /* ELF version. */
size_t d_size; /* Size in bytes. */
- loff_t d_off; /* Offset into section. */
+ int64_t d_off; /* Offset into section. */
size_t d_align; /* Alignment in section. */
} Elf_Data;
@@ -136,7 +137,7 @@ typedef struct
uid_t ar_uid; /* User ID. */
gid_t ar_gid; /* Group ID. */
mode_t ar_mode; /* File mode. */
- loff_t ar_size; /* File size. */
+ int64_t ar_size; /* File size. */
char *ar_rawname; /* Original name of archive member. */
} Elf_Arhdr;
@@ -177,13 +178,13 @@ extern Elf_Cmd elf_next (Elf *__elf);
extern int elf_end (Elf *__elf);
/* Update ELF descriptor and write file to disk. */
-extern loff_t elf_update (Elf *__elf, Elf_Cmd __cmd);
+extern int64_t elf_update (Elf *__elf, Elf_Cmd __cmd);
/* Determine what kind of file is associated with ELF. */
extern Elf_Kind elf_kind (Elf *__elf) __attribute__ ((__pure__));
/* Get the base offset for an object file. */
-extern loff_t elf_getbase (Elf *__elf);
+extern int64_t elf_getbase (Elf *__elf);
/* Retrieve file identification data. */
@@ -301,7 +302,7 @@ extern Elf_Data *elf_newdata (Elf_Scn *__scn);
would be for TYPE. The resulting Elf_Data pointer is valid until
elf_end (ELF) is called. */
extern Elf_Data *elf_getdata_rawchunk (Elf *__elf,
- loff_t __offset, size_t __size,
+ int64_t __offset, size_t __size,
Elf_Type __type);
@@ -313,7 +314,7 @@ extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset);
extern Elf_Arhdr *elf_getarhdr (Elf *__elf);
/* Return offset in archive for current file ELF. */
-extern loff_t elf_getaroff (Elf *__elf);
+extern int64_t elf_getaroff (Elf *__elf);
/* Select archive element at OFFSET. */
extern size_t elf_rand (Elf *__elf, size_t __offset);
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 3f4d654b..993c6556 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -316,7 +316,7 @@ struct Elf
int ehdr_flags; /* Flags (dirty) for ELF header. */
int phdr_flags; /* Flags (dirty|malloc) for program header. */
int shdr_malloced; /* Nonzero if shdr array was allocated. */
- off64_t sizestr_offset; /* Offset of the size string in the parent
+ off_t sizestr_offset; /* Offset of the size string in the parent
if this is an archive member. */
} elf;
@@ -335,7 +335,7 @@ struct Elf
int ehdr_flags; /* Flags (dirty) for ELF header. */
int phdr_flags; /* Flags (dirty|malloc) for program header. */
int shdr_malloced; /* Nonzero if shdr array was allocated. */
- off64_t sizestr_offset; /* Offset of the size string in the parent
+ off_t sizestr_offset; /* Offset of the size string in the parent
if this is an archive member. */
Elf32_Ehdr ehdr_mem; /* Memory used for ELF header when not
mmaped. */
@@ -360,7 +360,7 @@ struct Elf
int ehdr_flags; /* Flags (dirty) for ELF header. */
int phdr_flags; /* Flags (dirty|malloc) for program header. */
int shdr_malloced; /* Nonzero if shdr array was allocated. */
- off64_t sizestr_offset; /* Offset of the size string in the parent
+ off_t sizestr_offset; /* Offset of the size string in the parent
if this is an archive member. */
Elf64_Ehdr ehdr_mem; /* Memory used for ELF header when not
mmaped. */