summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-11-09 08:18:22 +0000
committerMark Wielaard <mark@klomp.org>2018-11-09 17:34:30 +0100
commit4789e0fb92b03c3d8de548489c871d17f8f35cd0 (patch)
tree12f4335f80e2a870c52b2819f26eb0025b70d05c
parent1628254ba2157ac2b78fc9e103fe0b16fa288a26 (diff)
libelf: Explicitly update section data after (de)compression.
We need to explictly trigger a section data reload after updating the ELF section rawdata to make sure it gets written out to disk on an elf_update. Doing this showed one bug/inefficiently when the underlying file has a different endianness. In that case for debug sections we would convert by allocating a new buffer and just copying over the raw data into a new buffer. This is not really necessary and would hide any relocations done on the rawdata by libdwfl. Added a couple of new ppc64 big endian testfiles that show the issue. Signed-off-by: Mark Wielaard <mark@klomp.org>
-rw-r--r--libelf/ChangeLog7
-rw-r--r--libelf/elf_compress.c6
-rw-r--r--libelf/elf_getdata.c3
-rw-r--r--tests/ChangeLog10
-rw-r--r--tests/Makefile.am5
-rwxr-xr-xtests/run-readelf-zdebug-rel.sh106
-rwxr-xr-xtests/run-strip-reloc.sh4
-rw-r--r--tests/testfile-debug-rel-ppc64-g.o.bz2bin0 -> 1400 bytes
-rw-r--r--tests/testfile-debug-rel-ppc64-z.o.bz2bin0 -> 1420 bytes
-rw-r--r--tests/testfile-debug-rel-ppc64.o.bz2bin0 -> 1103 bytes
10 files changed, 139 insertions, 2 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index af565036..53da9a65 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,10 @@
+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
+ even if endianness is different.
+
2018-10-18 Mark Wielaard <mark@klomp.org>
* libelf.h (Elf_Type): Add ELF_T_NHDR8.
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index fd412e8a..d96245df 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -326,6 +326,12 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
scn->rawdata_base = buf;
scn->flags |= ELF_F_MALLOCED;
+
+ /* Pretend we (tried to) read the data from the file and setup the
+ data (might have to convert the Chdr to native format). */
+ scn->data_read = 1;
+ scn->flags |= ELF_F_FILEDATA;
+ __libelf_set_data_list_rdlock (scn, 1);
}
int
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 4f80aaf2..2043bba2 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -146,7 +146,8 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
{
const size_t align = __libelf_type_align (eclass, type);
- if (data == MY_ELFDATA)
+ /* Do we need to convert the data and/or adjust for alignment? */
+ if (data == MY_ELFDATA || type == ELF_T_BYTE)
{
if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
/* No need to copy, we can use the raw data. */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 23e91133..7ce39808 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+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.
+ * Makefile.am (EXTRA_DIST): Add testfile-debug-rel-ppc64-g.o.bz2,
+ testfile-debug-rel-ppc64-z.o.bz2 and testfile-debug-rel-ppc64.o.bz2.
+ * run-strip-reloc.sh: Also test on testfile-debug-rel-ppc64.o.
+ * run-readelf-zdebug-rel.sh: Also test on testfile-debug-rel-ppc64*.o.
+
2018-10-26 Mark Wielaard <mark@klomp.org>
* run-strip-reloc.sh: Add a test for --reloc-debug-sections-only.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a2a381ac..d3ac345d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -412,7 +412,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
testfile-riscv64.bz2 testfile-riscv64-s.bz2 \
testfile-riscv64-core.bz2 \
run-copyadd-sections.sh run-copymany-sections.sh \
- run-typeiter-many.sh run-strip-test-many.sh
+ run-typeiter-many.sh run-strip-test-many.sh \
+ testfile-debug-rel-ppc64-g.o.bz2 \
+ testfile-debug-rel-ppc64-z.o.bz2 \
+ testfile-debug-rel-ppc64.o.bz2
if USE_VALGRIND
valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
diff --git a/tests/run-readelf-zdebug-rel.sh b/tests/run-readelf-zdebug-rel.sh
index 3f20078c..53fa42a2 100755
--- a/tests/run-readelf-zdebug-rel.sh
+++ b/tests/run-readelf-zdebug-rel.sh
@@ -146,4 +146,110 @@ cat loc.out | sed -e "s/'.debug_loc' at offset 0x185/'.zdebug_loc' at offset 0x1
cat loc.out | sed -e "s/at offset 0x185/at offset 0x150/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-z.o
+# Same as above, but on ppc64
+testfiles testfile-debug-rel-ppc64.o
+testfiles testfile-debug-rel-ppc64-g.o testfile-debug-rel-ppc64-z.o
+
+cat > info.out << \EOF
+
+DWARF section [ 6] '.debug_info' at offset 0x80:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [ b] compile_unit abbrev: 1
+ producer (strp) "GNU C11 7.3.1 20180712 (Red Hat 7.3.1-6) -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -g -Og"
+ language (data1) C99 (12)
+ name (strp) "testfile-zdebug-rel.c"
+ comp_dir (strp) "/home/mjw"
+ low_pc (addr) 000000000000000000
+ high_pc (data8) 44 (0x000000000000002c)
+ stmt_list (sec_offset) 0
+ [ 2d] subprogram abbrev: 2
+ external (flag_present) yes
+ name (strp) "main"
+ decl_file (data1) testfile-zdebug-rel.c (1)
+ decl_line (data1) 4
+ prototyped (flag_present) yes
+ type (ref4) [ 82]
+ low_pc (addr) 000000000000000000
+ high_pc (data8) 44 (0x000000000000002c)
+ frame_base (exprloc)
+ [ 0] call_frame_cfa
+ GNU_all_call_sites (flag_present) yes
+ sibling (ref4) [ 82]
+ [ 4e] formal_parameter abbrev: 3
+ name (strp) "argc"
+ decl_file (data1) testfile-zdebug-rel.c (1)
+ decl_line (data1) 4
+ type (ref4) [ 82]
+ location (sec_offset) location list [ 0]
+ [ 5d] formal_parameter abbrev: 4
+ name (strp) "argv"
+ decl_file (data1) testfile-zdebug-rel.c (1)
+ decl_line (data1) 4
+ type (ref4) [ 89]
+ location (exprloc)
+ [ 0] reg4
+ [ 6a] variable abbrev: 5
+ name (string) "a"
+ decl_file (data1) testfile-zdebug-rel.c (1)
+ decl_line (data1) 6
+ type (ref4) [ 9c]
+ const_value (sdata) 18446744073709551607 (-9)
+ [ 74] variable abbrev: 6
+ name (string) "b"
+ decl_file (data1) testfile-zdebug-rel.c (1)
+ decl_line (data1) 7
+ type (ref4) [ 9c]
+ location (sec_offset) location list [ 4e]
+ [ 82] base_type abbrev: 7
+ byte_size (data1) 4
+ encoding (data1) signed (5)
+ name (string) "int"
+ [ 89] pointer_type abbrev: 8
+ byte_size (data1) 8
+ type (ref4) [ 8f]
+ [ 8f] pointer_type abbrev: 8
+ byte_size (data1) 8
+ type (ref4) [ 95]
+ [ 95] base_type abbrev: 9
+ byte_size (data1) 1
+ encoding (data1) unsigned_char (8)
+ name (strp) "char"
+ [ 9c] base_type abbrev: 9
+ byte_size (data1) 8
+ encoding (data1) unsigned (7)
+ name (strp) "long unsigned int"
+EOF
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64.o
+
+cat info.out | sed -e "s/'.debug_info'/'.zdebug_info'/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64-g.o
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64-z.o
+
+cat > loc.out << \EOF
+
+DWARF section [ 9] '.debug_loc' at offset 0x1af:
+
+ CU [ b] base: 000000000000000000
+ [ 0] range 0, 4
+ [ 0] reg3
+ range 4, 14
+ [ 0] breg3 -42
+ [ 2] stack_value
+ range 14, 2c
+ [ 0] GNU_entry_value:
+ [ 0] reg3
+ [ 3] stack_value
+ [ 4e] range 8, 18
+ [ 0] reg3
+EOF
+
+cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64.o
+
+cat loc.out | sed -e "s/'.debug_loc' at offset 0x1af/'.zdebug_loc' at offset 0x15f/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64-g.o
+
+cat loc.out | sed -e "s/at offset 0x1af/at offset 0x177/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64-z.o
+
exit 0
diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
index 6e54ab4a..6f299aba 100755
--- a/tests/run-strip-reloc.sh
+++ b/tests/run-strip-reloc.sh
@@ -135,4 +135,8 @@ testrun ${abs_top_builddir}/src/elfcompress -o strip-compressed.o -t zlib \
runtest strip-uncompressed.o 1
runtest strip-compressed.o 1
+# See run-readelf-zdebug-rel.sh
+testfiles testfile-debug-rel-ppc64.o
+runtest testfile-debug-rel-ppc64.o 1
+
exit $status
diff --git a/tests/testfile-debug-rel-ppc64-g.o.bz2 b/tests/testfile-debug-rel-ppc64-g.o.bz2
new file mode 100644
index 00000000..8c5ec99e
--- /dev/null
+++ b/tests/testfile-debug-rel-ppc64-g.o.bz2
Binary files differ
diff --git a/tests/testfile-debug-rel-ppc64-z.o.bz2 b/tests/testfile-debug-rel-ppc64-z.o.bz2
new file mode 100644
index 00000000..df50465f
--- /dev/null
+++ b/tests/testfile-debug-rel-ppc64-z.o.bz2
Binary files differ
diff --git a/tests/testfile-debug-rel-ppc64.o.bz2 b/tests/testfile-debug-rel-ppc64.o.bz2
new file mode 100644
index 00000000..8340d0ce
--- /dev/null
+++ b/tests/testfile-debug-rel-ppc64.o.bz2
Binary files differ