[lld] cc7cb95 - [ELF][AArch64] Write addends for TLSDESC relocations with -z rel
Alex Richardson via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 9 02:42:05 PDT 2021
Author: Alex Richardson
Date: 2021-07-09T10:41:41+01:00
New Revision: cc7cb9523e6aafd8079ba2bf2185d051221e5451
URL: https://github.com/llvm/llvm-project/commit/cc7cb9523e6aafd8079ba2bf2185d051221e5451
DIFF: https://github.com/llvm/llvm-project/commit/cc7cb9523e6aafd8079ba2bf2185d051221e5451.diff
LOG: [ELF][AArch64] Write addends for TLSDESC relocations with -z rel
Since D100490 this case is diagnosed for -z rel. This commit implements
R_AARCH64_TLSDESC cases for AArch64::getImplicitAddend() and
AArch64::relocate(). However, there are probably further relocation types
that need to be handled for full support of -z rel.
Fixes https://bugs.llvm.org/show_bug.cgi?id=47009
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D100544
Added:
lld/test/ELF/aarch64-tlsdesc-zrel.s
Modified:
lld/ELF/Arch/AArch64.cpp
lld/ELF/Relocations.cpp
lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 58da44a86f65..c1ab0e97efe2 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -34,6 +34,7 @@ class AArch64 : public TargetInfo {
RelExpr getRelExpr(RelType type, const Symbol &s,
const uint8_t *loc) const override;
RelType getDynRel(RelType type) const override;
+ int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
void writePltHeader(uint8_t *buf) const override;
void writePlt(uint8_t *buf, const Symbol &sym,
@@ -194,6 +195,17 @@ RelType AArch64::getDynRel(RelType type) const {
return R_AARCH64_NONE;
}
+int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
+ switch (type) {
+ case R_AARCH64_TLSDESC:
+ return read64(buf + 8);
+ default:
+ internalLinkerError(getErrorLocation(buf),
+ "cannot read addend for relocation " + toString(type));
+ return 0;
+ }
+}
+
void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const {
write64(buf, in.plt->getVA());
}
@@ -467,6 +479,10 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
case R_AARCH64_TLSDESC_ADD_LO12:
or32AArch64Imm(loc, val);
break;
+ case R_AARCH64_TLSDESC:
+ // For R_AARCH64_TLSDESC the addend is stored in the second 64-bit word.
+ write64(loc + 8, val);
+ break;
default:
llvm_unreachable("unknown relocation");
}
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 7e44e2d8e825..e3cc210972b2 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -200,11 +200,8 @@ handleTlsRelocation(RelType type, Symbol &sym, InputSectionBase &c,
config->shared) {
if (in.got->addDynTlsEntry(sym)) {
uint64_t off = in.got->getGlobalDynOffset(sym);
- mainPart->relaDyn->addReloc({target->tlsDescRel, in.got, off,
- sym.isPreemptible
- ? DynamicReloc::AgainstSymbol
- : DynamicReloc::AddendOnlyWithTargetVA,
- sym, 0, R_ABS});
+ mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(
+ target->tlsDescRel, in.got, off, sym, target->tlsDescRel);
}
if (expr != R_TLSDESC_CALL)
c.relocations.push_back({expr, type, offset, addend, &sym});
@@ -1107,11 +1104,9 @@ static void addGotEntry(Symbol &sym) {
addRelativeReloc(in.got, off, sym, 0, R_ABS, target->symbolicRel);
return;
}
- mainPart->relaDyn->addReloc(
- sym.isPreemptible ? DynamicReloc::AgainstSymbol
- : DynamicReloc::AddendOnlyWithTargetVA,
- sym.isTls() ? target->tlsGotRel : target->gotRel, in.got, off, sym, 0,
- sym.isPreemptible ? R_ADDEND : R_ABS, target->symbolicRel);
+ mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(
+ sym.isTls() ? target->tlsGotRel : target->gotRel, in.got, off, sym,
+ target->symbolicRel);
}
// Return true if we can define a symbol in the executable that
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index a969ceddd226..55cd2715ab76 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1625,6 +1625,18 @@ void RelocationBaseSection::addRelativeReloc(
sym, addend, expr, addendRelType);
}
+void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
+ RelType dynType, InputSectionBase *isec, uint64_t offsetInSec, Symbol &sym,
+ RelType addendRelType) {
+ // No need to write an addend to the section for preemptible symbols.
+ if (sym.isPreemptible)
+ addReloc({dynType, isec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
+ R_ABS});
+ else
+ addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec, offsetInSec,
+ sym, 0, R_ABS, addendRelType);
+}
+
void RelocationBaseSection::addReloc(DynamicReloc::Kind kind, RelType dynType,
InputSectionBase *inputSec,
uint64_t offsetInSec, Symbol &sym,
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index ddf7e8daa458..bc24922598fe 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -531,6 +531,12 @@ class RelocationBaseSection : public SyntheticSection {
void addRelativeReloc(RelType dynType, InputSectionBase *isec,
uint64_t offsetInSec, Symbol &sym, int64_t addend,
RelType addendRelType, RelExpr expr);
+ /// Add a dynamic relocation using the target address of \p sym as the addend
+ /// if \p sym is non-preemptible. Otherwise add a relocation against \p sym.
+ void addAddendOnlyRelocIfNonPreemptible(RelType dynType,
+ InputSectionBase *isec,
+ uint64_t offsetInSec, Symbol &sym,
+ RelType addendRelType);
void addReloc(DynamicReloc::Kind kind, RelType dynType,
InputSectionBase *inputSec, uint64_t offsetInSec, Symbol &sym,
int64_t addend, RelExpr expr, RelType addendRelType);
diff --git a/lld/test/ELF/aarch64-tlsdesc-zrel.s b/lld/test/ELF/aarch64-tlsdesc-zrel.s
new file mode 100644
index 000000000000..f9f69c43d1a7
--- /dev/null
+++ b/lld/test/ELF/aarch64-tlsdesc-zrel.s
@@ -0,0 +1,60 @@
+/// Check that we write addends for AArch64 TLSDESC relocations with -z rel
+/// See https://bugs.llvm.org/show_bug.cgi?id=47009
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t-rela.so
+// RUN: llvm-readobj -W -r -x .got %t-rela.so | FileCheck %s --check-prefixes=RELA,RELA-NO-ADDENDS
+// RUN: ld.lld -shared %t.o -o %t-rela-addends.so --apply-dynamic-relocs
+// RUN: llvm-readobj -W -r -x .got %t-rela-addends.so | FileCheck %s --check-prefixes=RELA,RELA-WITH-ADDENDS
+
+// RELA: Relocations [
+// RELA-NEXT: Section (5) .rela.dyn {
+// RELA-NEXT: 0x20340 R_AARCH64_TLSDESC - 0x0
+// RELA-NEXT: 0x20350 R_AARCH64_TLSDESC - 0x4
+// RELA-NEXT: }
+// RELA-NEXT: ]
+// RELA-NEXT: Hex dump of section '.got':
+// RELA-NEXT: 0x00020340 00000000 00000000 00000000 00000000
+// RELA-NO-ADDENDS-NEXT: 0x00020350 00000000 00000000 00000000 00000000
+// RELA-WITH-ADDENDS-NEXT: 0x00020350 00000000 00000000 04000000 00000000
+/// Addend 0x4 for R_AARCH64_TLSDESC -----^
+// RELA-EMPTY:
+
+// RUN: ld.lld -shared %t.o -o %t-rel.so -z rel
+// RUN: llvm-readobj -W -r -x .got %t-rel.so | FileCheck %s --check-prefix=REL
+// REL: Relocations [
+// REL-NEXT: Section (5) .rel.dyn {
+// REL-NEXT: 0x20330 R_AARCH64_TLSDESC -{{$}}
+// REL-NEXT: 0x20340 R_AARCH64_TLSDESC -{{$}}
+// REL-NEXT: }
+// REL-NEXT: ]
+// REL-NEXT: Hex dump of section '.got':
+// REL-NEXT: 0x00020330 00000000 00000000 00000000 00000000
+// REL-NEXT: 0x00020340 00000000 00000000 04000000 00000000
+/// Addend 0x4 for R_AARCH64_TLSDESC -----^
+// REL-EMPTY:
+
+ .text
+foo:
+ adrp x0, :tlsdesc:x
+ ldr x1, [x0, :tlsdesc_lo12:x]
+ add x0, x0, :tlsdesc_lo12:x
+ .tlsdesccall x
+ blr x1
+ adrp x0, :tlsdesc:y
+ ldr x1, [x0, :tlsdesc_lo12:y]
+ add x0, x0, :tlsdesc_lo12:y
+ .tlsdesccall y
+ blr x1
+ ret
+
+ .section .tbss,"awT", at nobits
+ .p2align 2
+ .hidden x
+x:
+ .word 0
+
+ .p2align 2
+ .hidden y
+y:
+ .word 0
More information about the llvm-commits
mailing list