Index: lld/trunk/ELF/InputSection.h =================================================================== --- lld/trunk/ELF/InputSection.h +++ lld/trunk/ELF/InputSection.h @@ -257,17 +257,26 @@ const llvm::object::Elf_Mips_RegInfo *Reginfo = nullptr; }; -// A special kind of section used to store common symbols +// Common symbols don't belong to any section. But it is easier for us +// to handle them as if they belong to some input section. So we defined +// this class. CommonInputSection is a virtual singleton class that +// "contains" all common symbols. template class CommonInputSection : public InputSection { typedef typename ELFT::uint uintX_t; public: CommonInputSection(); + // The singleton instance of this class. + static CommonInputSection *X; + private: - typename ELFT::Shdr Hdr; + static typename ELFT::Shdr Hdr; }; +template CommonInputSection *CommonInputSection::X; +template typename ELFT::Shdr CommonInputSection::Hdr; + } // namespace elf } // namespace lld Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -667,17 +667,9 @@ return S->SectionKind == InputSectionBase::MipsOptions; } -// Due to initialization order in C++ memberwise initialization or -// construction is invoked after base class construction. This helper -// function is needed to zero initialize Elf_Shdr, before passing it -// to InputSection constructor -template static T *zero(T *Val) { - return static_cast(memset(Val, 0, sizeof(*Val))); -} - template CommonInputSection::CommonInputSection() - : InputSection(nullptr, zero(&Hdr)) { + : InputSection(nullptr, &Hdr) { std::vector *> Symbols; Hdr.sh_size = 0; Hdr.sh_type = SHT_NOBITS; Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -24,7 +24,6 @@ template class OutputSectionBase; template class OutputSectionFactory; template class DefinedCommon; -template class CommonInputSection; typedef std::function Expr; @@ -122,8 +121,7 @@ public: std::vector *> - createSections(OutputSectionFactory &Factory, - CommonInputSection *Common); + createSections(OutputSectionFactory &Factory); std::vector> createPhdrs(ArrayRef *> S); @@ -140,7 +138,7 @@ getSectionMap(); std::vector *> - getInputSections(const InputSectionDescription *, CommonInputSection *); + getInputSections(const InputSectionDescription *); // "ScriptConfig" is a bit too long, so define a short name for it. ScriptConfiguration &Opt = *ScriptConfig; Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -95,8 +95,7 @@ // Returns input sections filtered by given glob patterns. template std::vector *> -LinkerScript::getInputSections(const InputSectionDescription *I, - CommonInputSection *Common) { +LinkerScript::getInputSections(const InputSectionDescription *I) { ArrayRef Patterns = I->Patterns; ArrayRef ExcludedFiles = I->ExcludedFiles; std::vector *> Ret; @@ -109,15 +108,14 @@ Ret.push_back(S); if ((llvm::find(Patterns, "COMMON") != Patterns.end())) - Ret.push_back(Common); + Ret.push_back(CommonInputSection::X); return Ret; } template std::vector *> -LinkerScript::createSections(OutputSectionFactory &Factory, - CommonInputSection *Common) { +LinkerScript::createSections(OutputSectionFactory &Factory) { std::vector *> Ret; // Add input section to output section. If there is no output section yet, @@ -134,7 +132,7 @@ for (auto &P : getSectionMap()) { StringRef OutputName = P.first; const InputSectionDescription *I = P.second; - for (InputSectionBase *S : getInputSections(I, Common)) { + for (InputSectionBase *S : getInputSections(I)) { if (OutputName == "/DISCARD/") { S->Live = false; reportDiscarded(S); Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -72,7 +72,6 @@ BumpPtrAllocator Alloc; std::vector *> OutputSections; - std::unique_ptr> CommonSection; OutputSectionFactory Factory; void addRelIpltSymbols(); @@ -222,10 +221,12 @@ copyLocalSymbols(); addReservedSymbols(); - CommonSection = llvm::make_unique>(); + CommonInputSection Common; + CommonInputSection::X = &Common; + OutputSections = ScriptConfig->DoLayout - ? Script::X->createSections(Factory, CommonSection.get()) + ? Script::X->createSections(Factory) : createSections(); finalizeSections(); if (HasError) @@ -738,8 +739,8 @@ // If linker script processor hasn't added common symbol section yet, // then add it to .bss now. - if (!CommonSection->OutSec) { - Out::Bss->addSection(CommonSection.get()); + if (!CommonInputSection::X->OutSec) { + Out::Bss->addSection(CommonInputSection::X); Out::Bss->assignOffsets(); }