[lld] r262748 - Refactor target independent code.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 4 13:37:10 PST 2016
Author: rafael
Date: Fri Mar 4 15:37:09 2016
New Revision: 262748
URL: http://llvm.org/viewvc/llvm-project?rev=262748&view=rev
Log:
Refactor target independent code.
The rules for when we can relax tls relocations are target independent.
The only things that are target dependent are the relocation values.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Mar 4 15:37:09 2016
@@ -201,7 +201,7 @@ void InputSectionBase<ELFT>::relocate(ui
uintX_t AddrLoc = OutSec->getVA() + Offset;
auto NextRelocs = llvm::make_range(&RI, Rels.end());
- if (Target->isTlsLocalDynamicRel(Type) &&
+ if (Target->pointsToLocalDynamicGotEntry(Type) &&
!Target->canRelaxTls(Type, nullptr)) {
Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
Out<ELFT>::Got->getTlsIndexVA() +
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Mar 4 15:37:09 2016
@@ -83,8 +83,10 @@ public:
void writeGotPltHeader(uint8_t *Buf) const override;
unsigned getDynRel(unsigned Type) const override;
unsigned getTlsGotRel(unsigned Type) const override;
+ bool pointsToLocalDynamicGotEntry(unsigned Type) const override;
bool isTlsLocalDynamicRel(unsigned Type) const override;
bool isTlsGlobalDynamicRel(unsigned Type) const override;
+ bool isTlsInitialExecRel(unsigned Type) const override;
bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
void writePltZero(uint8_t *Buf) const override;
@@ -97,7 +99,6 @@ public:
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
- bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, const SymbolBody *S) const override;
bool isGotRelative(uint32_t Type) const override;
@@ -118,8 +119,10 @@ class X86_64TargetInfo final : public Ta
public:
X86_64TargetInfo();
unsigned getTlsGotRel(unsigned Type) const override;
+ bool pointsToLocalDynamicGotEntry(unsigned Type) const override;
bool isTlsLocalDynamicRel(unsigned Type) const override;
bool isTlsGlobalDynamicRel(unsigned Type) const override;
+ bool isTlsInitialExecRel(unsigned Type) const override;
bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
void writeGotPltHeader(uint8_t *Buf) const override;
void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
@@ -134,7 +137,6 @@ public:
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
bool isRelRelative(uint32_t Type) const override;
- bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
bool isSizeRel(uint32_t Type) const override;
unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, const SymbolBody *S) const override;
@@ -177,6 +179,7 @@ public:
AArch64TargetInfo();
unsigned getDynRel(unsigned Type) const override;
bool isTlsGlobalDynamicRel(unsigned Type) const override;
+ bool isTlsInitialExecRel(unsigned Type) const override;
void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
void writePltZero(uint8_t *Buf) const override;
void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
@@ -192,7 +195,6 @@ public:
uint8_t *PairedLoc = nullptr) const override;
unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, const SymbolBody *S) const override;
- bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
private:
void relocateTlsGdToLe(unsigned Type, uint8_t *Loc, uint8_t *BufEnd,
@@ -264,10 +266,23 @@ TargetInfo::~TargetInfo() {}
bool TargetInfo::canRelaxTls(unsigned Type, const SymbolBody *S) const {
if (Config->Shared || (S && !S->isTls()))
return false;
- return canRelaxTlsImpl(Type, S);
-}
-bool TargetInfo::canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const {
+ // We know we are producing an executable.
+
+ // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
+ // depending on the symbol being locally defined or not.
+ if (isTlsGlobalDynamicRel(Type))
+ return true;
+
+ // Local-Dynamic relocs can be relaxed to Local-Exec.
+ if (isTlsLocalDynamicRel(Type))
+ return true;
+
+ // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
+ // defined.
+ if (isTlsInitialExecRel(Type))
+ return !canBePreempted(S);
+
return false;
}
@@ -341,10 +356,14 @@ TargetInfo::PltNeed TargetInfo::needsPlt
return Plt_No;
}
-bool TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+bool TargetInfo::isTlsInitialExecRel(unsigned Type) const { return false; }
+
+bool TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
return false;
}
+bool TargetInfo::isTlsLocalDynamicRel(unsigned Type) const { return false; }
+
bool TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
return false;
}
@@ -398,9 +417,17 @@ bool X86TargetInfo::isTlsGlobalDynamicRe
}
bool X86TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+ return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM;
+}
+
+bool X86TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
return Type == R_386_TLS_LDM;
}
+bool X86TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+ return Type == R_386_TLS_IE || Type == R_386_TLS_GOTIE;
+}
+
bool X86TargetInfo::isTlsDynRel(unsigned Type, const SymbolBody &S) const {
if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 ||
Type == R_386_TLS_GOTIE)
@@ -528,12 +555,6 @@ void X86TargetInfo::relocateOne(uint8_t
}
}
-bool X86TargetInfo::canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const {
- return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM ||
- Type == R_386_TLS_GD || (Type == R_386_TLS_IE && !canBePreempted(S)) ||
- (Type == R_386_TLS_GOTIE && !canBePreempted(S));
-}
-
bool X86TargetInfo::needsDynRelative(unsigned Type) const {
return Config->Shared && Type == R_386_TLS_IE;
}
@@ -740,14 +761,22 @@ unsigned X86_64TargetInfo::getTlsGotRel(
return R_X86_64_PC32;
}
+bool X86_64TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+ return Type == R_X86_64_GOTTPOFF;
+}
+
bool X86_64TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
return Type == R_X86_64_TLSGD;
}
-bool X86_64TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+bool X86_64TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
return Type == R_X86_64_TLSLD;
}
+bool X86_64TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+ return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_TLSLD;
+}
+
bool X86_64TargetInfo::isTlsDynRel(unsigned Type, const SymbolBody &S) const {
return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD;
}
@@ -775,13 +804,6 @@ bool X86_64TargetInfo::isSizeRel(uint32_
return Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64;
}
-bool X86_64TargetInfo::canRelaxTlsImpl(unsigned Type,
- const SymbolBody *S) const {
- return Type == R_X86_64_TLSGD || Type == R_X86_64_TLSLD ||
- Type == R_X86_64_DTPOFF32 ||
- (Type == R_X86_64_GOTTPOFF && !canBePreempted(S));
-}
-
// "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5
// x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows
// how LD can be optimized to LE:
@@ -1221,6 +1243,11 @@ bool AArch64TargetInfo::isTlsGlobalDynam
Type == R_AARCH64_TLSDESC_CALL;
}
+bool AArch64TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+ return Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
+ Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
+}
+
unsigned AArch64TargetInfo::getDynRel(unsigned Type) const {
if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
return Type;
@@ -1459,23 +1486,6 @@ void AArch64TargetInfo::relocateOne(uint
}
}
-bool AArch64TargetInfo::canRelaxTlsImpl(unsigned Type,
- const SymbolBody *S) const {
- // Global-Dynamic relocs can be relaxed to Initial-Exec if the target is
- // an executable. And if the target is local it can also be fully relaxed to
- // Local-Exec.
- if (isTlsGlobalDynamicRel(Type))
- return !canBePreempted(S);
-
- // Initial-Exec relocs can be relaxed to Local-Exec if the target is a local
- // symbol.
- if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
- Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
- return !canBePreempted(S);
-
- return false;
-}
-
unsigned AArch64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
const SymbolBody *S) const {
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Mar 4 15:37:09 2016
@@ -22,6 +22,8 @@ class SymbolBody;
class TargetInfo {
public:
uint64_t getVAStart() const;
+ virtual bool isTlsInitialExecRel(unsigned Type) const;
+ virtual bool pointsToLocalDynamicGotEntry(unsigned Type) const;
virtual bool isTlsLocalDynamicRel(unsigned Type) const;
virtual bool isTlsGlobalDynamicRel(unsigned Type) const;
virtual unsigned getDynRel(unsigned Type) const { return Type; }
@@ -99,7 +101,6 @@ public:
private:
virtual bool needsCopyRelImpl(uint32_t Type) const;
virtual bool needsPltImpl(uint32_t Type) const;
- virtual bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const;
};
uint64_t getPPC64TocBase();
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Mar 4 15:37:09 2016
@@ -258,7 +258,7 @@ template <bool Is64Bits> struct DenseMap
template <class ELFT, class RelT>
static bool handleTlsRelocation(unsigned Type, SymbolBody *Body,
InputSectionBase<ELFT> &C, RelT &RI) {
- if (Target->isTlsLocalDynamicRel(Type)) {
+ if (Target->pointsToLocalDynamicGotEntry(Type)) {
if (Target->canRelaxTls(Type, nullptr))
return true;
if (Out<ELFT>::Got->addTlsIndex())
More information about the llvm-commits
mailing list