summaryrefslogtreecommitdiff
path: root/ELF/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/Target.cpp')
-rw-r--r--ELF/Target.cpp60
1 files changed, 27 insertions, 33 deletions
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index 4643c1a919aa..781d7fe3bc3f 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -351,15 +351,6 @@ X86TargetInfo::X86TargetInfo() {
RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S,
const uint8_t *Loc) const {
- // There are 4 different TLS variable models with varying degrees of
- // flexibility and performance. LocalExec and InitialExec models are fast but
- // less-flexible models. They cannot be used for dlopen(). If they are in use,
- // we set DF_STATIC_TLS in the ELF header so that the runtime can reject such
- // DSOs.
- if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
- Type == R_386_TLS_GOTIE)
- Config->HasStaticTlsModel = true;
-
switch (Type) {
case R_386_8:
case R_386_16:
@@ -429,7 +420,7 @@ RelExpr X86TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
}
void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
- write32le(Buf, In<ELF32LE>::Dynamic->getVA());
+ write32le(Buf, InX::Dynamic->getVA());
}
void X86TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
@@ -460,8 +451,8 @@ void X86TargetInfo::writePltHeader(uint8_t *Buf) const {
};
memcpy(Buf, V, sizeof(V));
- uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize();
- uint32_t GotPlt = In<ELF32LE>::GotPlt->getVA() - Ebx;
+ uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
+ uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
write32le(Buf + 2, GotPlt + 4);
write32le(Buf + 8, GotPlt + 8);
return;
@@ -473,7 +464,7 @@ void X86TargetInfo::writePltHeader(uint8_t *Buf) const {
0x90, 0x90, 0x90, 0x90 // nop
};
memcpy(Buf, PltData, sizeof(PltData));
- uint32_t GotPlt = In<ELF32LE>::GotPlt->getVA();
+ uint32_t GotPlt = InX::GotPlt->getVA();
write32le(Buf + 2, GotPlt + 4);
write32le(Buf + 8, GotPlt + 8);
}
@@ -490,7 +481,7 @@ void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
if (Config->Pic) {
// jmp *foo@GOT(%ebx)
- uint32_t Ebx = In<ELF32LE>::Got->getVA() + In<ELF32LE>::Got->getSize();
+ uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
Buf[1] = 0xa3;
write32le(Buf + 2, GotPltEntryAddr - Ebx);
} else {
@@ -718,7 +709,7 @@ void X86_64TargetInfo<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
// required, but it is documented in the psabi and the glibc dynamic linker
// seems to use it (note that this is relevant for linking ld.so, not any
// other program).
- write64le(Buf, In<ELFT>::Dynamic->getVA());
+ write64le(Buf, InX::Dynamic->getVA());
}
template <class ELFT>
@@ -736,8 +727,8 @@ void X86_64TargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
0x0f, 0x1f, 0x40, 0x00 // nop
};
memcpy(Buf, PltData, sizeof(PltData));
- uint64_t GotPlt = In<ELFT>::GotPlt->getVA();
- uint64_t Plt = In<ELFT>::Plt->getVA();
+ uint64_t GotPlt = InX::GotPlt->getVA();
+ uint64_t Plt = InX::Plt->getVA();
write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
}
@@ -760,7 +751,8 @@ void X86_64TargetInfo<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
template <class ELFT>
bool X86_64TargetInfo<ELFT>::isPicRel(uint32_t Type) const {
- return Type != R_X86_64_PC32 && Type != R_X86_64_32;
+ return Type != R_X86_64_PC32 && Type != R_X86_64_32 &&
+ Type != R_X86_64_TPOFF32;
}
template <class ELFT>
@@ -1140,7 +1132,7 @@ uint64_t getPPC64TocBase() {
// TOC starts where the first of these sections starts. We always create a
// .got when we see a relocation that uses it, so for us the start is always
// the .got.
- uint64_t TocVA = In<ELF64BE>::Got->getVA();
+ uint64_t TocVA = InX::Got->getVA();
// Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
// thus permitting a full 64 Kbytes segment. Note that the glibc startup
@@ -1369,7 +1361,7 @@ bool AArch64TargetInfo::isPicRel(uint32_t Type) const {
}
void AArch64TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
- write64le(Buf, In<ELF64LE>::Plt->getVA());
+ write64le(Buf, InX::Plt->getVA());
}
// Page(Expr) is the page address of the expression Expr, defined
@@ -1392,8 +1384,8 @@ void AArch64TargetInfo::writePltHeader(uint8_t *Buf) const {
};
memcpy(Buf, PltData, sizeof(PltData));
- uint64_t Got = In<ELF64LE>::GotPlt->getVA();
- uint64_t Plt = In<ELF64LE>::Plt->getVA();
+ uint64_t Got = InX::GotPlt->getVA();
+ uint64_t Plt = InX::Plt->getVA();
relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
@@ -1746,7 +1738,7 @@ uint32_t ARMTargetInfo::getDynRel(uint32_t Type) const {
}
void ARMTargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
- write32le(Buf, In<ELF32LE>::Plt->getVA());
+ write32le(Buf, InX::Plt->getVA());
}
void ARMTargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
@@ -1763,15 +1755,15 @@ void ARMTargetInfo::writePltHeader(uint8_t *Buf) const {
0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8
};
memcpy(Buf, PltData, sizeof(PltData));
- uint64_t GotPlt = In<ELF32LE>::GotPlt->getVA();
- uint64_t L1 = In<ELF32LE>::Plt->getVA() + 8;
+ uint64_t GotPlt = InX::GotPlt->getVA();
+ uint64_t L1 = InX::Plt->getVA() + 8;
write32le(Buf + 16, GotPlt - L1 - 8);
}
void ARMTargetInfo::addPltHeaderSymbols(InputSectionBase *ISD) const {
auto *IS = cast<InputSection>(ISD);
- addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, 0, 0, IS);
- addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, 16, 0, IS);
+ addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
+ addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
}
void ARMTargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
@@ -1793,8 +1785,8 @@ void ARMTargetInfo::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
void ARMTargetInfo::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
auto *IS = cast<InputSection>(ISD);
- addSyntheticLocal<ELF32LE>("$a", STT_NOTYPE, Off, 0, IS);
- addSyntheticLocal<ELF32LE>("$d", STT_NOTYPE, Off + 12, 0, IS);
+ addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
+ addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
}
bool ARMTargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
@@ -1874,7 +1866,8 @@ void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
// BLX (always unconditional) instruction to an ARM Target, select an
// unconditional BL.
write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
- // fall through as BL encoding is shared with B
+ // fall through as BL encoding is shared with B
+ LLVM_FALLTHROUGH;
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
@@ -1908,7 +1901,8 @@ void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
}
// Bit 12 is 0 for BLX, 1 for BL
write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
- // Fall through as rest of encoding is the same as B.W
+ // Fall through as rest of encoding is the same as B.W
+ LLVM_FALLTHROUGH;
case R_ARM_THM_JUMP24:
// Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
// FIXME: Use of I1 and I2 require v6T2ops
@@ -2132,7 +2126,7 @@ uint32_t MipsTargetInfo<ELFT>::getDynRel(uint32_t Type) const {
template <class ELFT>
void MipsTargetInfo<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
- write32<ELFT::TargetEndianness>(Buf, In<ELFT>::Plt->getVA());
+ write32<ELFT::TargetEndianness>(Buf, InX::Plt->getVA());
}
template <endianness E, uint8_t BSIZE, uint8_t SHIFT>
@@ -2201,7 +2195,7 @@ void MipsTargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
write32<E>(Buf + 24, 0x0320f809); // jalr $25
write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
- uint64_t GotPlt = In<ELFT>::GotPlt->getVA();
+ uint64_t GotPlt = InX::GotPlt->getVA();
writeMipsHi16<E>(Buf, GotPlt);
writeMipsLo16<E>(Buf + 4, GotPlt);
writeMipsLo16<E>(Buf + 8, GotPlt);