diff options
author | Rui Ueyama <ruiu@google.com> | 2017-03-08 17:24:24 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2017-03-08 17:24:24 +0000 |
commit | 007c002cb6fbe9575041fc46c3007717c768a0ff (patch) | |
tree | ca2793e835b121a15d574a30bc175c6bf9eb1f72 | |
parent | 9f495695bbdf4c21625915c8f1048bfe0583af7f (diff) | |
download | bcm5719-llvm-007c002cb6fbe9575041fc46c3007717c768a0ff.tar.gz bcm5719-llvm-007c002cb6fbe9575041fc46c3007717c768a0ff.zip |
Revert r297008: [ELF] - Make Bss and BssRelRo sections to be synthetic (#2).
This reverts commit r297008 because it's reported that that
change broke AArch64 bots.
llvm-svn: 297297
-rw-r--r-- | lld/ELF/OutputSections.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 27 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 20 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 7 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 23 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 14 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 42 |
8 files changed, 78 insertions, 59 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index c7b0182d834..2efb47b9fc8 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -31,6 +31,8 @@ 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 8836f9381ea..660096fde01 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -98,6 +98,8 @@ 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 82724bb55a4..c1631c6768a 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -479,20 +479,23 @@ 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); - BssRelSection<ELFT> *RelSec = IsReadOnly ? In<ELFT>::BssRelRo : In<ELFT>::Bss; - uintX_t Off = RelSec->addCopyRelocation(SS->getAlignment<ELFT>(), SymSize); + 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); // 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->symbol()->IsUsedInRegularObj = true; - replaceBody<DefinedRegular>(Sym->symbol(), Sym->getName(), - /*IsLocal=*/false, Sym->StOther, Sym->Type, Off, - Sym->getSize<ELFT>(), RelSec, nullptr); } - In<ELFT>::RelaDyn->addReloc({Target->CopyRel, RelSec, Off, false, SS, 0}); + In<ELFT>::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0}); } template <class ELFT> @@ -532,12 +535,14 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body, if (Body.isObject()) { // Produce a copy relocation. auto *B = cast<SharedSymbol>(&Body); - if (Config->ZNocopyreloc) - error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " + - toString(Type) + " against symbol '" + toString(*B) + - "'; recompile with -fPIC or remove '-z nocopyreloc'"); + if (!B->NeedsCopy) { + if (Config->ZNocopyreloc) + error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " + + toString(Type) + " against symbol '" + toString(*B) + + "'; recompile with -fPIC or remove '-z nocopyreloc'"); - addCopyRelSymbol<ELFT>(B); + addCopyRelSymbol<ELFT>(B); + } return Expr; } if (Body.isFunc()) { diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index d8c459795b3..9eb222362bb 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -112,10 +112,14 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { return 0; return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff + cast<DefinedCommon>(Body).Offset; - case SymbolBody::SharedKind: - if (cast<SharedSymbol>(Body).NeedsPltAddr) + case SymbolBody::SharedKind: { + auto &SS = cast<SharedSymbol>(Body); + if (SS.NeedsCopy) + return SS.Section->OutSec->Addr + SS.Section->OutSecOff; + if (SS.NeedsPltAddr) return Body.getPltVA<ELFT>(); return 0; + } case SymbolBody::UndefinedKind: return 0; case SymbolBody::LazyArchiveKind: @@ -128,7 +132,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type) - : SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal), + : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {} @@ -139,9 +143,10 @@ bool SymbolBody::isPreemptible() const { return false; // Shared symbols resolve to the definition in the DSO. The exceptions are - // symbols that needs plt entries (which resolve to that plt entry). + // symbols with copy relocations (which resolve to .bss) or preempt plt + // entries (which resolve to that plt entry). if (isShared()) - return !NeedsPltAddr; + return !NeedsCopy && !NeedsPltAddr; // That's all that can be preempted in a non-DSO. if (!Config->Shared) @@ -210,8 +215,11 @@ const OutputSection *SymbolBody::getOutputSection() const { return nullptr; } - if (isa<SharedSymbol>(this)) + if (auto *S = dyn_cast<SharedSymbol>(this)) { + if (S->NeedsCopy) + return S->Section->OutSec; return nullptr; + } if (isa<DefinedCommon>(this)) { if (Config->DefineCommon) diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index c454f80ad48..696a30cb390 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -102,6 +102,10 @@ protected: const unsigned SymbolKind : 8; public: + // True if the linker has to generate a copy relocation. + // For SharedSymbol only. + unsigned NeedsCopy : 1; + // True the symbol should point to its PLT entry. // For SharedSymbol only. unsigned NeedsPltAddr : 1; @@ -266,6 +270,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; + private: template <class ELFT> const typename ELFT::Sym &getSym() const { return *(const typename ELFT::Sym *)ElfSym; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index fca7d2ca2bd..d00bba1c266 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -377,17 +377,10 @@ void BuildIdSection<ELFT>::computeHash( } template <class ELFT> -BssRelSection<ELFT>::BssRelSection(bool RelRo) - : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, - RelRo ? ".bss.rel.ro" : ".bss"), - Size(0) {} - -template <class ELFT> -size_t BssRelSection<ELFT>::addCopyRelocation(uintX_t AddrAlign, size_t Size) { - OutSec->updateAlignment(AddrAlign); - this->Size = alignTo(this->Size, AddrAlign) + Size; - return this->Size - Size; -} +CopyRelSection<ELFT>::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S) + : SyntheticSection(SHF_ALLOC, SHT_NOBITS, AddrAlign, + ReadOnly ? ".bss.rel.ro" : ".bss"), + Size(S) {} template <class ELFT> void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) { @@ -2311,10 +2304,10 @@ template class elf::BuildIdSection<ELF32BE>; template class elf::BuildIdSection<ELF64LE>; template class elf::BuildIdSection<ELF64BE>; -template class elf::BssRelSection<ELF32LE>; -template class elf::BssRelSection<ELF32BE>; -template class elf::BssRelSection<ELF64LE>; -template class elf::BssRelSection<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>; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index e7b47ace37e..b54e70478e4 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -152,16 +152,14 @@ private: 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 ELFT> class BssRelSection final : public SyntheticSection { +// 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 { typedef typename ELFT::uint uintX_t; public: - BssRelSection(bool RelRo); + CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size); void writeTo(uint8_t *) override {} - bool empty() const override { return getSize() == 0; } - size_t addCopyRelocation(uintX_t AddrAlign, size_t Size); size_t getSize() const override { return Size; } size_t Size; }; @@ -764,8 +762,6 @@ SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, template <class ELFT> struct In { static InputSection *ARMAttributes; static BuildIdSection<ELFT> *BuildId; - static BssRelSection<ELFT> *Bss; - static BssRelSection<ELFT> *BssRelRo; static InputSection *Common; static DynamicSection<ELFT> *Dynamic; static StringTableSection<ELFT> *DynStrTab; @@ -795,8 +791,6 @@ template <class ELFT> struct In { }; template <class ELFT> InputSection *In<ELFT>::ARMAttributes; -template <class ELFT> BssRelSection<ELFT> *In<ELFT>::Bss; -template <class ELFT> BssRelSection<ELFT> *In<ELFT>::BssRelRo; template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId; template <class ELFT> InputSection *In<ELFT>::Common; template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index a548ca5cf60..ee225416a49 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.rel.ro.", - ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", + {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".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,6 +309,10 @@ 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<ELFT>>(".dynstr", true); In<ELFT>::Dynamic = make<DynamicSection<ELFT>>(); In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>( @@ -346,11 +350,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() { Add(Common); } - In<ELFT>::Bss = make<BssRelSection<ELFT>>(false /*RelRo*/); - Add(In<ELFT>::Bss); - In<ELFT>::BssRelRo = make<BssRelSection<ELFT>>(true /*RelRo*/); - Add(In<ELFT>::BssRelRo); - // Add MIPS-specific sections. bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() || Config->pic() || @@ -596,7 +595,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 == In<ELFT>::BssRelRo->OutSec) + if (Sec == Out::BssRelRo) return true; StringRef S = Sec->Name; @@ -1150,15 +1149,14 @@ 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<ELFT>( - {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}, + {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}, [](SyntheticSection *SS) { SS->finalizeContents(); }); // Some architectures use small displacements for jump instructions. @@ -1187,6 +1185,16 @@ 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<ELFT>(); + 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")); |