[ELF] Convert RelocationSection to input section

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

llvm-svn: 287092
This commit is contained in:
Eugene Leviant 2016-11-16 10:02:27 +00:00
parent 31055c6ace
commit a96d9027a3
7 changed files with 215 additions and 209 deletions

View File

@ -104,8 +104,12 @@ template <class ELFT>
typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
switch (kind()) {
case Regular:
case Synthetic:
return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
case Synthetic:
// For synthetic sections we treat offset -1 as the end of the section.
// The same approach is used for synthetic symbols (DefinedSynthetic).
return cast<InputSection<ELFT>>(this)->OutSecOff +
(Offset == uintX_t(-1) ? getSize() : Offset);
case EHFrame:
// The file crtbeginT.o has relocations pointing to the start of an empty
// .eh_frame that is known to be the first in the link. It does that to
@ -525,6 +529,11 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
if (this->Type == SHT_NOBITS)
return;
if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) {
S->writeTo(Buf);
return;
}
// If -r is given, then an InputSection may be a relocation section.
if (this->Type == SHT_RELA) {
copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
@ -535,11 +544,6 @@ template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
return;
}
if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) {
S->writeTo(Buf);
return;
}
// Copy section contents from source object file to output file.
ArrayRef<uint8_t> Data = this->Data;
memcpy(Buf + OutSecOff, Data.data(), Data.size());

View File

@ -132,7 +132,7 @@ template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.PltIndex = Entries.size();
unsigned RelOff = Out<ELFT>::RelaPlt->getRelocOffset();
unsigned RelOff = In<ELFT>::RelaPlt->getRelocOffset();
Entries.push_back(std::make_pair(&Sym, RelOff));
}
@ -140,69 +140,6 @@ template <class ELFT> void PltSection<ELFT>::finalize() {
this->Size = Target->PltHeaderSize + Entries.size() * Target->PltEntrySize;
}
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
: OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC),
Sort(Sort) {
this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
this->Addralign = sizeof(uintX_t);
}
template <class ELFT>
void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
if (Reloc.Type == Target->RelativeRel)
++NumRelativeRelocs;
Relocs.push_back(Reloc);
}
template <class ELFT, class RelTy>
static bool compRelocations(const RelTy &A, const RelTy &B) {
bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel;
bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel;
if (AIsRel != BIsRel)
return AIsRel;
return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL);
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
uint8_t *BufBegin = Buf;
for (const DynamicReloc<ELFT> &Rel : Relocs) {
auto *P = reinterpret_cast<Elf_Rela *>(Buf);
Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
if (Config->Rela)
P->r_addend = Rel.getAddend();
P->r_offset = Rel.getOffset();
if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got)
// Dynamic relocation against MIPS GOT section make deal TLS entries
// allocated in the end of the GOT. We need to adjust the offset to take
// in account 'local' and 'global' GOT entries.
P->r_offset += In<ELFT>::Got->getMipsTlsOffset();
P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
}
if (Sort) {
if (Config->Rela)
std::stable_sort((Elf_Rela *)BufBegin,
(Elf_Rela *)BufBegin + Relocs.size(),
compRelocations<ELFT, Elf_Rela>);
else
std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
compRelocations<ELFT, Elf_Rel>);
}
}
template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
return this->Entsize * Relocs.size();
}
template <class ELFT> void RelocationSection<ELFT>::finalize() {
this->Link = Out<ELFT>::DynSymTab ? Out<ELFT>::DynSymTab->SectionIndex
: Out<ELFT>::SymTab->SectionIndex;
this->Size = Relocs.size() * this->Entsize;
}
template <class ELFT>
HashTableSection<ELFT>::HashTableSection()
: OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
@ -463,20 +400,21 @@ OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags)
}
template <class ELFT> void OutputSection<ELFT>::finalize() {
if (!Config->Relocatable) {
// SHF_LINK_ORDER only has meaning in relocatable objects
this->Flags &= ~SHF_LINK_ORDER;
return;
}
uint32_t Type = this->Type;
if (this->Flags & SHF_LINK_ORDER) {
if (!Config->Relocatable) {
// SHF_LINK_ORDER only has meaning in relocatable objects
this->Flags &= ~SHF_LINK_ORDER;
} else if (!this->Sections.empty()) {
// When doing a relocatable link we must preserve the link order
// dependency of sections with the SHF_LINK_ORDER flag. The dependency
// is indicated by the sh_link field. We need to translate the
// InputSection sh_link to the OutputSection sh_link, all InputSections
// in the OutputSection have the same dependency.
if (auto *D = this->Sections.front()->getLinkOrderDep())
this->Link = D->OutSec->SectionIndex;
}
if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
// When doing a relocatable link we must preserve the link order
// dependency of sections with the SHF_LINK_ORDER flag. The dependency
// is indicated by the sh_link field. We need to translate the
// InputSection sh_link to the OutputSection sh_link, all InputSections
// in the OutputSection have the same dependency.
if (auto *D = this->Sections.front()->getLinkOrderDep())
this->Link = D->OutSec->SectionIndex;
}
if (Type != SHT_RELA && Type != SHT_REL)
@ -880,26 +818,6 @@ template <class ELFT> void MergeOutputSection<ELFT>::finalizePieces() {
Sec->finalizePieces();
}
template <class ELFT>
typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
if (OutputSec)
return OutputSec->Addr + OffsetInSec;
return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
}
template <class ELFT>
typename ELFT::uint DynamicReloc<ELFT>::getAddend() const {
if (UseSymVA)
return Sym->getVA<ELFT>(Addend);
return Addend;
}
template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
if (Sym && !UseSymVA)
return Sym->DynsymIndex;
return 0;
}
template <class ELFT>
SymbolTableSection<ELFT>::SymbolTableSection(
StringTableSection<ELFT> &StrTabSec)
@ -1350,11 +1268,6 @@ template class PltSection<ELF32BE>;
template class PltSection<ELF64LE>;
template class PltSection<ELF64BE>;
template class RelocationSection<ELF32LE>;
template class RelocationSection<ELF32BE>;
template class RelocationSection<ELF64LE>;
template class RelocationSection<ELF64BE>;
template class GnuHashTableSection<ELF32LE>;
template class GnuHashTableSection<ELF32BE>;
template class GnuHashTableSection<ELF64LE>;

