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 ELFT> -class InterpSection final : public OutputSectionBase<ELFT> { - typedef OutputSectionBase<ELFT> 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 ELFT> class StringTableSection final : public OutputSectionBase<ELFT> { typedef OutputSectionBase<ELFT> Base; @@ -755,7 +743,6 @@ static GotPltSection<ELFT> *GotPlt; static GotSection<ELFT> *Got; static HashTableSection<ELFT> *HashTab; - static InterpSection<ELFT> *Interp; static OutputSection<ELFT> *Bss; static OutputSection<ELFT> *MipsRldMap; static OutputSectionBase<ELFT> *Opd; @@ -822,7 +809,6 @@ 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> *Out<ELFT>::Interp; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss; template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap; template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::Opd; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -497,17 +497,6 @@ } template <class ELFT> -InterpSection<ELFT>::InterpSection() - : OutputSectionBase<ELFT>(".interp", SHT_PROGBITS, SHF_ALLOC) { - this->Header.sh_size = Config->DynamicLinker.size() + 1; -} - -template <class ELFT> void InterpSection<ELFT>::writeTo(uint8_t *Buf) { - StringRef S = Config->DynamicLinker; - memcpy(Buf, S.data(), S.size()); -} - -template <class ELFT> HashTableSection<ELFT>::HashTableSection() : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) { this->Header.sh_entsize = sizeof(Elf_Word); @@ -1969,11 +1958,6 @@ template class RelocationSection<ELF64LE>; template class RelocationSection<ELF64BE>; -template class InterpSection<ELF32LE>; -template class InterpSection<ELF32BE>; -template class InterpSection<ELF64LE>; -template class InterpSection<ELF64BE>; - template class GnuHashTableSection<ELF32LE>; template class GnuHashTableSection<ELF32BE>; template class GnuHashTableSection<ELF64LE>; 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 ELFT> class InterpSection final : public InputSection<ELFT> { +public: + InterpSection(); +}; + template <class ELFT> class BuildIdSection : public InputSection<ELFT> { public: virtual void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf) = 0; @@ -62,10 +67,12 @@ // Linker generated sections which can be used as inputs. template <class ELFT> struct In { static BuildIdSection<ELFT> *BuildId; + static InterpSection<ELFT> *Interp; static std::vector<InputSection<ELFT> *> Sections; }; template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId; +template <class ELFT> InterpSection<ELFT> *In<ELFT>::Interp; template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::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<uint8_t> 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 <class ELFT> +InterpSection<ELFT>::InterpSection() + : InputSection<ELFT>(SHF_ALLOC, SHT_PROGBITS, 1, createInterp(), + ".interp") {} + template <class ELFT> BuildIdSection<ELFT>::BuildIdSection(size_t HashSize) : InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(), @@ -95,6 +107,11 @@ Config->BuildIdVector.size()); } +template class elf::InterpSection<ELF32LE>; +template class elf::InterpSection<ELF32BE>; +template class elf::InterpSection<ELF64LE>; +template class elf::InterpSection<ELF64BE>; + template class elf::BuildIdSection<ELF32LE>; template class elf::BuildIdSection<ELF32BE>; template class elf::BuildIdSection<ELF64LE>; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -235,7 +235,7 @@ Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t)); if (needsInterpSection<ELFT>()) - Out<ELFT>::Interp = make<InterpSection<ELFT>>(); + In<ELFT>::Interp = make<InterpSection<ELFT>>(); if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) { Out<ELFT>::DynSymTab = @@ -284,7 +284,8 @@ In<ELFT>::BuildId = make<BuildIdUuid<ELFT>>(); else if (Config->BuildId == BuildIdKind::Hexstring) In<ELFT>::BuildId = make<BuildIdHexstring<ELFT>>(); - In<ELFT>::Sections = {In<ELFT>::BuildId}; + + In<ELFT>::Sections = {In<ELFT>::BuildId, In<ELFT>::Interp}; } template <class ELFT> @@ -408,6 +409,13 @@ template <class ELFT> static bool compareSectionsNonScript(OutputSectionBase<ELFT> *A, OutputSectionBase<ELFT> *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<ELFT>::Interp) - OutputSections.insert(OutputSections.begin(), Out<ELFT>::Interp); - // This order is not the same as the final output order // because we sort the sections using their attributes below. if (Out<ELFT>::GdbIndex && Out<ELFT>::DebugInfo) @@ -999,9 +1002,9 @@ Hdr.add(Out<ELFT>::ProgramHeaders); // PT_INTERP must be the second entry if exists. - if (Out<ELFT>::Interp) { - Phdr &Hdr = *AddHdr(PT_INTERP, Out<ELFT>::Interp->getPhdrFlags()); - Hdr.add(Out<ELFT>::Interp); + if (OutputSectionBase<ELFT> *Sec = findSection(".interp")) { + Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags()); + Hdr.add(Sec); } // Add the first PT_LOAD segment for regular output sections.