|
| 1 | +From 37ab072c3e4cc995715e7d32778c5cdb35d655ab Mon Sep 17 00:00:00 2001 |
| 2 | +From: Jim Wilson < [email protected]> |
| 3 | +Date: Thu, 15 Aug 2019 12:01:13 -0700 |
| 4 | +Subject: [PATCH] RISC-V: Fix lui relaxation issue with code at address 0. |
| 5 | + |
| 6 | +This fixes a problem originally reported at |
| 7 | + https://github.com/riscv/riscv-binutils-gdb/issues/173 |
| 8 | + |
| 9 | +If you have code linked at address zero, you can have a lui instruction |
| 10 | +loading a value 0x800 which gets relaxed to a c.lui which is valid (c.lui 0x1 |
| 11 | +followed by addi -0x800). Relaxation can reduce the value below 0x800 at which |
| 12 | +point the c.lui 0x0 is no longer valid. We can fix this by converting the |
| 13 | +c.lui to a c.li which can load 0. |
| 14 | + |
| 15 | + bfd/ |
| 16 | + * elfnn-riscv.c (perform_relocation) <R_RISCV_RVC_LUI>: If |
| 17 | + RISCV_CONST_HIGH_PART (value) is zero, then convert c.lui instruction |
| 18 | + to c.li instruction, and use ENCODE_RVC_IMM to set value. |
| 19 | + |
| 20 | + ld/ |
| 21 | + * testsuite/ld-riscv-elf/c-lui-2.d: New. |
| 22 | + * testsuite/ld-riscv-elf/c-lui-2.ld: New. |
| 23 | + * testsuite/ld-riscv-elf/c-lui-2.s: New. |
| 24 | + * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run the c-lui-2 test. |
| 25 | +--- |
| 26 | + bfd/ChangeLog | 6 ++++++ |
| 27 | + bfd/elfnn-riscv.c | 16 ++++++++++++++-- |
| 28 | + ld/testsuite/ld-riscv-elf/c-lui-2.d | 19 +++++++++++++++++++ |
| 29 | + ld/testsuite/ld-riscv-elf/c-lui-2.ld | 6 ++++++ |
| 30 | + ld/testsuite/ld-riscv-elf/c-lui-2.s | 12 ++++++++++++ |
| 31 | + ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 + |
| 32 | + 6 files changed, 58 insertions(+), 2 deletions(-) |
| 33 | + create mode 100644 ld/testsuite/ld-riscv-elf/c-lui-2.d |
| 34 | + create mode 100644 ld/testsuite/ld-riscv-elf/c-lui-2.ld |
| 35 | + create mode 100644 ld/testsuite/ld-riscv-elf/c-lui-2.s |
| 36 | + |
| 37 | +diff --git a/bfd/ChangeLog b/bfd/ChangeLog |
| 38 | +index 3584bfefc0..97ba6c97e8 100644 |
| 39 | +--- a/bfd/ChangeLog |
| 40 | ++++ b/bfd/ChangeLog |
| 41 | +@@ -1,3 +1,9 @@ |
| 42 | ++2019-08-15 Jim Wilson <[email protected]> |
| 43 | ++ |
| 44 | ++ * elfnn-riscv.c (perform_relocation) <R_RISCV_RVC_LUI>: If |
| 45 | ++ RISCV_CONST_HIGH_PART (value) is zero, then convert c.lui instruction |
| 46 | ++ to c.li instruction, and use ENCODE_RVC_IMM to set value. |
| 47 | ++ |
| 48 | + 2019-08-01 Ilia Diachkov < [email protected]> |
| 49 | + |
| 50 | + * elfnn-riscv.c (_bfd_riscv_relax_lui): Set lui relax safety area to |
| 51 | +diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c |
| 52 | +index abf0f6cf3f..d6455bb150 100644 |
| 53 | +--- a/bfd/elfnn-riscv.c |
| 54 | ++++ b/bfd/elfnn-riscv.c |
| 55 | +@@ -1482,9 +1482,21 @@ perform_relocation (const reloc_howto_type *howto, |
| 56 | + break; |
| 57 | + |
| 58 | + case R_RISCV_RVC_LUI: |
| 59 | +- if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value))) |
| 60 | ++ if (RISCV_CONST_HIGH_PART (value) == 0) |
| 61 | ++ { |
| 62 | ++ /* Linker relaxation can convert an address equal to or greater than |
| 63 | ++ 0x800 to slightly below 0x800. C.LUI does not accept zero as a |
| 64 | ++ valid immediate. We can fix this by converting it to a C.LI. */ |
| 65 | ++ bfd_vma insn = bfd_get (howto->bitsize, input_bfd, |
| 66 | ++ contents + rel->r_offset); |
| 67 | ++ insn = (insn & ~MATCH_C_LUI) | MATCH_C_LI; |
| 68 | ++ bfd_put (howto->bitsize, input_bfd, insn, contents + rel->r_offset); |
| 69 | ++ value = ENCODE_RVC_IMM (0); |
| 70 | ++ } |
| 71 | ++ else if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value))) |
| 72 | + return bfd_reloc_overflow; |
| 73 | +- value = ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)); |
| 74 | ++ else |
| 75 | ++ value = ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)); |
| 76 | + break; |
| 77 | + |
| 78 | + case R_RISCV_32: |
| 79 | +diff --git a/ld/testsuite/ld-riscv-elf/c-lui-2.d b/ld/testsuite/ld-riscv-elf/c-lui-2.d |
| 80 | +new file mode 100644 |
| 81 | +index 0000000000..622c0f7a31 |
| 82 | +--- /dev/null |
| 83 | ++++ b/ld/testsuite/ld-riscv-elf/c-lui-2.d |
| 84 | +@@ -0,0 +1,19 @@ |
| 85 | ++#name: c.lui to c.li relaxation |
| 86 | ++#source: c-lui-2.s |
| 87 | ++#as: -march=rv32ic |
| 88 | ++#ld: -melf32lriscv -Tc-lui-2.ld |
| 89 | ++#objdump: -d -M no-aliases,numeric |
| 90 | ++ |
| 91 | ++.*: file format .* |
| 92 | ++ |
| 93 | ++ |
| 94 | ++Disassembly of section \.text: |
| 95 | ++ |
| 96 | ++.* <_start>: |
| 97 | ++.*: 4501 c.li x10,0 |
| 98 | ++.*: 7fe00513 addi x10,x0,2046 |
| 99 | ++ ... |
| 100 | ++ |
| 101 | ++.* <foo>: |
| 102 | ++.*: 8082 c.jr x1 |
| 103 | ++#pass |
| 104 | +diff --git a/ld/testsuite/ld-riscv-elf/c-lui-2.ld b/ld/testsuite/ld-riscv-elf/c-lui-2.ld |
| 105 | +new file mode 100644 |
| 106 | +index 0000000000..1a0596dad9 |
| 107 | +--- /dev/null |
| 108 | ++++ b/ld/testsuite/ld-riscv-elf/c-lui-2.ld |
| 109 | +@@ -0,0 +1,6 @@ |
| 110 | ++ENTRY(_start) |
| 111 | ++SECTIONS { |
| 112 | ++ .text 0x00000000 : { |
| 113 | ++ *(.text*) |
| 114 | ++ } |
| 115 | ++} |
| 116 | +diff --git a/ld/testsuite/ld-riscv-elf/c-lui-2.s b/ld/testsuite/ld-riscv-elf/c-lui-2.s |
| 117 | +new file mode 100644 |
| 118 | +index 0000000000..7aa258606a |
| 119 | +--- /dev/null |
| 120 | ++++ b/ld/testsuite/ld-riscv-elf/c-lui-2.s |
| 121 | +@@ -0,0 +1,12 @@ |
| 122 | ++ .option nopic |
| 123 | ++ .text |
| 124 | ++ .align 1 |
| 125 | ++ .globl _start |
| 126 | ++ .type _start, @function |
| 127 | ++_start: |
| 128 | ++ lui a0,%hi(foo) |
| 129 | ++ addi a0,a0,%lo(foo) |
| 130 | ++ .skip 0x7f8 |
| 131 | ++foo: |
| 132 | ++ ret |
| 133 | ++ .size _start, .-_start |
| 134 | +diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |
| 135 | +index bce7bfeeba..c994a57c48 100644 |
| 136 | +--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |
| 137 | ++++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |
| 138 | +@@ -21,6 +21,7 @@ |
| 139 | + |
| 140 | + if [istarget "riscv*-*-*"] { |
| 141 | + run_dump_test "c-lui" |
| 142 | ++ run_dump_test "c-lui-2" |
| 143 | + run_dump_test "disas-jalr" |
| 144 | + run_dump_test "pcrel-lo-addend" |
| 145 | + run_dump_test "pcrel-lo-addend-2" |
| 146 | +-- |
| 147 | +2.20.1 |
| 148 | + |
0 commit comments