This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] strip: Also handle gnu compressed debug sections with --reloc-debug-sections


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 <mark@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  <mark@klomp.org>
 
+	* elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata.
+
+2018-11-09  Mark Wielaard  <mark@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  <mark@klomp.org>
+
+	* strip.c (remove_debug_relocations): Check if section is gnu
+	compressed and decompress and recompress it.
+
 2018-10-26  Mark Wielaard  <mark@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  <mark@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  <mark@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]