[lld] r353262 - [PPC64] Set the number of relocations processed for R_PPC64_TLS[GL]D to 2
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 5 18:00:25 PST 2019
Author: maskray
Date: Tue Feb 5 18:00:24 2019
New Revision: 353262
URL: http://llvm.org/viewvc/llvm-project?rev=353262&view=rev
Log:
[PPC64] Set the number of relocations processed for R_PPC64_TLS[GL]D to 2
Summary:
R_PPC64_TLSGD and R_PPC64_TLSLD are used as markers on TLS code sequences. After GD-to-IE or GD-to-LE relaxation, the next relocation R_PPC64_REL24 should be skipped to not create a false dependency on __tls_get_addr. When linking statically, the false dependency may cause an "undefined symbol: __tls_get_addr" error.
R_PPC64_GOT_TLSGD16_HA
R_PPC64_GOT_TLSGD16_LO
R_PPC64_TLSGD R_TLSDESC_CALL
R_PPC64_REL24 __tls_get_addr
Reviewers: ruiu, sfertile, syzaara, espindola
Reviewed By: sfertile
Subscribers: emaste, nemanjai, arichardson, kbarton, jsji, llvm-commits, tamur
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57673
Modified:
lld/trunk/ELF/Arch/PPC64.cpp
lld/trunk/ELF/Arch/X86.cpp
lld/trunk/ELF/Arch/X86_64.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Target.h
lld/trunk/test/ELF/ppc64-gd-to-ie.s
lld/trunk/test/ELF/ppc64-tls-gd-le.s
Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Tue Feb 5 18:00:24 2019
@@ -111,6 +111,7 @@ namespace {
class PPC64 final : public TargetInfo {
public:
PPC64();
+ int getTlsGdRelaxSkip(RelType Type) const override;
uint32_t calcEFlags() const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
@@ -241,6 +242,20 @@ PPC64::PPC64() {
write32(TrapInstr.data(), 0x7fe00008);
}
+int PPC64::getTlsGdRelaxSkip(RelType Type) const {
+ // A __tls_get_addr call instruction is marked with 2 relocations:
+ //
+ // R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
+ // R_PPC64_REL24: __tls_get_addr
+ //
+ // After the relaxation we no longer call __tls_get_addr and should skip both
+ // relocations to not create a false dependence on __tls_get_addr being
+ // defined.
+ if (Type == R_PPC64_TLSGD || Type == R_PPC64_TLSLD)
+ return 2;
+ return 1;
+}
+
static uint32_t getEFlags(InputFile *File) {
if (Config->EKind == ELF64BEKind)
return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
Modified: lld/trunk/ELF/Arch/X86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86.cpp?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86.cpp (original)
+++ lld/trunk/ELF/Arch/X86.cpp Tue Feb 5 18:00:24 2019
@@ -23,6 +23,7 @@ namespace {
class X86 : public TargetInfo {
public:
X86();
+ int getTlsGdRelaxSkip(RelType Type) const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
@@ -58,7 +59,6 @@ X86::X86() {
GotPltEntrySize = 4;
PltEntrySize = 16;
PltHeaderSize = 16;
- TlsGdRelaxSkip = 2;
TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the non-PAE large page size (known as a superpage or huge page).
@@ -66,6 +66,10 @@ X86::X86() {
DefaultImageBase = 0x400000;
}
+int X86::getTlsGdRelaxSkip(RelType Type) const {
+ return 2;
+}
+
RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const {
switch (Type) {
Modified: lld/trunk/ELF/Arch/X86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/X86_64.cpp?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/X86_64.cpp (original)
+++ lld/trunk/ELF/Arch/X86_64.cpp Tue Feb 5 18:00:24 2019
@@ -25,6 +25,7 @@ namespace {
template <class ELFT> class X86_64 : public TargetInfo {
public:
X86_64();
+ int getTlsGdRelaxSkip(RelType Type) const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
RelType getDynRel(RelType Type) const override;
@@ -65,7 +66,6 @@ template <class ELFT> X86_64<ELFT>::X86_
GotPltEntrySize = 8;
PltEntrySize = 16;
PltHeaderSize = 16;
- TlsGdRelaxSkip = 2;
TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the large page size (known as a superpage or huge page).
@@ -74,6 +74,11 @@ template <class ELFT> X86_64<ELFT>::X86_
}
template <class ELFT>
+int X86_64<ELFT>::getTlsGdRelaxSkip(RelType Type) const {
+ return 2;
+}
+
+template <class ELFT>
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const {
switch (Type) {
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Feb 5 18:00:24 2019
@@ -205,7 +205,7 @@ handleTlsRelocation(RelType Type, Symbol
C.Relocations.push_back(
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
Offset, Addend, &Sym});
- return Target->TlsGdRelaxSkip;
+ return Target->getTlsGdRelaxSkip(Type);
}
if (Expr == R_TLSLD_HINT)
return 1;
@@ -278,7 +278,7 @@ handleTlsRelocation(RelType Type, Symbol
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
Offset, Addend, &Sym});
}
- return Target->TlsGdRelaxSkip;
+ return Target->getTlsGdRelaxSkip(Type);
}
// Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Feb 5 18:00:24 2019
@@ -32,6 +32,7 @@ public:
virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
+ virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; }
// If lazy binding is supported, the first entry of the PLT has code
// to call the dynamic linker to resolve PLT entries the first time
@@ -80,7 +81,6 @@ public:
virtual ~TargetInfo();
- unsigned TlsGdRelaxSkip = 1;
unsigned PageSize = 4096;
unsigned DefaultMaxPageSize = 4096;
Modified: lld/trunk/test/ELF/ppc64-gd-to-ie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-gd-to-ie.s?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-gd-to-ie.s (original)
+++ lld/trunk/test/ELF/ppc64-gd-to-ie.s Tue Feb 5 18:00:24 2019
@@ -69,10 +69,6 @@ other_reg:
mtlr 0
blr
- .globl __tls_get_addr
- .type __tls_get_addr, at function
-__tls_get_addr:
-
# CheckGot: .got 00000018 00000000100200c0 DATA
# .got is at 0x100200c0 so the toc-base is 100280c0.
Modified: lld/trunk/test/ELF/ppc64-tls-gd-le.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-tls-gd-le.s?rev=353262&r1=353261&r2=353262&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-tls-gd-le.s (original)
+++ lld/trunk/test/ELF/ppc64-tls-gd-le.s Tue Feb 5 18:00:24 2019
@@ -50,10 +50,6 @@ _start:
.Lfunc_end0:
.size _start, .Lfunc_end0-.Lfunc_begin0
-.globl __tls_get_addr
-.type __tls_get_addr, at function
-__tls_get_addr:
-
# -- End function
.type a, at object # @a
.section .tdata,"awT", at progbits
More information about the llvm-commits
mailing list