[lld] Allow Arm PC-relative relocations in pic or shared library (PR #77304)
Eleanor Bonnici via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 9 15:31:16 PST 2024
https://github.com/eleanor-arm updated https://github.com/llvm/llvm-project/pull/77304
>From 8a310b6a98a0cdefc7e76b9123d20abb3c407130 Mon Sep 17 00:00:00 2001
From: Eleanor Bonnici <eleanor.bonnici at arm.com>
Date: Mon, 8 Jan 2024 13:50:27 +0000
Subject: [PATCH] Allow Arm PC-relative relocations in pic or shared library
The relocations that map to R_ARM_PCA are equivalent to R_PC. They are
PC-relative and safe to use in shared-libraries, but have a different
relocation code as they are evaluated differently. Now that LLVM may
generate these relocations in object files they may occur in
shared-libries or position-independent executables.
---
lld/ELF/Relocations.cpp | 21 ++++++++++-----------
lld/test/ELF/arm-adr-pic.s | 13 +++++++++++++
2 files changed, 23 insertions(+), 11 deletions(-)
create mode 100644 lld/test/ELF/arm-adr-pic.s
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 210b4d1eb1a7a6..05002494d4d94a 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -210,10 +210,10 @@ bool lld::elf::needsGot(RelExpr expr) {
// True if this expression is of the form Sym - X, where X is a position in the
// file (PC, or GOT for example).
static bool isRelExpr(RelExpr expr) {
- return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_MIPS_GOTREL, R_PPC64_CALL,
- R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC, R_RELAX_GOT_PC,
- R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC, R_LOONGARCH_PAGE_PC>(
- expr);
+ return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_ARM_PCA, R_MIPS_GOTREL,
+ R_PPC64_CALL, R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC,
+ R_RELAX_GOT_PC, R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC,
+ R_LOONGARCH_PAGE_PC>(expr);
}
static RelExpr toPlt(RelExpr expr) {
@@ -559,7 +559,7 @@ struct UndefinedDiag {
std::vector<UndefinedDiag> undefs;
std::mutex relocMutex;
-}
+} // namespace
// Check whether the definition name def is a mangled function name that matches
// the reference name ref.
@@ -1016,7 +1016,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
// We set the final symbols values for linker script defined symbols later.
// They always can be computed as a link time constant.
if (sym.scriptDefined)
- return true;
+ return true;
error("relocation " + toString(type) + " cannot refer to absolute symbol: " +
toString(sym) + getLocation(*sec, sym, relOff));
@@ -1282,11 +1282,10 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// relaxation.
// For PPC64, if the file has missing R_PPC64_TLSGD/R_PPC64_TLSLD, disable
// relaxation as well.
- bool toExecRelax = !config->shared && config->emachine != EM_ARM &&
- config->emachine != EM_HEXAGON &&
- config->emachine != EM_LOONGARCH &&
- config->emachine != EM_RISCV &&
- !c.file->ppc64DisableTLSRelax;
+ bool toExecRelax =
+ !config->shared && config->emachine != EM_ARM &&
+ config->emachine != EM_HEXAGON && config->emachine != EM_LOONGARCH &&
+ config->emachine != EM_RISCV && !c.file->ppc64DisableTLSRelax;
// If we are producing an executable and the symbol is non-preemptable, it
// must be defined and the code sequence can be relaxed to use Local-Exec.
diff --git a/lld/test/ELF/arm-adr-pic.s b/lld/test/ELF/arm-adr-pic.s
new file mode 100644
index 00000000000000..5c8efd08495491
--- /dev/null
+++ b/lld/test/ELF/arm-adr-pic.s
@@ -0,0 +1,13 @@
+// REQUIRES: arm
+// RUN: llvm-mc --triple=armv7-a %s -filetype=obj -o %t.o
+// RUN: ld.lld %t.o --shared -o %t.so
+
+// It should successfully link
+ .text
+ .type _start, %function
+ .global _start
+ .arm
+_start: adr r0, .Ldest
+ bx lr
+ .section .text.1, "ax", %progbits
+.Ldest: .word 10
More information about the llvm-commits
mailing list