public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
@ 2018-06-13 10:28 Andreas Schwab
  2018-06-14 23:28 ` Mark Wielaard
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-06-13 10:28 UTC (permalink / raw)
  To: elfutils-devel

From
<https://github.com/riscv/riscv-isa-manual/raw/master/release/riscv-spec-v2.2.pdf>
and GCC source.

Signed-off-by: Andreas Schwab <schwab@suse.de>
---
 backends/Makefile.am  |   2 +-
 backends/riscv_cfi.c  |  75 ++++++++++++++++++
 backends/riscv_init.c |   4 +
 backends/riscv_regs.c | 177 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 backends/riscv_cfi.c
 create mode 100644 backends/riscv_regs.c

diff --git a/backends/Makefile.am b/backends/Makefile.am
index 80aa00e752..0c14ec86b5 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -131,7 +131,7 @@ cpu_bpf = ../libcpu/libcpu_bpf.a
 libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
 am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
 
-riscv_SRCS = riscv_init.c riscv_symbol.c
+riscv_SRCS = riscv_init.c riscv_symbol.c riscv_cfi.c riscv_regs.c
 libebl_riscv_pic_a_SOURCES = $(riscv_SRCS)
 am_libebl_riscv_pic_a_OBJECTS = $(riscv_SRCS:.c=.os)
 
diff --git a/backends/riscv_cfi.c b/backends/riscv_cfi.c
new file mode 100644
index 0000000000..1a84a38237
--- /dev/null
+++ b/backends/riscv_cfi.c
@@ -0,0 +1,75 @@
+/* RISC-V ABI-specified defaults for DWARF CFI.
+   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 License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+
+int
+riscv_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* The initial Canonical Frame Address is the value of the
+         Stack Pointer (r2) as setup in the previous frame. */
+      DW_CFA_def_cfa, ULEB128_7 (2), ULEB128_7 (0),
+
+      /* The Stack Pointer (r2) is restored from CFA address by default.  */
+      DW_CFA_val_offset, ULEB128_7 (2), ULEB128_7 (0),
+
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* The return address register contains the return address setup by
+	 caller.  */
+      SV (1),
+
+      /* Callee-saved registers s0-s11, fs0-fs11.  */
+      SV(8), SV (9), SV (18), SV (19), SV (20), SV (21),
+      SV (22), SV (23), SV (24), SV (25), SV (26), SV (27),
+
+      SV (40), SV (41),  SV (50),  SV (51), SV (52),  SV (53),
+      SV (54), SV (55),  SV (56),  SV (57), SV (58),  SV (59),
+#undef SV
+
+      /* XXX Note: registers intentionally unused by the program,
+	 for example as a consequence of the procedure call standard
+	 should be initialized as if by DW_CFA_same_value.  */
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = -4;
+
+  abi_info->return_address_register = 1; /* ra.  */
+
+  return 0;
+}
diff --git a/backends/riscv_init.c b/backends/riscv_init.c
index 80be86d3c5..5588a6b7f0 100644
--- a/backends/riscv_init.c
+++ b/backends/riscv_init.c
@@ -51,6 +51,10 @@ riscv_init (Elf *elf __attribute__ ((unused)),
   eh->name = "RISC-V";
   riscv_init_reloc (eh);
   HOOK (eh, reloc_simple_type);
+  HOOK (eh, register_info);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
+  eh->frame_nregs = 66;
   HOOK (eh, check_special_symbol);
   HOOK (eh, machine_flag_check);
 
diff --git a/backends/riscv_regs.c b/backends/riscv_regs.c
new file mode 100644
index 0000000000..7b577ca0cb
--- /dev/null
+++ b/backends/riscv_regs.c
@@ -0,0 +1,177 @@
+/* Register names and numbers for RISC-V DWARF.
+   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 License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND riscv_
+#include "libebl_CPU.h"
+
+ssize_t
+riscv_register_info (Ebl *ebl, int regno, char *name, size_t namelen,
+		     const char **prefix, const char **setname,
+		     int *bits, int *type)
+{
+  if (name == NULL)
+    return 64;
+
+  *prefix = "";
+
+  if (regno < 32)
+    {
+      *setname = "integer";
+      *type = DW_ATE_signed;
+      *bits = ebl->class == ELFCLASS64 ? 64 : 32;
+    }
+  else
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+      *bits = 64;
+    }
+
+  switch (regno)
+    {
+    case 0:
+      return stpcpy (name, "zero") + 1 - name;
+
+    case 1:
+      *type = DW_ATE_address;
+      return stpcpy (name, "ra") + 1 - name;
+
+    case 2:
+      *type = DW_ATE_address;
+      return stpcpy (name, "sp") + 1 - name;
+
+    case 3:
+      *type = DW_ATE_address;
+      return stpcpy (name, "gp") + 1 - name;
+
+    case 4:
+      *type = DW_ATE_address;
+      return stpcpy (name, "tp") + 1 - name;
+
+    case 5 ... 7:
+      name[0] = 't';
+      name[1] = regno - 5 + '0';
+      namelen = 2;
+      break;
+
+    case 8 ... 9:
+      name[0] = 's';
+      name[1] = regno - 8 + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 17:
+      name[0] = 'a';
+      name[1] = regno - 10 + '0';
+      namelen = 2;
+      break;
+
+    case 18 ... 25:
+      name[0] = 's';
+      name[1] = regno - 18 + '2';
+      namelen = 2;
+      break;
+
+    case 26 ... 27:
+      name[0] = 's';
+      name[1] = '1';
+      name[1] = regno - 26 + '0';
+      namelen = 3;
+      break;
+
+    case 28 ... 31:
+      name[0] = 't';
+      name[1] = regno - 28 + '3';
+      namelen = 2;
+      break;
+
+    case 32 ... 39:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = regno - 32 + '0';
+      namelen = 3;
+      break;
+
+    case 40 ... 41:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = regno - 40 + '0';
+      namelen = 3;
+      break;
+
+    case 42 ... 49:
+      name[0] = 'f';
+      name[1] = 'a';
+      name[2] = regno - 42 + '0';
+      namelen = 3;
+      break;
+
+    case 50 ... 57:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = regno - 50 + '2';
+      namelen = 3;
+      break;
+
+    case 58 ... 59:
+      name[0] = 'f';
+      name[1] = 's';
+      name[2] = '1';
+      name[3] = regno - 58 + '0';
+      namelen = 4;
+      break;
+
+    case 60 ... 61:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = regno - 60 + '8';
+      namelen = 3;
+      break;
+
+    case 62 ... 63:
+      name[0] = 'f';
+      name[1] = 't';
+      name[2] = '1';
+      name[3] = regno - 62 + '0';
+      namelen = 4;
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
-- 
2.17.1

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-13 10:28 [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V Andreas Schwab
@ 2018-06-14 23:28 ` Mark Wielaard
  2018-06-18  8:01   ` Andreas Schwab
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Wielaard @ 2018-06-14 23:28 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

On Wed, Jun 13, 2018 at 12:28:00PM +0200, Andreas Schwab wrote:
> From
> <https://github.com/riscv/riscv-isa-manual/raw/master/release/riscv-spec-v2.2.pdf>
> and GCC source.

This looks good as far as I can see.

How does the result of make check look now on a native riscv system?

Could you provide a testcase for tests/run-allregs.sn and/or
tests/run-addrcfi.sh if possible so people can check things work on
other arches?

If this is enough to actually unwind could you look at providing an
tests/run-backtrace-core-riscv.sh testcase (the existing ones should
explain how to generate the (static) executable and core file for the
test, but if it is unclear please ask.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-14 23:28 ` Mark Wielaard
@ 2018-06-18  8:01   ` Andreas Schwab
  2018-06-20 11:16     ` Mark Wielaard
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-06-18  8:01 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

