Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -75,7 +75,6 @@ } template void GotPltSection::writeTo(uint8_t *Buf) { - Target->writeGotPltHeader(Buf); Buf += Target->GotPltHeaderEntriesNum * sizeof(uintX_t); for (const SymbolBody *B : Entries) { Target->writeGotPlt(Buf, B->getPltVA()); Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -28,7 +28,6 @@ virtual bool isTlsLocalDynamicRel(uint32_t Type) const; virtual bool isTlsGlobalDynamicRel(uint32_t Type) const; virtual uint32_t getDynRel(uint32_t Type) const { return Type; } - virtual void writeGotPltHeader(uint8_t *Buf) const {} virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {}; virtual uint64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const; @@ -78,7 +77,11 @@ uint32_t TlsOffsetRel; unsigned PltEntrySize = 8; unsigned PltZeroSize = 0; + + // At least on x86_64 positions 1 and 2 are used by the first plt entry + // to support lazy loading. Position 0 seems unused. unsigned GotPltHeaderEntriesNum = 3; + uint32_t ThunkSize = 0; bool UseLazyBinding = false; Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -81,7 +81,6 @@ X86TargetInfo(); RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const override; uint64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; - void writeGotPltHeader(uint8_t *Buf) const override; uint32_t getDynRel(uint32_t Type) const override; bool isTlsLocalDynamicRel(uint32_t Type) const override; bool isTlsGlobalDynamicRel(uint32_t Type) const override; @@ -106,7 +105,6 @@ bool isTlsLocalDynamicRel(uint32_t Type) const override; bool isTlsGlobalDynamicRel(uint32_t Type) const override; bool isTlsInitialExecRel(uint32_t Type) const override; - void writeGotPltHeader(uint8_t *Buf) const override; void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override; void writePltZero(uint8_t *Buf) const override; void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, @@ -298,10 +296,6 @@ } } -void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const { - write32le(Buf, Out::Dynamic->getVA()); -} - void X86TargetInfo::writeGotPlt(uint8_t *Buf, uint64_t Plt) const { // Entries in .got.plt initially points back to the corresponding // PLT entries with a fixed offset to skip the first instruction. @@ -530,10 +524,6 @@ } } -void X86_64TargetInfo::writeGotPltHeader(uint8_t *Buf) const { - write64le(Buf, Out::Dynamic->getVA()); -} - void X86_64TargetInfo::writeGotPlt(uint8_t *Buf, uint64_t Plt) const { // See comments in X86TargetInfo::writeGotPlt. write32le(Buf, Plt + 6);