Check whether a section was gnu compressed and decompress it first before trying to resolve relocations. Recompress it afterwards.
This found a bug in elf_compress_gnu which would use the "raw" file contents even if the user had just created the section (copying over the section from the original input file). Add compressed ET_REL tests to run-strip-reloc.sh testcase. Signed-off-by: Mark Wielaard <m...@klomp.org> --- libelf/ChangeLog | 4 ++++ libelf/elf_compress_gnu.c | 7 ++++--- src/ChangeLog | 5 +++++ src/strip.c | 29 +++++++++++++++++++++++------ tests/ChangeLog | 5 +++++ tests/run-strip-reloc.sh | 6 ++++++ 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 53da9a6..30760bf 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,5 +1,9 @@ 2018-11-09 Mark Wielaard <m...@klomp.org> + * elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata. + +2018-11-09 Mark Wielaard <m...@klomp.org> + * elf_compress.c (__libelf_reset_rawdata): Make rawdata change explicit by calling __libelf_set_data_list. * elf_getdata.c (convert_data): Don't convert if type is ELF_T_BYTE diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c index 198dc7d..1ecd6a0 100644 --- a/libelf/elf_compress_gnu.c +++ b/libelf/elf_compress_gnu.c @@ -144,9 +144,10 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) else if (inflate == 0) { /* In theory the user could have constucted a compressed section - by hand. But we always just take the rawdata directly and - decompress that. */ - Elf_Data *data = elf_rawdata (scn, NULL); + by hand. And in practice they do. For example when copying + a section from one file to another using elf_newdata. So we + have to use elf_getdata (not elf_rawdata). */ + Elf_Data *data = elf_getdata (scn, NULL); if (data == NULL) return -1; diff --git a/src/ChangeLog b/src/ChangeLog index 79e6872..e8b7ad8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-11-09 Mark Wielaard <m...@klomp.org> + + * strip.c (remove_debug_relocations): Check if section is gnu + compressed and decompress and recompress it. + 2018-10-26 Mark Wielaard <m...@klomp.org> * strip.c (OPT_RELOC_DEBUG_ONLY): New define. diff --git a/src/strip.c b/src/strip.c index e953c4d..1518073 100644 --- a/src/strip.c +++ b/src/strip.c @@ -485,12 +485,22 @@ remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr, (and recompress if necessary at the end). */ GElf_Chdr tchdr; int tcompress_type = 0; - if (gelf_getchdr (tscn, &tchdr) != NULL) + bool is_gnu_compressed = false; + if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0) { - tcompress_type = tchdr.ch_type; - if (elf_compress (tscn, 0, 0) != 1) + is_gnu_compressed = true; + if (elf_compress_gnu (tscn, 0, 0) != 1) INTERNAL_ERROR (fname); } + else + { + if (gelf_getchdr (tscn, &tchdr) != NULL) + { + tcompress_type = tchdr.ch_type; + if (elf_compress (tscn, 0, 0) != 1) + INTERNAL_ERROR (fname); + } + } Elf_Data *tdata = elf_getdata (tscn, NULL); if (tdata == NULL || tdata->d_buf == NULL @@ -686,9 +696,16 @@ remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr, shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize; gelf_update_shdr (scn, shdr); - if (tcompress_type != 0) - if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1) - INTERNAL_ERROR (fname); + if (is_gnu_compressed) + { + if (elf_compress_gnu (tscn, 1, ELF_CHF_FORCE) != 1) + INTERNAL_ERROR (fname); + } + else if (tcompress_type != 0) + { + if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1) + INTERNAL_ERROR (fname); + } } } } diff --git a/tests/ChangeLog b/tests/ChangeLog index 7ce3980..7472bc2 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,10 @@ 2018-11-09 Mark Wielaard <m...@klomp.org> + * run-strip-reloc.sh: Also test testfile-debug-rel-ppc64-z.o + testfile-debug-rel-ppc64-g.o. + +2018-11-09 Mark Wielaard <m...@klomp.org> + * testfile-debug-rel-ppc64-g.o.bz2: New test file. * testfile-debug-rel-ppc64-z.o.bz2: Likewise. * testfile-debug-rel-ppc64.o.bz2: Likewise. diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh index 6f299ab..0c6b1c2 100755 --- a/tests/run-strip-reloc.sh +++ b/tests/run-strip-reloc.sh @@ -139,4 +139,10 @@ runtest strip-compressed.o 1 testfiles testfile-debug-rel-ppc64.o runtest testfile-debug-rel-ppc64.o 1 +testfiles testfile-debug-rel-ppc64-z.o +runtest testfile-debug-rel-ppc64-z.o 1 + +testfiles testfile-debug-rel-ppc64-g.o +runtest testfile-debug-rel-ppc64-g.o 1 + exit $status -- 1.8.3.1