Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -52,7 +52,6 @@ Merge, Plt, Regular, - SymTable, VersDef, VersNeed, VersTable @@ -160,40 +159,6 @@ size_t StrTabOffset; }; -template -class SymbolTableSection final : public OutputSectionBase { - typedef OutputSectionBase Base; - -public: - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::Sym Elf_Sym; - typedef typename ELFT::SymRange Elf_Sym_Range; - typedef typename ELFT::uint uintX_t; - SymbolTableSection(StringTableSection &StrTabSec); - - void finalize() override; - void writeTo(uint8_t *Buf) override; - void addSymbol(SymbolBody *Body); - StringTableSection &getStrTabSec() const { return StrTabSec; } - unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } - typename Base::Kind getKind() const override { return Base::SymTable; } - static bool classof(const Base *B) { return B->getKind() == Base::SymTable; } - - ArrayRef getSymbols() const { return Symbols; } - - unsigned NumLocals = 0; - StringTableSection &StrTabSec; - -private: - void writeLocalSymbols(uint8_t *&Buf); - void writeGlobalSymbols(uint8_t *Buf); - - const OutputSectionBase *getOutputSection(SymbolBody *Sym); - - // A vector of symbols and their string table offsets. - std::vector Symbols; -}; - // For more information about .gnu.version and .gnu.version_r see: // https://www.akkadia.org/drepper/symbol-versioning @@ -468,8 +433,6 @@ static OutputSectionBase *Opd; static uint8_t *OpdBuf; static PltSection *Plt; - static SymbolTableSection *DynSymTab; - static SymbolTableSection *SymTab; static VersionDefinitionSection *VerDef; static VersionTableSection *VerSym; static VersionNeedSection *VerNeed; @@ -526,8 +489,6 @@ template OutputSectionBase *Out::Opd; template uint8_t *Out::OpdBuf; template PltSection *Out::Plt; -template SymbolTableSection *Out::DynSymTab; -template SymbolTableSection *Out::SymTab; template VersionDefinitionSection *Out::VerDef; template VersionTableSection *Out::VerSym; template VersionNeedSection *Out::VerNeed; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -148,20 +148,20 @@ } template void HashTableSection::finalize() { - this->Link = Out::DynSymTab->SectionIndex; + this->Link = In::DynSymTab->OutSec->SectionIndex; unsigned NumEntries = 2; // nbucket and nchain. - NumEntries += Out::DynSymTab->getNumSymbols(); // The chain entries. + NumEntries += In::DynSymTab->getNumSymbols(); // The chain entries. // Create as many buckets as there are symbols. // FIXME: This is simplistic. We can try to optimize it, but implementing // support for SHT_GNU_HASH is probably even more profitable. - NumEntries += Out::DynSymTab->getNumSymbols(); + NumEntries += In::DynSymTab->getNumSymbols(); this->Size = NumEntries * sizeof(Elf_Word); } template void HashTableSection::writeTo(uint8_t *Buf) { - unsigned NumSymbols = Out::DynSymTab->getNumSymbols(); + unsigned NumSymbols = In::DynSymTab->getNumSymbols(); auto *P = reinterpret_cast(Buf); *P++ = NumSymbols; // nbucket *P++ = NumSymbols; // nchain @@ -169,7 +169,7 @@ Elf_Word *Buckets = P; Elf_Word *Chains = P + NumSymbols; - for (const SymbolTableEntry &S : Out::DynSymTab->getSymbols()) { + for (const SymbolTableEntry &S : In::DynSymTab->getSymbols()) { SymbolBody *Body = S.Symbol; StringRef Name = Body->getName(); unsigned I = Body->DynsymIndex; @@ -234,7 +234,7 @@ // Second hash shift estimation: just predefined values. Shift2 = ELFT::Is64Bits ? 6 : 5; - this->Link = Out::DynSymTab->SectionIndex; + this->Link = In::DynSymTab->OutSec->SectionIndex; this->Size = sizeof(Elf_Word) * 4 // Header + sizeof(Elf_Off) * MaskWords // Bloom Filter + sizeof(Elf_Word) * NBuckets // Hash Buckets @@ -253,7 +253,7 @@ void GnuHashTableSection::writeHeader(uint8_t *&Buf) { auto *P = reinterpret_cast(Buf); *P++ = NBuckets; - *P++ = Out::DynSymTab->getNumSymbols() - Symbols.size(); + *P++ = In::DynSymTab->getNumSymbols() - Symbols.size(); *P++ = MaskWords; *P++ = Shift2; Buf = reinterpret_cast(P); @@ -419,7 +419,7 @@ if (Type != SHT_RELA && Type != SHT_REL) return; - this->Link = Out::SymTab->SectionIndex; + this->Link = In::SymTab->OutSec->SectionIndex; // sh_info for SHT_REL[A] sections should contain the section header index of // the section to which the relocation applies. InputSectionBase *S = Sections[0]->getRelocatedSection(); @@ -819,188 +819,6 @@ } template -SymbolTableSection::SymbolTableSection( - StringTableSection &StrTabSec) - : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab", - StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, - StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0), - StrTabSec(StrTabSec) { - this->Entsize = sizeof(Elf_Sym); - this->Addralign = sizeof(uintX_t); -} - -// Orders symbols according to their positions in the GOT, -// in compliance with MIPS ABI rules. -// See "Global Offset Table" in Chapter 5 in the following document -// for detailed description: -// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf -static bool sortMipsSymbols(const SymbolBody *L, const SymbolBody *R) { - // Sort entries related to non-local preemptible symbols by GOT indexes. - // All other entries go to the first part of GOT in arbitrary order. - bool LIsInLocalGot = !L->IsInGlobalMipsGot; - bool RIsInLocalGot = !R->IsInGlobalMipsGot; - if (LIsInLocalGot || RIsInLocalGot) - return !RIsInLocalGot; - return L->GotIndex < R->GotIndex; -} - -static uint8_t getSymbolBinding(SymbolBody *Body) { - Symbol *S = Body->symbol(); - if (Config->Relocatable) - return S->Binding; - uint8_t Visibility = S->Visibility; - if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) - return STB_LOCAL; - if (Config->NoGnuUnique && S->Binding == STB_GNU_UNIQUE) - return STB_GLOBAL; - return S->Binding; -} - -template void SymbolTableSection::finalize() { - if (this->Size) - return; // Already finalized. - - this->Size = getNumSymbols() * sizeof(Elf_Sym); - this->Link = StrTabSec.OutSec->SectionIndex; - this->Info = NumLocals + 1; - - if (Config->Relocatable) { - size_t I = NumLocals; - for (const SymbolTableEntry &S : Symbols) - S.Symbol->DynsymIndex = ++I; - return; - } - - if (!StrTabSec.isDynamic()) { - std::stable_sort(Symbols.begin(), Symbols.end(), - [](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return getSymbolBinding(L.Symbol) == STB_LOCAL && - getSymbolBinding(R.Symbol) != STB_LOCAL; - }); - return; - } - if (Out::GnuHashTab) - // NB: It also sorts Symbols to meet the GNU hash table requirements. - Out::GnuHashTab->addSymbols(Symbols); - else if (Config->EMachine == EM_MIPS) - std::stable_sort(Symbols.begin(), Symbols.end(), - [](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return sortMipsSymbols(L.Symbol, R.Symbol); - }); - size_t I = 0; - for (const SymbolTableEntry &S : Symbols) - S.Symbol->DynsymIndex = ++I; -} - -template void SymbolTableSection::addSymbol(SymbolBody *B) { - Symbols.push_back({B, StrTabSec.addString(B->getName(), false)}); -} - -template void SymbolTableSection::writeTo(uint8_t *Buf) { - Buf += sizeof(Elf_Sym); - - // All symbols with STB_LOCAL binding precede the weak and global symbols. - // .dynsym only contains global symbols. - if (Config->Discard != DiscardPolicy::All && !StrTabSec.isDynamic()) - writeLocalSymbols(Buf); - - writeGlobalSymbols(Buf); -} - -template -void SymbolTableSection::writeLocalSymbols(uint8_t *&Buf) { - // Iterate over all input object files to copy their local symbols - // to the output symbol table pointed by Buf. - for (ObjectFile *File : Symtab::X->getObjectFiles()) { - for (const std::pair *, size_t> &P : - File->KeptLocalSyms) { - const DefinedRegular &Body = *P.first; - InputSectionBase *Section = Body.Section; - auto *ESym = reinterpret_cast(Buf); - - if (!Section) { - ESym->st_shndx = SHN_ABS; - ESym->st_value = Body.Value; - } else { - const OutputSectionBase *OutSec = Section->OutSec; - ESym->st_shndx = OutSec->SectionIndex; - ESym->st_value = OutSec->Addr + Section->getOffset(Body); - } - ESym->st_name = P.second; - ESym->st_size = Body.template getSize(); - ESym->setBindingAndType(STB_LOCAL, Body.Type); - Buf += sizeof(*ESym); - } - } -} - -template -void SymbolTableSection::writeGlobalSymbols(uint8_t *Buf) { - // Write the internal symbol table contents to the output symbol table - // pointed by Buf. - auto *ESym = reinterpret_cast(Buf); - for (const SymbolTableEntry &S : Symbols) { - SymbolBody *Body = S.Symbol; - size_t StrOff = S.StrTabOffset; - - uint8_t Type = Body->Type; - uintX_t Size = Body->getSize(); - - ESym->setBindingAndType(getSymbolBinding(Body), Type); - ESym->st_size = Size; - ESym->st_name = StrOff; - ESym->setVisibility(Body->symbol()->Visibility); - ESym->st_value = Body->getVA(); - - if (const OutputSectionBase *OutSec = getOutputSection(Body)) - ESym->st_shndx = OutSec->SectionIndex; - else if (isa>(Body)) - ESym->st_shndx = SHN_ABS; - - if (Config->EMachine == EM_MIPS) { - // On MIPS we need to mark symbol which has a PLT entry and requires - // pointer equality by STO_MIPS_PLT flag. That is necessary to help - // dynamic linker distinguish such symbols and MIPS lazy-binding stubs. - // https://sourceware.org/ml/binutils/2008-07/txt00000.txt - if (Body->isInPlt() && Body->NeedsCopyOrPltAddr) - ESym->st_other |= STO_MIPS_PLT; - if (Config->Relocatable) { - auto *D = dyn_cast>(Body); - if (D && D->isMipsPIC()) - ESym->st_other |= STO_MIPS_PIC; - } - } - ++ESym; - } -} - -template -const OutputSectionBase * -SymbolTableSection::getOutputSection(SymbolBody *Sym) { - switch (Sym->kind()) { - case SymbolBody::DefinedSyntheticKind: - return cast>(Sym)->Section; - case SymbolBody::DefinedRegularKind: { - auto &D = cast>(*Sym); - if (D.Section) - return D.Section->OutSec; - break; - } - case SymbolBody::DefinedCommonKind: - return In::Common->OutSec; - case SymbolBody::SharedKind: - if (cast>(Sym)->needsCopy()) - return Out::Bss; - break; - case SymbolBody::UndefinedKind: - case SymbolBody::LazyArchiveKind: - case SymbolBody::LazyObjectKind: - break; - } - return nullptr; -} - -template VersionDefinitionSection::VersionDefinitionSection() : OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) { this->Addralign = sizeof(uint32_t); @@ -1065,16 +883,16 @@ template void VersionTableSection::finalize() { this->Size = - sizeof(Elf_Versym) * (Out::DynSymTab->getSymbols().size() + 1); + sizeof(Elf_Versym) * (In::DynSymTab->getSymbols().size() + 1); this->Entsize = sizeof(Elf_Versym); // At the moment of june 2016 GNU docs does not mention that sh_link field // should be set, but Sun docs do. Also readelf relies on this field. - this->Link = Out::DynSymTab->SectionIndex; + this->Link = In::DynSymTab->OutSec->SectionIndex; } template void VersionTableSection::writeTo(uint8_t *Buf) { auto *OutVersym = reinterpret_cast(Buf) + 1; - for (const SymbolTableEntry &S : Out::DynSymTab->getSymbols()) { + for (const SymbolTableEntry &S : In::DynSymTab->getSymbols()) { OutVersym->vs_index = S.Symbol->symbol()->VersionId; ++OutVersym; } @@ -1293,11 +1111,6 @@ template class MergeOutputSection; template class MergeOutputSection; -template class SymbolTableSection; -template class SymbolTableSection; -template class SymbolTableSection; -template class SymbolTableSection; - template class VersionTableSection; template class VersionTableSection; template class VersionTableSection; Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -11,6 +11,7 @@ #define LLD_ELF_SYNTHETIC_SECTION_H #include "InputSection.h" +#include "OutputSections.h" #include "llvm/ADT/SmallPtrSet.h" namespace lld { @@ -360,6 +361,37 @@ std::vector> Relocs; }; +template +class SymbolTableSection final : public SyntheticSection { +public: + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::Sym Elf_Sym; + typedef typename ELFT::SymRange Elf_Sym_Range; + typedef typename ELFT::uint uintX_t; + SymbolTableSection(StringTableSection &StrTabSec); + + void finalize() override; + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return getNumSymbols() * sizeof(Elf_Sym); } + void addSymbol(SymbolBody *Body); + StringTableSection &getStrTabSec() const { return StrTabSec; } + unsigned getNumSymbols() const { return NumLocals + Symbols.size() + 1; } + + ArrayRef getSymbols() const { return Symbols; } + + unsigned NumLocals = 0; + StringTableSection &StrTabSec; + +private: + void writeLocalSymbols(uint8_t *&Buf); + void writeGlobalSymbols(uint8_t *Buf); + + const OutputSectionBase *getOutputSection(SymbolBody *Sym); + + // A vector of symbols and their string table offsets. + std::vector Symbols; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -370,6 +402,7 @@ static InputSection *Common; static DynamicSection *Dynamic; static StringTableSection *DynStrTab; + static SymbolTableSection *DynSymTab; static GotSection *Got; static MipsGotSection *MipsGot; static GotPltSection *GotPlt; @@ -381,12 +414,14 @@ static RelocationSection *RelaPlt; static StringTableSection *ShStrTab; static StringTableSection *StrTab; + static SymbolTableSection *SymTab; }; template BuildIdSection *In::BuildId; template InputSection *In::Common; template DynamicSection *In::Dynamic; template StringTableSection *In::DynStrTab; +template SymbolTableSection *In::DynSymTab; template GotSection *In::Got; template MipsGotSection *In::MipsGot; template GotPltSection *In::GotPlt; @@ -398,6 +433,7 @@ template RelocationSection *In::RelaPlt; template StringTableSection *In::ShStrTab; template StringTableSection *In::StrTab; +template SymbolTableSection *In::SymTab; } // namespace elf } // namespace lld Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -788,7 +788,7 @@ add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); } - add({DT_SYMTAB, Out::DynSymTab}); + add({DT_SYMTAB, In::DynSymTab}); add({DT_SYMENT, sizeof(Elf_Sym)}); add({DT_STRTAB, In::DynStrTab}); add({DT_STRSZ, In::DynStrTab->getSize()}); @@ -831,12 +831,12 @@ add({DT_MIPS_RLD_VERSION, 1}); add({DT_MIPS_FLAGS, RHF_NOTPOT}); add({DT_MIPS_BASE_ADDRESS, Config->ImageBase}); - add({DT_MIPS_SYMTABNO, Out::DynSymTab->getNumSymbols()}); + add({DT_MIPS_SYMTABNO, In::DynSymTab->getNumSymbols()}); add({DT_MIPS_LOCAL_GOTNO, In::MipsGot->getMipsLocalEntriesNum()}); if (const SymbolBody *B = In::MipsGot->getMipsFirstGlobalEntry()) add({DT_MIPS_GOTSYM, B->DynsymIndex}); else - add({DT_MIPS_GOTSYM, Out::DynSymTab->getNumSymbols()}); + add({DT_MIPS_GOTSYM, In::DynSymTab->getNumSymbols()}); add({DT_PLTGOT, In::MipsGot}); if (Out::MipsRldMap) add({DT_MIPS_RLD_MAP, Out::MipsRldMap}); @@ -953,14 +953,193 @@ } template void RelocationSection::finalize() { - this->Link = Out::DynSymTab ? Out::DynSymTab->SectionIndex - : Out::SymTab->SectionIndex; + this->Link = In::DynSymTab ? In::DynSymTab->OutSec->SectionIndex + : In::SymTab->OutSec->SectionIndex; // Set required output section properties. this->OutSec->Link = this->Link; this->OutSec->Entsize = this->Entsize; } +template +SymbolTableSection::SymbolTableSection( + StringTableSection &StrTabSec) + : SyntheticSection(StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0, + StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, + sizeof(uintX_t), + StrTabSec.isDynamic() ? ".dynsym" : ".symtab"), + StrTabSec(StrTabSec) { + this->Entsize = sizeof(Elf_Sym); +} + +// Orders symbols according to their positions in the GOT, +// in compliance with MIPS ABI rules. +// See "Global Offset Table" in Chapter 5 in the following document +// for detailed description: +// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf +static bool sortMipsSymbols(const SymbolBody *L, const SymbolBody *R) { + // Sort entries related to non-local preemptible symbols by GOT indexes. + // All other entries go to the first part of GOT in arbitrary order. + bool LIsInLocalGot = !L->IsInGlobalMipsGot; + bool RIsInLocalGot = !R->IsInGlobalMipsGot; + if (LIsInLocalGot || RIsInLocalGot) + return !RIsInLocalGot; + return L->GotIndex < R->GotIndex; +} + +static uint8_t getSymbolBinding(SymbolBody *Body) { + Symbol *S = Body->symbol(); + if (Config->Relocatable) + return S->Binding; + uint8_t Visibility = S->Visibility; + if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) + return STB_LOCAL; + if (Config->NoGnuUnique && S->Binding == STB_GNU_UNIQUE) + return STB_GLOBAL; + return S->Binding; +} + +template void SymbolTableSection::finalize() { + this->OutSec->Link = this->Link = StrTabSec.OutSec->SectionIndex; + this->OutSec->Info = this->Info = NumLocals + 1; + this->OutSec->Entsize = this->Entsize; + + if (Config->Relocatable) { + size_t I = NumLocals; + for (const SymbolTableEntry &S : Symbols) + S.Symbol->DynsymIndex = ++I; + return; + } + + if (!StrTabSec.isDynamic()) { + std::stable_sort(Symbols.begin(), Symbols.end(), + [](const SymbolTableEntry &L, const SymbolTableEntry &R) { + return getSymbolBinding(L.Symbol) == STB_LOCAL && + getSymbolBinding(R.Symbol) != STB_LOCAL; + }); + return; + } + if (Out::GnuHashTab) + // NB: It also sorts Symbols to meet the GNU hash table requirements. + Out::GnuHashTab->addSymbols(Symbols); + else if (Config->EMachine == EM_MIPS) + std::stable_sort(Symbols.begin(), Symbols.end(), + [](const SymbolTableEntry &L, const SymbolTableEntry &R) { + return sortMipsSymbols(L.Symbol, R.Symbol); + }); + size_t I = 0; + for (const SymbolTableEntry &S : Symbols) + S.Symbol->DynsymIndex = ++I; +} + +template void SymbolTableSection::addSymbol(SymbolBody *B) { + Symbols.push_back({B, StrTabSec.addString(B->getName(), false)}); +} + +template void SymbolTableSection::writeTo(uint8_t *Buf) { + Buf += sizeof(Elf_Sym); + + // All symbols with STB_LOCAL binding precede the weak and global symbols. + // .dynsym only contains global symbols. + if (Config->Discard != DiscardPolicy::All && !StrTabSec.isDynamic()) + writeLocalSymbols(Buf); + + writeGlobalSymbols(Buf); +} + +template +void SymbolTableSection::writeLocalSymbols(uint8_t *&Buf) { + // Iterate over all input object files to copy their local symbols + // to the output symbol table pointed by Buf. + for (ObjectFile *File : Symtab::X->getObjectFiles()) { + for (const std::pair *, size_t> &P : + File->KeptLocalSyms) { + const DefinedRegular &Body = *P.first; + InputSectionBase *Section = Body.Section; + auto *ESym = reinterpret_cast(Buf); + + if (!Section) { + ESym->st_shndx = SHN_ABS; + ESym->st_value = Body.Value; + } else { + const OutputSectionBase *OutSec = Section->OutSec; + ESym->st_shndx = OutSec->SectionIndex; + ESym->st_value = OutSec->Addr + Section->getOffset(Body); + } + ESym->st_name = P.second; + ESym->st_size = Body.template getSize(); + ESym->setBindingAndType(STB_LOCAL, Body.Type); + Buf += sizeof(*ESym); + } + } +} + +template +void SymbolTableSection::writeGlobalSymbols(uint8_t *Buf) { + // Write the internal symbol table contents to the output symbol table + // pointed by Buf. + auto *ESym = reinterpret_cast(Buf); + for (const SymbolTableEntry &S : Symbols) { + SymbolBody *Body = S.Symbol; + size_t StrOff = S.StrTabOffset; + + uint8_t Type = Body->Type; + uintX_t Size = Body->getSize(); + + ESym->setBindingAndType(getSymbolBinding(Body), Type); + ESym->st_size = Size; + ESym->st_name = StrOff; + ESym->setVisibility(Body->symbol()->Visibility); + ESym->st_value = Body->getVA(); + + if (const OutputSectionBase *OutSec = getOutputSection(Body)) + ESym->st_shndx = OutSec->SectionIndex; + else if (isa>(Body)) + ESym->st_shndx = SHN_ABS; + + if (Config->EMachine == EM_MIPS) { + // On MIPS we need to mark symbol which has a PLT entry and requires + // pointer equality by STO_MIPS_PLT flag. That is necessary to help + // dynamic linker distinguish such symbols and MIPS lazy-binding stubs. + // https://sourceware.org/ml/binutils/2008-07/txt00000.txt + if (Body->isInPlt() && Body->NeedsCopyOrPltAddr) + ESym->st_other |= STO_MIPS_PLT; + if (Config->Relocatable) { + auto *D = dyn_cast>(Body); + if (D && D->isMipsPIC()) + ESym->st_other |= STO_MIPS_PIC; + } + } + ++ESym; + } +} + +template +const OutputSectionBase * +SymbolTableSection::getOutputSection(SymbolBody *Sym) { + switch (Sym->kind()) { + case SymbolBody::DefinedSyntheticKind: + return cast>(Sym)->Section; + case SymbolBody::DefinedRegularKind: { + auto &D = cast>(*Sym); + if (D.Section) + return D.Section->OutSec; + break; + } + case SymbolBody::DefinedCommonKind: + return In::Common->OutSec; + case SymbolBody::SharedKind: + if (cast>(Sym)->needsCopy()) + return Out::Bss; + break; + case SymbolBody::UndefinedKind: + case SymbolBody::LazyArchiveKind: + case SymbolBody::LazyObjectKind: + break; + } + return nullptr; +} + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -1050,3 +1229,8 @@ template class elf::RelocationSection; template class elf::RelocationSection; template class elf::RelocationSection; + +template class elf::SymbolTableSection; +template class elf::SymbolTableSection; +template class elf::SymbolTableSection; +template class elf::SymbolTableSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -232,7 +232,7 @@ } if (!Symtab::X->getSharedFiles().empty() || Config->Pic) { - Out::DynSymTab = make>(*In::DynStrTab); + In::DynSymTab = make>(*In::DynStrTab); } if (Config->EhFrameHdr) @@ -249,7 +249,7 @@ Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); if (Config->Strip != StripPolicy::All) { In::StrTab = make>(".strtab", false); - Out::SymTab = make>(*In::StrTab); + In::SymTab = make>(*In::StrTab); } if (Config->EMachine == EM_MIPS && !Config->Shared) { @@ -372,7 +372,7 @@ // Local symbols are not in the linker's symbol table. This function scans // each object file's symbol table to copy local symbols to the output. template void Writer::copyLocalSymbols() { - if (!Out::SymTab) + if (!In::SymTab) return; for (elf::ObjectFile *F : Symtab::X->getObjectFiles()) { StringRef StrTab = F->getStringTable(); @@ -392,11 +392,11 @@ InputSectionBase *Sec = DR->Section; if (!shouldKeepInSymtab(Sec, SymName, *B)) continue; - ++Out::SymTab->NumLocals; + ++In::SymTab->NumLocals; if (Config->Relocatable) - B->DynsymIndex = Out::SymTab->NumLocals; + B->DynsymIndex = In::SymTab->NumLocals; F->KeptLocalSyms.push_back( - std::make_pair(DR, Out::SymTab->StrTabSec.addString(SymName))); + std::make_pair(DR, In::SymTab->StrTabSec.addString(SymName))); } } } @@ -594,7 +594,7 @@ // need these symbols, since IRELATIVE relocs are resolved through GOT // and PLT. For details, see http://www.airs.com/blog/archives/403. template void Writer::addRelIpltSymbols() { - if (Out::DynSymTab) + if (In::DynSymTab) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; addOptionalRegular(S, In::RelaPlt, 0); @@ -647,7 +647,7 @@ // to avoid the undefined symbol error. As usual special cases are ARM and // MIPS - the libc for these targets defines __tls_get_addr itself because // there are no TLS optimizations for these targets. - if (!Out::DynSymTab && + if (!In::DynSymTab && (Config->EMachine != EM_MIPS && Config->EMachine != EM_ARM)) Symtab::X->addIgnored("__tls_get_addr"); @@ -893,7 +893,7 @@ // It should be okay as no one seems to care about the type. // Even the author of gold doesn't remember why gold behaves that way. // https://sourceware.org/ml/binutils/2002-03/msg00360.html - if (Out::DynSymTab) + if (In::DynSymTab) addRegular("_DYNAMIC", In::Dynamic, 0); // Define __rel[a]_iplt_{start,end} symbols if needed. @@ -915,11 +915,11 @@ if (!includeInSymtab(*Body)) continue; - if (Out::SymTab) - Out::SymTab->addSymbol(Body); + if (In::SymTab) + In::SymTab->addSymbol(Body); - if (Out::DynSymTab && S->includeInDynsym()) { - Out::DynSymTab->addSymbol(Body); + if (In::DynSymTab && S->includeInDynsym()) { + In::DynSymTab->addSymbol(Body); if (auto *SS = dyn_cast>(Body)) if (SS->file()->isNeeded()) Out::VerNeed->addSymbol(SS); @@ -942,10 +942,11 @@ Sec->ShName = In::ShStrTab->addString(Sec->getName()); } + // FIXME: this should be removed after converting GnuHashTableSection + // to input section. // Finalizers fix each section's size. // .dynsym is finalized early since that may fill up .gnu.hash. - if (Out::DynSymTab) - Out::DynSymTab->finalize(); + finalizeSynthetic({In::DynSymTab}); // Fill other section headers. The dynamic table is finalized // at the end because some tags like RELSZ depend on result @@ -955,9 +956,9 @@ // Dynamic section must be the last one in this list. finalizeSynthetic( - {In::ShStrTab, In::StrTab, In::DynStrTab, In::Got, - In::MipsGot, In::GotPlt, In::RelaDyn, - In::RelaPlt, In::Dynamic}); + {In::SymTab, In::ShStrTab, In::StrTab, + In::DynStrTab, In::Got, In::MipsGot, In::GotPlt, + In::RelaDyn, In::RelaPlt, In::Dynamic}); // Now that all output offsets are fixed. Finalize mergeable sections // to fix their maps from input offsets to output offsets. @@ -990,11 +991,11 @@ // because we sort the sections using their attributes below. if (Out::GdbIndex && Out::DebugInfo) Add(Out::GdbIndex); - Add(Out::SymTab); + addInputSec(In::SymTab); addInputSec(In::ShStrTab); addInputSec(In::StrTab); - if (Out::DynSymTab) { - Add(Out::DynSymTab); + if (In::DynSymTab) { + addInputSec(In::DynSymTab); bool HasVerNeed = Out::VerNeed->getNeedNum() != 0; if (Out::VerDef || HasVerNeed) @@ -1172,7 +1173,7 @@ Ret.push_back(std::move(TlsHdr)); // Add an entry for .dynamic. - if (Out::DynSymTab) { + if (In::DynSymTab) { Phdr &H = *AddHdr(PT_DYNAMIC, In::Dynamic->OutSec->getPhdrFlags()); H.add(In::Dynamic->OutSec); }