summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2016-08-06 15:13:19 +0200
committerMark Wielaard <mjw@redhat.com>2016-08-15 09:58:09 +0200
commit6ff6c215bfa4153874751cdc0bae26acfbba4a81 (patch)
treed66b9e7fd602ed1733cca45dcfab8edd05425b00
parenta8b2529facfbabfe4c8a0ca1a4387fe482d1c955 (diff)
downloadelfutils-6ff6c215bfa4153874751cdc0bae26acfbba4a81.tar.gz
strip: Handle compressed relocation target sections.
binutils 2.27 assembler will create compressed sections for x86 ELF targets. The linker will decompress them again and it doesn't do this for any other target. This broke one of the run-strip-reloc.sh self tests. Fix by checking if the target of a relocation section is compressed and first decompressing it before applying relocations and then compressing again if necessary. Add explicit testcases for compressed and uncompressed ET_REL files to run-strip-reloc.sh. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--src/ChangeLog5
-rw-r--r--src/strip.c22
-rw-r--r--tests/ChangeLog5
-rwxr-xr-xtests/run-strip-reloc.sh11
4 files changed, 38 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e5a3fce3..835888da 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2016-08-06 Mark Wielaard <mjw@redhat.com>
+
+ * strip.c (handle_elf): Uncompress and recompress relocation target
+ section if necessary.
+
2016-07-08 Mark Wielaard <mjw@redhat.com>
* Makefile.am (strip_LDADD): Add libdw.
diff --git a/src/strip.c b/src/strip.c
index 23d3d51b..f56554f7 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -1,5 +1,5 @@
/* Discard section not used at runtime from object files.
- Copyright (C) 2000-2012, 2014, 2015 Red Hat, Inc.
+ Copyright (C) 2000-2012, 2014, 2015, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -1791,10 +1791,18 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
Elf_Data *reldata = elf_getdata (scn, NULL);
if (reldata == NULL || reldata->d_buf == NULL)
INTERNAL_ERROR (fname);
- /* We actually wanted the rawdata, but since we already
- accessed it earlier as elf_getdata () that won't
- work. But debug sections are all ELF_T_BYTE, so it
- doesn't really matter. */
+
+ /* Make sure we adjust the uncompressed debug data
+ (and recompress if necessary at the end). */
+ GElf_Chdr tchdr;
+ int tcompress_type = 0;
+ 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
|| tdata->d_type != ELF_T_BYTE)
@@ -1976,6 +1984,10 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
nrels = next;
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, 0) != 1)
+ INTERNAL_ERROR (fname);
}
}
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d782ec30..f21a0b79 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2016-08-06 Mark Wielaard <mjw@redhat.com>
+
+ * run-strip-reloc.sh: Add explicit compressed and uncompressed
+ test cases.
+
2016-08-10 Richard Henderson <rth@redhat.com>
* file-bpf-dis1.expect.bz2: Fix expected mod and endian operations
diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
index 9fbba29b..e587eab3 100755
--- a/tests/run-strip-reloc.sh
+++ b/tests/run-strip-reloc.sh
@@ -108,4 +108,15 @@ runtest hello_m68k.ko 1
runtest ${abs_top_builddir}/src/strip 0
runtest ${abs_top_builddir}/src/strip.o 1
+# Copy ET_REL file for self-test and make sure to run with/without
+# elf section compression.
+tempfiles strip-uncompressed.o strip-compressed.o
+testrun ${abs_top_builddir}/src/elfcompress -o strip-uncompressed.o -t none \
+ ${abs_top_builddir}/src/strip.o
+testrun ${abs_top_builddir}/src/elfcompress -o strip-compressed.o -t zlib \
+ --force ${abs_top_builddir}/src/strip.o
+
+runtest strip-uncompressed.o 1
+runtest strip-compressed.o 1
+
exit $status