aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-06-22 12:02:52 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-06-22 17:14:55 +0800
commit50331d64f1080c2c9957fb608e0af236b96c1a41 (patch)
tree315aae4fb8f5472c8bbdfa4a8bfeabc803b93104 /ld
parent80dc83fd0e70f4d522a534bc601df5e05b81d564 (diff)
downloadfsf-binutils-gdb-50331d64f1080c2c9957fb608e0af236b96c1a41.zip
fsf-binutils-gdb-50331d64f1080c2c9957fb608e0af236b96c1a41.tar.gz
fsf-binutils-gdb-50331d64f1080c2c9957fb608e0af236b96c1a41.tar.bz2
RISC-V: Clarify the addends of pc-relative access.
The original discussion was here, https://github.com/riscv/riscv-elf-psabi-doc/issues/184 After discussing with Kito Cheng, I think the addends of %pcrel_hi and %pcrel_lo are both allowed in GNU toolchain. However, both of the them mean the offset of symbols, rather than the pc address. But the addends of %got_pcrel_hi and it's %pcrel_lo do not look reasonable. I believe gcc won't generate the got patterns with addends, so linker should report dangerous relocation errors, in case the assembly code use them. Another issue was here, https://sourceware.org/pipermail/binutils/2021-June/116983.html At the beginnig, I suppose %pcrel_hi and %pcrel_lo are valid only when they are in the same input section. But Jim Wilson points out that gcc may generate %hi and %lo in the different input sections, when -freorder-blocks-and-partition option is used. So that a memory references for a loop may have the %hi outside the loop, but the %lo remain in the loop. However, it is hard to create the testcases, to see if %pcrel_hi and %pcrel_lo have the same behavior. Unfortunately, I notice that the current pcrel resolver cannot work for the above case. For now we build a hash table for pcrel at the start of riscv_elf_relocate_section, and then free the hash at the end. But riscv_elf_relocate_section only handles an input section at a time, so that means we can only resolve the %pcrel_hi and %pcrel_lo which are in the same input section. Otherwise, like the above case, we will report "%pcrel_lo missing matching %pcrel_hi" for them. I have no plan to improve this in the short-term, so maybe we can wait until someone meets the problem before we deal with it. bfd/ * elfnn-riscv.c (riscv_pcrel_hi_reloc): Added field to store the original relocation type, in case the type is converted to R_RISCV_HI20. (riscv_pcrel_lo_reloc): Removed unused name field. (riscv_pcrel_relocs): Added comments. (riscv_zero_pcrel_hi_reloc): Removed unused input_bfd. (riscv_record_pcrel_hi_reloc): Updated. (riscv_record_pcrel_lo_reloc): Likewise. (riscv_resolve_pcrel_lo_relocs): Likewise. Check the original type of auipc, to make sure the %pcrel_lo without any addends. Otherwise, report dangerous relocation error. (riscv_elf_relocate_section): Updated above functions are changed. For R_RISCV_GOT_HI20, report dangerous relocation error when addend isn't zero. ld/ * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated. * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d: New testcase. * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d: New testcase. Should report error since the %pcrel_lo with addend refers to %got_pcrel_hi. * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d: New testcase. Should report error since the %got_pcrel_hi with addend. * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog14
-rw-r--r--ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp3
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld13
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d18
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s21
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d4
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s13
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d4
-rw-r--r--ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s13
9 files changed, 103 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index dc08ec9..b4c49cc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,17 @@
+2021-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d: New testcase.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s: Likewise.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d: New testcase.
+ Should report error since the %pcrel_lo with addend refers to
+ %got_pcrel_hi.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s: Likewise.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d: New testcase.
+ Should report error since the %got_pcrel_hi with addend.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s: Likewise.
+ * testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld: Likewise.
+
2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
PR ld/27998
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 0b49ddc..1f1245a 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -87,6 +87,9 @@ if [istarget "riscv*-*-*"] {
run_dump_test "pcrel-lo-addend"
run_dump_test "pcrel-lo-addend-2a"
run_dump_test "pcrel-lo-addend-2b"
+ run_dump_test "pcrel-lo-addend-3a"
+ run_dump_test "pcrel-lo-addend-3b"
+ run_dump_test "pcrel-lo-addend-3c"
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-3.ld b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld
new file mode 100644
index 0000000..fabb65b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld
@@ -0,0 +1,13 @@
+ENTRY(_start)
+SECTIONS
+{
+ .got 0x1000 : {
+ *(.got)
+ }
+ .data 0x2000: {
+ *(.data)
+ }
+ .text 0x900000000 : {
+ *(.text)
+ }
+}
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d
new file mode 100644
index 0000000..1f77e20
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d
@@ -0,0 +1,18 @@
+#source: pcrel-lo-addend-3a.s
+#as: -march=rv64i -mabi=lp64 -mno-relax
+#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
+#objdump: -d
+
+#...
+Disassembly of section .text:
+
+0+900000000 <_start>:
+.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
+.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,0\(a5\) # 2000 <ll>
+.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\)
+.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
+.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\) # 2004 <ll\+0x4>
+.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\)
+.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x1
+.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\) # 1008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s
new file mode 100644
index 0000000..14dc596
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s
@@ -0,0 +1,21 @@
+ .text
+ .globl _start
+ .align 3
+_start:
+.LA0: auipc a5, %pcrel_hi (ll)
+ ld a0, %pcrel_lo (.LA0)(a5)
+ ld a0, %pcrel_lo (.LA0 + 0x4)(a5)
+
+.LA1: auipc a5, %pcrel_hi (ll + 0x4)
+ ld a0, %pcrel_lo (.LA1)(a5)
+ ld a0, %pcrel_lo (.LA1 + 0x4)(a5)
+
+.LA2: auipc a5, %got_pcrel_hi (ll)
+ ld a0, %pcrel_lo (.LA2)(a5)
+
+ .globl ll
+ .data
+ll:
+ .dword 0
+ .dword 0
+ .dword 0
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d
new file mode 100644
index 0000000..9c87c16
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d
@@ -0,0 +1,4 @@
+#source: pcrel-lo-addend-3b.s
+#as: -march=rv64i -mabi=lp64 -mno-relax
+#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
+#error: .*dangerous relocation: The addend isn't allowed for R_RISCV_GOT_HI20
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s
new file mode 100644
index 0000000..0b7ebd6
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s
@@ -0,0 +1,13 @@
+ .text
+ .globl _start
+ .align 3
+_start:
+.LA0: auipc a5, %got_pcrel_hi (ll + 0x4)
+ ld a0, %pcrel_lo (.LA0)(a5)
+
+ .globl ll
+ .data
+ll:
+ .dword 0
+ .dword 0
+ .dword 0
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d
new file mode 100644
index 0000000..295895b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d
@@ -0,0 +1,4 @@
+#source: pcrel-lo-addend-3c.s
+#as: -march=rv64i -mabi=lp64 -mno-relax
+#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
+#error: .*dangerous relocation: %pcrel_lo with addend isn't allowed for R_RISCV_GOT_HI20
diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s
new file mode 100644
index 0000000..0495851
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s
@@ -0,0 +1,13 @@
+ .text
+ .globl _start
+ .align 3
+_start:
+.LA0: auipc a5, %got_pcrel_hi (ll)
+ ld a0, %pcrel_lo (.LA0 + 0x4)(a5)
+
+ .globl ll
+ .data
+ll:
+ .dword 0
+ .dword 0
+ .dword 0