[binutils-gdb] RISC-V: Check the overflow for %pcrel_lo addend more strictly.

Nelson Chu nelsonc1225@sourceware.org
Fri May 14 08:14:59 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=75f03fa77434ad49f1e7d333e0c93048639806e3

commit 75f03fa77434ad49f1e7d333e0c93048639806e3
Author: Nelson Chu <nelson.chu@sifive.com>
Date:   Fri May 14 13:30:02 2021 +0800

    RISC-V: Check the overflow for %pcrel_lo addend more strictly.
    
    The %pcrel_lo addend may causes the overflow, and need more than one
    %pcrel_hi values.  But there may be only one auipc, shared by those
    %pcrel_lo with addends.  However, the existing check method in the
    riscv_resolve_pcrel_lo_relocs, may not be able to work for some
    special/corner cases.
    
    Consider the testcases pcrel-lo-addend-2b.  Before applying this patch,
    I can compile it successfully.  But in fact the addend cause the value
    of %pcrel_hi to be different.  This patch try to check the value of
    %pcrel_hi directly, to make sure it won't be changed.  Otherwise, linker
    will report the following errors,
    
    (.text+0xa): dangerous relocation: %pcrel_lo overflow with an addend,
    the value of %pcrel_hi is 0x1000 without any addend, but may be 0x2000
    after adding the %pcrel_lo addend
    
    The toolchain regressions, rv64gc-linux/rv64gc-elf/rv32gc-linux/rv32i-elf,
    pass expectedly and looks fine.
    
    bfd/
        * elfnn-riscv.c (riscv_resolve_pcrel_lo_relocs): Check the values
        of %pcrel_hi, before and after adding the addend.  Make sure the
        value won't be changed, otherwise, report dangerous error.
    ld/
        * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
        * testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d: Renamed from
        pcrel-lo-addend-2.
        * testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s: Likewise.
        * testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d: New testcase.
        * testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s: Likewise.

Diff:
---
 bfd/ChangeLog                                      |  6 ++++++
 bfd/elfnn-riscv.c                                  | 22 ++++++++++++++++------
 ld/ChangeLog                                       |  9 +++++++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp         |  3 ++-
 ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d      |  5 -----
 ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d     |  5 +++++
 .../{pcrel-lo-addend-2.s => pcrel-lo-addend-2a.s}  |  2 +-
 ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d     |  5 +++++
 ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s     | 16 ++++++++++++++++
 9 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8dbe40c474d..b399aefd120 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2021-05-14  Nelson Chu  <nelson.chu@sifive.com>
