diff options
Diffstat (limited to 'ELF/Target.cpp')
-rw-r--r-- | ELF/Target.cpp | 60 |
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); |