Discussion:
[PATCH] strip: Also handle gnu compressed debug sections with --reloc-debug-sections
Mark Wielaard
2018-11-09 16:41:51 UTC
Permalink
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 <***@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 <***@klomp.org>

+ * elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata.
+
+2018-11-09 Mark Wielaard <***@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 <***@klomp.org>
+
+ * strip.c (remove_debug_relocations): Check if section is gnu
+ compressed and decompress and recompress it.
+
2018-10-26 Mark Wielaard <***@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 <***@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 <***@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
Mark Wielaard
2018-11-13 15:54:50 UTC
Permalink
Post by Mark Wielaard
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.
Pushed this to master.

Loading...