Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/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: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -479,23 +479,20 @@ // 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; - - // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc. - auto *ISec = - make>(IsReadOnly, SS->getAlignment(), SymSize); - OSec->addSection(ISec); + BssSection *Sec = IsReadOnly ? In::BssRelRo : In::Bss; + uintX_t Off = Sec->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 // interpose any aliases. for (SharedSymbol *Sym : getSymbolsAt(SS)) { Sym->NeedsCopy = true; - Sym->Section = ISec; + Sym->CopyRelSec = Sec; + Sym->CopyRelSecOff = Off; Sym->symbol()->IsUsedInRegularObj = true; } - In::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0}); + In::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0}); } template Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -238,8 +238,9 @@ // This field is a pointer to the symbol's version definition. const void *Verdef; - // Section is significant only when NeedsCopy is true. - InputSection *Section = nullptr; + // CopyRelSec and CopyRelSecOff are significant only when NeedsCopy is true. + InputSection *CopyRelSec; + size_t CopyRelSecOff; private: template const typename ELFT::Sym &getSym() const { Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -106,7 +106,8 @@ case SymbolBody::SharedKind: { auto &SS = cast(Body); if (SS.NeedsCopy) - return SS.Section->OutSec->Addr + SS.Section->OutSecOff; + return SS.CopyRelSec->OutSec->Addr + SS.CopyRelSec->OutSecOff + + SS.CopyRelSecOff; if (SS.NeedsPltAddr) return Body.getPltVA(); return 0; @@ -207,7 +208,7 @@ if (auto *S = dyn_cast(this)) { if (S->NeedsCopy) - return S->Section->OutSec; + return S->CopyRelSec->OutSec; return nullptr; } Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -153,16 +153,19 @@ uint8_t *HashBuf; }; -// For each copy relocation, we create an instance of this class to -// reserve space in .bss or .bss.rel.ro. -template class CopyRelSection final : public SyntheticSection { - typedef typename ELFT::uint uintX_t; - +// 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. +class BssSection final : public SyntheticSection { public: - CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size); + BssSection(StringRef Name); void writeTo(uint8_t *) override {} + bool empty() const override { return getSize() == 0; } + size_t reserveSpace(uint32_t Alignment, size_t Size); size_t getSize() const override { return Size; } - size_t Size; + +private: + size_t Size = 0; }; template class MipsGotSection final : public SyntheticSection { @@ -759,6 +762,8 @@ template struct In { static InputSection *ARMAttributes; static BuildIdSection *BuildId; + static BssSection *Bss; + static BssSection *BssRelRo; static InputSection *Common; static DynamicSection *Dynamic; static StringTableSection *DynStrTab; @@ -788,6 +793,8 @@ }; template InputSection *In::ARMAttributes; +template BssSection *In::Bss; +template BssSection *In::BssRelRo; template BuildIdSection *In::BuildId; template InputSection *In::Common; template DynamicSection *In::Dynamic; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -376,11 +376,14 @@ HashFn(HashBuf, Hashes); } -template -CopyRelSection::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S) - : SyntheticSection(SHF_ALLOC, SHT_NOBITS, AddrAlign, - ReadOnly ? ".bss.rel.ro" : ".bss"), - Size(S) {} +BssSection::BssSection(StringRef Name) + : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {} + +size_t BssSection::reserveSpace(uint32_t Alignment, size_t Size) { + OutSec->updateAlignment(Alignment); + this->Size = alignTo(this->Size, Alignment) + Size; + return this->Size - Size; +} template void BuildIdSection::writeBuildId(ArrayRef Buf) { @@ -2307,11 +2310,6 @@ template class elf::BuildIdSection; template class elf::BuildIdSection; -template class elf::CopyRelSection; -template class elf::CopyRelSection; -template class elf::CopyRelSection; -template class elf::CopyRelSection; - template class elf::GotSection; template class elf::GotSection; template class elf::GotSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/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) @@ -330,10 +330,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>( @@ -371,6 +367,11 @@ Add(Common); } + In::Bss = make(".bss"); + Add(In::Bss); + In::BssRelRo = make(".bss.rel.ro"); + Add(In::BssRelRo); + // Add MIPS-specific sections. bool HasDynSymTab = !Symtab::X->getSharedFiles().empty() || Config->pic() || @@ -620,7 +621,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; @@ -1170,14 +1171,15 @@ // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. applySynthetic( - {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::DynSymTab, In::Bss, In::BssRelRo, + 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}, [](SyntheticSection *SS) { SS->finalizeContents(); }); // Some architectures use small displacements for jump instructions. @@ -1206,16 +1208,6 @@ } 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"));