RISC-V: Fix lui relaxation issue with code at address 0.
This fixes a problem originally reported at https://github.com/riscv/riscv-binutils-gdb/issues/173 If you have code linked at address zero, you can have a lui instruction loading a value 0x800 which gets relaxed to a c.lui which is valid (c.lui 0x1 followed by addi -0x800). Relaxation can reduce the value below 0x800 at which point the c.lui 0x0 is no longer valid. We can fix this by converting the c.lui to a c.li which can load 0. bfd/ * elfnn-riscv.c (perform_relocation) <R_RISCV_RVC_LUI>: If RISCV_CONST_HIGH_PART (value) is zero, then convert c.lui instruction to c.li instruction, and use ENCODE_RVC_IMM to set value. ld/ * testsuite/ld-riscv-elf/c-lui-2.d: New. * testsuite/ld-riscv-elf/c-lui-2.ld: New. * testsuite/ld-riscv-elf/c-lui-2.s: New. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run the c-lui-2 test.
This commit is contained in:
parent
db502012fc
commit
080a488354
@ -1,3 +1,9 @@
|
||||
2019-08-15 Jim Wilson <jimw@sifive.com>
|
||||
|
||||
* elfnn-riscv.c (perform_relocation) <R_RISCV_RVC_LUI>: If
|
||||
RISCV_CONST_HIGH_PART (value) is zero, then convert c.lui instruction
|
||||
to c.li instruction, and use ENCODE_RVC_IMM to set value.
|
||||
|
||||
2019-08-15 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* dwarf2.c (scan_unit_for_symbols): Check for end of CU, not end
|
||||
|
@ -1482,9 +1482,21 @@ perform_relocation (const reloc_howto_type *howto,
|
||||
break;
|
||||
|
||||
case R_RISCV_RVC_LUI:
|
||||
if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)))
|
||||
if (RISCV_CONST_HIGH_PART (value) == 0)
|
||||
{
|
||||
/* Linker relaxation can convert an address equal to or greater than
|
||||
0x800 to slightly below 0x800. C.LUI does not accept zero as a
|
||||
valid immediate. We can fix this by converting it to a C.LI. */
|
||||
bfd_vma insn = bfd_get (howto->bitsize, input_bfd,
|
||||
contents + rel->r_offset);
|
||||
insn = (insn & ~MATCH_C_LUI) | MATCH_C_LI;
|
||||
bfd_put (howto->bitsize, input_bfd, insn, contents + rel->r_offset);
|
||||
value = ENCODE_RVC_IMM (0);
|
||||
}
|
||||
else if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)))
|
||||
return bfd_reloc_overflow;
|
||||
value = ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value));
|
||||
else
|
||||
value = ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value));
|
||||
break;
|
||||
|
||||
case R_RISCV_32:
|
||||
|
@ -1,3 +1,10 @@
|
||||
2019-08-15 Jim Wilson <jimw@sifive.com>
|
||||
|
||||
* testsuite/ld-riscv-elf/c-lui-2.d: New.
|
||||
* testsuite/ld-riscv-elf/c-lui-2.ld: New.
|
||||
* testsuite/ld-riscv-elf/c-lui-2.s: New.
|
||||
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run the c-lui-2 test.
|
||||
|
||||
2019-08-10 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ldlang.h (enum statement_enum): Sort.
|
||||
|
19
ld/testsuite/ld-riscv-elf/c-lui-2.d
Normal file
19
ld/testsuite/ld-riscv-elf/c-lui-2.d
Normal file
@ -0,0 +1,19 @@
|
||||
#name: c.lui to c.li relaxation
|
||||
#source: c-lui-2.s
|
||||
#as: -march=rv32ic
|
||||
#ld: -melf32lriscv -Tc-lui-2.ld
|
||||
#objdump: -d -M no-aliases,numeric
|
||||
|
||||
.*: file format .*
|
||||
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
.* <_start>:
|
||||
.*: 4501 c.li x10,0
|
||||
.*: 7fe00513 addi x10,x0,2046
|
||||
...
|
||||
|
||||
.* <foo>:
|
||||
.*: 8082 c.jr x1
|
||||
#pass
|
6
ld/testsuite/ld-riscv-elf/c-lui-2.ld
Normal file
6
ld/testsuite/ld-riscv-elf/c-lui-2.ld
Normal file
@ -0,0 +1,6 @@
|
||||
ENTRY(_start)
|
||||
SECTIONS {
|
||||
.text 0x00000000 : {
|
||||
*(.text*)
|
||||
}
|
||||
}
|
12
ld/testsuite/ld-riscv-elf/c-lui-2.s
Normal file
12
ld/testsuite/ld-riscv-elf/c-lui-2.s
Normal file
@ -0,0 +1,12 @@
|
||||
.option nopic
|
||||
.text
|
||||
.align 1
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
lui a0,%hi(foo)
|
||||
addi a0,a0,%lo(foo)
|
||||
.skip 0x7f8
|
||||
foo:
|
||||
ret
|
||||
.size _start, .-_start
|
@ -21,6 +21,7 @@
|
||||
|
||||
if [istarget "riscv*-*-*"] {
|
||||
run_dump_test "c-lui"
|
||||
run_dump_test "c-lui-2"
|
||||
run_dump_test "disas-jalr"
|
||||
run_dump_test "pcrel-lo-addend"
|
||||
run_dump_test "pcrel-lo-addend-2"
|
||||
|
Loading…
Reference in New Issue
Block a user