View File

@ -52,7 +52,6 @@ public:
Merge,
Plt,
Regular,
Reloc,
SymTable,
VersDef,
VersNeed,
@ -156,39 +155,6 @@ private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
};
template <class ELFT> class DynamicReloc {
typedef typename ELFT::uint uintX_t;
public:
DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec,
uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
uintX_t Addend)
: Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
UseSymVA(UseSymVA), Addend(Addend) {}
DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
uintX_t Addend)
: Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
UseSymVA(UseSymVA), Addend(Addend) {}
uintX_t getOffset() const;
uintX_t getAddend() const;
uint32_t getSymIndex() const;
const OutputSectionBase *getOutputSec() const { return OutputSec; }
const InputSectionBase<ELFT> *getInputSec() const { return InputSec; }
uint32_t Type;
private:
SymbolBody *Sym;
const InputSectionBase<ELFT> *InputSec = nullptr;
const OutputSectionBase *OutputSec = nullptr;
uintX_t OffsetInSec;
bool UseSymVA;
uintX_t Addend;
};
struct SymbolTableEntry {
SymbolBody *Symbol;
size_t StrTabOffset;
@ -305,30 +271,6 @@ public:
}
};
template <class ELFT> class RelocationSection final : public OutputSectionBase {
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::uint uintX_t;
public:
RelocationSection(StringRef Name, bool Sort);
void addReloc(const DynamicReloc<ELFT> &Reloc);
unsigned getRelocOffset();
void finalize() override;
void writeTo(uint8_t *Buf) override;
bool hasRelocs() const { return !Relocs.empty(); }
Kind getKind() const override { return Reloc; }
size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Reloc;
}
private:
bool Sort;
size_t NumRelativeRelocs = 0;
std::vector<DynamicReloc<ELFT>> Relocs;
};
template <class ELFT> class OutputSection final : public OutputSectionBase {
public:
@ -526,8 +468,6 @@ template <class ELFT> struct Out {
static OutputSectionBase *Opd;
static uint8_t *OpdBuf;
static PltSection<ELFT> *Plt;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
static SymbolTableSection<ELFT> *DynSymTab;
static SymbolTableSection<ELFT> *SymTab;
static VersionDefinitionSection<ELFT> *VerDef;
@ -586,8 +526,6 @@ template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt;
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef;

View File

@ -103,9 +103,9 @@ static unsigned handleNoRelaxTlsRelocation(uint32_t Type, SymbolBody &Body,
if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) {
if (In<ELFT>::Got->addTlsIndex() &&
(Config->Pic || Config->EMachine == EM_ARM))
Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
In<ELFT>::Got->getTlsIndexOff(), false,
nullptr, 0});
In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
In<ELFT>::Got->getTlsIndexOff(), false,
nullptr, 0});
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
}
@ -114,12 +114,12 @@ static unsigned handleNoRelaxTlsRelocation(uint32_t Type, SymbolBody &Body,
if (In<ELFT>::Got->addDynTlsEntry(Body) &&
(Body.isPreemptible() || Config->EMachine == EM_ARM)) {
uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
Out<ELFT>::RelaDyn->addReloc(
In<ELFT>::RelaDyn->addReloc(
{Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0});
if (Body.isPreemptible())
Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
Off + (uintX_t)sizeof(uintX_t), false,
&Body, 0});
In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
Off + (uintX_t)sizeof(uintX_t), false,
&Body, 0});
}
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
@ -149,7 +149,7 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
Config->Shared) {
if (In<ELFT>::Got->addDynTlsEntry(Body)) {
uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
Out<ELFT>::RelaDyn->addReloc(
In<ELFT>::RelaDyn->addReloc(
{Target->TlsDescRel, In<ELFT>::Got, Off, false, &Body, 0});
}
if (Expr != R_TLSDESC_CALL)
@ -165,9 +165,9 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
return 2;
}
if (In<ELFT>::Got->addTlsIndex())
Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
In<ELFT>::Got->getTlsIndexOff(), false,
nullptr, 0});
In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
In<ELFT>::Got->getTlsIndexOff(), false,
nullptr, 0});
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
}
@ -184,15 +184,15 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
if (Config->Shared) {
if (In<ELFT>::Got->addDynTlsEntry(Body)) {
uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
Out<ELFT>::RelaDyn->addReloc(
In<ELFT>::RelaDyn->addReloc(
{Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0});
// If the symbol is preemptible we need the dynamic linker to write
// the offset too.
if (isPreemptible(Body, Type))
Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
Off + (uintX_t)sizeof(uintX_t), false,
&Body, 0});
In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
Off + (uintX_t)sizeof(uintX_t), false,
&Body, 0});
}
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
@ -206,9 +206,9 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body,
Offset, Addend, &Body});
if (!Body.isInGot()) {
In<ELFT>::Got->addEntry(Body);
Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::Got,
Body.getGotOffset<ELFT>(), false, &Body,
0});
In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::Got,
Body.getGotOffset<ELFT>(), false, &Body,
0});
}
return Target->TlsGdRelaxSkip;
}
@ -417,7 +417,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
Alias->NeedsCopyOrPltAddr = true;
Alias->symbol()->IsUsedInRegularObj = true;
}
Out<ELFT>::RelaDyn->addReloc(
In<ELFT>::RelaDyn->addReloc(
{Target->CopyRel, Out<ELFT>::Bss, SS->OffsetInBss, false, SS, 0});
}
@ -619,7 +619,7 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
bool IsWrite = C.Flags & SHF_WRITE;
auto AddDyn = [=](const DynamicReloc<ELFT> &Reloc) {
Out<ELFT>::RelaDyn->addReloc(Reloc);
In<ELFT>::RelaDyn->addReloc(Reloc);
};
const elf::ObjectFile<ELFT> *File = C.getFile();
@ -754,9 +754,9 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
Rel = Target->PltRel;
In<ELFT>::GotPlt->addEntry(Body);
Out<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
Body.getGotPltOffset<ELFT>(), !Preemptible,
&Body, 0});
In<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
Body.getGotPltOffset<ELFT>(), !Preemptible,
&Body, 0});
continue;
}

