summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/OutputSections.cpp16
-rw-r--r--lld/ELF/Target.cpp7
-rw-r--r--lld/ELF/Target.h3
3 files changed, 17 insertions, 9 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 70d458b0829..fbdbce8cb43 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -35,17 +35,15 @@ GotPltSection<ELFT>::GotPltSection()
: OutputSectionBase<ELFT>(".got.plt", llvm::ELF::SHT_PROGBITS,
llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) {
this->Header.sh_addralign = sizeof(uintX_t);
- // .got.plt has 3 reserved entry
- Entries.resize(3);
}
template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody *Sym) {
- Sym->GotPltIndex = Entries.size();
+ Sym->GotPltIndex = Target->getGotPltHeaderEntriesNum() + Entries.size();
Entries.push_back(Sym);
}
template <class ELFT> bool GotPltSection<ELFT>::empty() const {
- return Entries.size() == 3;
+ return Entries.empty();
}
template <class ELFT>
@@ -55,15 +53,15 @@ GotPltSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
}
template <class ELFT> void GotPltSection<ELFT>::finalize() {
- this->Header.sh_size = Entries.size() * sizeof(uintX_t);
+ this->Header.sh_size =
+ (Target->getGotPltHeaderEntriesNum() + Entries.size()) * sizeof(uintX_t);
}
template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) {
- write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(
- Buf, Out<ELFT>::Dynamic->getVA());
+ Target->writeGotPltHeaderEntries(Buf);
+ Buf += Target->getGotPltHeaderEntriesNum() * sizeof(uintX_t);
for (const SymbolBody *B : Entries) {
- if (B)
- Target->writeGotPltEntry(Buf, Out<ELFT>::Plt->getEntryAddr(*B));
+ Target->writeGotPltEntry(Buf, Out<ELFT>::Plt->getEntryAddr(*B));
Buf += sizeof(uintX_t);
}
}
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index d28fcfee2b1..269a4d7dc63 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -62,6 +62,7 @@ class X86_64TargetInfo final : public TargetInfo {
public:
X86_64TargetInfo();
unsigned getPLTRefReloc(unsigned Type) const override;
+ void writeGotPltHeaderEntries(uint8_t *Buf) const override;
void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const override;
@@ -159,6 +160,8 @@ bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {}
+void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {}
+
X86TargetInfo::X86TargetInfo() {
PCRelReloc = R_386_PC32;
GotReloc = R_386_GLOB_DAT;
@@ -226,6 +229,10 @@ X86_64TargetInfo::X86_64TargetInfo() {
PltZeroEntrySize = 16;
}
+void X86_64TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {
+ write64le(Buf, Out<ELF64LE>::Dynamic->getVA());
+}
+
void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
// Skip 6 bytes of "jmpq *got(%rip)"
write32le(Buf, Plt + 6);
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index ae85d7762ba..c095c67b5c6 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -43,8 +43,10 @@ public:
unsigned getPltEntrySize() const { return PltEntrySize; }
bool supportsLazyRelocations() const { return LazyRelocations; }
unsigned getGotHeaderEntriesNum() const { return GotHeaderEntriesNum; }
+ unsigned getGotPltHeaderEntriesNum() const { return GotPltHeaderEntriesNum; }
virtual unsigned getPLTRefReloc(unsigned Type) const;
virtual void writeGotHeaderEntries(uint8_t *Buf) const;
+ virtual void writeGotPltHeaderEntries(uint8_t *Buf) const;
virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0;
virtual void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const = 0;
@@ -86,6 +88,7 @@ protected:
unsigned PltEntrySize = 8;
unsigned PltZeroEntrySize = 0;
unsigned GotHeaderEntriesNum = 0;
+ unsigned GotPltHeaderEntriesNum = 3;
bool LazyRelocations = false;
};
OpenPOWER on IntegriCloud