- Fix libelf regression.
This commit is contained in:
parent
28fe4de80f
commit
169e650811
236
elfutils-0.138-libelf-padding-fix.patch
Normal file
236
elfutils-0.138-libelf-padding-fix.patch
Normal file
@ -0,0 +1,236 @@
|
||||
commit ed9d3bc176b3f0318551d9214b1cec4e49197842
|
||||
Author: Roland McGrath <roland@redhat.com>
|
||||
Date: Thu Jan 1 21:22:18 2009 -0800
|
||||
|
||||
Fill gaps and update bookkeeping between all sections, not only before a dirty one.
|
||||
---
|
||||
libelf/ChangeLog | 7 ++
|
||||
libelf/elf32_updatefile.c | 142 +++++++++++++++++++++++++++------------------
|
||||
2 files changed, 93 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
|
||||
index 9578f8b..bb487b1 100644
|
||||
--- a/libelf/ChangeLog
|
||||
+++ b/libelf/ChangeLog
|
||||
@@ -1,3 +1,10 @@
|
||||
+2009-01-01 Roland McGrath <roland@redhat.com>
|
||||
+
|
||||
+ * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)):
|
||||
+ Fill gaps and update bookkeeping between all sections,
|
||||
+ not only before a dirty one.
|
||||
+ (__elfw2(LIBELFBITS,updatefile)): Likewise.
|
||||
+
|
||||
2008-12-11 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle
|
||||
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
|
||||
index e88f4a4..4e170cb 100644
|
||||
--- a/libelf/elf32_updatefile.c
|
||||
+++ b/libelf/elf32_updatefile.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Write changed data structures.
|
||||
- Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||
+ Copyright (C) 2000,2001,2002,2004,2005,2006,2007,2008,2009 Red Hat, Inc.
|
||||
This file is part of Red Hat elfutils.
|
||||
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
|
||||
|
||||
@@ -127,7 +127,6 @@ internal_function
|
||||
__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
|
||||
{
|
||||
ElfW2(LIBELFBITS,Ehdr) *ehdr;
|
||||
- char *last_position;
|
||||
|
||||
/* We need the ELF header several times. */
|
||||
ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
|
||||
@@ -204,10 +203,11 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
|
||||
|
||||
/* From now on we have to keep track of the last position to eventually
|
||||
fill the gaps with the prescribed fill byte. */
|
||||
- last_position = ((char *) elf->map_address + elf->start_offset
|
||||
- + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
|
||||
- ehdr->e_phoff)
|
||||
- + elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum));
|
||||
+ char *last_position = ((char *) elf->map_address + elf->start_offset
|
||||
+ + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
|
||||
+ ehdr->e_phoff)
|
||||
+ + elf_typesize (LIBELFBITS,
|
||||
+ ELF_T_PHDR, ehdr->e_phnum));
|
||||
|
||||
/* Write all the sections. Well, only those which are modified. */
|
||||
if (shnum > 0)
|
||||
@@ -278,6 +278,35 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Prepare to write at START, and then update LAST_POSITION.
|
||||
+ If LAST_POSITION was before START, fill in the gap. */
|
||||
+ inline void prepare_position (char *start)
|
||||
+ {
|
||||
+ if (start > last_position)
|
||||
+ {
|
||||
+ /* This code assumes that the data blocks for
|
||||
+ a section are ordered by offset. */
|
||||
+ size_t written = 0;
|
||||
+
|
||||
+ if (last_position < shdr_start)
|
||||
+ {
|
||||
+ written = MIN (start - last_position,
|
||||
+ shdr_start - last_position);
|
||||
+
|
||||
+ memset (last_position, __libelf_fill_byte, written);
|
||||
+ }
|
||||
+
|
||||
+ if (last_position + written != start && shdr_end < start)
|
||||
+ memset (shdr_end, __libelf_fill_byte, start - shdr_end);
|
||||
+ }
|
||||
+
|
||||
+ /* Let it go backward if the sections use a bogus layout with
|
||||
+ overlaps. We'll overwrite the stupid user's section data
|
||||
+ with the latest one, rather than crashing. */
|
||||
+
|
||||
+ last_position = start;
|
||||
+ }
|
||||
+
|
||||
/* Iterate over all the section in the order in which they
|
||||
appear in the output file. */
|
||||
for (size_t cnt = 0; cnt < shnum; ++cnt)
|
||||
@@ -298,38 +327,10 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
|
||||
assert (dl->data.d.d_size <= (shdr->sh_size
|
||||
- (GElf_Off) dl->data.d.d_off));
|
||||
|
||||
+ prepare_position (scn_start + dl->data.d.d_off);
|
||||
+
|
||||
if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
|
||||
{
|
||||
- if (scn_start + dl->data.d.d_off > last_position)
|
||||
- {
|
||||
- /* This code assumes that the data blocks for
|
||||
- a section are ordered by offset. */
|
||||
- size_t written = 0;
|
||||
-
|
||||
- if (last_position < shdr_start)
|
||||
- {
|
||||
- written = MIN (scn_start + dl->data.d.d_off
|
||||
- - last_position,
|
||||
- shdr_start - last_position);
|
||||
-
|
||||
- memset (last_position, __libelf_fill_byte,
|
||||
- written);
|
||||
- }
|
||||
-
|
||||
- if (last_position + written
|
||||
- != scn_start + dl->data.d.d_off
|
||||
- && shdr_end < scn_start + dl->data.d.d_off)
|
||||
- memset (shdr_end, __libelf_fill_byte,
|
||||
- scn_start + dl->data.d.d_off - shdr_end);
|
||||
- }
|
||||
-
|
||||
- /* Let it go backward if the sections use a bogus
|
||||
- layout with overlaps. We'll overwrite the stupid
|
||||
- user's section data with the latest one, rather than
|
||||
- crashing. */
|
||||
-
|
||||
- last_position = scn_start + dl->data.d.d_off;
|
||||
-
|
||||
if (unlikely (change_bo))
|
||||
{
|
||||
#if EV_NUM != 2
|
||||
@@ -362,9 +363,19 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
|
||||
dl = dl->next;
|
||||
}
|
||||
while (dl != NULL);
|
||||
- else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
|
||||
- /* We have to trust the existing section header information. */
|
||||
- last_position += shdr->sh_size;
|
||||
+ else if (shdr->sh_type != SHT_NOBITS && scn->index != 0
|
||||
+ && shdr->sh_size != 0)
|
||||
+ {
|
||||
+ /* We have to trust the existing section header information.
|
||||
+
|
||||
+ If there are any contents at all, we must be sure we've
|
||||
+ filled in any gap before them, even if it turns out we
|
||||
+ aren't touching the contents after the gap. */
|
||||
+
|
||||
+ prepare_position (scn_start);
|
||||
+
|
||||
+ last_position += shdr->sh_size;
|
||||
+ }
|
||||
|
||||
scn->flags &= ~ELF_F_DIRTY;
|
||||
}
|
||||
@@ -622,31 +633,39 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
|
||||
off_t scn_start = elf->start_offset + shdr->sh_offset;
|
||||
Elf_Data_List *dl = &scn->data_list;
|
||||
|
||||
+ /* Prepare to write at START, and then update LAST_OFFSET.
|
||||
+ If LAST_OFFSET was before START, fill in the gap. */
|
||||
+ inline bool prepare_offset (off_t start)
|
||||
+ {
|
||||
+ if (start > last_offset)
|
||||
+ {
|
||||
+ if (unlikely (fill (elf->fildes, last_offset,
|
||||
+ start - last_offset, fillbuf,
|
||||
+ &filled) != 0))
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /* Let it go backward if the sections use a bogus layout with
|
||||
+ overlaps. We'll overwrite the stupid user's section data
|
||||
+ with the latest one, rather than crashing. */
|
||||
+
|
||||
+ last_offset = start;
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (shdr->sh_type != SHT_NOBITS && scn->data_list_rear != NULL
|
||||
&& scn->index != 0)
|
||||
do
|
||||
{
|
||||
+ if (unlikely (prepare_offset (scn_start + dl->data.d.d_off)))
|
||||
+ return 1;
|
||||
+
|
||||
if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
|
||||
{
|
||||
char tmpbuf[MAX_TMPBUF];
|
||||
void *buf = dl->data.d.d_buf;
|
||||
|
||||
- if (scn_start + dl->data.d.d_off > last_offset)
|
||||
- {
|
||||
- if (unlikely (fill (elf->fildes, last_offset,
|
||||
- (scn_start + dl->data.d.d_off)
|
||||
- - last_offset, fillbuf,
|
||||
- &filled) != 0))
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- /* Let it go backward if the sections use a bogus
|
||||
- layout with overlaps. We'll overwrite the stupid
|
||||
- user's section data with the latest one, rather than
|
||||
- crashing. */
|
||||
-
|
||||
- last_offset = scn_start + dl->data.d.d_off;
|
||||
-
|
||||
if (unlikely (change_bo))
|
||||
{
|
||||
#if EV_NUM != 2
|
||||
@@ -696,7 +715,18 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
|
||||
}
|
||||
while (dl != NULL);
|
||||
else if (shdr->sh_type != SHT_NOBITS && scn->index != 0)
|
||||
- last_offset = scn_start + shdr->sh_size;
|
||||
+ {
|
||||
+ /* We have to trust the existing section header information.
|
||||
+
|
||||
+ If there are any contents at all, we must be sure we've
|
||||
+ filled in any gap before them, even if it turns out we
|
||||
+ aren't touching the contents after the gap. */
|
||||
+
|
||||
+ if (shdr->sh_size != 0 && unlikely (prepare_offset (scn_start)))
|
||||
+ return 1;
|
||||
+
|
||||
+ last_offset = scn_start + shdr->sh_size;
|
||||
+ }
|
||||
|
||||
/* Collect the section header table information. */
|
||||
if (unlikely (change_bo))
|
@ -1,5 +1,5 @@
|
||||
%define eu_version 0.138
|
||||
%define eu_release 1
|
||||
%define eu_release 2
|
||||
|
||||
%if %{?_with_compat:1}%{!?_with_compat:0}
|
||||
%define compat 1
|
||||
@ -38,6 +38,8 @@ Patch2: elfutils-robustify.patch
|
||||
Requires: elfutils-libelf-%{_arch} = %{version}-%{release}
|
||||
Requires: elfutils-libs-%{_arch} = %{version}-%{release}
|
||||
|
||||
Patch3: elfutils-0.138-libelf-padding-fix.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: bison >= 1.875
|
||||
BuildRequires: flex >= 2.5.4a
|
||||
@ -156,6 +158,8 @@ find . \( -name configure -o -name config.h.in \) -print | xargs touch
|
||||
|
||||
%patch2 -p1 -b .robustify
|
||||
|
||||
%patch3 -p1 -b .fixes
|
||||
|
||||
find . -name \*.sh ! -perm -0100 -print | xargs chmod +x
|
||||
|
||||
%build
|
||||
@ -263,6 +267,9 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%{_libdir}/libelf.a
|
||||
|
||||
%changelog
|
||||
* Thu Jan 1 2009 Roland McGrath <roland@redhat.com> - 0.138-2
|
||||
- Fix libelf regression.
|
||||
|
||||
* Wed Dec 31 2008 Roland McGrath <roland@redhat.com> - 0.138-1
|
||||
- Update to 0.138
|
||||
- Install <elfutils/version.h> header file for applications to use in
|
||||
|
Loading…
Reference in New Issue
Block a user