Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -1121,14 +1121,6 @@ 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. markLive(); Index: lld/trunk/ELF/InputSection.h =================================================================== --- lld/trunk/ELF/InputSection.h +++ lld/trunk/ELF/InputSection.h @@ -24,7 +24,6 @@ namespace lld { namespace elf { -class DefinedCommon; class Symbol; struct SectionPiece; @@ -55,6 +54,8 @@ // If GC is disabled, all sections are considered live by default. unsigned Live : 1; + unsigned Bss : 1; + // These corresponds to the fields in Elf_Shdr. uint32_t Alignment; uint64_t Flags; @@ -78,7 +79,7 @@ SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags, uint64_t Entsize, uint64_t Alignment, uint32_t Type, uint32_t Info, uint32_t Link) - : Name(Name), SectionKind(SectionKind), Live(false), + : Name(Name), SectionKind(SectionKind), Live(false), Bss(false), Alignment(Alignment), Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {} }; Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -19,6 +19,7 @@ #include "LinkerScript.h" #include "Memory.h" #include "Symbols.h" +#include "SyntheticSections.h" #include "lld/Common/ErrorHandler.h" #include "llvm/ADT/STLExtras.h" @@ -365,13 +366,13 @@ S->Binding = Binding; return Cmp; } - if (isa(S)) { - // Non-common symbols take precedence over common symbols. - if (Config->WarnCommon) - warn("common " + S->getName() + " is overridden"); - return 1; - } if (auto *R = dyn_cast(S)) { + if (R->Section && isa(R->Section)) { + // Non-common symbols take precedence over common symbols. + if (Config->WarnCommon) + warn("common " + S->getName() + " is overridden"); + return 1; + } if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute && R->Value == Value) return -1; @@ -388,11 +389,18 @@ /*CanOmitFromDynSym*/ false, File); int Cmp = compareDefined(S, WasInserted, Binding, N); if (Cmp > 0) { + auto *Bss = make("COMMON", Size, Alignment); + Bss->File = File; + Bss->Live = !Config->GcSections; + InputSections.push_back(Bss); + S->Binding = Binding; - replaceSymbol(S, File, N, Size, Alignment, StOther, Type); + replaceSymbol(S, File, N, /*IsLocal=*/false, StOther, Type, + 0, Size, Bss); } else if (Cmp == 0) { - auto *C = dyn_cast(S); - if (!C) { + auto *D = cast(S); + auto *Bss = dyn_cast_or_null(D->Section); + if (!Bss) { // Non-common symbols take precedence over common symbols. if (Config->WarnCommon) warn("common " + S->getName() + " is overridden"); @@ -400,11 +408,13 @@ } if (Config->WarnCommon) - warn("multiple common of " + S->getName()); + warn("multiple common of " + D->getName()); - Alignment = C->Alignment = std::max(C->Alignment, Alignment); - if (Size > C->Size) - replaceSymbol(S, File, N, Size, Alignment, StOther, Type); + Bss->Alignment = std::max(Bss->Alignment, Alignment); + if (Size > Bss->Size) { + D->File = Bss->File = File; + D->Size = Bss->Size = Size; + } } return S; } Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -40,8 +40,7 @@ enum Kind { DefinedFirst, DefinedRegularKind = DefinedFirst, - DefinedCommonKind, - DefinedLast = DefinedCommonKind, + DefinedLast = DefinedRegularKind, SharedKind, UndefinedKind, LazyArchiveKind, @@ -97,7 +96,6 @@ bool isUndefined() const { return SymbolKind == UndefinedKind; } bool isDefined() const { return SymbolKind <= DefinedLast; } - bool isCommon() const { return SymbolKind == DefinedCommonKind; } bool isShared() const { return SymbolKind == SharedKind; } bool isLocal() const { return IsLocal; } @@ -106,7 +104,7 @@ } bool isInCurrentOutput() const { - return SymbolKind == DefinedRegularKind || SymbolKind == DefinedCommonKind; + return SymbolKind == DefinedRegularKind; } // True is this is an undefined weak symbol. This only works once @@ -199,26 +197,6 @@ static bool classof(const Symbol *S) { return S->isDefined(); } }; -class DefinedCommon : public Defined { -public: - DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment, - uint8_t StOther, uint8_t Type) - : Defined(DefinedCommonKind, Name, /*IsLocal=*/false, StOther, Type), - Alignment(Alignment), Size(Size) {} - - static bool classof(const Symbol *S) { - return S->kind() == DefinedCommonKind; - } - - // The maximum alignment we have seen for this symbol. - uint32_t Alignment; - - // The output offset of this common symbol in the output bss. - // Computed by the writer. - uint64_t Size; - BssSection *Section = nullptr; -}; - // Regular defined symbols read from object file symbol tables. class DefinedRegular : public Defined { public: @@ -378,7 +356,6 @@ // using the placement new. union SymbolUnion { alignas(DefinedRegular) char A[sizeof(DefinedRegular)]; - alignas(DefinedCommon) char B[sizeof(DefinedCommon)]; alignas(Undefined) char C[sizeof(Undefined)]; alignas(SharedSymbol) char D[sizeof(SharedSymbol)]; alignas(LazyArchive) char E[sizeof(LazyArchive)]; Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -99,8 +99,6 @@ } return VA; } - case Symbol::DefinedCommonKind: - llvm_unreachable("common are converted to bss"); case Symbol::SharedKind: { auto &SS = cast(Sym); if (SS.CopyRelSec) @@ -182,8 +180,6 @@ } uint64_t Symbol::getSize() const { - if (const auto *C = dyn_cast(this)) - return C->Size; if (const auto *DR = dyn_cast(this)) return DR->Size; if (const auto *S = dyn_cast(this)) @@ -204,12 +200,6 @@ return nullptr; } - if (auto *S = dyn_cast(this)) { - if (Config->DefineCommon) - return S->Section->getParent(); - return nullptr; - } - return nullptr; } @@ -321,12 +311,12 @@ std::string S; if (Sym->isUndefined()) S = ": reference to "; - else if (Sym->isCommon()) - S = ": common definition of "; else if (Sym->isLazy()) S = ": lazy definition of "; else if (Sym->isShared()) S = ": shared definition of "; + else if (dyn_cast_or_null(cast(Sym)->Section)) + S = ": common definition of "; else S = ": definition of "; Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -159,7 +159,7 @@ bool empty() const override { return getSize() == 0; } size_t getSize() const override { return Size; } -private: + static bool classof(const SectionBase *S) { return S->Bss; } uint64_t Size; }; @@ -821,7 +821,6 @@ size_t Size = 0; }; -template void createCommonSections(); InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); void decompressSections(); Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -63,29 +63,6 @@ return 0; } -// Create a .bss section for each common symbol and replace the common symbol -// with a DefinedRegular symbol. -template void elf::createCommonSections() { - for (Symbol *S : Symtab->getSymbols()) { - auto *Sym = dyn_cast(S); - - if (!Sym) - continue; - - // Create a synthetic section for the common data. - auto *Section = make("COMMON", Sym->Size, Sym->Alignment); - Section->File = Sym->getFile(); - Section->Live = !Config->GcSections; - 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. - replaceSymbol( - S, Sym->getFile(), Sym->getName(), static_cast(Sym->isLocal()), - Sym->StOther, Sym->Type, 0, Sym->getSize(), Section); - } -} - // Returns an LLD version string. static ArrayRef getVersion() { // Check LLD_VERSION first for ease of testing. @@ -367,6 +344,7 @@ BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment) : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) { + this->Bss = true; if (OutputSection *Sec = getParent()) Sec->Alignment = std::max(Sec->Alignment, Alignment); this->Size = Size; @@ -1596,12 +1574,16 @@ ESym->st_name = Ent.StrTabOffset; // Set a section index. - if (const OutputSection *OutSec = Sym->getOutputSection()) + BssSection *CommonSec = nullptr; + if (!Config->DefineCommon) + if (auto *D = dyn_cast(Sym)) + CommonSec = dyn_cast_or_null(D->Section); + if (CommonSec) + ESym->st_shndx = SHN_COMMON; + else if (const OutputSection *OutSec = Sym->getOutputSection()) ESym->st_shndx = OutSec->SectionIndex; else if (isa(Sym)) ESym->st_shndx = SHN_ABS; - else if (isa(Sym)) - ESym->st_shndx = SHN_COMMON; else ESym->st_shndx = SHN_UNDEF; @@ -1618,8 +1600,8 @@ // st_value is usually an address of a symbol, but that has a // special meaining for uninstantiated common symbols (this can // occur if -r is given). - if (!Config->DefineCommon && isa(Sym)) - ESym->st_value = cast(Sym)->Alignment; + if (CommonSec) + ESym->st_value = CommonSec->Alignment; else ESym->st_value = Sym->getVA(); @@ -2642,11 +2624,6 @@ template void PltSection::addEntry(Symbol &Sym); template void PltSection::addEntry(Symbol &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: lld/trunk/test/ELF/relocatable-common.s =================================================================== --- lld/trunk/test/ELF/relocatable-common.s +++ lld/trunk/test/ELF/relocatable-common.s @@ -30,7 +30,7 @@ # DEFCOMM-NEXT: Binding: Global # DEFCOMM-NEXT: Type: Object # DEFCOMM-NEXT: Other: 0 -# DEFCOMM-NEXT: Section: COMMON (0x2) +# DEFCOMM-NEXT: Section: COMMON # DEFCOMM-NEXT: } .comm common,4,4