mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 18:20:38 +00:00
[ELF] Detemplate ThunkSection and Thunk classes. NFC.
llvm-svn: 297939
This commit is contained in:
parent
49a47f2a6d
commit
7b8270424e
@ -863,9 +863,9 @@ template <class ELFT> void scanRelocations(InputSectionBase &S) {
|
||||
// This may invalidate any output section offsets stored outside of InputSection
|
||||
template <class ELFT>
|
||||
static void mergeThunks(OutputSection *OS,
|
||||
std::vector<ThunkSection<ELFT> *> &Thunks) {
|
||||
std::vector<ThunkSection *> &Thunks) {
|
||||
// Order Thunks in ascending OutSecOff
|
||||
auto ThunkCmp = [](const ThunkSection<ELFT> *A, const ThunkSection<ELFT> *B) {
|
||||
auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
|
||||
return A->OutSecOff < B->OutSecOff;
|
||||
};
|
||||
std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
|
||||
@ -880,7 +880,7 @@ static void mergeThunks(OutputSection *OS,
|
||||
if (A->OutSecOff == B->OutSecOff)
|
||||
// Check if Thunk is immediately before any specific Target InputSection
|
||||
// for example Mips LA25 Thunks.
|
||||
if (auto *TA = dyn_cast<ThunkSection<ELFT>>(A))
|
||||
if (auto *TA = dyn_cast<ThunkSection>(A))
|
||||
if (TA && TA->getTargetInputSection() == B)
|
||||
return true;
|
||||
return false;
|
||||
@ -904,11 +904,11 @@ static void mergeThunks(OutputSection *OS,
|
||||
template <class ELFT>
|
||||
bool createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||
// Track Symbols that already have a Thunk
|
||||
DenseMap<SymbolBody *, Thunk<ELFT> *> ThunkedSymbols;
|
||||
DenseMap<SymbolBody *, Thunk *> ThunkedSymbols;
|
||||
// Track InputSections that have a ThunkSection placed in front
|
||||
DenseMap<InputSection *, ThunkSection<ELFT> *> ThunkedSections;
|
||||
DenseMap<InputSection *, ThunkSection *> ThunkedSections;
|
||||
// Track the ThunksSections that need to be inserted into an OutputSection
|
||||
std::map<OutputSection *, std::vector<ThunkSection<ELFT> *>> ThunkSections;
|
||||
std::map<OutputSection *, std::vector<ThunkSection *>> ThunkSections;
|
||||
|
||||
// Find or create a Thunk for Body for relocation Type
|
||||
auto GetThunk = [&](SymbolBody &Body, uint32_t Type) {
|
||||
@ -920,18 +920,18 @@ bool createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||
|
||||
// Find or create a ThunkSection to be placed immediately before IS
|
||||
auto GetISThunkSec = [&](InputSection *IS, OutputSection *OS) {
|
||||
ThunkSection<ELFT> *TS = ThunkedSections.lookup(IS);
|
||||
ThunkSection *TS = ThunkedSections.lookup(IS);
|
||||
if (TS)
|
||||
return TS;
|
||||
auto *TOS = cast<OutputSection>(IS->OutSec);
|
||||
TS = make<ThunkSection<ELFT>>(TOS, IS->OutSecOff);
|
||||
TS = make<ThunkSection>(TOS, IS->OutSecOff);
|
||||
ThunkSections[TOS].push_back(TS);
|
||||
ThunkedSections[IS] = TS;
|
||||
return TS;
|
||||
};
|
||||
// Find or create a ThunkSection to be placed as last executable section in
|
||||
// OS.
|
||||
auto GetOSThunkSec = [&](ThunkSection<ELFT> *&TS, OutputSection *OS) {
|
||||
auto GetOSThunkSec = [&](ThunkSection *&TS, OutputSection *OS) {
|
||||
if (TS == nullptr) {
|
||||
uint32_t Off = 0;
|
||||
for (auto *IS : OS->Sections) {
|
||||
@ -939,7 +939,7 @@ bool createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||
if ((IS->Flags & SHF_EXECINSTR) == 0)
|
||||
break;
|
||||
}
|
||||
TS = make<ThunkSection<ELFT>>(OS, Off);
|
||||
TS = make<ThunkSection>(OS, Off);
|
||||
ThunkSections[OS].push_back(TS);
|
||||
}
|
||||
return TS;
|
||||
@ -955,18 +955,18 @@ bool createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||
if (OS == nullptr)
|
||||
continue;
|
||||
|
||||
ThunkSection<ELFT> *OSTS = nullptr;
|
||||
ThunkSection *OSTS = nullptr;
|
||||
for (InputSection *IS : OS->Sections) {
|
||||
for (Relocation &Rel : IS->Relocations) {
|
||||
SymbolBody &Body = *Rel.Sym;
|
||||
if (Target->needsThunk(Rel.Expr, Rel.Type, IS->template getFile<ELFT>(),
|
||||
Body)) {
|
||||
Thunk<ELFT> *T;
|
||||
Thunk *T;
|
||||
bool IsNew;
|
||||
std::tie(T, IsNew) = GetThunk(Body, Rel.Type);
|
||||
if (IsNew) {
|
||||
// Find or create a ThunkSection for the new Thunk
|
||||
ThunkSection<ELFT> *TS;
|
||||
ThunkSection *TS;
|
||||
if (auto *TIS = T->getTargetInputSection())
|
||||
TS = GetISThunkSec(TIS, OS);
|
||||
else
|
||||
|
@ -2234,15 +2234,14 @@ void ARMExidxSentinelSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
write32le(Buf + 4, 0x1);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ThunkSection<ELFT>::ThunkSection(OutputSection *OS, uint64_t Off)
|
||||
ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
|
||||
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
|
||||
sizeof(typename ELFT::uint), ".text.thunk") {
|
||||
Config->is64Bit() ? 8 : 4, ".text.thunk") {
|
||||
this->OutSec = OS;
|
||||
this->OutSecOff = Off;
|
||||
}
|
||||
|
||||
template <class ELFT> void ThunkSection<ELFT>::addThunk(Thunk<ELFT> *T) {
|
||||
void ThunkSection::addThunk(Thunk *T) {
|
||||
uint64_t Off = alignTo(Size, T->alignment);
|
||||
T->Offset = Off;
|
||||
Thunks.push_back(T);
|
||||
@ -2250,14 +2249,13 @@ template <class ELFT> void ThunkSection<ELFT>::addThunk(Thunk<ELFT> *T) {
|
||||
Size = Off + T->size();
|
||||
}
|
||||
|
||||
template <class ELFT> void ThunkSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
for (const Thunk<ELFT> *T : Thunks)
|
||||
void ThunkSection::writeTo(uint8_t *Buf) {
|
||||
for (const Thunk *T : Thunks)
|
||||
T->writeTo(Buf + T->Offset, *this);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
InputSection *ThunkSection<ELFT>::getTargetInputSection() const {
|
||||
const Thunk<ELFT> *T = Thunks.front();
|
||||
InputSection *ThunkSection::getTargetInputSection() const {
|
||||
const Thunk *T = Thunks.front();
|
||||
return T->getTargetInputSection();
|
||||
}
|
||||
|
||||
@ -2389,11 +2387,6 @@ template class elf::ARMExidxSentinelSection<ELF32BE>;
|
||||
template class elf::ARMExidxSentinelSection<ELF64LE>;
|
||||
template class elf::ARMExidxSentinelSection<ELF64BE>;
|
||||
|
||||
template class elf::ThunkSection<ELF32LE>;
|
||||
template class elf::ThunkSection<ELF32BE>;
|
||||
template class elf::ThunkSection<ELF64LE>;
|
||||
template class elf::ThunkSection<ELF64BE>;
|
||||
|
||||
template class elf::EhFrameSection<ELF32LE>;
|
||||
template class elf::EhFrameSection<ELF32BE>;
|
||||
template class elf::EhFrameSection<ELF64LE>;
|
||||
|
@ -727,7 +727,7 @@ public:
|
||||
|
||||
// A container for one or more linker generated thunks. Instances of these
|
||||
// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.
|
||||
template <class ELFT> class ThunkSection : public SyntheticSection {
|
||||
class ThunkSection : public SyntheticSection {
|
||||
public:
|
||||
// ThunkSection in OS, with desired OutSecOff of Off
|
||||
ThunkSection(OutputSection *OS, uint64_t Off);
|
||||
@ -736,13 +736,13 @@ public:
|
||||
// Thunk is given offset from start of this InputSection
|
||||
// Thunk defines a symbol in this InputSection that can be used as target
|
||||
// of a relocation
|
||||
void addThunk(Thunk<ELFT> *T);
|
||||
void addThunk(Thunk *T);
|
||||
size_t getSize() const override { return Size; }
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
InputSection *getTargetInputSection() const;
|
||||
|
||||
private:
|
||||
std::vector<const Thunk<ELFT> *> Thunks;
|
||||
std::vector<const Thunk *> Thunks;
|
||||
size_t Size = 0;
|
||||
};
|
||||
|
||||
|
@ -50,56 +50,54 @@ namespace {
|
||||
|
||||
// Specific ARM Thunk implementations. The naming convention is:
|
||||
// Source State, TargetState, Target Requirement, ABS or PI, Range
|
||||
template <class ELFT>
|
||||
class ARMToThumbV7ABSLongThunk final : public Thunk<ELFT> {
|
||||
template <class ELFT> class ARMToThumbV7ABSLongThunk final : public Thunk {
|
||||
public:
|
||||
ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
|
||||
ARMToThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {}
|
||||
|
||||
uint32_t size() const override { return 12; }
|
||||
void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
|
||||
void addSymbols(ThunkSection<ELFT> &IS) override;
|
||||
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
|
||||
void addSymbols(ThunkSection &IS) override;
|
||||
};
|
||||
|
||||
template <class ELFT> class ARMToThumbV7PILongThunk final : public Thunk<ELFT> {
|
||||
template <class ELFT> class ARMToThumbV7PILongThunk final : public Thunk {
|
||||
public:
|
||||
ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
|
||||
ARMToThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {}
|
||||
|
||||
uint32_t size() const override { return 16; }
|
||||
void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
|
||||
void addSymbols(ThunkSection<ELFT> &IS) override;
|
||||
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
|
||||
void addSymbols(ThunkSection &IS) override;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
class ThumbToARMV7ABSLongThunk final : public Thunk<ELFT> {
|
||||
template <class ELFT> class ThumbToARMV7ABSLongThunk final : public Thunk {
|
||||
public:
|
||||
ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {
|
||||
ThumbToARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {
|
||||
this->alignment = 2;
|
||||
}
|
||||
|
||||
uint32_t size() const override { return 10; }
|
||||
void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
|
||||
void addSymbols(ThunkSection<ELFT> &IS) override;
|
||||
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
|
||||
void addSymbols(ThunkSection &IS) override;
|
||||
};
|
||||
|
||||
template <class ELFT> class ThumbToARMV7PILongThunk final : public Thunk<ELFT> {
|
||||
template <class ELFT> class ThumbToARMV7PILongThunk final : public Thunk {
|
||||
public:
|
||||
ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {
|
||||
ThumbToARMV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {
|
||||
this->alignment = 2;
|
||||
}
|
||||
|
||||
uint32_t size() const override { return 12; }
|
||||
void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
|
||||
void addSymbols(ThunkSection<ELFT> &IS) override;
|
||||
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
|
||||
void addSymbols(ThunkSection &IS) override;
|
||||
};
|
||||
|
||||
// MIPS LA25 thunk
|
||||
template <class ELFT> class MipsThunk final : public Thunk<ELFT> {
|
||||
template <class ELFT> class MipsThunk final : public Thunk {
|
||||
public:
|
||||
MipsThunk(const SymbolBody &Dest) : Thunk<ELFT>(Dest) {}
|
||||
MipsThunk(const SymbolBody &Dest) : Thunk(Dest) {}
|
||||
|
||||
uint32_t size() const override { return 16; }
|
||||
void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const override;
|
||||
void addSymbols(ThunkSection<ELFT> &IS) override;
|
||||
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
|
||||
void addSymbols(ThunkSection &IS) override;
|
||||
InputSection *getTargetInputSection() const override;
|
||||
};
|
||||
|
||||
@ -113,7 +111,7 @@ template <class ELFT> static uint64_t getARMThunkDestVA(const SymbolBody &S) {
|
||||
|
||||
template <class ELFT>
|
||||
void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
ThunkSection<ELFT> &IS) const {
|
||||
ThunkSection &IS) const {
|
||||
const uint8_t Data[] = {
|
||||
0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
|
||||
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
|
||||
@ -126,7 +124,7 @@ void ARMToThumbV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ARMToThumbV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
void ARMToThumbV7ABSLongThunk<ELFT>::addSymbols(ThunkSection &IS) {
|
||||
this->ThunkSym = addSyntheticLocal<ELFT>(
|
||||
Saver.save("__ARMToThumbv7ABSLongThunk_" + this->Destination.getName()),
|
||||
STT_FUNC, this->Offset, size(), &IS);
|
||||
@ -135,7 +133,7 @@ void ARMToThumbV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
|
||||
template <class ELFT>
|
||||
void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
ThunkSection<ELFT> &IS) const {
|
||||
ThunkSection &IS) const {
|
||||
const uint8_t Data[] = {
|
||||
0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
|
||||
0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
|
||||
@ -148,7 +146,7 @@ void ThumbToARMV7ABSLongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ThumbToARMV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
void ThumbToARMV7ABSLongThunk<ELFT>::addSymbols(ThunkSection &IS) {
|
||||
this->ThunkSym = addSyntheticLocal<ELFT>(
|
||||
Saver.save("__ThumbToARMv7ABSLongThunk_" + this->Destination.getName()),
|
||||
STT_FUNC, this->Offset, size(), &IS);
|
||||
@ -157,7 +155,7 @@ void ThumbToARMV7ABSLongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
|
||||
template <class ELFT>
|
||||
void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
ThunkSection<ELFT> &IS) const {
|
||||
ThunkSection &IS) const {
|
||||
const uint8_t Data[] = {
|
||||
0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) +8)
|
||||
0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P+4) +8)
|
||||
@ -172,7 +170,7 @@ void ARMToThumbV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ARMToThumbV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
void ARMToThumbV7PILongThunk<ELFT>::addSymbols(ThunkSection &IS) {
|
||||
this->ThunkSym = addSyntheticLocal<ELFT>(
|
||||
Saver.save("__ARMToThumbV7PILongThunk_" + this->Destination.getName()),
|
||||
STT_FUNC, this->Offset, size(), &IS);
|
||||
@ -181,7 +179,7 @@ void ARMToThumbV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
|
||||
template <class ELFT>
|
||||
void ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
ThunkSection<ELFT> &IS) const {
|
||||
ThunkSection &IS) const {
|
||||
const uint8_t Data[] = {
|
||||
0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
|
||||
0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P+4) + 4)
|
||||
@ -196,7 +194,7 @@ void ThumbToARMV7PILongThunk<ELFT>::writeTo(uint8_t *Buf,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ThumbToARMV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
void ThumbToARMV7PILongThunk<ELFT>::addSymbols(ThunkSection &IS) {
|
||||
this->ThunkSym = addSyntheticLocal<ELFT>(
|
||||
Saver.save("__ThumbToARMV7PILongThunk_" + this->Destination.getName()),
|
||||
STT_FUNC, this->Offset, size(), &IS);
|
||||
@ -205,7 +203,7 @@ void ThumbToARMV7PILongThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
|
||||
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
|
||||
template <class ELFT>
|
||||
void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection<ELFT> &) const {
|
||||
void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection &) const {
|
||||
const endianness E = ELFT::TargetEndianness;
|
||||
|
||||
uint64_t S = this->Destination.template getVA<ELFT>();
|
||||
@ -217,7 +215,7 @@ void MipsThunk<ELFT>::writeTo(uint8_t *Buf, ThunkSection<ELFT> &) const {
|
||||
Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
|
||||
}
|
||||
|
||||
template <class ELFT> void MipsThunk<ELFT>::addSymbols(ThunkSection<ELFT> &IS) {
|
||||
template <class ELFT> void MipsThunk<ELFT>::addSymbols(ThunkSection &IS) {
|
||||
this->ThunkSym = addSyntheticLocal<ELFT>(
|
||||
Saver.save("__LA25Thunk_" + this->Destination.getName()), STT_FUNC,
|
||||
this->Offset, size(), &IS);
|
||||
@ -229,14 +227,13 @@ InputSection *MipsThunk<ELFT>::getTargetInputSection() const {
|
||||
return dyn_cast<InputSection>(DR->Section);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
Thunk<ELFT>::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {}
|
||||
Thunk::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {}
|
||||
|
||||
template <class ELFT> Thunk<ELFT>::~Thunk() = default;
|
||||
Thunk::~Thunk() = default;
|
||||
|
||||
// Creates a thunk for Thumb-ARM interworking.
|
||||
template <class ELFT>
|
||||
static Thunk<ELFT> *addThunkArm(uint32_t Reloc, SymbolBody &S) {
|
||||
static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) {
|
||||
// ARM relocations need ARM to Thumb interworking Thunks.
|
||||
// Thumb relocations need Thumb to ARM relocations.
|
||||
// Use position independent Thunks if we require position independent code.
|
||||
@ -256,11 +253,11 @@ static Thunk<ELFT> *addThunkArm(uint32_t Reloc, SymbolBody &S) {
|
||||
fatal("unrecognized relocation type");
|
||||
}
|
||||
|
||||
template <class ELFT> static Thunk<ELFT> *addThunkMips(SymbolBody &S) {
|
||||
template <class ELFT> static Thunk *addThunkMips(SymbolBody &S) {
|
||||
return make<MipsThunk<ELFT>>(S);
|
||||
}
|
||||
|
||||
template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType, SymbolBody &S) {
|
||||
template <class ELFT> Thunk *addThunk(uint32_t RelocType, SymbolBody &S) {
|
||||
if (Config->EMachine == EM_ARM)
|
||||
return addThunkArm<ELFT>(RelocType, S);
|
||||
else if (Config->EMachine == EM_MIPS)
|
||||
@ -269,15 +266,9 @@ template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType, SymbolBody &S) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template Thunk<ELF32LE> *addThunk<ELF32LE>(uint32_t, SymbolBody &);
|
||||
template Thunk<ELF32BE> *addThunk<ELF32BE>(uint32_t, SymbolBody &);
|
||||
template Thunk<ELF64LE> *addThunk<ELF64LE>(uint32_t, SymbolBody &);
|
||||
template Thunk<ELF64BE> *addThunk<ELF64BE>(uint32_t, SymbolBody &);
|
||||
|
||||
template class Thunk<ELF32LE>;
|
||||
template class Thunk<ELF32BE>;
|
||||
template class Thunk<ELF64LE>;
|
||||
template class Thunk<ELF64BE>;
|
||||
|
||||
template Thunk *addThunk<ELF32LE>(uint32_t, SymbolBody &);
|
||||
template Thunk *addThunk<ELF32BE>(uint32_t, SymbolBody &);
|
||||
template Thunk *addThunk<ELF64LE>(uint32_t, SymbolBody &);
|
||||
template Thunk *addThunk<ELF64BE>(uint32_t, SymbolBody &);
|
||||
} // end namespace elf
|
||||
} // end namespace lld
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace lld {
|
||||
namespace elf {
|
||||
class SymbolBody;
|
||||
template <class ELFT> class ThunkSection;
|
||||
class ThunkSection;
|
||||
// Class to describe an instance of a Thunk.
|
||||
// A Thunk is a code-sequence inserted by the linker in between a caller and
|
||||
// the callee. The relocation to the callee is redirected to the Thunk, which
|
||||
@ -25,17 +25,17 @@ template <class ELFT> class ThunkSection;
|
||||
//
|
||||
// Thunks can be created for DefinedRegular, Shared and Undefined Symbols.
|
||||
// Thunks are assigned to synthetic ThunkSections
|
||||
template <class ELFT> class Thunk {
|
||||
class Thunk {
|
||||
public:
|
||||
Thunk(const SymbolBody &Destination);
|
||||
virtual ~Thunk();
|
||||
|
||||
virtual uint32_t size() const { return 0; }
|
||||
virtual void writeTo(uint8_t *Buf, ThunkSection<ELFT> &IS) const {}
|
||||
virtual void writeTo(uint8_t *Buf, ThunkSection &IS) const {}
|
||||
|
||||
// All Thunks must define at least one symbol ThunkSym so that we can
|
||||
// redirect relocations to it.
|
||||
virtual void addSymbols(ThunkSection<ELFT> &IS) {}
|
||||
virtual void addSymbols(ThunkSection &IS) {}
|
||||
|
||||
// Some Thunks must be placed immediately before their Target as they elide
|
||||
// a branch and fall through to the first Symbol in the Target.
|
||||
@ -51,7 +51,7 @@ public:
|
||||
|
||||
// For a Relocation to symbol S create a Thunk to be added to a synthetic
|
||||
// ThunkSection. At present there are implementations for ARM and Mips Thunks.
|
||||
template <class ELFT> Thunk<ELFT> *addThunk(uint32_t RelocType, SymbolBody &S);
|
||||
template <class ELFT> Thunk *addThunk(uint32_t RelocType, SymbolBody &S);
|
||||
|
||||
} // namespace elf
|
||||
} // namespace lld
|
||||
|
Loading…
x
Reference in New Issue
Block a user