Skip to content

Commit 4ad27cf

Browse files
committed
Fix for link error on RISC-V
Fix for issue zephyrproject-rtos/zephyr#18198 Signed-off-by: Kumar Gala <[email protected]>
1 parent fbbb329 commit 4ad27cf

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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

Comments
 (0)