Re: [PATCH 4/4] strip: Add --reloc-debug-sections-only option.

2018-11-09 Thread Mark Wielaard
On Tue, Nov 06, 2018 at 03:21:24PM +0100, Mark Wielaard wrote:
> The buildbot didn't sent any failure emails (I am still looking into
> why), but this new cmp test failed on debian-armhf, fedora-ppc64 and
> fedora-ppc64le:
> https://builder.wildebeest.org/buildbot/#/builders/15/builds/81
> https://builder.wildebeest.org/buildbot/#/builders/12/builds/242
> https://builder.wildebeest.org/buildbot/#/builders/11/builds/244
> 
> It succeeds on everything else. Still investigating.

The buildbot did sent email. I was too fast.
The issue was kind of subtle, but is easily fixable.
I committed the attached patch with some extra testcases to
(hopefully) get the build green again on all arches.

Cheers,

Mark
>From c6e3290a9722df58191c1ac181ce587f406d7b7a Mon Sep 17 00:00:00 2001
From: Mark Wielaard 
Date: Fri, 9 Nov 2018 08:18:22 +
Subject: [PATCH] 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 
---
 libelf/ChangeLog   |   7 ++
 libelf/elf_compress.c  |   6 ++
 libelf/elf_getdata.c   |   3 +-
 tests/ChangeLog|  10 +++
 tests/Makefile.am  |   5 +-
 tests/run-readelf-zdebug-rel.sh| 106 +
 tests/run-strip-reloc.sh   |   4 +
 tests/testfile-debug-rel-ppc64-g.o.bz2 | Bin 0 -> 1400 bytes
 tests/testfile-debug-rel-ppc64-z.o.bz2 | Bin 0 -> 1420 bytes
 tests/testfile-debug-rel-ppc64.o.bz2   | Bin 0 -> 1103 bytes
 10 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 tests/testfile-debug-rel-ppc64-g.o.bz2
 create mode 100644 tests/testfile-debug-rel-ppc64-z.o.bz2
 create mode 100644 tests/testfile-debug-rel-ppc64.o.bz2

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index af5650360..53da9a65f 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-09  Mark Wielaard  
+
+	* 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  
 
 	* libelf.h (Elf_Type): Add ELF_T_NHDR8.
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index fd412e8a6..d96245df2 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 4f80aaf2d..2043bba2d 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 23e911336..7ce39808d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+2018-11-09  Mark Wielaard  
+
+	* 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  
 
 	* run-strip-reloc.sh: Add a test for --reloc-debug-sections-only.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a2a381ac8..d3ac345df 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-ty

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

2018-11-09 Thread 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.

Signed-off-by: Mark Wielaard 
---
 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  
 
+   * elf_compress_gnu.c (elf_compress_gnu): Use elf_getdata.
+
+2018-11-09  Mark Wielaard  
+
* 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  
+
+   * strip.c (remove_debug_relocations): Check if section is gnu
+   compressed and decompress and recompress it.
+
 2018-10-26  Mark Wielaard  
 
* 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  
 
+   * run-strip-reloc.sh: Also test testfile-debug-rel-ppc64-z.o
+   testfile-debug-rel-ppc64-g.o.
+
+2018-11-09  Mark Wielaard  
+
* 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-re

Re: [PATCH] Also find CFI in sections of type SHT_X86_64_UNWIND

2018-11-09 Thread Mark Wielaard
On Wed, Nov 07, 2018 at 10:02:54AM +0100, Milian Wolff wrote:
> On Dienstag, 6. November 2018 12:06:57 CET Mark Wielaard wrote:
> > It seems to only happen with a specific combination of gcc and the gold
> > linker, I could only generate the SHT_X86_64_UNWIND sections only on
> > fedora 29 with gcc 8.2.1 and gold version 2.31.1-13.fc29 (1.16).
> 
> At least on my system, that doesn't seem to be enough. Both my desktop and my 
> laptop are running on ArchLinux with the same versions of GCC and Gold, yet 
> one shows this behavior while the other one isn't...

Strange indeed. My system doesn't have ccache, it does show the issue.

> Both patches work for me:
> 
> Tested-by: Milian Wolff 

Great. I pushed both to master now.

Thanks,

Mark


Re: [PATCH] libdwelf: New function dwelf_elf_begin.

2018-11-09 Thread Mark Wielaard
On Sun, Nov 04, 2018 at 05:37:42PM +0100, Mark Wielaard wrote:
> On Mon, 2018-10-22 at 01:47 +0200, Mark Wielaard wrote:
> > It currently wraps __libdw_open_file which makes error handling
> > slight tricky and needs duplicating the file handle.
> 
> Which introduced some confusion that could cause the file descriptor to
> leak. The attached updated patch adds a variant to the
> __libdw_open_file function that doesn't try to play tricks with the
> given file descriptor which is easier to wrap for dwelf_elf_begin.

> From 940515f0ba9641b9ac38d721aaac87fd898bb1fd Mon Sep 17 00:00:00 2001
> From: Mark Wielaard 
> Date: Sun, 21 Oct 2018 23:41:32 +0200
> Subject: [PATCH] libdwelf: New function dwelf_elf_begin.
> 
> This introduces a new function dwelf_elf_begin which creates a (read-only)
> ELF handle from a possibly compressed file handle or a file that start
> with a linux kernel header. This can be used in eu-readelf to (re)open a
> (pure) ELF.
> 
> eu-readelf uses libdwfl to relocate addresses in the original file in
> case it is ET_REL. But to show the "raw" data it might need to (re)open
> the file. Which could fail if the file was compressed. And produced an
> obscure error message: "cannot create EBL handle".
> 
> This rewrites __libdw_open_file a little so that the given file handle
> will never be closed (whether on success or failure) and introduces a
> new internal function __libdw_open_elf that dwelf_elf_begin wraps.

I pushed this variant to master now.

Cheers,

Mark


Re: [PATCH] libcpu: Recognize bpf jump variants BPF_JLT, BPF_JLE, BPF_JSLT and BPF_JSLE

2018-11-09 Thread Mark Wielaard
On Sun, Nov 04, 2018 at 09:40:32PM +0100, Mark Wielaard wrote:
> Linux kernel 4.13 introduced 4 more jump class variants.
> 
>   commit 92b31a9af73b3a3fc801899335d6c47966351830
>   Author: Daniel Borkmann 
>   Date:   Thu Aug 10 01:39:55 2017 +0200
> 
> bpf: add BPF_J{LT,LE,SLT,SLE} instructions
> 
> For conditional jumping on unsigned and signed < and <= between a register
> and another register or immediate.
> 
> Add these new constants to bpf.h, recognize them in bpf_disasm and update
> the testfile-bpf-dis1.expect file.

Pushed to master.