diff --git a/elfutils-0.138-libelf-padding-fix.patch b/elfutils-0.138-libelf-padding-fix.patch new file mode 100644 index 0000000..fcd505d --- /dev/null +++ b/elfutils-0.138-libelf-padding-fix.patch @@ -0,0 +1,236 @@ +commit ed9d3bc176b3f0318551d9214b1cec4e49197842 +Author: Roland McGrath +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 ++ ++ * 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 + + * 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 , 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)) diff --git a/elfutils.spec b/elfutils.spec index de61463..5fc169e 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -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 - 0.138-2 +- Fix libelf regression. + * Wed Dec 31 2008 Roland McGrath - 0.138-1 - Update to 0.138 - Install header file for applications to use in