[lld] [LLD][RISCV] Warn on PCREL_LO referencing other Section (PR #107558)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 6 03:33:11 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Sam Elliott (lenary)

<details>
<summary>Changes</summary>

The RISC-V psABI states that "The `R_RISCV_PCREL_LO12_I` or `R_RISCV_PCREL_LO12_S` relocations contain a label pointing to an instruction in the same section with an `R_RISCV_PCREL_HI20` relocation entry that points to the target symbol."

In this case, GNU ld errors, but LLD does not -- I think because it is doing the right thing, certainly in the testcase provided.

Nonetheless, it would be good for LLD to at least warn the user, so they know the objects they are using are not following the psABI as written.

Fixes #<!-- -->107304

---
Full diff: https://github.com/llvm/llvm-project/pull/107558.diff


2 Files Affected:

- (modified) lld/ELF/Arch/RISCV.cpp (+9) 
- (added) lld/test/ELF/riscv-pcrel-hilo-error-sections.s (+35) 


``````````diff
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 2435864ce5a7f0..80a7909c42f2e5 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -671,6 +671,15 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
       errorOrWarn(sec.getLocation(rel.offset) +
                   ": R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128");
       return;
+    case R_RISCV_PC_INDIRECT:
+      if (Defined *def = dyn_cast<Defined>(rel.sym);
+          def->section && def->section != &sec) {
+        errorOrWarn(sec.getLocation(rel.offset) +
+              ": R_RISCV_PCREL_LO12 relocation points to a symbol '" +
+              rel.sym->getName() + "' in a different section '" +
+              def->section->name + "'");
+      }
+      break;
     default:
       break;
     }
diff --git a/lld/test/ELF/riscv-pcrel-hilo-error-sections.s b/lld/test/ELF/riscv-pcrel-hilo-error-sections.s
new file mode 100644
index 00000000000000..deffbd91b0ff61
--- /dev/null
+++ b/lld/test/ELF/riscv-pcrel-hilo-error-sections.s
@@ -0,0 +1,35 @@
+# REQUIRES: riscv
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
+# RUN: not ld.lld %t.o 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}:(.text.sec_one+0x0): R_RISCV_PCREL_LO12 relocation points to a symbol '.Lpcrel_hi0' in a different section '.text.sec_two'
+# CHECK: error: {{.*}}:(.text.sec_one+0x4): R_RISCV_PCREL_LO12 relocation points to a symbol '.Lpcrel_hi1' in a different section '.text.sec_two'
+# CHECK-NOT: R_RISCV_PCREL_LO12 relocation points to a symbol '.Lpcrel_hi2'
+
+## This test is checking that we warn the user when the relocations in their
+## object don't follow the RISC-V psABI. In particular, the psABI requires
+## that PCREL_LO12 relocations are in the same section as the pcrel_hi
+## instruction they point to.
+
+  .section .text.sec_one
+  .globl sec_one
+sec_one:
+  addi a0, a0, %pcrel_lo(.Lpcrel_hi0)
+  sw a0, %pcrel_lo(.Lpcrel_hi1)(a1)
+
+  .section .text.sec_two
+sec_two:
+.Lpcrel_hi0:
+  auipc a0, %pcrel_hi(a)
+.Lpcrel_hi1:
+  auipc a1, %pcrel_hi(a)
+
+.Lpcrel_hi2:
+  auipc a2, %pcrel_hi(a)
+  addi a2, a2, %pcrel_lo(.Lpcrel_hi2)
+
+  .data
+  .global a
+a:
+  .word 50

``````````

</details>


https://github.com/llvm/llvm-project/pull/107558


More information about the llvm-commits mailing list