On Jun 15 2018, Mark Wielaard <mark@klomp.org> wrote:

> How does the result of make check look now on a native riscv system?

FAIL: run-native-test.sh

return_value_location is missing

FAIL: run-low_high_pc.sh

lowpc: 220, highpc: 220lx
../../elfutils/src/size.c: [c84] 'handle_elf' highpc <= lowpc

lowpc: 41c, highpc: 41clx
../../elfutils/src/strip.c: [1c00] 'update_section_size' highpc <= lowpc

FAIL: run-backtrace-native.sh
FAIL: run-backtrace-dwarf.sh
FAIL: run-deleted.sh

set_initial_registers_tid is missing

FAIL: run-backtrace-native-core.sh

no corefile support

SKIP: run-backtrace-data.sh

no unwinding support

> Could you provide a testcase for tests/run-allregs.sn and/or
> tests/run-addrcfi.sh if possible so people can check things work on
> other arches?
>
> If this is enough to actually unwind could you look at providing an
> tests/run-backtrace-core-riscv.sh testcase (the existing ones should
> explain how to generate the (static) executable and core file for the
> test, but if it is unclear please ask.

I will work on these.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-18  8:01   ` Andreas Schwab
@ 2018-06-20 11:16     ` Mark Wielaard
  2018-06-20 12:38       ` Andreas Schwab
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Wielaard @ 2018-06-20 11:16 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

Hi Andreas,

On Mon, 2018-06-18 at 09:59 +0200, Andreas Schwab wrote:
> On Jun 15 2018, Mark Wielaard <mark@klomp.org> wrote:
> 
> > How does the result of make check look now on a native riscv
> > system?
> 
> FAIL: run-native-test.sh
> 
> return_value_location is missing

Sadly DWARF doesn't describe how return values are passed back. So
you'll have to write that by hand for the abi. It normally isn't that
hard for scalar types, sometimes there is some trickery for floats or
small structs.

> FAIL: run-low_high_pc.sh
> 
> lowpc: 220, highpc: 220lx
> ../../elfutils/src/size.c: [c84] 'handle_elf' highpc <= lowpc
> 
> lowpc: 41c, highpc: 41clx
> ../../elfutils/src/strip.c: [1c00] 'update_section_size' highpc <=
> lowpc

That is odd. For which testfile is this? Is it for a native (self test)
file? If it is for an ET_REL object file it might be that we don't
handle all relocations correctly. If you could post the file somewhere,
that might be helpful to track down the issue.

> FAIL: run-backtrace-native.sh
> FAIL: run-backtrace-dwarf.sh
> FAIL: run-deleted.sh
> 
> set_initial_registers_tid is missing

If the target has ptrace support this probably wouldn't be too hard to
get going.

> FAIL: run-backtrace-native-core.sh
> 
> no corefile support

That would need a corenote backend implementation.

> SKIP: run-backtrace-data.sh
> 
> no unwinding support

That is expected. It really is an architecture specific (x86_64) test.

> > Could you provide a testcase for tests/run-allregs.sn and/or
> > tests/run-addrcfi.sh if possible so people can check things work on
> > other arches?
> > 
> > If this is enough to actually unwind could you look at providing an
> > tests/run-backtrace-core-riscv.sh testcase (the existing ones
> > should
> > explain how to generate the (static) executable and core file for
> > the
> > test, but if it is unclear please ask.
> 
> I will work on these.

Thanks. Without tests it is hard to know if an arch is really fully
functional and it risks bit-rotting.

I have added a ChangeLog entry for your patch and pushed it to master.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 11:16     ` Mark Wielaard
@ 2018-06-20 12:38       ` Andreas Schwab
  2018-06-20 12:59         ` Mark Wielaard
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-06-20 12:38 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

On Jun 20 2018, Mark Wielaard <mark@klomp.org> wrote:

>> FAIL: run-low_high_pc.sh
>> 
>> lowpc: 220, highpc: 220lx
>> ../../elfutils/src/size.c: [c84] 'handle_elf' highpc <= lowpc
>> 
>> lowpc: 41c, highpc: 41clx
>> ../../elfutils/src/strip.c: [1c00] 'update_section_size' highpc <=
>> lowpc
>
> That is odd. For which testfile is this? Is it for a native (self test)
> file?

Yes, the object files for these sources.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 12:38       ` Andreas Schwab
@ 2018-06-20 12:59         ` Mark Wielaard
  2018-06-20 13:55           ` Andreas Schwab
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Wielaard @ 2018-06-20 12:59 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

On Wed, 2018-06-20 at 14:38 +0200, Andreas Schwab wrote:
> On Jun 20 2018, Mark Wielaard <mark@klomp.org> wrote:
> 
> > > FAIL: run-low_high_pc.sh
> > > 
> > > lowpc: 220, highpc: 220lx
> > > ../../elfutils/src/size.c: [c84] 'handle_elf' highpc <= lowpc
> > > 
> > > lowpc: 41c, highpc: 41clx
> > > ../../elfutils/src/strip.c: [1c00] 'update_section_size' highpc
> > > <=
> > > lowpc
> > 
> > That is odd. For which testfile is this? Is it for a native (self
> > test)
> > file?
> 
> Yes, the object files for these sources.

If you could post them somewhere we can see what is wrong.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 12:59         ` Mark Wielaard
@ 2018-06-20 13:55           ` Andreas Schwab
  2018-06-20 20:49             ` Mark Wielaard
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-06-20 13:55 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 964 bytes --]

