Skip to content

Commit

Permalink
[ELF] - Recommit "[ELF] - Make Bss and BssRelRo sections to be synthe…
Browse files Browse the repository at this point in the history
…tic (#3)."

Was fixed, details on review page.

Original commit message:

That removes CopyRelSection class completely, making
Bss/BssRelRo to be just regular synthetics.

This is splitted from D30541 and polished.
Difference from D30541 that all logic of SharedSymbol
converting to DefinedRegular was removed for now and
probably will be posted as separate patch.

Differential revision: https://reviews.llvm.org/D30892

llvm-svn: 298062
  • Loading branch information
George Rimar committed Mar 17, 2017
1 parent 872305e commit 1ab9cf4
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 59 deletions.
2 changes: 0 additions & 2 deletions lld/ELF/OutputSections.cpp
Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions lld/ELF/OutputSections.h
Expand Up @@ -95,8 +95,6 @@ class OutputSection final : public SectionBase {
// 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;
Expand Down
13 changes: 5 additions & 8 deletions lld/ELF/Relocations.cpp
Expand Up @@ -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>
Expand Down
5 changes: 3 additions & 2 deletions lld/ELF/Symbols.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions lld/ELF/Symbols.h
Expand Up @@ -238,8 +238,9 @@ class SharedSymbol : public Defined {
// 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 {
Expand Down
22 changes: 11 additions & 11 deletions lld/ELF/SyntheticSections.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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>;
Expand Down
18 changes: 12 additions & 6 deletions lld/ELF/SyntheticSections.h
Expand Up @@ -153,15 +153,19 @@ template <class ELFT> class BuildIdSection : public SyntheticSection {
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 {
Expand Down Expand Up @@ -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;
Expand Down
43 changes: 17 additions & 26 deletions lld/ELF/Writer.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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>>(
Expand Down Expand Up @@ -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() ||
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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"));
Expand Down
7 changes: 7 additions & 0 deletions lld/test/ELF/Inputs/relocation-copy-align-common.s
@@ -0,0 +1,7 @@
.data
.global foo
.type foo, @object
.align 8
.size foo, 8
foo:
.quad 0
40 changes: 40 additions & 0 deletions lld/test/ELF/relocation-copy-align-common.s
@@ -0,0 +1,40 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
# RUN: %p/Inputs/relocation-copy-align-common.s -o %t2.o
# RUN: ld.lld -shared %t2.o -o %t.so
# RUN: ld.lld %t.o %t.so -o %t3
# RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s

# CHECK: Section {
# CHECK: Index:
# CHECK: Name: .bss
# CHECK-NEXT: Type: SHT_NOBITS
# CHECK-NEXT: Flags [
# CHECK-NEXT: SHF_ALLOC
# CHECK-NEXT: SHF_WRITE
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x203000
# CHECK-NEXT: Offset: 0x20B0
# CHECK-NEXT: Size: 16
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }

# CHECK: Relocations [
# CHECK-NEXT: Section {{.*}} .rela.dyn {
# CHECK-NEXT: Relocation {
# CHECK-NEXT: Offset: 0x203008
# CHECK-NEXT: Type: R_X86_64_COPY
# CHECK-NEXT: Symbol: foo
# CHECK-NEXT: Addend: 0x0
# CHECK-NEXT: }
# CHECK-NEXT: }
# CHECK-NEXT: ]

.global _start
_start:
.comm sym1,4,4
movl $5, foo

0 comments on commit 1ab9cf4

Please sign in to comment.