Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -35,17 +35,15 @@ : OutputSectionBase(".got.plt", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) { this->Header.sh_addralign = sizeof(uintX_t); - // .got.plt has 3 reserved entry - Entries.resize(3); } template void GotPltSection::addEntry(SymbolBody *Sym) { - Sym->GotPltIndex = Entries.size(); + Sym->GotPltIndex = Target->getGotPltHeaderEntriesNum() + Entries.size(); Entries.push_back(Sym); } template bool GotPltSection::empty() const { - return Entries.size() == 3; + return Entries.empty(); } template @@ -55,15 +53,15 @@ } template void GotPltSection::finalize() { - this->Header.sh_size = Entries.size() * sizeof(uintX_t); + this->Header.sh_size = + (Target->getGotPltHeaderEntriesNum() + Entries.size()) * sizeof(uintX_t); } template void GotPltSection::writeTo(uint8_t *Buf) { - write( - Buf, Out::Dynamic->getVA()); + Target->writeGotPltHeaderEntries(Buf); + Buf += Target->getGotPltHeaderEntriesNum() * sizeof(uintX_t); for (const SymbolBody *B : Entries) { - if (B) - Target->writeGotPltEntry(Buf, Out::Plt->getEntryAddr(*B)); + Target->writeGotPltEntry(Buf, Out::Plt->getEntryAddr(*B)); Buf += sizeof(uintX_t); } } Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -43,8 +43,10 @@ unsigned getPltEntrySize() const { return PltEntrySize; } bool supportsLazyRelocations() const { return LazyRelocations; } unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; } + unsigned getGotPltHeaderEntriesNum() const { return GotPltHeaderEntriesNum; } virtual unsigned getPLTRefReloc(unsigned Type) const; virtual void writeGotHeaderEntries(uint8_t *Buf) const; + virtual void writeGotPltHeaderEntries(uint8_t *Buf) const; 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; @@ -86,6 +88,7 @@ unsigned PltEntrySize = 8; unsigned PltZeroEntrySize = 0; unsigned GotHeaderEntriesNum = 0; + unsigned GotPltHeaderEntriesNum = 3; bool LazyRelocations = false; }; Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -62,6 +62,7 @@ public: X86_64TargetInfo(); unsigned getPLTRefReloc(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, uint64_t PltEntryAddr) const override; @@ -159,6 +160,8 @@ void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {} +void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {} + X86TargetInfo::X86TargetInfo() { PCRelReloc = R_386_PC32; GotReloc = R_386_GLOB_DAT; @@ -226,6 +229,10 @@ PltZeroEntrySize = 16; } +void X86_64TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const { + write64le(Buf, Out::Dynamic->getVA()); +} + void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { // Skip 6 bytes of "jmpq *got(%rip)" write32le(Buf, Plt + 6);