On Jun 20 2018, Mark Wielaard <mark@klomp.org> wrote:

> On Wed, 2018-06-20 at 14:38 +0200, Andreas Schwab wrote:
>> On Jun 20 2018, Mark Wielaard <mark@klomp.org> wrote:
>> 
>> > > FAIL: run-low_high_pc.sh
>> > > 
>> > > lowpc: 220, highpc: 220lx
>> > > ../../elfutils/src/size.c: [c84] 'handle_elf' highpc <= lowpc
>> > > 
>> > > lowpc: 41c, highpc: 41clx
>> > > ../../elfutils/src/strip.c: [1c00] 'update_section_size' highpc
>> > > <=
>> > > lowpc
>> > 
>> > That is odd. For which testfile is this? Is it for a native (self
>> > test)
>> > file?
>> 
>> Yes, the object files for these sources.
>
> If you could post them somewhere we can see what is wrong.

It's probably because there are more than just simple relocations on
debug sections, more than reloc_simple_type can handle.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

[-- Attachment #2: size.o --]
[-- Type: application/octet-stream, Size: 177480 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 13:55           ` Andreas Schwab
@ 2018-06-20 20:49             ` Mark Wielaard
  2018-07-11 13:40               ` Andreas Schwab
  2018-07-24 14:13               ` Andreas Schwab
  0 siblings, 2 replies; 13+ messages in thread
From: Mark Wielaard @ 2018-06-20 20:49 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

On Wed, 2018-06-20 at 15:55 +0200, Andreas Schwab wrote:
> It's probably because there are more than just simple relocations on
> debug sections, more than reloc_simple_type can handle.

aha, ok, but it looks like RISCV_(ADD|SUB)(8|16|32|64) should not be
too hard to handle. The other ones (RISCV_SETX) might be a little
harder. They are not used much though and only against .debug_frame. So
if you get RISC_ADD/SUB going that probably handles most uses. Maybe
backend reloc_simple_type hook needs to be changed a bit to handle
them. But that shouldn't really be a problem, all callers are internal
(libdwfl/relocate.c and strip.c).

Cheers,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 20:49             ` Mark Wielaard
@ 2018-07-11 13:40               ` Andreas Schwab
  2018-07-24 14:13               ` Andreas Schwab
  1 sibling, 0 replies; 13+ messages in thread
From: Andreas Schwab @ 2018-07-11 13:40 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

On Jun 20 2018, Mark Wielaard <mark@klomp.org> wrote:

> aha, ok, but it looks like RISCV_(ADD|SUB)(8|16|32|64) should not be
> too hard to handle. The other ones (RISCV_SETX) might be a little
> harder.

The SETX relocs are simple absolute relocs (SET32 is the same as 32, but
the dynamic linker does not need to handle SETX).

> They are not used much though and only against .debug_frame. So
> if you get RISC_ADD/SUB going that probably handles most uses.

Both size --reloc-debug-sections and readelf -wframe need to handle all
relocs, including SET6/ADD6/SUB6.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-06-20 20:49             ` Mark Wielaard
  2018-07-11 13:40               ` Andreas Schwab
@ 2018-07-24 14:13               ` Andreas Schwab
  2018-07-26 16:03                 ` Mark Wielaard
  1 sibling, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-07-24 14:13 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

How about this, does it look reasonable?  It doesn't handle SET6/SUB6
yet, and eu-readelf -wframe doesn't agree with readelf -wf, so this is
only a RFC.

Andreas.

diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c
index dce8e3586b..866be8f093 100644
--- a/backends/riscv_symbol.c
+++ b/backends/riscv_symbol.c
@@ -44,10 +44,27 @@ riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
 {
   switch (type)
     {
+    case R_RISCV_SET8:
+      return ELF_T_BYTE;
+    case R_RISCV_SET16:
+      return ELF_T_HALF;
     case R_RISCV_32:
+    case R_RISCV_SET32:
       return ELF_T_WORD;
     case R_RISCV_64:
       return ELF_T_XWORD;
+    case R_RISCV_ADD16:
+      return ELF_T_ADD_HALF;
+    case R_RISCV_SUB16:
+      return ELF_T_SUB_HALF;
+    case R_RISCV_ADD32:
+      return ELF_T_ADD_WORD;
+    case R_RISCV_SUB32:
+      return ELF_T_SUB_WORD;
+    case R_RISCV_ADD64:
+      return ELF_T_ADD_XWORD;
+    case R_RISCV_SUB64:
+      return ELF_T_SUB_XWORD;
     default:
       return ELF_T_NUM;
     }
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 9afcdebecc..1c4a1bade2 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -379,9 +379,18 @@ relocate (Dwfl_Module * const mod,
     DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);			\
     DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
     size_t size;
+    bool is_add_sub = false;
     switch (type)
       {
 #define DO_TYPE(NAME, Name)			\
+	case ELF_T_ADD_##NAME:			\
+	case ELF_T_SUB_##NAME:			\
+	  if (addend == NULL)			\
+	    /* These do not make sense with SHT_REL.  */ \
+	    return DWFL_E_BADRELTYPE;		\
+	  is_add_sub = true;			\
+	  size = sizeof (GElf_##Name);		\
+	  break;				\
 	case ELF_T_##NAME:			\
 	  size = sizeof (GElf_##Name);		\
 	break
@@ -417,9 +426,23 @@ relocate (Dwfl_Module * const mod,
       {
 	/* For the addend form, we have the value already.  */
 	value += *addend;
+	if (is_add_sub)
+	  {
+	    Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
+					 ehdr->e_ident[EI_DATA]);
+	    if (d == NULL)
+	      return DWFL_E_LIBELF;
+	    assert (d == &tmpdata);
+	  }
 	switch (type)
 	  {
 #define DO_TYPE(NAME, Name)			\
+	    case ELF_T_ADD_##NAME:		\
+	      tmpbuf.Name += value;		\
+	      break;				\
+	    case ELF_T_SUB_##NAME:		\
+	      tmpbuf.Name -= value;		\
+	      break;				\
 	    case ELF_T_##NAME:			\
 	      tmpbuf.Name = value;		\
 	    break
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index 0c509265cb..faa6d6fd4b 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -52,6 +52,18 @@ const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
       [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
       [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
       [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_ADD_BYTE]	= 1,						      \
+      [ELF_T_ADD_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_ADD_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_ADD_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_ADD_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_ADD_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_SUB_BYTE]	= 1,						      \
+      [ELF_T_SUB_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_SUB_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_SUB_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_SUB_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_SUB_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
       [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
       [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
       [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
diff --git a/libelf/libelf.h b/libelf/libelf.h
index 547c0f5081..38eeea31ab 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -117,6 +117,18 @@ typedef enum
   ELF_T_GNUHASH,		/* GNU-style hash section.  */
   ELF_T_AUXV,			/* Elf32_auxv_t, Elf64_auxv_t, ... */
   ELF_T_CHDR,			/* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
+  ELF_T_ADD_BYTE,
+  ELF_T_SUB_BYTE,
+  ELF_T_ADD_HALF,
+  ELF_T_SUB_HALF,
+  ELF_T_ADD_WORD,
+  ELF_T_SUB_WORD,
+  ELF_T_ADD_SWORD,
+  ELF_T_SUB_SWORD,
+  ELF_T_ADD_XWORD,
+  ELF_T_SUB_XWORD,
+  ELF_T_ADD_SXWORD,
+  ELF_T_SUB_SXWORD,
   /* Keep this the last entry.  */
   ELF_T_NUM
 } Elf_Type;
diff --git a/src/strip.c b/src/strip.c
index 791347c1dd..32190344ba 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -1968,6 +1968,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		if (ebl_debugscn_p (ebl, shdr_info[sec].name))
 		  {
 		    size_t size;
+		    bool is_add_sub;
 
 #define DO_TYPE(NAME, Name) GElf_##Name Name;
 		    union { TYPES; } tmpbuf;
@@ -1976,9 +1977,16 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		    switch (type)
 		      {
 #define DO_TYPE(NAME, Name)				\
+			case ELF_T_ADD_##NAME:		\
+			case ELF_T_SUB_##NAME:		\
+			  size = sizeof (GElf_##Name);	\
+			  tmpbuf.Name = 0;		\
+			  is_add_sub = true;		\
+			  break;			\
 			case ELF_T_##NAME:		\
 			  size = sizeof (GElf_##Name);	\
 			  tmpbuf.Name = 0;		\
+			  is_add_sub = false;		\
 			  break;
 			TYPES;
 #undef DO_TYPE
@@ -2024,6 +2032,15 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 			/* For SHT_RELA sections we just take the
 			   given addend and add it to the value.  */
 			value += addend;
+			if (is_add_sub)
+			  {
+			    Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
+							 &rdata,
+							 ehdr->e_ident[EI_DATA]);
+			    if (d == NULL)
+			      INTERNAL_ERROR (fname);
+			    assert (d == &tmpdata);
+			  }
 		      }
 		    else
 		      {
@@ -2042,7 +2059,11 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		      {
 #define DO_TYPE(NAME, Name)					\
 			case ELF_T_##NAME:			\
+			case ELF_T_ADD_##NAME:			\
 			  tmpbuf.Name += (GElf_##Name) value;	\
+			  break;				\
+			case ELF_T_SUB_##NAME:			\
+			  tmpbuf.Name -= (GElf_##Name) value;	\
 			  break;
 			TYPES;
 #undef DO_TYPE
-- 
2.18.0

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V
  2018-07-24 14:13               ` Andreas Schwab
@ 2018-07-26 16:03                 ` Mark Wielaard
  2018-10-02 12:46                   ` [PATCH] Handle ADD/SUB relocations Andreas Schwab
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Wielaard @ 2018-07-26 16:03 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

On Tue, 2018-07-24 at 16:13 +0200, Andreas Schwab wrote:
> How about this, does it look reasonable?  It doesn't handle SET6/SUB6
> yet, and eu-readelf -wframe doesn't agree with readelf -wf, so this
> is only a RFC.

I don't really like adding not really existing types to the translation
types ELF_T_... I rather see the add/sub part be done as extra argument
to the reloc_simple_type callback. Maybe simply as an int addsub, which
can be -1, 0, 1. It does mean more code needs to be adjusted, but this
is an internal interface, so it can just be changed.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] Handle ADD/SUB relocations
  2018-07-26 16:03                 ` Mark Wielaard
@ 2018-10-02 12:46                   ` Andreas Schwab
  2018-10-13 21:23                     ` Mark Wielaard
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2018-10-02 12:46 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

This adds support for ADD and SUB relocations as seen on RISC-V.

Signed-off-by: Andreas Schwab <schwab@suse.de>
---
 backends/ChangeLog          | 20 ++++++++++++++++++++
 backends/aarch64_symbol.c   |  3 ++-
 backends/alpha_symbol.c     |  3 ++-
 backends/arm_symbol.c       |  3 ++-
 backends/bpf_symbol.c       |  3 ++-
 backends/i386_symbol.c      |  3 ++-
 backends/ia64_symbol.c      |  3 ++-
 backends/m68k_symbol.c      |  3 ++-
 backends/ppc64_symbol.c     |  3 ++-
 backends/ppc_symbol.c       |  3 ++-
 backends/riscv_symbol.c     | 26 +++++++++++++++++++++++++-
 backends/s390_symbol.c      |  3 ++-
 backends/sh_symbol.c        |  3 ++-
 backends/sparc_symbol.c     |  3 ++-
 backends/tilegx_symbol.c    |  3 ++-
 backends/x86_64_symbol.c    |  3 ++-
 libdwfl/ChangeLog           |  4 ++++
 libdwfl/relocate.c          | 21 +++++++++++++++++++--
 libebl/ChangeLog            |  7 +++++++
 libebl/ebl-hooks.h          |  2 +-
 libebl/eblopenbackend.c     |  5 +++--
 libebl/eblrelocsimpletype.c |  4 ++--
 libebl/libebl.h             |  6 ++++--
 src/ChangeLog               |  4 ++++
 src/strip.c                 | 23 +++++++++++++++++++----
 25 files changed, 136 insertions(+), 28 deletions(-)

diff --git a/backends/ChangeLog b/backends/ChangeLog
index fdff302194..a7434dd2d3 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,23 @@
+2018-10-02  Andreas Schwab  <schwab@suse.de>
+
+	* riscv_symbol.c (riscv_reloc_simple_type): Add parameter addsub.
+	Set it for ADD and SUB relocations.
+	* aarch64_symbol.c (aarch64_reloc_simple_type): Add and ignore
+	third parameter.
+	* alpha_symbol.c (alpha_reloc_simple_type): Likewise.
+	* arm_symbol.c (arm_reloc_simple_type): Likewise.
+	* bpf_symbol.c (bpf_reloc_simple_type): Likewise.
+	* i386_symbol.c (i386_reloc_simple_type): Likewise.
+	* ia64_symbol.c (ia64_reloc_simple_type): Likewise.
+	* m68k_symbol.c (m68k_reloc_simple_type): Likewise.
+	* ppc64_symbol.c (ppc64_reloc_simple_type): Likewise.
+	* ppc_symbol.c (ppc_reloc_simple_type): Likewise.
+	* s390_symbol.c (s390_reloc_simple_type): Likewise.
+	* sh_symbol.c (sh_reloc_simple_type): Likewise.
+	* sparc_symbol.c (sparc_reloc_simple_type): Likewise.
+	* tilegx_symbol.c (tilegx_reloc_simple_type): Likewise.
+	* x86_64_symbol.c (x86_64_reloc_simple_type): Likewise.
+
 2018-09-12  Mark Wielaard  <mark@klomp.org>
 
 	* ppc64_init.c (ppc64_init): Use elf_getshdrstrndx.
diff --git a/backends/aarch64_symbol.c b/backends/aarch64_symbol.c
index dfd755a54b..e30c409d74 100644
--- a/backends/aarch64_symbol.c
+++ b/backends/aarch64_symbol.c
@@ -40,7 +40,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			   int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/alpha_symbol.c b/backends/alpha_symbol.c
index b7f7c17a00..53a9e7b7b4 100644
--- a/backends/alpha_symbol.c
+++ b/backends/alpha_symbol.c
@@ -61,7 +61,8 @@ alpha_dynamic_tag_check (int64_t tag)
 
 /* Check for the simple reloc types.  */
 Elf_Type
-alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			 int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/arm_symbol.c b/backends/arm_symbol.c
index 3edda7247e..c8e1d7f914 100644
--- a/backends/arm_symbol.c
+++ b/backends/arm_symbol.c
@@ -109,7 +109,8 @@ arm_machine_flag_check (GElf_Word flags)
 
 /* Check for the simple reloc types.  */
 Elf_Type
-arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+		       int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/bpf_symbol.c b/backends/bpf_symbol.c
index c9856f2638..85c948ab81 100644
--- a/backends/bpf_symbol.c
+++ b/backends/bpf_symbol.c
@@ -40,7 +40,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+		       int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/i386_symbol.c b/backends/i386_symbol.c
index 7dbf899fd2..a4b6ec08b6 100644
--- a/backends/i386_symbol.c
+++ b/backends/i386_symbol.c
@@ -49,7 +49,8 @@ i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
 
 /* Check for the simple reloc types.  */
 Elf_Type
-i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c
index f928b0b7f7..0c038f0dc8 100644
--- a/backends/ia64_symbol.c
+++ b/backends/ia64_symbol.c
@@ -115,7 +115,8 @@ ia64_section_type_name (int type,
 
 /* Check for the simple reloc types.  */
 Elf_Type
-ia64_reloc_simple_type (Ebl *ebl, int type)
+ia64_reloc_simple_type (Ebl *ebl, int type,
+			int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/m68k_symbol.c b/backends/m68k_symbol.c
index 269d12e5bb..9551cdfefd 100644
--- a/backends/m68k_symbol.c
+++ b/backends/m68k_symbol.c
@@ -54,7 +54,8 @@ m68k_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
 
 /* Check for the simple reloc types.  */
 Elf_Type
-m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/ppc64_symbol.c b/backends/ppc64_symbol.c
index 40ba4f7449..81b94cfd9f 100644
--- a/backends/ppc64_symbol.c
+++ b/backends/ppc64_symbol.c
@@ -42,7 +42,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			 int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/ppc_symbol.c b/backends/ppc_symbol.c
index 35b143190c..5a169d5410 100644
--- a/backends/ppc_symbol.c
+++ b/backends/ppc_symbol.c
@@ -42,7 +42,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+		       int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c
index 866a2d7a4b..c34b770206 100644
--- a/backends/riscv_symbol.c
+++ b/backends/riscv_symbol.c
@@ -40,14 +40,38 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			 int *addsub)
 {
   switch (type)
     {
+    case R_RISCV_SET8:
+      return ELF_T_BYTE;
+    case R_RISCV_SET16:
+      return ELF_T_HALF;
     case R_RISCV_32:
+    case R_RISCV_SET32:
       return ELF_T_WORD;
     case R_RISCV_64:
       return ELF_T_XWORD;
+    case R_RISCV_ADD16:
+      *addsub = 1;
+      return ELF_T_HALF;
+    case R_RISCV_SUB16:
+      *addsub = -1;
+      return ELF_T_HALF;
+    case R_RISCV_ADD32:
+      *addsub = 1;
+      return ELF_T_WORD;
+    case R_RISCV_SUB32:
+      *addsub = -1;
+      return ELF_T_WORD;
+    case R_RISCV_ADD64:
+      *addsub = 1;
+      return ELF_T_XWORD;
+    case R_RISCV_SUB64:
+      *addsub = -1;
+      return ELF_T_XWORD;
     default:
       return ELF_T_NUM;
     }
diff --git a/backends/s390_symbol.c b/backends/s390_symbol.c
index a0a4fafaf5..f91e13735e 100644
--- a/backends/s390_symbol.c
+++ b/backends/s390_symbol.c
@@ -38,7 +38,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/sh_symbol.c b/backends/sh_symbol.c
index 8101e96f51..2761d92c20 100644
--- a/backends/sh_symbol.c
+++ b/backends/sh_symbol.c
@@ -47,7 +47,8 @@ sh_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
 
 /* Check for the simple reloc types.  */
 Elf_Type
-sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+		      int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/sparc_symbol.c b/backends/sparc_symbol.c
index ec11dc9731..e8ee39112b 100644
--- a/backends/sparc_symbol.c
+++ b/backends/sparc_symbol.c
@@ -39,7 +39,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			 int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/tilegx_symbol.c b/backends/tilegx_symbol.c
index b6533266a6..62a469070b 100644
--- a/backends/tilegx_symbol.c
+++ b/backends/tilegx_symbol.c
@@ -39,7 +39,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			  int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/backends/x86_64_symbol.c b/backends/x86_64_symbol.c
index 1622461d39..e07b1806d5 100644
--- a/backends/x86_64_symbol.c
+++ b/backends/x86_64_symbol.c
@@ -40,7 +40,8 @@
 
 /* Check for the simple reloc types.  */
 Elf_Type
-x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+			  int *addsub __attribute__ ((unused)))
 {
   switch (type)
     {
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5e9b986d02..c5ea563425 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-02  Andreas Schwab  <schwab@suse.de>
+
+	* relocate.c (relocate): Handle ADD/SUB relocations.
+
 2018-09-13  Mark Wielaard  <mark@klomp.org>
 
 	* dwfl_segment_report_module.c (dwfl_segment_report_module):
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 9afcdebecc..58c56786dd 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -338,7 +338,8 @@ relocate (Dwfl_Module * const mod,
 	 So we just pretend it's OK without further relocation.  */
       return DWFL_E_NOERROR;
 
-    Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
+    int addsub = 0;
+    Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype, &addsub);
     if (unlikely (type == ELF_T_NUM))
       return DWFL_E_BADRELTYPE;
 
@@ -383,6 +384,9 @@ relocate (Dwfl_Module * const mod,
       {
 #define DO_TYPE(NAME, Name)			\
 	case ELF_T_##NAME:			\
+	  if (addsub != 0 && addend == NULL)	\
+	    /* These do not make sense with SHT_REL.  */ \
+	    return DWFL_E_BADRELTYPE;		\
 	  size = sizeof (GElf_##Name);		\
 	break
 	TYPES;
@@ -417,11 +421,24 @@ relocate (Dwfl_Module * const mod,
       {
 	/* For the addend form, we have the value already.  */
 	value += *addend;
+	/* For ADD/SUB relocations we need to fetch the section
+	   contents.  */
+	if (addsub != 0)
+	  {
+	    Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
+					 ehdr->e_ident[EI_DATA]);
+	    if (d == NULL)
+	      return DWFL_E_LIBELF;
+	    assert (d == &tmpdata);
+	  }
 	switch (type)
 	  {
 #define DO_TYPE(NAME, Name)			\
 	    case ELF_T_##NAME:			\
-	      tmpbuf.Name = value;		\
+	      if (addsub != 0)			\
+		tmpbuf.Name += value * addsub;	\
+	      else				\
+		tmpbuf.Name = value;		\
 	    break
 	    TYPES;
 #undef DO_TYPE
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index d36a268158..aec848b9cd 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-02  Andreas Schwab  <schwab@suse.de>
+
+	* ebl-hooks.h (EBLHOOK(reloc_simple_type)): Add third parameter.
+	* libebl.h (ebl_reloc_simple_type): Likewise.
+	* eblopenbackend.c (default_reloc_simple_type): Likewise.
+	* eblrelocsimpletype.c (ebl_reloc_simple_type): Pass it down.
+
 2018-09-12  Mark Wielaard  <mark@klomp.org>
 
 	* eblsectionstripp.c (ebl_section_strip_p): Drop ehdr argument.
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index 7a355cd129..1e7960b896 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -33,7 +33,7 @@ const char *EBLHOOK(reloc_type_name) (int, char *, size_t);
 bool EBLHOOK(reloc_type_check) (int);
 
 /* Check if relocation type is for simple absolute relocations.  */
-Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int);
+Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int, int *);
 
 /* Check relocation type use.  */
 bool EBLHOOK(reloc_valid_use) (Elf *, int);
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index f5b3de29f7..d54b720756 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -145,7 +145,7 @@ static const struct
 static const char *default_reloc_type_name (int ignore, char *buf, size_t len);
 static bool default_reloc_type_check (int ignore);
 static bool default_reloc_valid_use (Elf *elf, int ignore);
-static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore);
+static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore, int *addsub);
 static bool default_gotpc_reloc_check (Elf *elf, int ignore);
 static const char *default_segment_type_name (int ignore, char *buf,
 					      size_t len);
@@ -452,7 +452,8 @@ default_reloc_valid_use (Elf *elf __attribute__ ((unused)),
 
 static Elf_Type
 default_reloc_simple_type (Ebl *eh __attribute__ ((unused)),
-			   int ignore __attribute__ ((unused)))
+			   int ignore __attribute__ ((unused)),
+			   int *addsub __attribute__ ((unused)))
 {
   return ELF_T_NUM;
 }
diff --git a/libebl/eblrelocsimpletype.c b/libebl/eblrelocsimpletype.c
index 9bd29285a3..12292804df 100644
--- a/libebl/eblrelocsimpletype.c
+++ b/libebl/eblrelocsimpletype.c
@@ -34,7 +34,7 @@
 
 
 Elf_Type
-ebl_reloc_simple_type (Ebl *ebl, int reloc)
+ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub)
 {
-  return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc) : ELF_T_NUM;
+  return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc, addsub) : ELF_T_NUM;
 }
diff --git a/libebl/libebl.h b/libebl/libebl.h
index 5abc02d87a..a34fe48ddc 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -99,8 +99,10 @@ extern bool ebl_reloc_type_check (Ebl *ebl, int reloc);
 extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc);
 
 /* Check if relocation type is for simple absolute relocations.
-   Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM.  */
-extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc);
+   Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM.
+   If the relocation type is an ADD or SUB relocation, set *ADDSUB to 1 or -1,
+   resp.  */
+extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub);
 
 /* Return true if the symbol type is that referencing the GOT.  E.g.,
    R_386_GOTPC.  */
diff --git a/src/ChangeLog b/src/ChangeLog
index 6a702ee1cc..7b59ed60b9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-02  Andreas Schwab  <schwab@suse.de>
+
+	* strip.c (handle_elf): Handle ADD/SUB relocation.
+
 2018-09-13  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (print_shdr): Get number of section with elf_getshdrnum.
diff --git a/src/strip.c b/src/strip.c
index 4a3db1b55e..1f7b3cabc0 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -2030,7 +2030,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 		  return true;
 
 		/* We only do simple absolute relocations.  */
-		Elf_Type type = ebl_reloc_simple_type (ebl, rtype);
+		int addsub = 0;
+		Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
 		if (type == ELF_T_NUM)
 		  return false;
 
@@ -2109,6 +2110,17 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 			/* For SHT_RELA sections we just take the
 			   given addend and add it to the value.  */
 			value += addend;
+			/* For ADD/SUB relocations we need to fetch the
+			   current section contents.  */
+			if (addsub != 0)
+			  {
+			    Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
+							 &rdata,
+							 ehdr->e_ident[EI_DATA]);
+			    if (d == NULL)
+			      INTERNAL_ERROR (fname);
+			    assert (d == &tmpdata);
+			  }
 		      }
 		    else
 		      {
@@ -2125,9 +2137,12 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 
 		    switch (type)
 		      {
-#define DO_TYPE(NAME, Name)					\
-			case ELF_T_##NAME:			\
-			  tmpbuf.Name += (GElf_##Name) value;	\
+#define DO_TYPE(NAME, Name)					 \
+			case ELF_T_##NAME:			 \
+			  if (addsub < 0)			 \
+			    tmpbuf.Name -= (GElf_##Name) value; \
+			  else					 \
+			    tmpbuf.Name += (GElf_##Name) value; \
 			  break;
 			TYPES;
 #undef DO_TYPE
-- 
2.19.0

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Handle ADD/SUB relocations
  2018-10-02 12:46                   ` [PATCH] Handle ADD/SUB relocations Andreas Schwab
@ 2018-10-13 21:23                     ` Mark Wielaard
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Wielaard @ 2018-10-13 21:23 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: elfutils-devel

Hi Andreas,

On Tue, 2018-10-02 at 14:46 +0200, Andreas Schwab wrote:
> This adds support for ADD and SUB relocations as seen on RISC-V.

Sorry this took 2 weeks. I should have reviewed it immediately because
it looks just perfect. I pushed it to master.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-10-13 21:23 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-13 10:28 [PATCH] backends: add abi_cfi and register_info callbacks for RISC-V Andreas Schwab
2018-06-14 23:28 ` Mark Wielaard
2018-06-18  8:01   ` Andreas Schwab
2018-06-20 11:16     ` Mark Wielaard
2018-06-20 12:38       ` Andreas Schwab
2018-06-20 12:59         ` Mark Wielaard
2018-06-20 13:55           ` Andreas Schwab
2018-06-20 20:49             ` Mark Wielaard
2018-07-11 13:40               ` Andreas Schwab
2018-07-24 14:13               ` Andreas Schwab
2018-07-26 16:03                 ` Mark Wielaard
2018-10-02 12:46                   ` [PATCH] Handle ADD/SUB relocations Andreas Schwab
2018-10-13 21:23                     ` Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).