diff options
Diffstat (limited to 'lld/ELF')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 13 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 5 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 5 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 22 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 18 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 43 |
8 files changed, 51 insertions, 59 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 1c0bdfa07ba..335b3c9d9c2 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -31,8 +31,6 @@ using namespace lld; using namespace lld::elf; uint8_t Out::First; -OutputSection *Out::Bss; -OutputSection *Out::BssRelRo; OutputSection *Out::Opd; uint8_t *Out::OpdBuf; PhdrEntry *Out::TlsPhdr; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 6746afad6e2..649d1fa4834 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -95,8 +95,6 @@ public: // 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; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index d8863e56c15..b7b6f0298e2 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -479,23 +479,20 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) { // 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<ELFT>(SS); - OutputSection *OSec = IsReadOnly ? Out::BssRelRo : Out::Bss; - - // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc. - auto *ISec = - make<CopyRelSection<ELFT>>(IsReadOnly, SS->getAlignment<ELFT>(), SymSize); - OSec->addSection(ISec); + BssSection *Sec = IsReadOnly ? In<ELFT>::BssRelRo : In<ELFT>::Bss; + uintX_t Off = Sec->reserveSpace(SS->getAlignment<ELFT>(), 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<ELFT>(SS)) { Sym->NeedsCopy = true; - Sym->Section = ISec; + Sym->CopyRelSec = Sec; + Sym->CopyRelSecOff = Off; Sym->symbol()->IsUsedInRegularObj = true; } - In<ELFT>::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0}); + In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0}); } template <class ELFT> diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 081cc582952..4b9186557d9 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -106,7 +106,8 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { case SymbolBody::SharedKind: { auto &SS = cast<SharedSymbol>(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<ELFT>(); return 0; @@ -207,7 +208,7 @@ OutputSection *SymbolBody::getOutputSection() const { if (auto *S = dyn_cast<SharedSymbol>(this)) { if (S->NeedsCopy) - return S->Section->OutSec; + return S->CopyRelSec->OutSec; return nullptr; } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 568fe08cfd1..e53dacacd50 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -238,8 +238,9 @@ public: // 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 <class ELFT> const typename ELFT::Sym &getSym() const { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 4a4fa5b6962..cb91596f21f 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -376,12 +376,15 @@ void BuildIdSection<ELFT>::computeHash( HashFn(HashBuf, Hashes); } -template <class ELFT> -CopyRelSection<ELFT>::CopyRelSection(bool ReadOnly, uint32_t Alignment, - size_t S) - : SyntheticSection(SHF_ALLOC, SHT_NOBITS, Alignment, - 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; + this->Alignment = std::max<uint32_t>(this->Alignment, Alignment); + return this->Size - Size; +} template <class ELFT> void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) { @@ -2260,6 +2263,8 @@ InputSection *ThunkSection::getTargetInputSection() const { } InputSection *InX::ARMAttributes; +BssSection *InX::Bss; +BssSection *InX::BssRelRo; InputSection *InX::Common; StringTableSection *InX::DynStrTab; InputSection *InX::Interp; @@ -2312,11 +2317,6 @@ template class elf::BuildIdSection<ELF32BE>; template class elf::BuildIdSection<ELF64LE>; template class elf::BuildIdSection<ELF64BE>; -template class elf::CopyRelSection<ELF32LE>; -template class elf::CopyRelSection<ELF32BE>; -template class elf::CopyRelSection<ELF64LE>; -template class elf::CopyRelSection<ELF64BE>; - template class elf::GotSection<ELF32LE>; template class elf::GotSection<ELF32BE>; template class elf::GotSection<ELF64LE>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 1ae6318e25b..b8648de6499 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -153,15 +153,19 @@ private: 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 ELFT> class CopyRelSection final : public SyntheticSection { +// 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, uint32_t Alignment, 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 ELFT> class MipsGotSection final : public SyntheticSection { @@ -754,6 +758,8 @@ SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, // Linker generated sections which can be used as inputs. struct InX { static InputSection *ARMAttributes; + static BssSection *Bss; + static BssSection *BssRelRo; static InputSection *Common; static StringTableSection *DynStrTab; static InputSection *Interp; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7f8391080f6..ad3c68b608c 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -111,8 +111,8 @@ StringRef elf::getOutputSectionName(StringRef Name) { } 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) @@ -327,11 +327,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); }; - // Create singleton output sections. - Out::Bss = make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - Out::BssRelRo = - make<OutputSection>(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - In<ELFT>::DynStrTab = make<StringTableSection>(".dynstr", true); In<ELFT>::Dynamic = make<DynamicSection<ELFT>>(); In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( @@ -369,6 +364,11 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { Add(Common); } + In<ELFT>::Bss = make<BssSection>(".bss"); + Add(In<ELFT>::Bss); + In<ELFT>::BssRelRo = make<BssSection>(".bss.rel.ro"); + Add(In<ELFT>::BssRelRo); + // Add MIPS-specific sections. bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() || Config->pic() || @@ -617,7 +617,7 @@ template <class ELFT> bool elf::isRelroSection(const OutputSection *Sec) { return true; if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec) return true; - if (Sec == Out::BssRelRo) + if (Sec == In<ELFT>::BssRelRo->OutSec) return true; StringRef S = Sec->Name; @@ -1163,14 +1163,15 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { // Dynamic section must be the last one in this list and dynamic // symbol table section (DynSymTab) must be the first one. - applySynthetic({In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab, - In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab, - In<ELFT>::VerDef, In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, - In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::IgotPlt, - In<ELFT>::GotPlt, In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, - In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Iplt, - In<ELFT>::Plt, In<ELFT>::EhFrameHdr, In<ELFT>::VerSym, - In<ELFT>::VerNeed, In<ELFT>::Dynamic}, + applySynthetic({In<ELFT>::DynSymTab, In<ELFT>::Bss, In<ELFT>::BssRelRo, + In<ELFT>::GnuHashTab, In<ELFT>::HashTab, In<ELFT>::SymTab, + In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::VerDef, + In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, In<ELFT>::Got, + In<ELFT>::MipsGot, In<ELFT>::IgotPlt, In<ELFT>::GotPlt, + In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, In<ELFT>::RelaPlt, + In<ELFT>::Plt, In<ELFT>::Iplt, In<ELFT>::Plt, + In<ELFT>::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed, + In<ELFT>::Dynamic}, [](SyntheticSection *SS) { SS->finalizeContents(); }); // Some architectures use small displacements for jump instructions. @@ -1199,16 +1200,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { } template <class ELFT> void Writer<ELFT>::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<OutputSection>(findSection(".ARM.exidx")); |