[ELF] Convert .got.plt section to input section
Differential revision: https://reviews.llvm.org/D26349 llvm-svn: 286443
This commit is contained in:
parent
d0b9173caa
commit
41ca327b5e
|
@ -14,6 +14,7 @@
|
|||
#include "InputFiles.h"
|
||||
#include "LinkerScript.h"
|
||||
#include "OutputSections.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
#include "Thunks.h"
|
||||
|
||||
|
@ -80,9 +81,13 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
|
|||
}
|
||||
|
||||
template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const {
|
||||
if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this))
|
||||
return S->getSize();
|
||||
|
||||
if (auto *D = dyn_cast<InputSection<ELFT>>(this))
|
||||
if (D->getThunksSize() > 0)
|
||||
return D->getThunkOff() + D->getThunksSize();
|
||||
|
||||
return Data.size();
|
||||
}
|
||||
|
||||
|
@ -95,6 +100,7 @@ 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 EHFrame:
|
||||
// The file crtbeginT.o has relocations pointing to the start of an empty
|
||||
|
@ -184,10 +190,10 @@ InputSection<ELFT>::InputSection() : InputSectionBase<ELFT>() {}
|
|||
template <class ELFT>
|
||||
InputSection<ELFT>::InputSection(uintX_t Flags, uint32_t Type,
|
||||
uintX_t Addralign, ArrayRef<uint8_t> Data,
|
||||
StringRef Name)
|
||||
StringRef Name, Kind K)
|
||||
: InputSectionBase<ELFT>(nullptr, Flags, Type,
|
||||
/*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Addralign,
|
||||
Data, Name, Base::Regular) {}
|
||||
Data, Name, K) {}
|
||||
|
||||
template <class ELFT>
|
||||
InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
|
||||
|
@ -196,7 +202,7 @@ InputSection<ELFT>::InputSection(elf::ObjectFile<ELFT> *F,
|
|||
|
||||
template <class ELFT>
|
||||
bool InputSection<ELFT>::classof(const InputSectionData *S) {
|
||||
return S->kind() == Base::Regular;
|
||||
return S->kind() == Base::Regular || S->kind() == Base::Synthetic;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -528,6 +534,11 @@ 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());
|
||||
|
|
|
@ -39,7 +39,7 @@ class OutputSectionBase;
|
|||
// section
|
||||
class InputSectionData {
|
||||
public:
|
||||
enum Kind { Regular, EHFrame, Merge };
|
||||
enum Kind { Regular, EHFrame, Merge, Synthetic, };
|
||||
|
||||
// The garbage collector sets sections' Live bits.
|
||||
// If GC is disabled, all sections are considered live by default.
|
||||
|
@ -232,11 +232,13 @@ template <class ELFT> class InputSection : public InputSectionBase<ELFT> {
|
|||
typedef typename ELFT::Rel Elf_Rel;
|
||||
typedef typename ELFT::Sym Elf_Sym;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
typedef InputSectionData::Kind Kind;
|
||||
|
||||
public:
|
||||
InputSection();
|
||||
InputSection(uintX_t Flags, uint32_t Type, uintX_t Addralign,
|
||||
ArrayRef<uint8_t> Data, StringRef Name);
|
||||
ArrayRef<uint8_t> Data, StringRef Name,
|
||||
Kind K = InputSectionData::Regular);
|
||||
InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header, StringRef Name);
|
||||
|
||||
static InputSection<ELFT> Discarded;
|
||||
|
|
|
@ -108,35 +108,6 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
GotPltSection<ELFT>::GotPltSection()
|
||||
: OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
|
||||
this->Addralign = Target->GotPltEntrySize;
|
||||
}
|
||||
|
||||
template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) {
|
||||
Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
|
||||
Entries.push_back(&Sym);
|
||||
}
|
||||
|
||||
template <class ELFT> bool GotPltSection<ELFT>::empty() const {
|
||||
return Entries.empty();
|
||||
}
|
||||
|
||||
template <class ELFT> void GotPltSection<ELFT>::finalize() {
|
||||
this->Size = (Target->GotPltHeaderEntriesNum + Entries.size()) *
|
||||
Target->GotPltEntrySize;
|
||||
}
|
||||
|
||||
template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
Target->writeGotPltHeader(Buf);
|
||||
Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize;
|
||||
for (const SymbolBody *B : Entries) {
|
||||
Target->writeGotPlt(Buf, *B);
|
||||
Buf += sizeof(uintX_t);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
GotSection<ELFT>::GotSection()
|
||||
: OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
|
||||
|
@ -775,7 +746,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
|
|||
Add({DT_JMPREL, Out<ELFT>::RelaPlt});
|
||||
Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
|
||||
Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
|
||||
Out<ELFT>::GotPlt});
|
||||
In<ELFT>::GotPlt});
|
||||
Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
|
||||
}
|
||||
|
||||
|
@ -846,6 +817,9 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
case Entry::SecAddr:
|
||||
P->d_un.d_ptr = E.OutSec->Addr;
|
||||
break;
|
||||
case Entry::InSecAddr:
|
||||
P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
|
||||
break;
|
||||
case Entry::SecSize:
|
||||
P->d_un.d_val = E.OutSec->Size;
|
||||
break;
|
||||
|
@ -1789,6 +1763,7 @@ OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key,
|
|||
uint32_t Type = C->Type;
|
||||
switch (C->kind()) {
|
||||
case InputSectionBase<ELFT>::Regular:
|
||||
case InputSectionBase<ELFT>::Synthetic:
|
||||
Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags);
|
||||
break;
|
||||
case InputSectionBase<ELFT>::EHFrame:
|
||||
|
@ -1845,11 +1820,6 @@ template class EhFrameHeader<ELF32BE>;
|
|||
template class EhFrameHeader<ELF64LE>;
|
||||
template class EhFrameHeader<ELF64BE>;
|
||||
|
||||
template class GotPltSection<ELF32LE>;
|
||||
template class GotPltSection<ELF32BE>;
|
||||
template class GotPltSection<ELF64LE>;
|
||||
template class GotPltSection<ELF64BE>;
|
||||
|
||||
template class GotSection<ELF32LE>;
|
||||
template class GotSection<ELF32BE>;
|
||||
template class GotSection<ELF64LE>;
|
||||
|
|
|
@ -51,7 +51,6 @@ public:
|
|||
EHFrameHdr,
|
||||
GnuHashTable,
|
||||
Got,
|
||||
GotPlt,
|
||||
HashTable,
|
||||
Merge,
|
||||
Plt,
|
||||
|
@ -211,24 +210,6 @@ private:
|
|||
void writeMipsGot(uint8_t *Buf);
|
||||
};
|
||||
|
||||
template <class ELFT> class GotPltSection final : public OutputSectionBase {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
GotPltSection();
|
||||
void finalize() override;
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
void addEntry(SymbolBody &Sym);
|
||||
bool empty() const;
|
||||
Kind getKind() const override { return GotPlt; }
|
||||
static bool classof(const OutputSectionBase *B) {
|
||||
return B->getKind() == GotPlt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<const SymbolBody *> Entries;
|
||||
};
|
||||
|
||||
template <class ELFT> class PltSection final : public OutputSectionBase {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
|
@ -603,12 +584,15 @@ template <class ELFT> class DynamicSection final : public OutputSectionBase {
|
|||
int32_t Tag;
|
||||
union {
|
||||
OutputSectionBase *OutSec;
|
||||
InputSection<ELFT> *InSec;
|
||||
uint64_t Val;
|
||||
const SymbolBody *Sym;
|
||||
};
|
||||
enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind;
|
||||
enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
|
||||
Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
|
||||
: Tag(Tag), OutSec(OutSec), Kind(Kind) {}
|
||||
Entry(int32_t Tag, InputSection<ELFT> *Sec)
|
||||
: Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
|
||||
Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
|
||||
Entry(int32_t Tag, const SymbolBody *Sym)
|
||||
: Tag(Tag), Sym(Sym), Kind(SymAddr) {}
|
||||
|
@ -677,7 +661,6 @@ template <class ELFT> struct Out {
|
|||
static EhOutputSection<ELFT> *EhFrame;
|
||||
static GdbIndexSection<ELFT> *GdbIndex;
|
||||
static GnuHashTableSection<ELFT> *GnuHashTab;
|
||||
static GotPltSection<ELFT> *GotPlt;
|
||||
static GotSection<ELFT> *Got;
|
||||
static HashTableSection<ELFT> *HashTab;
|
||||
static OutputSection<ELFT> *Bss;
|
||||
|
@ -743,7 +726,6 @@ template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
|||
template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
|
||||
template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;
|
||||
template <class ELFT> GnuHashTableSection<ELFT> *Out<ELFT>::GnuHashTab;
|
||||
template <class ELFT> GotPltSection<ELFT> *Out<ELFT>::GotPlt;
|
||||
template <class ELFT> GotSection<ELFT> *Out<ELFT>::Got;
|
||||
template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
|
||||
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
|
||||
|
|
|
@ -44,10 +44,11 @@
|
|||
#include "Relocations.h"
|
||||
#include "Config.h"
|
||||
#include "OutputSections.h"
|
||||
#include "Strings.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
#include "Thunks.h"
|
||||
#include "Strings.h"
|
||||
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -743,8 +744,8 @@ static void scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
|
|||
else
|
||||
Rel = Target->PltRel;
|
||||
|
||||
Out<ELFT>::GotPlt->addEntry(Body);
|
||||
Out<ELFT>::RelaPlt->addReloc({Rel, Out<ELFT>::GotPlt,
|
||||
In<ELFT>::GotPlt->addEntry(Body);
|
||||
Out<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
|
||||
Body.getGotPltOffset<ELFT>(), !Preemptible,
|
||||
&Body, 0});
|
||||
continue;
|
||||
|
|
|
@ -159,7 +159,7 @@ template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const {
|
|||
}
|
||||
|
||||
template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
|
||||
return Out<ELFT>::GotPlt->Addr + getGotPltOffset<ELFT>();
|
||||
return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
|
||||
}
|
||||
|
||||
template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const {
|
||||
|
|
|
@ -313,6 +313,36 @@ void BuildIdHexstring<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
|
|||
Config->BuildIdVector.size());
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
GotPltSection<ELFT>::GotPltSection()
|
||||
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
|
||||
Target->GotPltEntrySize, ".got.plt") {
|
||||
this->Live = true;
|
||||
}
|
||||
|
||||
template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) {
|
||||
Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
|
||||
Entries.push_back(&Sym);
|
||||
}
|
||||
|
||||
template <class ELFT> bool GotPltSection<ELFT>::empty() const {
|
||||
return Entries.empty();
|
||||
}
|
||||
|
||||
template <class ELFT> size_t GotPltSection<ELFT>::getSize() const {
|
||||
return (Target->GotPltHeaderEntriesNum + Entries.size()) *
|
||||
Target->GotPltEntrySize;
|
||||
}
|
||||
|
||||
template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
Target->writeGotPltHeader(Buf);
|
||||
Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize;
|
||||
for (const SymbolBody *B : Entries) {
|
||||
Target->writeGotPlt(Buf, *B);
|
||||
Buf += sizeof(uintX_t);
|
||||
}
|
||||
}
|
||||
|
||||
template InputSection<ELF32LE> *elf::createCommonSection();
|
||||
template InputSection<ELF32BE> *elf::createCommonSection();
|
||||
template InputSection<ELF64LE> *elf::createCommonSection();
|
||||
|
@ -367,3 +397,8 @@ template class elf::BuildIdHexstring<ELF32LE>;
|
|||
template class elf::BuildIdHexstring<ELF32BE>;
|
||||
template class elf::BuildIdHexstring<ELF64LE>;
|
||||
template class elf::BuildIdHexstring<ELF64BE>;
|
||||
|
||||
template class elf::GotPltSection<ELF32LE>;
|
||||
template class elf::GotPltSection<ELF32BE>;
|
||||
template class elf::GotPltSection<ELF64LE>;
|
||||
template class elf::GotPltSection<ELF64BE>;
|
||||
|
|
|
@ -58,6 +58,26 @@ private:
|
|||
Elf_Mips_RegInfo Reginfo = {};
|
||||
};
|
||||
|
||||
template <class ELFT> class SyntheticSection : public InputSection<ELFT> {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
SyntheticSection(uintX_t Flags, uint32_t Type, uintX_t Addralign,
|
||||
StringRef Name)
|
||||
: InputSection<ELFT>(Flags, Type, Addralign, ArrayRef<uint8_t>(), Name,
|
||||
InputSectionData::Synthetic) {}
|
||||
|
||||
virtual void writeTo(uint8_t *Buf) {}
|
||||
virtual size_t getSize() const { return this->Data.size(); }
|
||||
|
||||
static bool classof(const InputSectionData *D) {
|
||||
return D->kind() == InputSectionData::Synthetic;
|
||||
}
|
||||
|
||||
protected:
|
||||
~SyntheticSection() = default;
|
||||
};
|
||||
|
||||
// .note.gnu.build-id section.
|
||||
template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
|
||||
public:
|
||||
|
@ -109,6 +129,22 @@ public:
|
|||
void writeBuildId(llvm::MutableArrayRef<uint8_t>) override;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
class GotPltSection final : public SyntheticSection<ELFT> {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
GotPltSection();
|
||||
void addEntry(SymbolBody &Sym);
|
||||
bool empty() const;
|
||||
size_t getSize() const override;
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
uintX_t getVA() { return this->OutSec->Addr + this->OutSecOff; }
|
||||
|
||||
private:
|
||||
std::vector<const SymbolBody *> Entries;
|
||||
};
|
||||
|
||||
template <class ELFT> InputSection<ELFT> *createCommonSection();
|
||||
template <class ELFT> InputSection<ELFT> *createInterpSection();
|
||||
|
||||
|
@ -116,6 +152,7 @@ template <class ELFT> InputSection<ELFT> *createInterpSection();
|
|||
template <class ELFT> struct In {
|
||||
static BuildIdSection<ELFT> *BuildId;
|
||||
static InputSection<ELFT> *Common;
|
||||
static GotPltSection<ELFT> *GotPlt;
|
||||
static InputSection<ELFT> *Interp;
|
||||
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
|
||||
static MipsOptionsSection<ELFT> *MipsOptions;
|
||||
|
@ -124,6 +161,7 @@ template <class ELFT> struct In {
|
|||
|
||||
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
|
||||
template <class ELFT> InputSection<ELFT> *In<ELFT>::Common;
|
||||
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
|
||||
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
|
||||
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
|
||||
template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "InputFiles.h"
|
||||
#include "OutputSections.h"
|
||||
#include "Symbols.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Thunks.h"
|
||||
#include "Writer.h"
|
||||
|
||||
|
@ -403,7 +404,7 @@ void X86TargetInfo::writePltHeader(uint8_t *Buf) const {
|
|||
0x90, 0x90, 0x90, 0x90 // nop; nop; nop; nop
|
||||
};
|
||||
memcpy(Buf, PltData, sizeof(PltData));
|
||||
uint32_t Got = Out<ELF32LE>::GotPlt->Addr;
|
||||
uint32_t Got = In<ELF32LE>::GotPlt->getVA();
|
||||
write32le(Buf + 2, Got + 4);
|
||||
write32le(Buf + 8, Got + 8);
|
||||
}
|
||||
|
@ -420,7 +421,7 @@ void X86TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
|
|||
|
||||
// jmp *foo@GOT(%ebx) or jmp *foo_in_GOT
|
||||
Buf[1] = Config->Pic ? 0xa3 : 0x25;
|
||||
uint32_t Got = Out<ELF32LE>::GotPlt->Addr;
|
||||
uint32_t Got = In<ELF32LE>::GotPlt->getVA();
|
||||
write32le(Buf + 2, Config->Shared ? GotEntryAddr - Got : GotEntryAddr);
|
||||
write32le(Buf + 7, RelOff);
|
||||
write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16);
|
||||
|
@ -613,7 +614,7 @@ void X86_64TargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
|
|||
0x0f, 0x1f, 0x40, 0x00 // nopl 0x0(rax)
|
||||
};
|
||||
memcpy(Buf, PltData, sizeof(PltData));
|
||||
uint64_t Got = Out<ELFT>::GotPlt->Addr;
|
||||
uint64_t Got = In<ELFT>::GotPlt->getVA();
|
||||
uint64_t Plt = Out<ELFT>::Plt->Addr;
|
||||
write32le(Buf + 2, Got - Plt + 2); // GOT+8
|
||||
write32le(Buf + 8, Got - Plt + 4); // GOT+16
|
||||
|
@ -1274,7 +1275,7 @@ void AArch64TargetInfo::writePltHeader(uint8_t *Buf) const {
|
|||
};
|
||||
memcpy(Buf, PltData, sizeof(PltData));
|
||||
|
||||
uint64_t Got = Out<ELF64LE>::GotPlt->Addr;
|
||||
uint64_t Got = In<ELF64LE>::GotPlt->getVA();
|
||||
uint64_t Plt = Out<ELF64LE>::Plt->Addr;
|
||||
relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
|
||||
getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
|
||||
|
@ -1628,7 +1629,7 @@ void ARMTargetInfo::writePltHeader(uint8_t *Buf) const {
|
|||
0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8
|
||||
};
|
||||
memcpy(Buf, PltData, sizeof(PltData));
|
||||
uint64_t GotPlt = Out<ELF32LE>::GotPlt->Addr;
|
||||
uint64_t GotPlt = In<ELF32LE>::GotPlt->getVA();
|
||||
uint64_t L1 = Out<ELF32LE>::Plt->Addr + 8;
|
||||
write32le(Buf + 16, GotPlt - L1 - 8);
|
||||
}
|
||||
|
@ -2063,7 +2064,7 @@ void MipsTargetInfo<ELFT>::writePltHeader(uint8_t *Buf) const {
|
|||
write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
|
||||
write32<E>(Buf + 24, 0x0320f809); // jalr $25
|
||||
write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
|
||||
uint64_t Got = Out<ELFT>::GotPlt->Addr;
|
||||
uint64_t Got = In<ELFT>::GotPlt->getVA();
|
||||
writeMipsHi16<E>(Buf, Got);
|
||||
writeMipsLo16<E>(Buf + 4, Got);
|
||||
writeMipsLo16<E>(Buf + 8, Got);
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
uint32_t TlsModuleIndexRel;
|
||||
uint32_t TlsOffsetRel;
|
||||
unsigned GotEntrySize;
|
||||
unsigned GotPltEntrySize;
|
||||
unsigned GotPltEntrySize = 0;
|
||||
unsigned PltEntrySize;
|
||||
unsigned PltHeaderSize;
|
||||
|
||||
|
|
|
@ -248,7 +248,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
if (Config->GdbIndex)
|
||||
Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
|
||||
|
||||
Out<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
|
||||
Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
|
||||
Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
|
||||
if (Config->Strip != StripPolicy::All) {
|
||||
|
@ -312,6 +311,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
Symtab<ELFT>::X->Sections.push_back(RegSec);
|
||||
}
|
||||
}
|
||||
|
||||
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -423,7 +424,7 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
|
|||
if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
|
||||
Type == SHT_PREINIT_ARRAY)
|
||||
return true;
|
||||
if (Sec == Out<ELFT>::GotPlt)
|
||||
if (Sec == In<ELFT>::GotPlt->OutSec)
|
||||
return Config->ZNow;
|
||||
if (Sec == Out<ELFT>::Dynamic || Sec == Out<ELFT>::Got)
|
||||
return true;
|
||||
|
@ -893,6 +894,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
// This function adds linker-created Out<ELFT>::* sections.
|
||||
addPredefinedSections();
|
||||
|
||||
// We fill .got.plt section in scanRelocs(). This is the
|
||||
// reason we don't add it earlier in createSections().
|
||||
if (!In<ELFT>::GotPlt->empty()) {
|
||||
addInputSec(In<ELFT>::GotPlt);
|
||||
In<ELFT>::GotPlt->OutSec->assignOffsets();
|
||||
}
|
||||
|
||||
sortSections();
|
||||
|
||||
unsigned I = 1;
|
||||
|
@ -976,8 +984,6 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
|
|||
|
||||
if (needsGot())
|
||||
Add(Out<ELFT>::Got);
|
||||
if (Out<ELFT>::GotPlt && !Out<ELFT>::GotPlt->empty())
|
||||
Add(Out<ELFT>::GotPlt);
|
||||
if (!Out<ELFT>::Plt->empty())
|
||||
Add(Out<ELFT>::Plt);
|
||||
if (!Out<ELFT>::EhFrame->empty())
|
||||
|
|
Loading…
Reference in New Issue