diff options
author | Mark Wielaard <mark@klomp.org> | 2018-11-09 08:18:22 +0000 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2018-11-09 17:34:30 +0100 |
commit | 4789e0fb92b03c3d8de548489c871d17f8f35cd0 (patch) | |
tree | 12f4335f80e2a870c52b2819f26eb0025b70d05c | |
parent | 1628254ba2157ac2b78fc9e103fe0b16fa288a26 (diff) | |
download | elfutils-4789e0fb92b03c3d8de548489c871d17f8f35cd0.tar.gz |
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/ChangeLog | 7 | ||||
-rw-r--r-- | libelf/elf_compress.c | 6 | ||||
-rw-r--r-- | libelf/elf_getdata.c | 3 | ||||
-rw-r--r-- | tests/ChangeLog | 10 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rwxr-xr-x | tests/run-readelf-zdebug-rel.sh | 106 | ||||
-rwxr-xr-x | tests/run-strip-reloc.sh | 4 | ||||
-rw-r--r-- | tests/testfile-debug-rel-ppc64-g.o.bz2 | bin | 0 -> 1400 bytes | |||
-rw-r--r-- | tests/testfile-debug-rel-ppc64-z.o.bz2 | bin | 0 -> 1420 bytes | |||
-rw-r--r-- | tests/testfile-debug-rel-ppc64.o.bz2 | bin | 0 -> 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 Binary files differnew file mode 100644 index 00000000..8c5ec99e --- /dev/null +++ b/tests/testfile-debug-rel-ppc64-g.o.bz2 diff --git a/tests/testfile-debug-rel-ppc64-z.o.bz2 b/tests/testfile-debug-rel-ppc64-z.o.bz2 Binary files differnew file mode 100644 index 00000000..df50465f --- /dev/null +++ b/tests/testfile-debug-rel-ppc64-z.o.bz2 diff --git a/tests/testfile-debug-rel-ppc64.o.bz2 b/tests/testfile-debug-rel-ppc64.o.bz2 Binary files differnew file mode 100644 index 00000000..8340d0ce --- /dev/null +++ b/tests/testfile-debug-rel-ppc64.o.bz2 |