Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -98,8 +98,6 @@ // until Writer is initialized. struct Out { static uint8_t First; - static OutputSection *Bss; - static OutputSection *BssRelRo; static OutputSection *Opd; static uint8_t *OpdBuf; static PhdrEntry *TlsPhdr; Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -31,8 +31,6 @@ using namespace lld::elf; uint8_t Out::First; -OutputSection *Out::Bss; -OutputSection *Out::BssRelRo; OutputSection *Out::Opd; uint8_t *Out::OpdBuf; PhdrEntry *Out::TlsPhdr; 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); - OutputSection *OSec = IsReadOnly ? Out::BssRelRo : Out::Bss; - + OutputSection *OSec = + IsReadOnly ? In::BssRelRo->OutSec : In::Bss->OutSec; // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc. auto *ISec = make>(IsReadOnly, SS->getAlignment(), SymSize); Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -155,6 +155,7 @@ public: CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size); void writeTo(uint8_t *) override {} + bool empty() const override; size_t getSize() const override { return Size; } size_t Size; }; @@ -765,6 +766,8 @@ template struct In { static InputSection *ARMAttributes; static BuildIdSection *BuildId; + static CopyRelSection *Bss; + static CopyRelSection *BssRelRo; static InputSection *Common; static DynamicSection *Dynamic; static StringTableSection *DynStrTab; @@ -794,6 +797,8 @@ }; template InputSection *In::ARMAttributes; +template CopyRelSection *In::Bss; +template CopyRelSection *In::BssRelRo; template BuildIdSection *In::BuildId; template InputSection *In::Common; template DynamicSection *In::Dynamic; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -369,10 +369,14 @@ template CopyRelSection::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S) - : SyntheticSection(SHF_ALLOC, SHT_NOBITS, AddrAlign, + : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, AddrAlign, ReadOnly ? ".bss.rel.ro" : ".bss"), Size(S) {} +template bool CopyRelSection::empty() const { + return !OutSec || OutSec->Sections.size() <= 1; +} + template void BuildIdSection::writeBuildId(ArrayRef Buf) { switch (Config->BuildId) { Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -111,8 +111,8 @@ } for (StringRef V : - {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", - ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", + {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", + ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", ".gcc_except_table.", ".tdata.", ".ARM.exidx."}) { StringRef Prefix = V.drop_back(); if (Name.startswith(V) || Name == Prefix) @@ -309,10 +309,6 @@ auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); }; - // Create singleton output sections. - Out::Bss = make(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - Out::BssRelRo = - make(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); In::DynStrTab = make>(".dynstr", true); In::Dynamic = make>(); In::RelaDyn = make>( @@ -350,6 +346,14 @@ Add(Common); } + // Add .bss and .bss.rel.ro stubs. These sections are used to + // create output sections for copy relocations. Sections has size + // of zero, so do not affect output. + In::Bss = make>(false /*RO*/, 0, 0); + Add(In::Bss); + In::BssRelRo = make>(true /*RO*/, 0, 0); + Add(In::BssRelRo); + // Add MIPS-specific sections. bool HasDynSymTab = !Symtab::X->getSharedFiles().empty() || Config->pic() || @@ -594,7 +598,7 @@ return true; if (In::Got && Sec == In::Got->OutSec) return true; - if (Sec == Out::BssRelRo) + if (Sec == In::BssRelRo->OutSec) return true; StringRef S = Sec->Name; @@ -1160,27 +1164,18 @@ // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. finalizeSynthetic( - {In::DynSymTab, In::GnuHashTab, In::HashTab, - In::SymTab, In::ShStrTab, In::StrTab, - In::VerDef, In::DynStrTab, In::GdbIndex, - In::Got, In::MipsGot, In::IgotPlt, - In::GotPlt, In::RelaDyn, In::RelaIplt, - In::RelaPlt, In::Plt, In::Iplt, - In::Plt, In::EhFrameHdr, In::VerSym, - In::VerNeed, In::Dynamic}); + {In::Bss, In::BssRelRo, In::DynSymTab, + In::GnuHashTab, In::HashTab, In::SymTab, + In::ShStrTab, In::StrTab, In::VerDef, + In::DynStrTab, In::GdbIndex, In::Got, + In::MipsGot, In::IgotPlt, In::GotPlt, + In::RelaDyn, In::RelaIplt, In::RelaPlt, + In::Plt, In::Iplt, In::Plt, + In::EhFrameHdr, In::VerSym, In::VerNeed, + In::Dynamic}); } template void Writer::addPredefinedSections() { - // Add BSS sections. - auto Add = [=](OutputSection *Sec) { - if (!Sec->Sections.empty()) { - Sec->assignOffsets(); - OutputSections.push_back(Sec); - } - }; - Add(Out::Bss); - Add(Out::BssRelRo); - // ARM ABI requires .ARM.exidx to be terminated by some piece of data. // We have the terminater synthetic section class. Add that at the end. auto *OS = dyn_cast_or_null(findSection(".ARM.exidx")); Index: test/ELF/map-file.s =================================================================== --- test/ELF/map-file.s +++ test/ELF/map-file.s @@ -48,6 +48,7 @@ // CHECK-NEXT: 0000000000201014 0000000000000000 0 baz // CHECK-NEXT: 0000000000202000 0000000000000004 16 .bss // CHECK-NEXT: 0000000000202000 0000000000000004 16 COMMON +// CHECK-NEXT: 0000000000202004 0000000000000000 1 .bss // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment // CHECK-NEXT: 0000000000000000 00000000000000f0 8 .symtab