Re: [PATCH] libdwelf: New function dwelf_elf_begin.

2018-11-04 Thread Mark Wielaard
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.

Signed-off-by: Mark Wielaard 
---
 libdw/ChangeLog |  4 +++
 libdw/libdw.map |  5 
 libdwelf/ChangeLog  |  8 +-
 libdwelf/Makefile.am|  2 +-
 libdwelf/dwelf_elf_begin.c  | 62 +
 libdwelf/libdwelf.h | 10 ++-
 libdwfl/ChangeLog   |  8 ++
 libdwfl/libdwflP.h  |  4 +++
 libdwfl/open.c  | 30 ++--
 src/ChangeLog   |  7 +++--
 src/readelf.c   |  8 --
 tests/ChangeLog |  6 
 tests/Makefile.am   |  2 ++
 tests/run-readelf-compressed.sh | 34 ++
 14 files changed, 174 insertions(+), 16 deletions(-)
 create mode 100644 libdwelf/dwelf_elf_begin.c
 create mode 100755 tests/run-readelf-compressed.sh

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index ebe002c..e5d01c1 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-20  Mark Wielaard  
+
+	* libdw.map (ELFUTILS_0.175): New section. Add dwelf_elf_begin.
+
 2018-09-13  Mark Wielaard  
 
 	* dwarf_begin_elf.c (check_section): Drop ehdr argument, add and
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 3fef2ed..55482d5 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -356,3 +356,8 @@ ELFUTILS_0.173 {
   global:
 dwarf_next_lines;
 } ELFUTILS_0.171;
+
+ELFUTILS_0.175 {
+  global:
+dwelf_elf_begin;
+} ELFUTILS_0.173;
\ No newline at end of file
diff --git a/libdwelf/ChangeLog b/libdwelf/ChangeLog
index ba92134..88be342 100644
--- a/libdwelf/ChangeLog
+++ b/libdwelf/ChangeLog
@@ -1,9 +1,15 @@
+2018-10-21  Mark Wielaard  
+
+	* libdwelf.h (dwelf_elf_begin): Add function declaration.
+	* dwelf_elf_begin.c: New file.
+	* Makefile.am (libdwelf_a_SOURCES): Add dwelf_elf_begin.c.
+
 2018-10-18  Mark Wielaard  
 
 	* dwelf_elf_gnu_build_id.c (find_elf_build_id): Check p_align to
 	set ELF type.
 
-2015-10-11  Akihiko Odaki  
+2016-10-11  Akihiko Odaki  
 
 	* dwelf_strtab.c: Remove sys/param.h include.
 	(MIN): Remove definition.
diff --git a/libdwelf/Makefile.am b/libdwelf/Makefile.am
index 7ca767a..a7933fd 100644
--- a/libdwelf/Makefile.am
+++ b/libdwelf/Makefile.am
@@ -41,7 +41,7 @@ noinst_HEADERS = libdwelfP.h
 
 libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \
 		 dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \
-		 dwelf_strtab.c
+		 dwelf_strtab.c dwelf_elf_begin.c
 
 libdwelf = $(libdw)
 
