summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Target.cpp')
-rw-r--r--lld/ELF/Target.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 33cea220a37..6c0a2224cd5 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -46,6 +46,8 @@ namespace {
class X86TargetInfo final : public TargetInfo {
public:
X86TargetInfo();
+ unsigned getDynReloc(unsigned Type) const override;
+ bool isTlsDynReloc(unsigned Type) const override;
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const override;
@@ -62,6 +64,7 @@ class X86_64TargetInfo final : public TargetInfo {
public:
X86_64TargetInfo();
unsigned getPltRefReloc(unsigned Type) const override;
+ bool isTlsDynReloc(unsigned Type) const override;
void writeGotPltHeaderEntries(uint8_t *Buf) const override;
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -182,6 +185,20 @@ X86TargetInfo::X86TargetInfo() {
PltReloc = R_386_JUMP_SLOT;
}
+unsigned X86TargetInfo::getDynReloc(unsigned Type) const {
+ if (Type == R_386_TLS_LE)
+ return R_386_TLS_TPOFF;
+ if (Type == R_386_TLS_LE_32)
+ return R_386_TLS_TPOFF32;
+ return Type;
+}
+
+bool X86TargetInfo::isTlsDynReloc(unsigned Type) const {
+ if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32)
+ return Config->Shared;
+ return false;
+}
+
void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const {}
@@ -225,6 +242,12 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
case R_386_32:
add32le(Loc, SA);
break;
+ case R_386_TLS_LE:
+ write32le(Loc, SA - Out<ELF32LE>::TlsPhdr->p_memsz);
+ break;
+ case R_386_TLS_LE_32:
+ write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA);
+ break;
default:
error("unrecognized reloc " + Twine(Type));
}
@@ -242,7 +265,6 @@ X86_64TargetInfo::X86_64TargetInfo() {
TlsGlobalDynamicReloc = R_X86_64_TLSGD;
TlsModuleIndexReloc = R_X86_64_DTPMOD64;
TlsOffsetReloc = R_X86_64_DTPOFF64;
- TlsPcRelGotReloc = R_X86_64_GOTTPOFF;
LazyRelocations = true;
PltEntrySize = 16;
PltZeroEntrySize = 16;
@@ -300,6 +322,10 @@ bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
relocNeedsPlt(Type, S);
}
+bool X86_64TargetInfo::isTlsDynReloc(unsigned Type) const {
+ return Type == R_X86_64_GOTTPOFF;
+}
+
unsigned X86_64TargetInfo::getPltRefReloc(unsigned Type) const {
if (Type == R_X86_64_PLT32)
return R_X86_64_PC32;
OpenPOWER on IntegriCloud