From: Nelson Chu Date: Fri, 14 May 2021 05:30:02 +0000 (+0800) Subject: RISC-V: Check the overflow for %pcrel_lo addend more strictly. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=75f03fa77434ad49f1e7d333e0c93048639806e3;p=binutils-gdb.git 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 --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 + + * 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 * 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 + + * 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 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-2.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.s deleted file mode 100644 index b7f82129ef3..00000000000 --- a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.s +++ /dev/null @@ -1,16 +0,0 @@ - .text - .globl _start - .align 3 -_start: - nop - .LA0: auipc a5,%pcrel_hi(ll) - lw a0,%pcrel_lo(.LA0)(a5) - lw a0,%pcrel_lo(.LA0+4)(a5) - ret - .globl ll - .data - .align 3 - .zero 2024 -ll: - .word 0 - .word 0 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-2a.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.s new file mode 100644 index 00000000000..1e367741d54 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2a.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+0x4)(a5) + ret + .globl ll + .data + .align 3 + .zero 2024 +ll: + .word 0 + .word 0 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