diff --git a/libdwelf/dwelf_elf_begin.c b/libdwelf/dwelf_elf_begin.c
new file mode 100644
index 000..7982533
--- /dev/null
+++ b/libdwelf/dwelf_elf_begin.c
@@ -0,0 +1,62 @@
+/* Creates an ELF handle from a possibly compressed file descriptor.
+   Copyright (C) 2018 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at
+   your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public Lic

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

2018-11-04 Thread Mark Wielaard
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.

Signed-off-by: Mark Wielaard 
---
 lib/ChangeLog  |   4 
 lib/bpf.h  |   4 
 libcpu/ChangeLog   |   5 +
 libcpu/bpf_disasm.c|  26 +-
 tests/ChangeLog|   5 +
 tests/testfile-bpf-dis1.expect.bz2 | Bin 1467 -> 1516 bytes
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 86a53d2..0914b2c 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2018-11-04  Mark Wielaard  
+
+   * bpf.h: Add BPF_JLT, BPF_JLE, BPF_JSLT and BPF_JSLE.
+
 2018-07-04  Ross Burton 
 
* color.c: Remove error.h, add system.h include.
diff --git a/lib/bpf.h b/lib/bpf.h
index db80a51..efb26f8 100644
--- a/lib/bpf.h
+++ b/lib/bpf.h
@@ -23,6 +23,10 @@
 #define BPF_JSGE 0x70
 #define BPF_CALL 0x80
 #define BPF_EXIT 0x90
+#define BPF_JLT  0xa0
+#define BPF_JLE  0xb0
+#define BPF_JSLT 0xc0
+#define BPF_JSLE 0xd0
 
 #define BPF_W 0x00
 #define BPF_H 0x08
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index 86d2947..adebbef 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-04  Mark Wielaard  
+
+   * bpf_disasm.c (bpf_disasm): Recognize BPF_JLT, BPF_JLE, BPF_JSLT
+   and BPF_JSLE.
+
 2018-02-09  Joshua Watt  
 
* i386_disasm.c (i386_disasm): Use FALLTHOUGH macro instead of
diff --git a/libcpu/bpf_disasm.c b/libcpu/bpf_disasm.c
index 054aba2..3d92d01 100644
--- a/libcpu/bpf_disasm.c
+++ b/libcpu/bpf_disasm.c
@@ -1,5 +1,5 @@
 /* Disassembler for BPF.
-   Copyright (C) 2016 Red Hat, Inc.
+   Copyright (C) 2016, 2018 Red Hat, Inc.
This file is part of elfutils.
 
This file is free software; you can redistribute it and/or modify
@@ -346,6 +346,18 @@ bpf_disasm (Ebl *ebl, const uint8_t **startp, const 
uint8_t *end,
case BPF_JMP | BPF_JSGE | BPF_K:
  code_fmt = J64(REGS(1), >=, IMMS(2));
  goto do_dst_imm_jmp;
+   case BPF_JMP | BPF_JLT | BPF_K:
+ code_fmt = J64(REG(1), <, IMMS(2));
+ goto do_dst_imm_jmp;
+   case BPF_JMP | BPF_JLE | BPF_K:
+ code_fmt = J64(REG(1), <=, IMMS(2));
+ goto do_dst_imm_jmp;
+   case BPF_JMP | BPF_JSLT | BPF_K:
+ code_fmt = J64(REGS(1), <, IMMS(2));
+ goto do_dst_imm_jmp;
+   case BPF_JMP | BPF_JSLE | BPF_K:
+ code_fmt = J64(REGS(1), <=, IMMS(2));
+ goto do_dst_imm_jmp;
 
case BPF_JMP | BPF_JEQ | BPF_X:
  code_fmt = J64(REG(1), ==, REG(2));
@@ -368,6 +380,18 @@ bpf_disasm (Ebl *ebl, const uint8_t **startp, const 
uint8_t *end,
case BPF_JMP | BPF_JSGE | BPF_X:
  code_fmt = J64(REGS(1), >=, REGS(2));
  goto do_dst_src_jmp;
+   case BPF_JMP | BPF_JLT | BPF_X:
+ code_fmt = J64(REG(1), <, REG(2));
+ goto do_dst_src_jmp;
+   case BPF_JMP | BPF_JLE | BPF_X:
+ code_fmt = J64(REG(1), <=, REG(2));
+ goto do_dst_src_jmp;
+   case BPF_JMP | BPF_JSLT | BPF_X:
+ code_fmt = J64(REGS(1), <, REGS(2));
+ goto do_dst_src_jmp;
+   case BPF_JMP | BPF_JSLE | BPF_X:
+ code_fmt = J64(REGS(1), <=, REGS(2));
+ goto do_dst_src_jmp;
 
case BPF_LDX | BPF_MEM | BPF_B:
  code_fmt = LOAD(u8);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d5a0656..5edd616 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-04  Mark Wielaard  
+
+   * testfile-bpf-reloc.expect.bz2: Update with new expected jump
+   variants.
+
 2018-10-18  Mark Wielaard  
 
* run-readelf-n.sh: New test.
diff --git a/tests/testfile-bpf-dis1.expect.bz2 
b/tests/testfile-bpf-dis1.expect.bz2
index 
21b55e94431e96914d38ad86683b54f29c58c617..61a8afb1f7a06ab2ad261d7c60e1b330611310a2
 100644
GIT binary patch
literal 1516
zcmZ9LdpOg39LIk%F{CqcS=6yPa~qEcCvs_6GGf9WZ837orBTYWghC5>kmeS`$elUI
zWlQ8zxu$Ru4#Ok=kEjaRI_qHc5DsR%Tm^+j|c{*hBahQnH(>wq2h(YH2HiV
z*o{2EN7@~_&isC}rh2=$8Vi8PnqV})EmR~H-L;Y3Tc;E+P#x0THf??Lq1McS<~S&J
zbn~pO31Q6bn`@L>N`;9r0ClReM9S&FdI*R-<9qJ?>vSLpI+gxA4u?BkJpVx;+})kX
zeB;Q8%cVjrbH>F#u;cZo#JrmKf}=fI1vwvHL~zTdAM2~;_@ZiSy@&r=L^OKNOmXRL
zLDN6B?de-bjEvw2Lr6;?i0>#C5hsC!Bulf)TruN`izKhiEB?Xmjmx6J&kDd{IDo+d
zEm-I{Jl+s0_)=_tTgdHW6|~<{ji&MYs@SNk@#f|*5=835#98xjB{gEbpHNaKz(F_cXK(QQjqcyYkWdm7XV-vY3>0}SUz
z59jjt-_eXf#}XGzse_GrN1mcQ`AvyEj&j<0Qo3ZLVh*h&rsJa<@Qbnn-QFIDFj(?_
zxN#?_fy~#N)!wPsoV%_F_pWy7)Ii3=Sr$wKWvt)Z(Ahay1DPatbvHLrEEL&;Rv?EE)umgYr7uVJd+p@7_&YOSWR&qd_$
zjvaw%H)=O^Bfy^Q%E-XCIz{40{a|7$)eXSs3M
zidh}|o?fVdLZOsMMh^vMLsyb*pZK

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

2018-11-04 Thread Mark Wielaard
On Mon, 2018-10-29 at 16:21 +0100, Milian Wolff wrote:
> On my system with g++ (GCC) 8.2.1 20180831 with GNU gold (GNU
> Binutils
> 2.31.1) 1.16, the .eh_frame section does not have type PROGBITS
> but rather is using X86_64_UNWIND nowadays:

Urgh, who thought it would be a good idea to have a architecture
specific (instead of a GNU specific) section type for unwind tables...
And why is there no separate type for .eh_frame_hdr. Now you still need
to check the name anyway...

But, given that we have that now, yes, lets deal with it.

> ```
> $ echo "int main(){ return 0; }" > test.c
> $ gcc test.c
> $ readelf --sections a.out | grep .eh_frame
>   [14] .eh_frame X86_64_UNWIND0670  0670
>   [15] .eh_frame_hdr X86_64_UNWIND0724  0724
> ```
> 
> Without this patch, libdw refuses to use the available unwind
> information, leading to broken backtraces while unwinding. With the
> patch applied, unwinding works once more in such situations.

Three questions:

- What testcase did you use?
  In theory dwarf_getcfi_elf () should fall back to using phdrs and
  find the PT_GNU_EH_FRAME data instead.

- It might be better to change the check to shdr->sh_type != SHT_NOBITS
  The idea is probably that we don't want to look at the data in case
  this is a .debug file which has it removed. This might be better than
  adding a check for X86_64_UNWIND since then we would also need to
  check the arch. Does != SHT_NOBITS work for you?

- What does eu-readelf -S show?
  I think we need a x86_64_section_type_name () ebl hook to show it
  correctly.

Thanks,

Mark