This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] RISC-V: Fix readelf's R_RISCV_{ADD,SUB}{8,16,32,64} handling


I'm not entirely sure this is correct, but it does pass the test cases
(as well as a handful of small modifications I made to them).  The
implementation is patterned off the existing ones, with the additional
wrinkle that we have more relocations than the other ports do.

It feels a bit odd to handle the relocations this way, as I'd expect
this to either be handled by BFD or at least to look up the relocations
via address (as opposed to just assuming tehy're in a particular order),
but I can't figure out a better way to do this.

binutils/ChangeLog

2017-10-16  Palmer Dabbelt  <palmer@dabbelt.com>

        * readelf.c (target_specific_reloc_handling) <EM_RISCV>: Handle
        R_RISCV_{ADD,SUB}{8,16,32,64} relocations.

gas/ChangeLog

2017-10-16  Palmer Dabbelt  <palmer@dabbelt.com>

        * testsuite/gas/lns/lns.exp: Use lns-common-1-alt instead of
        lns-common-1 for RISC-V targets.
---
 binutils/readelf.c            | 74 +++++++++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/lns/lns.exp |  1 +
 2 files changed, 75 insertions(+)

diff --git a/binutils/readelf.c b/binutils/readelf.c
index b2f75c0048bf..cfea265369a2 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -11993,6 +11993,80 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
 	  }
 	break;
       }
+
+    case EM_RISCV:
+      {
+	static bfd_vma saved_sym1 = 0;
+	static bfd_vma saved_sym2 = 0;
+	bfd_vma size_bytes, multiplier, value;
+
+	switch (reloc_type)
+	  {
+	  case 1: /* R_RISCV_32 */
+	    size_bytes = 4;
+	    multiplier = 0;
+	    goto handle_abs_reloc;
+	  case 2: /* R_RISCV_64 */
+	    size_bytes = 8;
+	    multiplier = 0;
+	    goto handle_abs_reloc;
+
+	  case 33: /* R_RISCV_ADD8  */
+	    size_bytes = 1;
+	    multiplier = 1;
+	    goto handle_add_sub_reloc;
+	  case 34: /* R_RISCV_ADD16 */
+	    size_bytes = 2;
+	    multiplier = 1;
+	    goto handle_add_sub_reloc;
+	  case 35: /* R_RISCV_ADD32 */
+	    size_bytes = 4;
+	    multiplier = 1;
+	    goto handle_add_sub_reloc;
+	  case 36: /* R_RISCV_ADD64 */
+	    size_bytes = 8;
+	    multiplier = 1;
+	    goto handle_add_sub_reloc;
+	  case 37: /* R_RISCV_SUB8  */
+	    size_bytes = 1;
+	    multiplier = -1;
+	    goto handle_add_sub_reloc;
+	  case 38: /* R_RISCV_SUB16 */
+	    size_bytes = 2;
+	    multiplier = -1;
+	    goto handle_add_sub_reloc;
+	  case 39: /* R_RISCV_SUB32 */
+	    size_bytes = 4;
+	    multiplier = -1;
+	    goto handle_add_sub_reloc;
+	  case 40: /* R_RISCV_SUB64 */
+	    size_bytes = 8;
+	    multiplier = -1;
+	    goto handle_add_sub_reloc;
+
+	  default:
+	    return FALSE;
+	  }
+
+	handle_abs_reloc:
+	  /* This symbol is an absolute address, so just push it onto the
+	   * stack.  */
+	  saved_sym2 = saved_sym1;
+	  saved_sym1 = symtab[sym_index].st_value + reloc->r_addend;
+	  return FALSE;
+
+	handle_add_sub_reloc:
+	  /* This symbol is a sum or difference, so compute the original value
+	   * of the relocation by looking at the previous two symbol values.  */
+	  saved_sym2 = saved_sym1;
+	  saved_sym1 = symtab[sym_index].st_value + reloc->r_addend;
+
+	  value = (multiplier * saved_sym1) + (-1 * multiplier * saved_sym2);
+	  if (IN_RANGE (start, end, start + reloc->r_offset, size_bytes)) {
+	    byte_put(start + reloc->r_offset, value, size_bytes);
+	  }
+	  return TRUE;
+      }
     }
 
   return FALSE;
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index 281b621f7243..02312c3e2c7e 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -38,6 +38,7 @@ if {
 	 || [istarget msp430-*-*]
 	 || [istarget nds32*-*-*]
 	 || [istarget pru-*-*]
+	 || [istarget riscv*-*-*]
 	 || [istarget rl78-*-*]
 	 || [istarget xtensa*-*-*] } {
       run_dump_test "lns-common-1-alt"
-- 
2.13.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]