+
+	* elfnn-riscv.c (riscv_resolve_pcrel_lo_relocs): Check the values
+	of %pcrel_hi, before and after adding the addend.  Make sure the
+	value won't be changed, otherwise, report dangerous error.
+
 2021-05-13  Nelson Chu  <nelson.chu@sifive.com>
 
 	* elfxx-riscv.c (check_implicit_always): The check_func, always add
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index a944b330227..2068edebdb6 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1883,13 +1883,23 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
       riscv_pcrel_hi_reloc search = {r->addr, 0};
       riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search);
       if (entry == NULL
-	  /* Check for overflow into bit 11 when adding reloc addend.  */
-	  || (!(entry->value & 0x800)
-	      && ((entry->value + r->reloc->r_addend) & 0x800)))
+	  /* Check the overflow when adding reloc addend.  */
+	  || (RISCV_CONST_HIGH_PART (entry->value)
+	      != RISCV_CONST_HIGH_PART (entry->value + r->reloc->r_addend)))
 	{
-	  char *string = (entry == NULL
-			  ? "%pcrel_lo missing matching %pcrel_hi"
-			  : "%pcrel_lo overflow with an addend");
+	  char *string;
+	  if (entry == NULL)
+	    string = _("%pcrel_lo missing matching %pcrel_hi");
+	  else if (asprintf (&string,
+			     _("%%pcrel_lo overflow with an addend, the "
+			       "value of %%pcrel_hi is 0x%" PRIx64 " without "
+			       "any addend, but may be 0x%" PRIx64 " after "
+			       "adding the %%pcrel_lo addend"),
+			     (int64_t) RISCV_CONST_HIGH_PART (entry->value),
+			     (int64_t) RISCV_CONST_HIGH_PART
+				(entry->value + r->reloc->r_addend)) == -1)
+	    string = _("%pcrel_lo overflow with an addend");
+
 	  (*r->info->callbacks->reloc_dangerous)
 	    (r->info, string, input_bfd, r->input_section, r->reloc->r_offset);
 	  return true;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index e9aae885988..3969b8c80fa 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2021-05-14  Nelson Chu  <nelson.chu@sifive.com>
+
+	* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
+	* testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d: Renamed from
+	pcrel-lo-addend-2.
+	* testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s: Likewise.
+	* testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d: New testcase.
+	* testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s: Likewise.
+
 2021-05-13  Fangrui Song  <maskray@google.com>
 
 	PR 27834
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index f3ff95cf96e..319ac7e2b83 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -85,7 +85,8 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "c-lui-2"
     run_dump_test "disas-jalr"
     run_dump_test "pcrel-lo-addend"
-    run_dump_test "pcrel-lo-addend-2"
+    run_dump_test "pcrel-lo-addend-2a"
+    run_dump_test "pcrel-lo-addend-2b"
     run_dump_test "restart-relax"
     run_dump_test "attr-merge-arch-01"
     run_dump_test "attr-merge-arch-02"
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d
deleted file mode 100644
index 895c6cc5814..00000000000
--- a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d
+++ /dev/null
@@ -1,5 +0,0 @@
-#name: %pcrel_lo overflow with an addend
-#source: pcrel-lo-addend-2.s
-#as: -march=rv32ic
-#ld: -m[riscv_choose_ilp32_emul] --no-relax
-#error: .*dangerous relocation: %pcrel_lo overflow with an addend
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d
new file mode 100644
index 00000000000..cd50cbfd262
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.d
@@ -0,0 +1,5 @@
+#name: %pcrel_lo overflow with an addend (2a)
+#source: pcrel-lo-addend-2a.s
+#as: -march=rv32ic
+#ld: -m[riscv_choose_ilp32_emul] --no-relax
+#error: .*dangerous relocation: %pcrel_lo overflow with an addend, the value of %pcrel_hi is 0x1000 without any addend, but may be 0x2000 after adding the %pcrel_lo addend
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s
similarity index 84%
rename from ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.s
rename to ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s
index b7f82129ef3..1e367741d54 100644
--- a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.s
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s
@@ -5,7 +5,7 @@ _start:
 	nop
 	.LA0: auipc	a5,%pcrel_hi(ll)
 	lw	a0,%pcrel_lo(.LA0)(a5)
-	lw	a0,%pcrel_lo(.LA0+4)(a5)
+	lw	a0,%pcrel_lo(.LA0+0x4)(a5)
 	ret
 	.globl ll
 	.data
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d
new file mode 100644
index 00000000000..d20f8c1bc87
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.d
@@ -0,0 +1,5 @@
+#name: %pcrel_lo overflow with an addend (2b)
+#source: pcrel-lo-addend-2b.s
+#as: -march=rv32ic
+#ld: -m[riscv_choose_ilp32_emul] --no-relax
+#error: .*dangerous relocation: %pcrel_lo overflow with an addend, the value of %pcrel_hi is 0x1000 without any addend, but may be 0x2000 after adding the %pcrel_lo addend
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s
new file mode 100644
index 00000000000..9fd063f93e5
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2b.s
@@ -0,0 +1,16 @@
+	.text
+	.globl _start
+	.align 3
+_start:
+	nop
+	.LA0: auipc	a5,%pcrel_hi(ll)
+	lw	a0,%pcrel_lo(.LA0)(a5)
+	lw	a0,%pcrel_lo(.LA0+0x1000)(a5)
+	ret
+	.globl ll
+	.data
+	.align 3
+	.zero 2024
+ll:
+	.word 0
+	.word 0


More information about the Binutils-cvs mailing list