View File

@ -737,10 +737,10 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
if (Out<ELFT>::RelaDyn->hasRelocs()) {
if (In<ELFT>::RelaDyn->hasRelocs()) {
bool IsRela = Config->Rela;
Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->Size});
Add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
Add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getSize()});
Add({IsRela ? DT_RELAENT : DT_RELENT,
uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
@ -748,14 +748,14 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
// The problem is in the tight relation between dynamic
// relocations and GOT. So do not emit this tag on MIPS.
if (Config->EMachine != EM_MIPS) {
size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
size_t NumRelativeRels = In<ELFT>::RelaDyn->getRelativeRelocCount();
if (Config->ZCombreloc && NumRelativeRels)
Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
}
if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
Add({DT_JMPREL, Out<ELFT>::RelaPlt});
Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
if (In<ELFT>::RelaPlt->hasRelocs()) {
Add({DT_JMPREL, In<ELFT>::RelaPlt});
Add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getSize()});
Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
In<ELFT>::GotPlt});
Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
@ -848,6 +848,92 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
}
}
template <class ELFT>
typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
if (OutputSec)
return OutputSec->Addr + OffsetInSec;
return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
}
template <class ELFT>
typename ELFT::uint DynamicReloc<ELFT>::getAddend() const {
if (UseSymVA)
return Sym->getVA<ELFT>(Addend);
return Addend;
}
template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
if (Sym && !UseSymVA)
return Sym->DynsymIndex;
return 0;
}
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
: SyntheticSection<ELFT>(SHF_ALLOC, Config->Rela ? SHT_RELA : SHT_REL,
sizeof(uintX_t), Name),
Sort(Sort) {
this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
template <class ELFT>
void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
if (Reloc.Type == Target->RelativeRel)
++NumRelativeRelocs;
Relocs.push_back(Reloc);
}
template <class ELFT, class RelTy>
static bool compRelocations(const RelTy &A, const RelTy &B) {
bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel;
bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel;
if (AIsRel != BIsRel)
return AIsRel;
return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL);
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
uint8_t *BufBegin = Buf;
for (const DynamicReloc<ELFT> &Rel : Relocs) {
auto *P = reinterpret_cast<Elf_Rela *>(Buf);
Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
if (Config->Rela)
P->r_addend = Rel.getAddend();
P->r_offset = Rel.getOffset();
if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got)
// Dynamic relocation against MIPS GOT section make deal TLS entries
// allocated in the end of the GOT. We need to adjust the offset to take
// in account 'local' and 'global' GOT entries.
P->r_offset += In<ELFT>::Got->getMipsTlsOffset();
P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
}
if (Sort) {
if (Config->Rela)
std::stable_sort((Elf_Rela *)BufBegin,
(Elf_Rela *)BufBegin + Relocs.size(),
compRelocations<ELFT, Elf_Rela>);
else
std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
compRelocations<ELFT, Elf_Rel>);
}
}
template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
return this->Entsize * Relocs.size();
}
template <class ELFT> void RelocationSection<ELFT>::finalize() {
this->Link = Out<ELFT>::DynSymTab ? Out<ELFT>::DynSymTab->SectionIndex
: Out<ELFT>::SymTab->SectionIndex;
// Set required output section properties.
this->OutSec->Link = this->Link;
this->OutSec->Entsize = this->Entsize;
}
template InputSection<ELF32LE> *elf::createCommonSection();
template InputSection<ELF32BE> *elf::createCommonSection();
template InputSection<ELF64LE> *elf::createCommonSection();
@ -927,3 +1013,8 @@ template class elf::DynamicSection<ELF32LE>;
template class elf::DynamicSection<ELF32BE>;
template class elf::DynamicSection<ELF64LE>;
template class elf::DynamicSection<ELF64BE>;
template class elf::RelocationSection<ELF32LE>;
template class elf::RelocationSection<ELF32BE>;
template class elf::RelocationSection<ELF64LE>;
template class elf::RelocationSection<ELF64BE>;

