Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -56,7 +56,6 @@ Got, GotPlt, HashTable, - Interp, Merge, MipsReginfo, MipsOptions, @@ -517,17 +516,6 @@ }; template -class InterpSection final : public OutputSectionBase { - typedef OutputSectionBase Base; - -public: - InterpSection(); - void writeTo(uint8_t *Buf) override; - typename Base::Kind getKind() const override { return Base::Interp; } - static bool classof(const Base *B) { return B->getKind() == Base::Interp; } -}; - -template class StringTableSection final : public OutputSectionBase { typedef OutputSectionBase Base; @@ -755,7 +743,6 @@ static GotPltSection *GotPlt; static GotSection *Got; static HashTableSection *HashTab; - static InterpSection *Interp; static OutputSection *Bss; static OutputSection *MipsRldMap; static OutputSectionBase *Opd; @@ -822,7 +809,6 @@ template GotPltSection *Out::GotPlt; template GotSection *Out::Got; template HashTableSection *Out::HashTab; -template InterpSection *Out::Interp; template OutputSection *Out::Bss; template OutputSection *Out::MipsRldMap; template OutputSectionBase *Out::Opd; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -497,17 +497,6 @@ } template -InterpSection::InterpSection() - : OutputSectionBase(".interp", SHT_PROGBITS, SHF_ALLOC) { - this->Header.sh_size = Config->DynamicLinker.size() + 1; -} - -template void InterpSection::writeTo(uint8_t *Buf) { - StringRef S = Config->DynamicLinker; - memcpy(Buf, S.data(), S.size()); -} - -template HashTableSection::HashTableSection() : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { this->Header.sh_entsize = sizeof(Elf_Word); @@ -1969,11 +1958,6 @@ template class RelocationSection; template class RelocationSection; -template class InterpSection; -template class InterpSection; -template class InterpSection; -template class InterpSection; - template class GnuHashTableSection; template class GnuHashTableSection; template class GnuHashTableSection; Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -15,6 +15,11 @@ namespace lld { namespace elf { +template class InterpSection final : public InputSection { +public: + InterpSection(); +}; + template class BuildIdSection : public InputSection { public: virtual void writeBuildId(llvm::MutableArrayRef Buf) = 0; @@ -62,10 +67,12 @@ // Linker generated sections which can be used as inputs. template struct In { static BuildIdSection *BuildId; + static InterpSection *Interp; static std::vector *> Sections; }; template BuildIdSection *In::BuildId; +template InterpSection *In::Interp; template std::vector *> In::Sections; } // namespace elf Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -18,6 +18,7 @@ #include "Config.h" #include "Error.h" #include "InputFiles.h" +#include "Memory.h" #include "OutputSections.h" #include "Strings.h" @@ -36,6 +37,17 @@ using namespace lld; using namespace lld::elf; +static ArrayRef createInterp() { + // StringSaver guarantees that the returned string ends with '\0'. + StringRef S = Saver.save(Config->DynamicLinker); + return {(uint8_t *)S.data(), S.size() + 1}; +} + +template +InterpSection::InterpSection() + : InputSection(SHF_ALLOC, SHT_PROGBITS, 1, createInterp(), + ".interp") {} + template BuildIdSection::BuildIdSection(size_t HashSize) : InputSection(SHF_ALLOC, SHT_NOTE, 1, ArrayRef(), @@ -95,6 +107,11 @@ Config->BuildIdVector.size()); } +template class elf::InterpSection; +template class elf::InterpSection; +template class elf::InterpSection; +template class elf::InterpSection; + template class elf::BuildIdSection; template class elf::BuildIdSection; template class elf::BuildIdSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -235,7 +235,7 @@ Out::ProgramHeaders->updateAlignment(sizeof(uintX_t)); if (needsInterpSection()) - Out::Interp = make>(); + In::Interp = make>(); if (!Symtab::X->getSharedFiles().empty() || Config->Pic) { Out::DynSymTab = @@ -284,7 +284,8 @@ In::BuildId = make>(); else if (Config->BuildId == BuildIdKind::Hexstring) In::BuildId = make>(); - In::Sections = {In::BuildId}; + + In::Sections = {In::BuildId, In::Interp}; } template @@ -408,6 +409,13 @@ template static bool compareSectionsNonScript(OutputSectionBase *A, OutputSectionBase *B) { + // Put .interp first because some loaders want to see that section + // on the first page of the executable file when loaded into memory. + bool AIsInterp = A->getName() == ".interp"; + bool BIsInterp = B->getName() == ".interp"; + if (AIsInterp != BIsInterp) + return AIsInterp; + typedef typename ELFT::uint uintX_t; uintX_t AFlags = A->getFlags(); uintX_t BFlags = B->getFlags(); @@ -872,11 +880,6 @@ OutputSections.push_back(OS); }; - // Add .interp at first because some loaders want to see that section - // on the first page of the executable file when loaded into memory. - if (Out::Interp) - OutputSections.insert(OutputSections.begin(), Out::Interp); - // This order is not the same as the final output order // because we sort the sections using their attributes below. if (Out::GdbIndex && Out::DebugInfo) @@ -999,9 +1002,9 @@ Hdr.add(Out::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (Out::Interp) { - Phdr &Hdr = *AddHdr(PT_INTERP, Out::Interp->getPhdrFlags()); - Hdr.add(Out::Interp); + if (OutputSectionBase *Sec = findSection(".interp")) { + Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags()); + Hdr.add(Sec); } // Add the first PT_LOAD segment for regular output sections.