Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1081,6 +1081,14 @@ if (!Config->Relocatable) InputSections.push_back(createCommentSection()); + // Create a .bss section for each common symbol and then replace the common + // symbol with a DefinedRegular symbol. As a result, all common symbols are + // "instantiated" as regular defined symbols, so that we don't need to care + // about common symbols beyond this point. Note that if -r is given, we just + // need to pass through common symbols as-is. + if (Config->DefineCommon) + createCommonSections(); + // Do size optimizations: garbage collection, merging of SHF_MERGE sections // and identical code folding. if (Config->GcSections) Index: ELF/MarkLive.cpp =================================================================== --- ELF/MarkLive.cpp +++ ELF/MarkLive.cpp @@ -64,11 +64,6 @@ std::function Fn) { SymbolBody &B = Sec.getFile()->getRelocTargetSym(Rel); - if (auto *Sym = dyn_cast(&B)) { - Sym->Live = true; - return; - } - if (auto *D = dyn_cast(&B)) { if (!D->Section) return; @@ -226,10 +221,7 @@ if (auto *D = dyn_cast_or_null(Sym)) { if (auto *IS = cast_or_null(D->Section)) Enqueue(IS, D->Value); - return; } - if (auto *S = dyn_cast_or_null(Sym)) - S->Live = true; }; // Add GC root symbols. Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -167,11 +167,6 @@ return S->kind() == SymbolBody::DefinedCommonKind; } - // True if this symbol is not GC'ed. Liveness is usually a notion of - // input sections and not of symbols, but since common symbols don't - // belong to any input section, their liveness is managed by this bit. - bool Live; - // The maximum alignment we have seen for this symbol. uint32_t Alignment; Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -99,14 +99,8 @@ } return VA; } - case SymbolBody::DefinedCommonKind: { - if (!Config->DefineCommon) - return 0; - auto DC = cast(Body); - if (!DC.Live) - return 0; - return DC.Section->getParent()->Addr + DC.Section->OutSecOff; - } + case SymbolBody::DefinedCommonKind: + llvm_unreachable("common are converted to bss"); case SymbolBody::SharedKind: { auto &SS = cast(Body); if (SS.CopyRelSec) @@ -286,7 +280,7 @@ uint8_t StOther, uint8_t Type) : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther, Type), - Live(!Config->GcSections), Alignment(Alignment), Size(Size) {} + Alignment(Alignment), Size(Size) {} // If a shared symbol is referred via a copy relocation, its alignment // becomes part of the ABI. This function returns a symbol alignment. Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -768,7 +768,7 @@ size_t Size = 0; }; -std::vector createCommonSections(); +template void createCommonSections(); InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); void decompressAndMergeSections(); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -54,24 +54,28 @@ return 0; } -std::vector elf::createCommonSections() { - if (!Config->DefineCommon) - return {}; - - std::vector Ret; +// Create a .bss section for each common section and replace the common symbol +// with a DefinedRegular symbol. +template void elf::createCommonSections() { for (Symbol *S : Symtab->getSymbols()) { auto *Sym = dyn_cast(S->body()); - if (!Sym || !Sym->Live) + + if (!Sym) continue; - Sym->Section = make("COMMON"); - size_t Pos = Sym->Section->reserveSpace(Sym->Size, Sym->Alignment); - assert(Pos == 0); - (void)Pos; - Sym->Section->File = Sym->getFile(); - Ret.push_back(Sym->Section); + // Create a synthetic section for the common data. + auto *Section = make("COMMON"); + Section->File = Sym->getFile(); + Section->Live = !Config->GcSections; + Section->reserveSpace(Sym->Size, Sym->Alignment); + InputSections.push_back(Section); + + // Replace all DefinedCommon symbols with DefinedRegular symbols so that we + // don't have to care about DefinedCommon symbols beyond this point. + replaceBody(S, Sym->getFile(), Sym->getName(), Sym->IsLocal, + Sym->StOther, Sym->Type, 0, + Sym->getSize(), Section); } - return Ret; } // Returns an LLD version string. @@ -2376,6 +2380,11 @@ template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); +template void elf::createCommonSections(); +template void elf::createCommonSections(); +template void elf::createCommonSections(); +template void elf::createCommonSections(); + template MergeInputSection *elf::createCommentSection(); template MergeInputSection *elf::createCommentSection(); template MergeInputSection *elf::createCommentSection(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -290,9 +290,6 @@ Add(InX::BuildId); } - for (InputSection *S : createCommonSections()) - Add(S); - InX::Bss = make(".bss"); Add(InX::Bss); InX::BssRelRo = make(".bss.rel.ro"); @@ -441,11 +438,7 @@ if (auto *S = dyn_cast(Sec)) if (!S->getSectionPiece(D->Value)->Live) return false; - return true; } - - if (auto *Sym = dyn_cast(&B)) - return Sym->Live; return true; }