Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -479,8 +479,8 @@ // See if this symbol is in a read-only segment. If so, preserve the symbol's // memory protection by reserving space in the .bss.rel.ro section. bool IsReadOnly = isReadOnly(SS); - BssRelSection *RelSec = IsReadOnly ? In::BssRelRo : In::Bss; - uintX_t Off = RelSec->addCopyRelocation(SS->getAlignment(), SymSize); + BssSection *RelSec = IsReadOnly ? In::BssRelRo : In::Bss; + uintX_t Off = RelSec->reserveSpace(SS->getAlignment(), SymSize); // Look through the DSO's dynamic symbol table for aliases and create a // dynamic symbol for each one. This causes the copy relocation to correctly Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -147,16 +147,17 @@ uint8_t *HashBuf; }; -// Section used for storing copy relocations. We create two sections now, -// .bss.rel.ro for RelRo case and .bss for regular case. -template class BssRelSection final : public SyntheticSection { +// Section used for common symbols and storing copy relocations. We create +// three sections now: ".bss.rel.ro", ".bss" for relro and regular copy +// relocations and "COMMON" section for holding common symbols. +template class BssSection final : public SyntheticSection { typedef typename ELFT::uint uintX_t; public: - BssRelSection(bool RelRo); + BssSection(StringRef Name); void writeTo(uint8_t *) override {} bool empty() const override { return getSize() == 0; } - size_t addCopyRelocation(uintX_t AddrAlign, size_t Size); + size_t reserveSpace(uintX_t AddrAlign, size_t Size); size_t getSize() const override { return Size; } size_t Size; }; @@ -759,8 +760,8 @@ template struct In { static InputSection *ARMAttributes; static BuildIdSection *BuildId; - static BssRelSection *Bss; - static BssRelSection *BssRelRo; + static BssSection *Bss; + static BssSection *BssRelRo; static InputSection *Common; static DynamicSection *Dynamic; static StringTableSection *DynStrTab; @@ -790,8 +791,8 @@ }; template InputSection *In::ARMAttributes; -template BssRelSection *In::Bss; -template BssRelSection *In::BssRelRo; +template BssSection *In::Bss; +template BssSection *In::BssRelRo; template BuildIdSection *In::BuildId; template InputSection *In::Common; template DynamicSection *In::Dynamic; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -63,33 +63,21 @@ // 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; }); - - // Assign offsets to symbols. - size_t Size = 0; - size_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); + BssSection *Ret = make>("COMMON"); + for (DefinedCommon *Sym : Syms) + Sym->Offset = Ret->reserveSpace(Sym->Alignment, Sym->Size); return Ret; } @@ -377,15 +365,15 @@ } template -BssRelSection::BssRelSection(bool RelRo) - : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, - RelRo ? ".bss.rel.ro" : ".bss"), - Size(0) {} +BssSection::BssSection(StringRef Name) + : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name), Size(0) {} template -size_t BssRelSection::addCopyRelocation(uintX_t AddrAlign, size_t Size) { - OutSec->updateAlignment(AddrAlign); +size_t BssSection::reserveSpace(uintX_t AddrAlign, size_t Size) { this->Size = alignTo(this->Size, AddrAlign) + Size; + this->Alignment = std::max(this->Alignment, AddrAlign); + if (OutSec) + OutSec->updateAlignment(AddrAlign); return this->Size - Size; } @@ -2305,10 +2293,10 @@ template class elf::BuildIdSection; template class elf::BuildIdSection; -template class elf::BssRelSection; -template class elf::BssRelSection; -template class elf::BssRelSection; -template class elf::BssRelSection; +template class elf::BssSection; +template class elf::BssSection; +template class elf::BssSection; +template class elf::BssSection; template class elf::GotSection; template class elf::GotSection; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -340,15 +340,12 @@ 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>(false /*RelRo*/); + In::Bss = make>(".bss"); Add(In::Bss); - In::BssRelRo = make>(true /*RelRo*/); + In::BssRelRo = make>(".bss.rel.ro"); Add(In::BssRelRo); // Add MIPS-specific sections.