summaryrefslogtreecommitdiffstats
path: root/lld/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/OutputSections.cpp2
-rw-r--r--lld/ELF/OutputSections.h2
-rw-r--r--lld/ELF/Relocations.cpp13
-rw-r--r--lld/ELF/Symbols.cpp5
-rw-r--r--lld/ELF/Symbols.h5
-rw-r--r--lld/ELF/SyntheticSections.cpp22
-rw-r--r--lld/ELF/SyntheticSections.h18
-rw-r--r--lld/ELF/Writer.cpp43
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"));
OpenPOWER on IntegriCloud