View File

@ -239,6 +239,39 @@ private:
std::vector<StringRef> Strings;
};
template <class ELFT> class DynamicReloc {
typedef typename ELFT::uint uintX_t;
public:
DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec,
uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
uintX_t Addend)
: Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
UseSymVA(UseSymVA), Addend(Addend) {}
DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
uintX_t Addend)
: Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
UseSymVA(UseSymVA), Addend(Addend) {}
uintX_t getOffset() const;
uintX_t getAddend() const;
uint32_t getSymIndex() const;
const OutputSectionBase *getOutputSec() const { return OutputSec; }
const InputSectionBase<ELFT> *getInputSec() const { return InputSec; }
uint32_t Type;
private:
SymbolBody *Sym;
const InputSectionBase<ELFT> *InputSec = nullptr;
const OutputSectionBase *OutputSec = nullptr;
uintX_t OffsetInSec;
bool UseSymVA;
uintX_t Addend;
};
template <class ELFT>
class DynamicSection final : public SyntheticSection<ELFT> {
typedef typename ELFT::Dyn Elf_Dyn;
@ -287,6 +320,28 @@ private:
uintX_t Size = 0;
};
template <class ELFT>
class RelocationSection final : public SyntheticSection<ELFT> {
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::uint uintX_t;
public:
RelocationSection(StringRef Name, bool Sort);
void addReloc(const DynamicReloc<ELFT> &Reloc);
unsigned getRelocOffset();
void finalize() override;
void writeTo(uint8_t *Buf) override;
size_t getSize() const override { return Relocs.size() * this->Entsize; }
bool hasRelocs() const { return !Relocs.empty(); }
size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
private:
bool Sort;
size_t NumRelativeRelocs = 0;
std::vector<DynamicReloc<ELFT>> Relocs;
};
template <class ELFT> InputSection<ELFT> *createCommonSection();
template <class ELFT> InputSection<ELFT> *createInterpSection();
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@ -303,6 +358,8 @@ template <class ELFT> struct In {
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
static MipsOptionsSection<ELFT> *MipsOptions;
static MipsReginfoSection<ELFT> *MipsReginfo;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
static StringTableSection<ELFT> *ShStrTab;
static StringTableSection<ELFT> *StrTab;
};
@ -317,6 +374,8 @@ template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
} // namespace elf

