diff options
| author | Ulf Hermann <[email protected]> | 2018-10-11 17:20:12 +0200 |
|---|---|---|
| committer | Ulf Hermann <[email protected]> | 2018-10-11 17:54:03 +0200 |
| commit | 5da108a40dd24c7d3e4183ec9ae1904bb3f01575 (patch) | |
| tree | b3aacdcce39ec53a581137229e4a30ccb235f09d /libelf | |
| parent | c8dd3e3985dce3ae94bb09d6df82a516852e78c4 (diff) | |
| parent | 52b6b2f1f49e7385527e9f311f248092be0c0b61 (diff) | |
Merge tag 'elfutils-0.174'
elfutils 0.174 release
Change-Id: Ibcbdfca61cf0b65391ab6d0ad00f18ba61027e07
Diffstat (limited to 'libelf')
| -rw-r--r-- | libelf/ChangeLog | 24 | ||||
| -rw-r--r-- | libelf/elf32_updatefile.c | 12 | ||||
| -rw-r--r-- | libelf/elf_compress_gnu.c | 4 | ||||
| -rw-r--r-- | libelf/elf_getscn.c | 33 | ||||
| -rw-r--r-- | libelf/elf_update.c | 32 | ||||
| -rw-r--r-- | libelf/libelf.h | 13 |
6 files changed, 100 insertions, 18 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index bc9ea954..5c3c0b27 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -21,6 +21,30 @@ * Makefile.am: Link libelf agaist libgnu.a if requested. +2018-09-13 Mark Wielaard <[email protected]> + + * elf32_updatefile.c (updatemmap): Use shnum, not ehdr->e_shnum. + * elf_getscn.c (elf_getscn): Create section zero if it is requested, + but doesn't exist yet. + +2018-09-12 Mark Wielaard <[email protected]> + + * elf32_updatefile.c (updatemmap): Use memmove, not memcpy. + * elf_update.c (write_file): Try to mremap if file needs to be + extended. + +2018-08-18 Mark Wielaard <[email protected]> + + * libelf.h (elf_compress_gnu): Add documentation about + interaction between SHF_COMPRESED and elf_compress_gnu. + * elf_compress_gnu.c (elf_compress_gnu): Return error if section + sh_flags has SHF_COMPRESSED set. + +2018-07-27 Mark Wielaard <[email protected]> + + * libelf.h (elf_getshdrstrndx): Fix documentation. + (elf_getshstrndx): Likewise. + 2018-06-19 Mark Wielaard <[email protected]> * libelfP.h (__libelf_type_align): Remove !ALLOW_UNALIGNED guard. diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index 7ac99510..f2e9a288 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -203,7 +203,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1); } else - memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff, + memmove (elf->map_address + elf->start_offset + ehdr->e_phoff, elf->state.ELFW(elf,LIBELFBITS).phdr, sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); @@ -236,7 +236,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) } 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; + char *const shdr_end = shdr_start + shnum * ehdr->e_shentsize; #if EV_NUM != 2 xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]; @@ -371,9 +371,11 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) last_position += dl->data.d.d_size; } else if (dl->data.d.d_size != 0) - last_position = mempcpy (last_position, - dl->data.d.d_buf, - dl->data.d.d_size); + { + memmove (last_position, dl->data.d.d_buf, + dl->data.d.d_size); + last_position += dl->data.d.d_size; + } scn_changed = true; } diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c index c35dc395..dfa7c571 100644 --- a/libelf/elf_compress_gnu.c +++ b/libelf/elf_compress_gnu.c @@ -80,7 +80,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) sh_addralign = shdr->sh_addralign; } - if ((sh_flags & SHF_ALLOC) != 0) + /* Allocated sections, or sections that are already are compressed + cannot (also) be GNU compressed. */ + if ((sh_flags & SHF_ALLOC) != 0 || (sh_flags & SHF_COMPRESSED)) { __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS); return -1; diff --git a/libelf/elf_getscn.c b/libelf/elf_getscn.c index 9f7213b4..e1fbaaaa 100644 --- a/libelf/elf_getscn.c +++ b/libelf/elf_getscn.c @@ -59,6 +59,38 @@ elf_getscn (Elf *elf, size_t idx) || (offsetof (struct Elf, state.elf32.scns) == offsetof (struct Elf, state.elf64.scns)) ? &elf->state.elf32.scns : &elf->state.elf64.scns); + + /* Section zero is special. It always exists even if there is no + "first" section. And it is needed to store "overflow" values + from the Elf header. */ + if (idx == 0 && runp->cnt == 0 && runp->max > 0) + { + Elf_Scn *scn0 = &runp->data[0]; + if (elf->class == ELFCLASS32) + { + scn0->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr)); + if (scn0->shdr.e32 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + else + { + scn0->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr)); + if (scn0->shdr.e64 == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + goto out; + } + } + scn0->elf = elf; + scn0->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; + scn0->list = elf->state.elf.scns_last; + scn0->data_read = 1; + runp->cnt = 1; + } + while (1) { if (idx < runp->max) @@ -80,6 +112,7 @@ elf_getscn (Elf *elf, size_t idx) } } + out: rwlock_unlock (elf->lock); return result; diff --git a/libelf/elf_update.c b/libelf/elf_update.c index b6014cdb..4ed899ff 100644 --- a/libelf/elf_update.c +++ b/libelf/elf_update.c @@ -80,7 +80,6 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) if (elf->map_address != NULL) { -#if HAVE_DECL_POSIX_FALLOCATE /* 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 @@ -94,15 +93,32 @@ write_file (Elf *elf, off_t size, int change_bo, size_t shnum) 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; - } + || (size_t) size > elf->maximum_size)) + { +#if HAVE_DECL_POSIX_FALLOCATE + if (unlikely (posix_fallocate (elf->fildes, 0, size) != 0)) + if (errno == ENOSPC) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } #endif + /* Extend the mmap address if needed. */ + if (elf->cmd == ELF_C_RDWR_MMAP + && (size_t) size > elf->maximum_size) + { + if (mremap (elf->map_address, elf->maximum_size, + size, 0) == MAP_FAILED) + { + __libelf_seterrno (ELF_E_WRITE_ERROR); + return -1; + } + elf->maximum_size = size; + } + + } + /* The file is mmaped. */ if ((class == ELFCLASS32 ? __elf32_updatemmap (elf, change_bo, shnum) diff --git a/libelf/libelf.h b/libelf/libelf.h index 547c0f50..d11358cc 100644 --- a/libelf/libelf.h +++ b/libelf/libelf.h @@ -310,13 +310,13 @@ extern int elf_getshnum (Elf *__elf, size_t *__dst) /* Get the section index of the section header string table in the ELF - file. If the index cannot be represented in the e_shnum field of + file. If the index cannot be represented in the e_shstrndx field of the ELF header the information from the sh_link field in the zeroth section header is used. */ extern int elf_getshdrstrndx (Elf *__elf, size_t *__dst); -/* Sun messed up the implementation of 'elf_getshnum' in their implementation. - It was agreed to make the same functionality available under a different - name and obsolete the old name. */ +/* Sun messed up the implementation of 'elf_getshstrndx' in their + implementation. It was agreed to make the same functionality available + under a different name and obsolete the old name. */ extern int elf_getshstrndx (Elf *__elf, size_t *__dst) __deprecated_attribute__; @@ -366,6 +366,11 @@ extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn); It is an error to request compression for a section that already has SHF_COMPRESSED set, or (for elf_compress) to request decompression for an section that doesn't have SHF_COMPRESSED set. + If a section has SHF_COMPRESSED set then calling elf_compress_gnu + will result in an error. The section has to be decompressed first + using elf_compress. Calling elf_compress on a section compressed + with elf_compress_gnu is fine, but probably useless. + It is always an error to call these functions on SHT_NOBITS sections or if the section has the SHF_ALLOC flag set. elf_compress_gnu will not check whether the section name starts |
