diff options
-rw-r--r-- | lld/ELF/OutputSections.cpp | 91 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 23 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 2 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 101 | ||||
-rw-r--r-- | lld/ELF/Target.h | 40 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 20 | ||||
-rw-r--r-- | lld/test/elf2/plt-i686.s | 59 | ||||
-rw-r--r-- | lld/test/elf2/plt.s | 45 | ||||
-rw-r--r-- | lld/test/elf2/relocation-i686.s | 13 | ||||
-rw-r--r-- | lld/test/elf2/relocation.s | 35 |
10 files changed, 92 insertions, 337 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 3b9ab973a64..bbe2964db59 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -30,43 +30,6 @@ OutputSectionBase<Is64Bits>::OutputSectionBase(StringRef Name, uint32_t sh_type, } template <class ELFT> -GotPltSection<ELFT>::GotPltSection() - : OutputSectionBase<ELFT::Is64Bits>(".got.plt", llvm::ELF::SHT_PROGBITS, - llvm::ELF::SHF_ALLOC | - llvm::ELF::SHF_WRITE) { - this->Header.sh_addralign = this->getAddrSize(); - // .got.plt has 3 reserved entry - Entries.resize(3); -} - -template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody *Sym) { - Sym->GotPltIndex = Entries.size(); - Entries.push_back(Sym); -} - -template <class ELFT> bool GotPltSection<ELFT>::empty() const { - return Entries.size() == 3; -} - -template <class ELFT> -typename GotPltSection<ELFT>::uintX_t -GotPltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { - return this->getVA() + B.GotPltIndex * this->getAddrSize(); -} - -template <class ELFT> void GotPltSection<ELFT>::finalize() { - this->Header.sh_size = Entries.size() * this->getAddrSize(); -} - -template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { - for (const SymbolBody *B : Entries) { - if (B) - Target->writeGotPltEntry(Buf, Out<ELFT>::Plt->getEntryAddr(*B)); - Buf += sizeof(uintX_t); - } -} - -template <class ELFT> GotSection<ELFT>::GotSection() : OutputSectionBase<ELFT::Is64Bits>(".got", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | @@ -106,13 +69,10 @@ PltSection<ELFT>::PltSection() template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) { size_t Off = 0; - // First write PLT[0] entry which is special. - Target->writePltZeroEntry(Buf, Out<ELFT>::GotPlt->getVA(), this->getVA()); - Off += Target->getPltZeroEntrySize(); for (const SymbolBody *E : Entries) { - uint64_t Got = Out<ELFT>::GotPlt->getEntryAddr(*E); + uint64_t Got = Out<ELFT>::Got->getEntryAddr(*E); uint64_t Plt = this->getVA() + Off; - Target->writePltEntry(Buf + Off, Got, Plt, E->PltIndex); + Target->writePltEntry(Buf + Off, Got, Plt); Off += Target->getPltEntrySize(); } } @@ -125,20 +85,19 @@ template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) { template <class ELFT> typename PltSection<ELFT>::uintX_t PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const { - return this->getVA() + Target->getPltZeroEntrySize() + - B.PltIndex * Target->getPltEntrySize(); + return this->getVA() + B.PltIndex * Target->getPltEntrySize(); } template <class ELFT> void PltSection<ELFT>::finalize() { - this->Header.sh_size = - Target->getPltZeroEntrySize() + Entries.size() * Target->getPltEntrySize(); + this->Header.sh_size = Entries.size() * Target->getPltEntrySize(); } template <class ELFT> -RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela) - : OutputSectionBase<ELFT::Is64Bits>(Name, IsRela ? llvm::ELF::SHT_RELA - : llvm::ELF::SHT_REL, +RelocationSection<ELFT>::RelocationSection(bool IsRela) + : OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn", + IsRela ? llvm::ELF::SHT_RELA + : llvm::ELF::SHT_REL, llvm::ELF::SHF_ALLOC), IsRela(IsRela) { this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); @@ -176,22 +135,10 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { } if (Body && Target->relocNeedsGot(Type, *Body)) { - // Each symbol that needs plt relocation is placed to Plt and GotPlt, - // otherwise to Got. - // Also symbol can be placed both to Got and Plt + GotPlt, for example - // when we take address of function from DSO and also make a call to it. - // So here depending on what type of relocation is we switch from which - // table to take the offset from. - bool NeedsPlt = Target->relocNeedsPlt(Type, *Body); - if (NeedsPlt) - P->r_offset = Out<ELFT>::GotPlt->getEntryAddr(*Body); - else - P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); + P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); if (CanBePreempted) P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - NeedsPlt ? Target->getPltReloc() - : Target->getGotReloc(), - IsMips64EL); + Target->getGotReloc(), IsMips64EL); } else { if (IsRela) Addend += static_cast<const Elf_Rela &>(RI).r_addend; @@ -308,12 +255,6 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { ++NumEntries; // DT_RELASZ / DT_RELSZ ++NumEntries; // DT_RELAENT / DT_RELENT } - if (Out<ELFT>::RelaPlt->hasRelocs()) { - ++NumEntries; // DT_JMPREL - ++NumEntries; // DT_PLTRELSZ - ++NumEntries; // DT_PLTGOT - ++NumEntries; // DT_PLTREL - } ++NumEntries; // DT_SYMTAB ++NumEntries; // DT_SYMENT ++NumEntries; // DT_STRTAB @@ -382,12 +323,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { WriteVal(IsRela ? DT_RELAENT : DT_RELENT, IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); } - if (Out<ELFT>::RelaPlt->hasRelocs()) { - WritePtr(DT_JMPREL, Out<ELFT>::RelaPlt->getVA()); - WriteVal(DT_PLTRELSZ, Out<ELFT>::RelaPlt->getSize()); - WritePtr(DT_PLTGOT, Out<ELFT>::Got->getVA()); - WriteVal(DT_PLTREL, Out<ELFT>::RelaPlt->isRela() ? DT_RELA : DT_REL); - } + WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA()); WritePtr(DT_SYMENT, sizeof(Elf_Sym)); WritePtr(DT_STRTAB, Out<ELFT>::DynStrTab->getVA()); @@ -759,11 +695,6 @@ template void OutputSectionBase<false>::writeHeaderTo<support::big>( template void OutputSectionBase<true>::writeHeaderTo<support::big>( ELFFile<ELFType<support::big, true>>::Elf_Shdr *SHdr); -template class GotPltSection<ELF32LE>; -template class GotPltSection<ELF32BE>; -template class GotPltSection<ELF64LE>; -template class GotPltSection<ELF64BE>; - template class GotSection<ELF32LE>; template class GotSection<ELF32BE>; template class GotSection<ELF64LE>; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 40bcb9fc3c5..a8c597b03bf 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -117,23 +117,6 @@ private: }; template <class ELFT> -class GotPltSection final : public OutputSectionBase<ELFT::Is64Bits> { - typedef OutputSectionBase<ELFT::Is64Bits> Base; - typedef typename Base::uintX_t uintX_t; - -public: - GotPltSection(); - void finalize() override; - void writeTo(uint8_t *Buf) override; - void addEntry(SymbolBody *Sym); - bool empty() const; - uintX_t getEntryAddr(const SymbolBody &B) const; - -private: - std::vector<const SymbolBody *> Entries; -}; - -template <class ELFT> class PltSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef OutputSectionBase<ELFT::Is64Bits> Base; typedef typename Base::uintX_t uintX_t; @@ -189,7 +172,7 @@ class RelocationSection final : public OutputSectionBase<ELFT::Is64Bits> { typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; public: - RelocationSection(StringRef Name, bool IsRela); + RelocationSection(bool IsRela); void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); } void finalize() override; void writeTo(uint8_t *Buf) override; @@ -301,7 +284,6 @@ private: // until Writer is initialized. template <class ELFT> struct Out { static DynamicSection<ELFT> *Dynamic; - static GotPltSection<ELFT> *GotPlt; static GotSection<ELFT> *Got; static HashTableSection<ELFT> *HashTab; static InterpSection<ELFT::Is64Bits> *Interp; @@ -310,7 +292,6 @@ template <class ELFT> struct Out { static uint8_t *OpdBuf; static PltSection<ELFT> *Plt; static RelocationSection<ELFT> *RelaDyn; - static RelocationSection<ELFT> *RelaPlt; static StringTableSection<ELFT::Is64Bits> *DynStrTab; static StringTableSection<ELFT::Is64Bits> *StrTab; static SymbolTableSection<ELFT> *DynSymTab; @@ -318,7 +299,6 @@ template <class ELFT> struct Out { }; template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic; -template <class ELFT> GotPltSection<ELFT> *Out<ELFT>::GotPlt; template <class ELFT> GotSection<ELFT> *Out<ELFT>::Got; template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab; template <class ELFT> InterpSection<ELFT::Is64Bits> *Out<ELFT>::Interp; @@ -327,7 +307,6 @@ template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Opd; template <class ELFT> uint8_t *Out<ELFT>::OpdBuf; template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt; template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn; -template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt; template <class ELFT> StringTableSection<ELFT::Is64Bits> *Out<ELFT>::DynStrTab; template <class ELFT> StringTableSection<ELFT::Is64Bits> *Out<ELFT>::StrTab; template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab; diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index b519edd3cd0..f53d956bd8f 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -79,10 +79,8 @@ public: void setDynamicSymbolTableIndex(unsigned V) { DynamicSymbolTableIndex = V; } uint32_t GotIndex = -1; - uint32_t GotPltIndex = -1; uint32_t PltIndex = -1; bool isInGot() const { return GotIndex != -1U; } - bool isInGotPlt() const { return GotPltIndex != -1U; } bool isInPlt() const { return PltIndex != -1U; } // A SymbolBody has a backreference to a Symbol. Originally they are diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 08d3a7b41d1..7009b7f721a 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -55,40 +55,16 @@ X86TargetInfo::X86TargetInfo() { PCRelReloc = R_386_PC32; GotReloc = R_386_GLOB_DAT; GotRefReloc = R_386_GOT32; - PltReloc = R_386_JUMP_SLOT; - PltEntrySize = 16; VAStart = 0x10000; } -void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { - // Skip 6 bytes of "jmpq *got(%rip)" - write32le(Buf, Plt + 6); -} - -void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const { - const uint8_t PltData[] = { - 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip) - 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip) - 0x00, 0x00, 0x00, 0x00 - }; - memcpy(Buf, PltData, sizeof(PltData)); - write32le(Buf + 2, GotEntryAddr - PltEntryAddr + 2); // GOT+8 - write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16 -} - void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const { - const uint8_t Inst[] = { - 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip) - 0x68, 0x00, 0x00, 0x00, 0x00, // pushq <relocation index> - 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0] - }; + uint64_t PltEntryAddr) const { + // jmpl *val; nop; nop + const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90}; memcpy(Buf, Inst, sizeof(Inst)); - - write32le(Buf + 2, GotEntryAddr - PltEntryAddr - 6); - write32le(Buf + 7, Index); - write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16); + assert(isUInt<32>(GotEntryAddr)); + write32le(Buf + 2, GotEntryAddr); } bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { @@ -133,9 +109,7 @@ X86_64TargetInfo::X86_64TargetInfo() { PCRelReloc = R_X86_64_PC32; GotReloc = R_X86_64_GLOB_DAT; GotRefReloc = R_X86_64_PC32; - PltReloc = R_X86_64_JUMP_SLOT; RelativeReloc = R_X86_64_RELATIVE; - PltEntrySize = 16; // On freebsd x86_64 the first page cannot be mmaped. // On linux that is controled by vm.mmap_min_addr. At least on some x86_64 @@ -146,35 +120,16 @@ X86_64TargetInfo::X86_64TargetInfo() { VAStart = 0x10000; } -void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { - // Skip 6 bytes of "jmpq *got(%rip)" - write32le(Buf, Plt + 6); -} - -void X86_64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const { - const uint8_t PltData[] = { - 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip) - 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip) - 0x0f, 0x1f, 0x40, 0x00 // nopl 0x0(rax) - }; - memcpy(Buf, PltData, sizeof(PltData)); - write32le(Buf + 2, GotEntryAddr - PltEntryAddr + 2); // GOT+8 - write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16 -} - void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const { - const uint8_t Inst[] = { - 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip) - 0x68, 0x00, 0x00, 0x00, 0x00, // pushq <relocation index> - 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0] - }; + uint64_t PltEntryAddr) const { + // jmpq *val(%rip); nop; nop + const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90}; memcpy(Buf, Inst, sizeof(Inst)); - write32le(Buf + 2, GotEntryAddr - PltEntryAddr - 6); - write32le(Buf + 7, Index); - write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16); + uint64_t NextPC = PltEntryAddr + 6; + int64_t Delta = GotEntryAddr - NextPC; + assert(isInt<32>(Delta)); + write32le(Buf + 2, Delta); } bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { @@ -286,9 +241,7 @@ PPC64TargetInfo::PPC64TargetInfo() { GotReloc = R_PPC64_GLOB_DAT; GotRefReloc = R_PPC64_REL64; RelativeReloc = R_PPC64_RELATIVE; - // PltReloc = FIXME PltEntrySize = 32; - PltZeroEntrySize = 0; //FIXME // We need 64K pages (at least under glibc/Linux, the loader won't // set different permissions on a finer granularity than that). @@ -314,12 +267,8 @@ static uint64_t getPPC64TocBase() { return TocVA + 0x8000; } - -void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} -void PPC64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const { + uint64_t PltEntryAddr) const { uint64_t Off = GotEntryAddr - getPPC64TocBase(); // FIXME: What we should do, in theory, is get the offset of the function @@ -508,16 +457,11 @@ void PPC64TargetInfo::relocateOne(uint8_t *Buf, uint8_t *BufEnd, PPCTargetInfo::PPCTargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME - // PltReloc = FIXME PageSize = 65536; VAStart = 0x10000000; } - -void PPCTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} -void PPCTargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} void PPCTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const {} + uint64_t PltEntryAddr) const {} bool PPCTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; } @@ -531,16 +475,10 @@ void PPCTargetInfo::relocateOne(uint8_t *Buf, uint8_t *BufEnd, AArch64TargetInfo::AArch64TargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME - // PltReloc = FIXME VAStart = 0x400000; } - -void AArch64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} -void AArch64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, - int32_t Index) const {} + uint64_t PltEntryAddr) const {} bool AArch64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; @@ -615,19 +553,12 @@ void AArch64TargetInfo::relocateOne(uint8_t *Buf, uint8_t *BufEnd, MipsTargetInfo::MipsTargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME - // PltReloc = FIXME PageSize = 65536; VAStart = 0x400000; } -void MipsTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} - -void MipsTargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} - void MipsTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const { -} + uint64_t PltEntryAddr) const {} bool MipsTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 1d1f8e531e7..0ffaddc36f0 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -24,16 +24,11 @@ public: uint64_t getVAStart() const { return VAStart; } unsigned getPCRelReloc() const { return PCRelReloc; } unsigned getGotReloc() const { return GotReloc; } - unsigned getPltReloc() const { return PltReloc; } unsigned getGotRefReloc() const { return GotRefReloc; } unsigned getRelativeReloc() const { return RelativeReloc; } - unsigned getPltZeroEntrySize() const { return PltZeroEntrySize; } unsigned getPltEntrySize() const { return PltEntrySize; } - virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0; - virtual void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const = 0; virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const = 0; + uint64_t PltEntryAddr) const = 0; virtual bool isRelRelative(uint32_t Type) const; virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0; virtual bool relocPointsToGot(uint32_t Type) const; @@ -50,21 +45,15 @@ protected: unsigned PCRelReloc; unsigned GotRefReloc; unsigned GotReloc; - unsigned PltReloc; unsigned RelativeReloc; unsigned PltEntrySize = 8; - unsigned PltZeroEntrySize = 16; - llvm::StringRef DefaultEntry = "_start"; }; class X86TargetInfo final : public TargetInfo { public: X86TargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocPointsToGot(uint32_t Type) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; @@ -76,11 +65,8 @@ public: class X86_64TargetInfo final : public TargetInfo { public: X86_64TargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP, @@ -92,11 +78,8 @@ public: class PPC64TargetInfo final : public TargetInfo { public: PPC64TargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP, @@ -108,11 +91,8 @@ public: class PPCTargetInfo final : public TargetInfo { public: PPCTargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP, @@ -123,11 +103,8 @@ public: class AArch64TargetInfo final : public TargetInfo { public: AArch64TargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP, @@ -138,11 +115,8 @@ public: class MipsTargetInfo final : public TargetInfo { public: MipsTargetInfo(); - void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; - void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr, int32_t Index) const override; + uint64_t PltEntryAddr) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP, diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 5458b872cc2..d5b61a6da92 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -98,8 +98,6 @@ template <class ELFT> void lld::elf2::writeResult(SymbolTable<ELFT> *Symtab) { Out<ELFT>::Bss = &Bss; GotSection<ELFT> Got; Out<ELFT>::Got = &Got; - GotPltSection<ELFT> GotPlt; - Out<ELFT>::GotPlt = &GotPlt; PltSection<ELFT> Plt; Out<ELFT>::Plt = &Plt; SymbolTableSection<ELFT> SymTab(*Symtab, *Out<ELFT>::StrTab); @@ -108,11 +106,8 @@ template <class ELFT> void lld::elf2::writeResult(SymbolTable<ELFT> *Symtab) { Out<ELFT>::DynSymTab = &DynSymTab; HashTableSection<ELFT> HashTab; Out<ELFT>::HashTab = &HashTab; - bool IsRela = Symtab->shouldUseRela(); - RelocationSection<ELFT> RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela); + RelocationSection<ELFT> RelaDyn(Symtab->shouldUseRela()); Out<ELFT>::RelaDyn = &RelaDyn; - RelocationSection<ELFT> RelaPlt(IsRela ? ".rela.plt" : ".rel.plt", IsRela); - Out<ELFT>::RelaPlt = &RelaPlt; DynamicSection<ELFT> Dynamic(*Symtab); Out<ELFT>::Dynamic = &Dynamic; @@ -192,8 +187,8 @@ void Writer<ELFT>::scanRelocs( if (Body->isInPlt()) continue; Out<ELFT>::Plt->addEntry(Body); - Out<ELFT>::GotPlt->addEntry(Body); - } else if (Target->relocNeedsGot(Type, *Body)) { + } + if (Target->relocNeedsGot(Type, *Body)) { if (Body->isInGot()) continue; Out<ELFT>::Got->addEntry(Body); @@ -205,10 +200,7 @@ void Writer<ELFT>::scanRelocs( continue; if (CBP) Body->setUsedInDynamicReloc(); - if (Body && Target->relocNeedsPlt(Type, *Body)) - Out<ELFT>::RelaPlt->addReloc({ C, RI }); - else - Out<ELFT>::RelaDyn->addReloc({ C, RI }); + Out<ELFT>::RelaDyn->addReloc({C, RI}); } } @@ -455,13 +447,9 @@ template <class ELFT> void Writer<ELFT>::createSections() { OutputSections.push_back(Out<ELFT>::DynStrTab); if (Out<ELFT>::RelaDyn->hasRelocs()) OutputSections.push_back(Out<ELFT>::RelaDyn); - if (Out<ELFT>::RelaPlt->hasRelocs()) - OutputSections.push_back(Out<ELFT>::RelaPlt); } if (!Out<ELFT>::Got->empty()) OutputSections.push_back(Out<ELFT>::Got); - if (!Out<ELFT>::GotPlt->empty()) - OutputSections.push_back(Out<ELFT>::GotPlt); if (!Out<ELFT>::Plt->empty()) OutputSections.push_back(Out<ELFT>::Plt); diff --git a/lld/test/elf2/plt-i686.s b/lld/test/elf2/plt-i686.s index c28107d29d6..b6a91cded23 100644 --- a/lld/test/elf2/plt-i686.s +++ b/lld/test/elf2/plt-i686.s @@ -14,62 +14,41 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x11010 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 48 +// CHECK-NEXT: Size: 16 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 -// CHECK: Name: .got.plt -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: SHF_WRITE -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x12058 -// CHECK-NEXT: Offset: 0x2058 -// CHECK-NEXT: Size: 20 -// CHECK-NEXT: Link: 0 -// CHECK-NEXT: Info: 0 -// CHECK-NEXT: AddressAlignment: 4 -// CHECK-NEXT: EntrySize: 0 - // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rel.plt { -// CHECK-NEXT: 0x12064 R_386_JUMP_SLOT bar 0x0 -// CHECK-NEXT: 0x12068 R_386_JUMP_SLOT zed 0x0 +// CHECK-NEXT: Section ({{.*}}) .rel.dyn { +// CHECK-NEXT: 0x12050 R_386_GLOB_DAT bar 0x0 +// CHECK-NEXT: 0x12054 R_386_GLOB_DAT zed 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // Unfortunately FileCheck can't do math, so we have to check for explicit // values: -// 16 is the size of PLT[0] -// (0x11010 + 16) - (0x11000 + 1) - 4 = 27 -// (0x11010 + 16) - (0x11005 + 1) - 4 = 22 -// (0x11020 + 16) - (0x1100a + 1) - 4 = 33 +// 0x11010 - (0x11000 + 1) - 4 = 11 +// 0x11010 - (0x11005 + 1) - 4 = 2 +// 0x11018 - (0x1100a + 1) - 4 = 9 // DISASM: _start: -// DISASM-NEXT: 11000: e9 1b 00 00 00 jmp 27 -// DISASM-NEXT: 11005: e9 16 00 00 00 jmp 22 -// DISASM-NEXT: 1100a: e9 21 00 00 00 jmp 33 +// DISASM-NEXT: 11000: e9 0b 00 00 00 jmp 11 +// DISASM-NEXT: 11005: e9 06 00 00 00 jmp 6 +// DISASM-NEXT: 1100a: e9 09 00 00 00 jmp 9 + +// 0x12050 = 73808 +// 0x12054 = 73812 -// 0x12064 - 0x11020 - 6 = 4158 -// 0x12068 - 0x11030 - 6 = 4146 -// 0x11010 - 0x1102b - 5 = -32 -// 0x11010 - 0x1103b - 5 = -48 // DISASM: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 11010: ff 35 4a 10 00 00 pushl 4170 -// DISASM-NEXT: 11016: ff 25 4c 10 00 00 jmpl *4172 -// DISASM-NEXT: 1101c: 00 00 addb %al, (%eax) -// DISASM-NEXT: 1101e: 00 00 addb %al, (%eax) -// DISASM-NEXT: 11020: ff 25 3e 10 00 00 jmpl *4158 -// DISASM-NEXT: 11026: 68 00 00 00 00 pushl $0 -// DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 -// DISASM-NEXT: 11030: ff 25 32 10 00 00 jmpl *4146 -// DISASM-NEXT: 11036: 68 01 00 00 00 pushl $1 -// DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 - +// DISASM-NEXT: 11010: ff 25 {{.*}} jmpl *73808 +// DISASM-NEXT: 11016: 90 nop +// DISASM-NEXT: 11017: 90 nop +// DISASM-NEXT: 11018: ff 25 {{.*}} jmpl *73812 +// DISASM-NEXT: 1101e: 90 nop +// DISASM-NEXT: 1101f: 90 nop .global _start _start: diff --git a/lld/test/elf2/plt.s b/lld/test/elf2/plt.s index f893fca3c36..b88a3f72866 100644 --- a/lld/test/elf2/plt.s +++ b/lld/test/elf2/plt.s @@ -14,49 +14,42 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x1020 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 64 +// CHECK-NEXT: Size: 24 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rela.plt { -// CHECK-NEXT: 0x20C8 R_X86_64_JUMP_SLOT bar 0x0 -// CHECK-NEXT: 0x20D0 R_X86_64_JUMP_SLOT zed 0x0 -// CHECK-NEXT: 0x20D8 R_X86_64_JUMP_SLOT _start 0x0 +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x20A0 R_X86_64_GLOB_DAT bar 0x0 +// CHECK-NEXT: 0x20A8 R_X86_64_GLOB_DAT zed 0x0 +// CHECK-NEXT: 0x20B0 R_X86_64_GLOB_DAT _start 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // Unfortunately FileCheck can't do math, so we have to check for explicit // values: -// 0x1030 - (0x1000 + 5) = 43 -// 0x1030 - (0x1005 + 5) = 38 -// 0x1040 - (0x100a + 5) = 49 +// 0x11020 - (0x11000 + 1) - 4 = 27 +// 0x11020 - (0x11005 + 1) - 4 = 22 +// 0x11028 - (0x1100a + 1) - 4 = 25 // DISASM: _start: -// DISASM-NEXT: 1000: e9 {{.*}} jmp 43 -// DISASM-NEXT: 1005: e9 {{.*}} jmp 38 -// DISASM-NEXT: 100a: e9 {{.*}} jmp 49 +// DISASM-NEXT: 1000: e9 {{.*}} jmp 27 +// DISASM-NEXT: 1005: e9 {{.*}} jmp 22 +// DISASM-NEXT: 100a: e9 {{.*}} jmp 25 -// 0x20C8 - 0x1036 = 4242 -// 0x20D0 - 0x1046 = 4234 +// 0x120A0 - 0x11026 = 4218 +// 0x120A8 - 0x1102e = 4218 // DISASM: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 1020: ff 35 92 10 00 00 pushq 4242(%rip) -// DISASM-NEXT: 1026: ff 25 94 10 00 00 jmpq *4244(%rip) -// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax) -// DISASM-NEXT: 1030: ff 25 92 10 00 00 jmpq *4242(%rip) -// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0 -// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <bar+1020> -// DISASM-NEXT: 1040: ff 25 8a 10 00 00 jmpq *4234(%rip) -// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1 -// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <bar+1020> -// DISASM-NEXT: 1050: ff 25 82 10 00 00 jmpq *4226(%rip) -// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2 -// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <bar+1020> - +// DISASM-NEXT: 1020: ff 25 {{.*}} jmpq *4218(%rip) +// DISASM-NEXT: 1026: 90 nop +// DISASM-NEXT: 1027: 90 nop +// DISASM-NEXT: 1028: ff 25 {{.*}} jmpq *4218(%rip) +// DISASM-NEXT: 102e: 90 nop +// DISASM-NEXT: 102f: 90 nop .global _start _start: diff --git a/lld/test/elf2/relocation-i686.s b/lld/test/elf2/relocation-i686.s index 5d39751bd59..2daf671a6c1 100644 --- a/lld/test/elf2/relocation-i686.s +++ b/lld/test/elf2/relocation-i686.s @@ -47,7 +47,7 @@ movl bar@GOT, %eax // ADDR-NEXT: ] // ADDR-NEXT: Address: 0x11030 // ADDR-NEXT: Offset: 0x1030 -// ADDR-NEXT: Size: 32 +// ADDR-NEXT: Size: 8 // ADDR: Name: .got // ADDR-NEXT: Type: SHT_PROGBITS @@ -55,25 +55,24 @@ movl bar@GOT, %eax // ADDR-NEXT: SHF_ALLOC // ADDR-NEXT: SHF_WRITE // ADDR-NEXT: ] -// ADDR-NEXT: Address: 0x12070 +// ADDR-NEXT: Address: 0x12050 .section .R_386_GOTPC,"ax",@progbits R_386_GOTPC: movl $_GLOBAL_OFFSET_TABLE_, %eax -// 0x12070 - 0x11014 = 4188 +// 0x12050 - 0x11014 = 4156 // CHECK: Disassembly of section .R_386_GOTPC: // CHECK-NEXT: R_386_GOTPC: -// CHECK-NEXT: 11014: {{.*}} movl $4188, %eax +// CHECK-NEXT: 11014: {{.*}} movl $4156, %eax .section .dynamic_reloc, "ax",@progbits call bar -// (0x11030 + 16) - (0x11019 + 5) = 34 -// 16 - is a size of PLT[0] +// 0x11030 - (0x11019 + 5) = 18 // CHECK: Disassembly of section .dynamic_reloc: // CHECK-NEXT: .dynamic_reloc: -// CHECK-NEXT: 11019: e8 22 00 00 00 calll 34 +// CHECK-NEXT: 11019: e8 12 00 00 00 calll 18 .section .R_386_GOT32,"ax",@progbits .global R_386_GOT32 diff --git a/lld/test/elf2/relocation.s b/lld/test/elf2/relocation.s index 7174779ef86..84b8d8c91aa 100644 --- a/lld/test/elf2/relocation.s +++ b/lld/test/elf2/relocation.s @@ -14,39 +14,23 @@ // SEC-NEXT: ] // SEC-NEXT: Address: 0x11020 // SEC-NEXT: Offset: 0x1020 -// SEC-NEXT: Size: 32 +// SEC-NEXT: Size: 8 -// SEC: Name: .got +// SEC: Name: .got // SEC-NEXT: Type: SHT_PROGBITS // SEC-NEXT: Flags [ // SEC-NEXT: SHF_ALLOC // SEC-NEXT: SHF_WRITE // SEC-NEXT: ] -// SEC-NEXT: Address: 0x120E0 +// SEC-NEXT: Address: 0x120A0 // SEC-NEXT: Offset: -// SEC-NEXT: Size: 8 +// SEC-NEXT: Size: 16 // SEC-NEXT: Link: 0 // SEC-NEXT: Info: 0 // SEC-NEXT: AddressAlignment: 8 // SEC-NEXT: EntrySize: 0 // SEC-NEXT: } -// SEC: Name: .got.plt -// SEC-NEXT: Type: SHT_PROGBITS -// SEC-NEXT: Flags [ -// SEC-NEXT: SHF_ALLOC -// SEC-NEXT: SHF_WRITE -// SEC-NEXT: ] -// SEC-NEXT: Address: 0x120E8 -// SEC-NEXT: Offset: 0x20E8 -// SEC-NEXT: Size: 32 -// SEC-NEXT: Link: 0 -// SEC-NEXT: Info: 0 -// SEC-NEXT: AddressAlignment: 8 -// SEC-NEXT: EntrySize: 0 -// SEC-NEXT: } - - .section .text,"ax",@progbits,unique,1 .global _start _start: @@ -91,11 +75,10 @@ R_X86_64_32S: .global R_X86_64_PC32 R_X86_64_PC32: call bar -// (0x11020 + 16) - (0x11017 + 5) = 20 -// 16 - is a size of PLT[0] +// 0x11020 - (0x11017 + 5) = 4 // CHECK: Disassembly of section .R_X86_64_PC32: // CHECK-NEXT: R_X86_64_PC32: -// CHECK-NEXT: 11017: e8 14 00 00 00 callq 20 +// CHECK-NEXT: 11017: e8 04 00 00 00 callq 4 .section .R_X86_64_64,"a",@progbits .global R_X86_64_64 @@ -110,7 +93,7 @@ R_X86_64_64: R_X86_64_GOTPCREL: .long zed@gotpcrel -// 0x120E0 - 0x10160 = 8064 -// 8064 = 0x801f0000 in little endian +// 0x120A8 - 0x10160 = 8008 +// 8008 = 0x481f0000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL -// CHECK-NEXT: 10160 801f0000 +// CHECK-NEXT: 10160 481f0000 |