diff options
| -rw-r--r-- | lld/ELF/InputSection.cpp | 17 | ||||
| -rw-r--r-- | lld/ELF/InputSection.h | 6 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 40 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 26 | ||||
| -rw-r--r-- | lld/ELF/Relocations.cpp | 7 | ||||
| -rw-r--r-- | lld/ELF/Symbols.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 35 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.h | 38 | ||||
| -rw-r--r-- | lld/ELF/Target.cpp | 13 | ||||
| -rw-r--r-- | lld/ELF/Target.h | 2 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 14 | 
11 files changed, 123 insertions, 77 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index da261c6e8c0..d4d854e9874 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -14,6 +14,7 @@  #include "InputFiles.h"  #include "LinkerScript.h"  #include "OutputSections.h" +#include "SyntheticSections.h"  #include "Target.h"  #include "Thunks.h" @@ -80,9 +81,13 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,  }  template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const { +  if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) +    return S->getSize(); +    if (auto *D = dyn_cast<InputSection<ELFT>>(this))      if (D->getThunksSize() > 0)        return D->getThunkOff() + D->getThunksSize(); +    return Data.size();  } @@ -95,6 +100,7 @@ template <class ELFT>  typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {    switch (kind()) {    case Regular: +  case Synthetic:      return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;    case EHFrame:      // The file crtbeginT.o has relocations pointing to the start of an empty @@ -184,10 +190,10 @@ InputSection<ELFT>::InputSection() : InputSectionBase<ELFT>() {}  template <class ELFT>  InputSection<ELFT>::InputSection(uintX_t Flags, uint32_t Type,                                   uintX_t Addralign, ArrayRef<uint8_t> Data, -                                 StringRef Name) +                                 StringRef Name, Kind K)      : InputSectionBase<ELFT>(nullptr, Flags, Type,                               /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Addralign, -                             Data, Name, Base::Regular) {} +                             Data, Name, K) {}  template <class ELFT>  InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F, @@ -196,7 +202,7 @@ InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,  template <class ELFT>  bool InputSection<ELFT>::classof(const InputSectionData *S) { -  return S->kind() == Base::Regular; +  return S->kind() == Base::Regular || S->kind() == Base::Synthetic;  }  template <class ELFT> @@ -528,6 +534,11 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {      return;    } +  if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) { +    S->writeTo(Buf); +    return; +  } +    // Copy section contents from source object file to output file.    ArrayRef<uint8_t> Data = this->Data;    memcpy(Buf + OutSecOff, Data.data(), Data.size()); diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index e6766aebf9c..d6032af3a8b 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -39,7 +39,7 @@ class OutputSectionBase;  // section  class InputSectionData {  public: -  enum Kind { Regular, EHFrame, Merge }; +  enum Kind { Regular, EHFrame, Merge, Synthetic, };    // The garbage collector sets sections' Live bits.    // If GC is disabled, all sections are considered live by default. @@ -232,11 +232,13 @@ template <class ELFT> class InputSection : public InputSectionBase<ELFT> {    typedef typename ELFT::Rel Elf_Rel;    typedef typename ELFT::Sym Elf_Sym;    typedef typename ELFT::uint uintX_t; +  typedef InputSectionData::Kind Kind;  public:    InputSection();    InputSection(uintX_t Flags, uint32_t Type, uintX_t Addralign, -               ArrayRef<uint8_t> Data, StringRef Name); +               ArrayRef<uint8_t> Data, StringRef Name, +               Kind K = InputSectionData::Regular);    InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);    static InputSection<ELFT> Discarded; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 5e7050ff14f..5402c3a40a5 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -109,35 +109,6 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) {  }  template <class ELFT> -GotPltSection<ELFT>::GotPltSection() -    : OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) { -  this->Addralign = Target->GotPltEntrySize; -} - -template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) { -  Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); -  Entries.push_back(&Sym); -} - -template <class ELFT> bool GotPltSection<ELFT>::empty() const { -  return Entries.empty(); -} - -template <class ELFT> void GotPltSection<ELFT>::finalize() { -  this->Size = (Target->GotPltHeaderEntriesNum + Entries.size()) * -               Target->GotPltEntrySize; -} - -template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { -  Target->writeGotPltHeader(Buf); -  Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize; -  for (const SymbolBody *B : Entries) { -    Target->writeGotPlt(Buf, *B); -    Buf += sizeof(uintX_t); -  } -} - -template <class ELFT>  GotSection<ELFT>::GotSection()      : OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {    if (Config->EMachine == EM_MIPS) @@ -775,7 +746,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {      Add({DT_JMPREL, Out<ELFT>::RelaPlt});      Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});      Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, -         Out<ELFT>::GotPlt}); +         In<ELFT>::GotPlt});      Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});    } @@ -846,6 +817,9 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {      case Entry::SecAddr:        P->d_un.d_ptr = E.OutSec->Addr;        break; +    case Entry::InSecAddr: +      P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff; +      break;      case Entry::SecSize:        P->d_un.d_val = E.OutSec->Size;        break; @@ -1789,6 +1763,7 @@ OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key,    uint32_t Type = C->Type;    switch (C->kind()) {    case InputSectionBase<ELFT>::Regular: +  case InputSectionBase<ELFT>::Synthetic:      Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);      break;    case InputSectionBase<ELFT>::EHFrame: @@ -1845,11 +1820,6 @@ template class EhFrameHeader<ELF32BE>;  template class EhFrameHeader<ELF64LE>;  template class EhFrameHeader<ELF64BE>; -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 f06c2ed632d..f99f39e2bca 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -51,7 +51,6 @@ public:      EHFrameHdr,      GnuHashTable,      Got, -    GotPlt,      HashTable,      Merge,      Plt, @@ -211,24 +210,6 @@ private:    void writeMipsGot(uint8_t *Buf);  }; -template <class ELFT> class GotPltSection final : public OutputSectionBase { -  typedef typename ELFT::uint uintX_t; - -public: -  GotPltSection(); -  void finalize() override; -  void writeTo(uint8_t *Buf) override; -  void addEntry(SymbolBody &Sym); -  bool empty() const; -  Kind getKind() const override { return GotPlt; } -  static bool classof(const OutputSectionBase *B) { -    return B->getKind() == GotPlt; -  } - -private: -  std::vector<const SymbolBody *> Entries; -}; -  template <class ELFT> class PltSection final : public OutputSectionBase {    typedef typename ELFT::uint uintX_t; @@ -603,12 +584,15 @@ template <class ELFT> class DynamicSection final : public OutputSectionBase {      int32_t Tag;      union {        OutputSectionBase *OutSec; +      InputSection<ELFT> *InSec;        uint64_t Val;        const SymbolBody *Sym;      }; -    enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind; +    enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;      Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)          : Tag(Tag), OutSec(OutSec), Kind(Kind) {} +    Entry(int32_t Tag, InputSection<ELFT> *Sec) +        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}      Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}      Entry(int32_t Tag, const SymbolBody *Sym)          : Tag(Tag), Sym(Sym), Kind(SymAddr) {} @@ -677,7 +661,6 @@ template <class ELFT> struct Out {    static EhOutputSection<ELFT> *EhFrame;    static GdbIndexSection<ELFT> *GdbIndex;    static GnuHashTableSection<ELFT> *GnuHashTab; -  static GotPltSection<ELFT> *GotPlt;    static GotSection<ELFT> *Got;    static HashTableSection<ELFT> *HashTab;    static OutputSection<ELFT> *Bss; @@ -743,7 +726,6 @@ template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;  template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;  template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;  template <class ELFT> GnuHashTableSection<ELFT> *Out<ELFT>::GnuHashTab; -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> OutputSection<ELFT> *Out<ELFT>::Bss; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 20995c7fd02..190e303f31c 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -44,10 +44,11 @@  #include "Relocations.h"  #include "Config.h"  #include "OutputSections.h" +#include "Strings.h"  #include "SymbolTable.h" +#include "SyntheticSections.h"  #include "Target.h"  #include "Thunks.h" -#include "Strings.h"  #include "llvm/Support/Endian.h"  #include "llvm/Support/raw_ostream.h" @@ -743,8 +744,8 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {        else          Rel = Target->PltRel; -      Out<ELFT>::GotPlt->addEntry(Body); -      Out<ELFT>::RelaPlt->addReloc({Rel, Out<ELFT>::GotPlt, +      In<ELFT>::GotPlt->addEntry(Body); +      Out<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,                                      Body.getGotPltOffset<ELFT>(), !Preemptible,                                      &Body, 0});        continue; diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index decf62b963a..fc1bbd16014 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -159,7 +159,7 @@ template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {  }  template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const { -  return Out<ELFT>::GotPlt->Addr + getGotPltOffset<ELFT>(); +  return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();  }  template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index e1010c2ff0e..51e0fc45d44 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -313,6 +313,36 @@ void BuildIdHexstring<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {           Config->BuildIdVector.size());  } +template <class ELFT> +GotPltSection<ELFT>::GotPltSection() +    : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, +                             Target->GotPltEntrySize, ".got.plt") { +  this->Live = true; +} + +template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) { +  Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); +  Entries.push_back(&Sym); +} + +template <class ELFT> bool GotPltSection<ELFT>::empty() const { +  return Entries.empty(); +} + +template <class ELFT> size_t GotPltSection<ELFT>::getSize() const { +  return (Target->GotPltHeaderEntriesNum + Entries.size()) * +         Target->GotPltEntrySize; +} + +template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { +  Target->writeGotPltHeader(Buf); +  Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize; +  for (const SymbolBody *B : Entries) { +    Target->writeGotPlt(Buf, *B); +    Buf += sizeof(uintX_t); +  } +} +  template InputSection<ELF32LE> *elf::createCommonSection();  template InputSection<ELF32BE> *elf::createCommonSection();  template InputSection<ELF64LE> *elf::createCommonSection(); @@ -367,3 +397,8 @@ template class elf::BuildIdHexstring<ELF32LE>;  template class elf::BuildIdHexstring<ELF32BE>;  template class elf::BuildIdHexstring<ELF64LE>;  template class elf::BuildIdHexstring<ELF64BE>; + +template class elf::GotPltSection<ELF32LE>; +template class elf::GotPltSection<ELF32BE>; +template class elf::GotPltSection<ELF64LE>; +template class elf::GotPltSection<ELF64BE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index ece9ee7e53b..9901b645d73 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -58,6 +58,26 @@ private:    Elf_Mips_RegInfo Reginfo = {};  }; +template <class ELFT> class SyntheticSection : public InputSection<ELFT> { +  typedef typename ELFT::uint uintX_t; + +public: +  SyntheticSection(uintX_t Flags, uint32_t Type, uintX_t Addralign, +                   StringRef Name) +      : InputSection<ELFT>(Flags, Type, Addralign, ArrayRef<uint8_t>(), Name, +                           InputSectionData::Synthetic) {} + +  virtual void writeTo(uint8_t *Buf) {} +  virtual size_t getSize() const { return this->Data.size(); } + +  static bool classof(const InputSectionData *D) { +    return D->kind() == InputSectionData::Synthetic; +  } + +protected: +  ~SyntheticSection() = default; +}; +  // .note.gnu.build-id section.  template <class ELFT> class BuildIdSection : public InputSection<ELFT> {  public: @@ -109,6 +129,22 @@ public:    void writeBuildId(llvm::MutableArrayRef<uint8_t>) override;  }; +template <class ELFT> +class GotPltSection final : public SyntheticSection<ELFT> { +  typedef typename ELFT::uint uintX_t; + +public: +  GotPltSection(); +  void addEntry(SymbolBody &Sym); +  bool empty() const; +  size_t getSize() const override; +  void writeTo(uint8_t *Buf) override; +  uintX_t getVA() { return this->OutSec->Addr + this->OutSecOff; } + +private: +  std::vector<const SymbolBody *> Entries; +}; +  template <class ELFT> InputSection<ELFT> *createCommonSection();  template <class ELFT> InputSection<ELFT> *createInterpSection(); @@ -116,6 +152,7 @@ template <class ELFT> InputSection<ELFT> *createInterpSection();  template <class ELFT> struct In {    static BuildIdSection<ELFT> *BuildId;    static InputSection<ELFT> *Common; +  static GotPltSection<ELFT> *GotPlt;    static InputSection<ELFT> *Interp;    static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;    static MipsOptionsSection<ELFT> *MipsOptions; @@ -124,6 +161,7 @@ template <class ELFT> struct In {  template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;  template <class ELFT> InputSection<ELFT> *In<ELFT>::Common; +template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;  template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;  template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;  template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index bb1b5889855..5f8cf7ce829 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -29,6 +29,7 @@  #include "InputFiles.h"  #include "OutputSections.h"  #include "Symbols.h" +#include "SyntheticSections.h"  #include "Thunks.h"  #include "Writer.h" @@ -403,7 +404,7 @@ void X86TargetInfo::writePltHeader(uint8_t *Buf) const {        0x90, 0x90, 0x90, 0x90              // nop; nop; nop; nop    };    memcpy(Buf, PltData, sizeof(PltData)); -  uint32_t Got = Out<ELF32LE>::GotPlt->Addr; +  uint32_t Got = In<ELF32LE>::GotPlt->getVA();    write32le(Buf + 2, Got + 4);    write32le(Buf + 8, Got + 8);  } @@ -420,7 +421,7 @@ void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,    // jmp *foo@GOT(%ebx) or jmp *foo_in_GOT    Buf[1] = Config->Pic ? 0xa3 : 0x25; -  uint32_t Got = Out<ELF32LE>::GotPlt->Addr; +  uint32_t Got = In<ELF32LE>::GotPlt->getVA();    write32le(Buf + 2, Config->Shared ? GotEntryAddr - Got : GotEntryAddr);    write32le(Buf + 7, RelOff);    write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); @@ -613,7 +614,7 @@ void X86_64TargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {        0x0f, 0x1f, 0x40, 0x00              // nopl 0x0(rax)    };    memcpy(Buf, PltData, sizeof(PltData)); -  uint64_t Got = Out<ELFT>::GotPlt->Addr; +  uint64_t Got = In<ELFT>::GotPlt->getVA();    uint64_t Plt = Out<ELFT>::Plt->Addr;    write32le(Buf + 2, Got - Plt + 2); // GOT+8    write32le(Buf + 8, Got - Plt + 4); // GOT+16 @@ -1274,7 +1275,7 @@ void AArch64TargetInfo::writePltHeader(uint8_t *Buf) const {    };    memcpy(Buf, PltData, sizeof(PltData)); -  uint64_t Got = Out<ELF64LE>::GotPlt->Addr; +  uint64_t Got = In<ELF64LE>::GotPlt->getVA();    uint64_t Plt = Out<ELF64LE>::Plt->Addr;    relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,                getAArch64Page(Got + 16) - getAArch64Page(Plt + 4)); @@ -1628,7 +1629,7 @@ 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 = Out<ELF32LE>::GotPlt->Addr; +  uint64_t GotPlt = In<ELF32LE>::GotPlt->getVA();    uint64_t L1 = Out<ELF32LE>::Plt->Addr + 8;    write32le(Buf + 16, GotPlt - L1 - 8);  } @@ -2063,7 +2064,7 @@ void MipsTargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2    write32<E>(Buf + 24, 0x0320f809); // jalr  $25    write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2 -  uint64_t Got = Out<ELFT>::GotPlt->Addr; +  uint64_t Got = In<ELFT>::GotPlt->getVA();    writeMipsHi16<E>(Buf, Got);    writeMipsLo16<E>(Buf + 4, Got);    writeMipsLo16<E>(Buf + 8, Got); diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index de5a101be06..d158ee3ae84 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -82,7 +82,7 @@ public:    uint32_t TlsModuleIndexRel;    uint32_t TlsOffsetRel;    unsigned GotEntrySize; -  unsigned GotPltEntrySize; +  unsigned GotPltEntrySize = 0;    unsigned PltEntrySize;    unsigned PltHeaderSize; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 581401d94df..5a45a4a35a8 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -248,7 +248,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {    if (Config->GdbIndex)      Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>(); -  Out<ELFT>::GotPlt = make<GotPltSection<ELFT>>();    Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(        Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);    if (Config->Strip != StripPolicy::All) { @@ -312,6 +311,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {        Symtab<ELFT>::X->Sections.push_back(RegSec);      }    } + +  In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();  }  template <class ELFT> @@ -423,7 +424,7 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {    if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||        Type == SHT_PREINIT_ARRAY)      return true; -  if (Sec == Out<ELFT>::GotPlt) +  if (Sec == In<ELFT>::GotPlt->OutSec)      return Config->ZNow;    if (Sec == Out<ELFT>::Dynamic || Sec == Out<ELFT>::Got)      return true; @@ -893,6 +894,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {    // This function adds linker-created Out<ELFT>::* sections.    addPredefinedSections(); +  // We fill .got.plt section in scanRelocs(). This is the +  // reason we don't add it earlier in createSections(). +  if (!In<ELFT>::GotPlt->empty()) { +    addInputSec(In<ELFT>::GotPlt); +    In<ELFT>::GotPlt->OutSec->assignOffsets(); +  } +    sortSections();    unsigned I = 1; @@ -976,8 +984,6 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {    if (needsGot())      Add(Out<ELFT>::Got); -  if (Out<ELFT>::GotPlt && !Out<ELFT>::GotPlt->empty()) -    Add(Out<ELFT>::GotPlt);    if (!Out<ELFT>::Plt->empty())      Add(Out<ELFT>::Plt);    if (!Out<ELFT>::EhFrame->empty())  | 