View File

@ -213,7 +213,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
Out<ELFT>::Plt = make<PltSection<ELFT>>();
Out<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
@ -245,7 +245,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
if (Config->GdbIndex)
Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
if (Config->Strip != StripPolicy::All) {
In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false);
@ -589,11 +589,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
if (Out<ELFT>::DynSymTab)
return;
StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt, 0);
addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, 0);
S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt,
DefinedSynthetic<ELFT>::SectionEnd);
addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, -1);
}
// The linker is expected to define some symbols depending on
@ -945,8 +944,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
for (OutputSectionBase *Sec : OutputSections)
Sec->finalize();
// Dynamic section must be the last one in this list.
finalizeSynthetic<ELFT>({In<ELFT>::ShStrTab, In<ELFT>::StrTab,
In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::GotPlt,
In<ELFT>::RelaDyn, In<ELFT>::RelaPlt,
In<ELFT>::Dynamic});
// Now that all output offsets are fixed. Finalize mergeable sections
@ -997,15 +998,15 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
Add(Out<ELFT>::HashTab);
addInputSec(In<ELFT>::Dynamic);
addInputSec(In<ELFT>::DynStrTab);
if (Out<ELFT>::RelaDyn->hasRelocs())
Add(Out<ELFT>::RelaDyn);
if (In<ELFT>::RelaDyn->hasRelocs())
addInputSec(In<ELFT>::RelaDyn);
Add(Out<ELFT>::MipsRldMap);
}
// We always need to add rel[a].plt to output if it has entries.
// Even during static linking it can contain R_[*]_IRELATIVE relocations.
if (Out<ELFT>::RelaPlt->hasRelocs())
Add(Out<ELFT>::RelaPlt);
if (In<ELFT>::RelaPlt->hasRelocs())
addInputSec(In<ELFT>::RelaPlt);
// We fill .got and .got.plt sections in scanRelocs(). This is the
// reason we don't add it earlier in createSections().