Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -153,9 +153,10 @@ uint8_t *HashBuf; }; -// BssSection is used to reserve space for copy relocations. We create two -// instances of this class for .bss and .bss.rel.ro. .bss is used for writable -// symbols, and .bss.rel.ro is used for read-only symbols. +// BssSection is used to reserve space for copy relocations and common symbols. +// We create three instances of this class for .bss, .bss.rel.ro and "COMMON". +// .bss is used for writable symbols, .bss.rel.ro is used for read-only symbols +// and latter used for common symbols. class BssSection final : public SyntheticSection { public: BssSection(StringRef Name); Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -63,33 +63,22 @@ // Find all common symbols and allocate space for them. template InputSection *elf::createCommonSection() { - auto *Ret = make(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1, - ArrayRef(), "COMMON"); - Ret->Live = true; - if (!Config->DefineCommon) - return Ret; + return nullptr; // Sort the common symbols by alignment as an heuristic to pack them better. std::vector Syms = getCommonSymbols(); + if (Syms.empty()) + return nullptr; + std::stable_sort(Syms.begin(), Syms.end(), [](const DefinedCommon *A, const DefinedCommon *B) { return A->Alignment > B->Alignment; }); + BssSection *Ret = make("COMMON"); + for (DefinedCommon *Sym : Syms) + Sym->Offset = Ret->reserveSpace(Sym->Alignment, Sym->Size); - // Assign offsets to symbols. - size_t Size = 0; - uint32_t Alignment = 1; - for (DefinedCommon *Sym : Syms) { - Alignment = std::max(Alignment, Sym->Alignment); - Size = alignTo(Size, Sym->Alignment); - - // Compute symbol offset relative to beginning of input section. - Sym->Offset = Size; - Size += Sym->Size; - } - Ret->Alignment = Alignment; - Ret->Data = makeArrayRef(nullptr, Size); return Ret; } @@ -380,7 +369,8 @@ : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {} size_t BssSection::reserveSpace(uint32_t Alignment, size_t Size) { - OutSec->updateAlignment(Alignment); + if (OutSec) + OutSec->updateAlignment(Alignment); this->Size = alignTo(this->Size, Alignment) + Size; this->Alignment = std::max(this->Alignment, Alignment); return this->Size - Size; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -358,11 +358,8 @@ Add(In::BuildId); } - InputSection *Common = createCommonSection(); - if (!Common->Data.empty()) { - In::Common = Common; - Add(Common); - } + if (In::Common = createCommonSection()) + Add(In::Common); In::Bss = make(".bss"); Add(In::Bss);