Skip to content

[LLD][RISCV] Error on PCREL_LO referencing other Section #107558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 8, 2024

Conversation

lenary
Copy link
Member

@lenary lenary commented Sep 6, 2024

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, I think an error is good here to bring LLD in line with what GNU ld is doing in showing that the object they are using is not following the psABI as written.

Fixes #107304

@llvmbot
Copy link
Member

llvmbot commented Sep 6, 2024

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Sam Elliott (lenary)

Changes

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 --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

Copy link

github-actions bot commented Sep 6, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@lenary lenary force-pushed the lld/riscv-pcrel-hilo-warning branch from e6346f6 to 4e77a57 Compare September 6, 2024 10:39
@lenary lenary changed the title [LLD][RISCV] Warn on PCREL_LO referencing other Section [LLD][RISCV] Error on PCREL_LO referencing other Section Sep 6, 2024
@lenary
Copy link
Member Author

lenary commented Sep 6, 2024

Some notes on how I fixed this:

  • The function which does the other validation of PCREL_LO relocations is getRISCVPCRelHi20 - but it, and where it is called from (InputSectionBase::getRelocTargetVA) do not have access to the input section, for comparison with the section of the symbol referenced by the relocation. Changing this seems quite an invasive change (likely needing to make getRelocTargetVA non-static, changing quite a few call sites)

  • I've been fairly indecisive about whether this should be an errorOrWarn, or a warn. Guidance about which is preferred would be helpful.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I am on vacation and is likely slow to respond.)

@lenary lenary force-pushed the lld/riscv-pcrel-hilo-warning branch from 4e77a57 to d35afe9 Compare September 13, 2024 14:53
@lenary
Copy link
Member Author

lenary commented Sep 18, 2024

ping

@lenary
Copy link
Member Author

lenary commented Oct 7, 2024

Thanks for the refactor in 2b5cb1bf628fc54473355e0675f629d9332089df - I'll change the approach and implement this in getRISCVPCRelHi20 - updated PR coming imminently.

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 LLD is
doing the right thing, certainly in the testcase provided.

Nonetheless, I think an error is good here to bring LLD in line with
what GNU ld is doing in showing that the object they are using is not
following the psABI as written.

Fixes llvm#107304
@lenary lenary force-pushed the lld/riscv-pcrel-hilo-warning branch from faab323 to a781311 Compare October 7, 2024 17:58
@lenary
Copy link
Member Author

lenary commented Oct 7, 2024

I also took the opportunity to improve the other errors/warnings emitted by the same function to point to exactly where the issue is.

@lenary lenary merged commit db1a762 into llvm:main Oct 8, 2024
7 of 9 checks passed
@lenary lenary deleted the lld/riscv-pcrel-hilo-warning branch October 8, 2024 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[lld][RISC-V] No Warning/Error on R_RISCV_PCREL_LO referencing symbol/relocation in different section
3 participants