diff options
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 6563b1a61ca..0006ccf3c08 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -150,18 +150,25 @@ template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) { Target->writePltZeroEntry(Buf, Out<ELFT>::GotPlt->getVA(), this->getVA()); Off += Target->getPltZeroEntrySize(); } - for (const SymbolBody *E : Entries) { - uint64_t Got = LazyReloc ? Out<ELFT>::GotPlt->getEntryAddr(*E) - : Out<ELFT>::Got->getEntryAddr(*E); + for (std::pair<const SymbolBody *, unsigned> &I : Entries) { + const SymbolBody *E = I.first; + unsigned RelOff = I.second; + uint64_t GotVA = + LazyReloc ? Out<ELFT>::GotPlt->getVA() : Out<ELFT>::Got->getVA(); + uint64_t GotE = LazyReloc ? Out<ELFT>::GotPlt->getEntryAddr(*E) + : Out<ELFT>::Got->getEntryAddr(*E); uint64_t Plt = this->getVA() + Off; - Target->writePltEntry(Buf + Off, Got, Plt, E->PltIndex); + Target->writePltEntry(Buf + Off, GotVA, GotE, Plt, E->PltIndex, RelOff); Off += Target->getPltEntrySize(); } } template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) { Sym->PltIndex = Entries.size(); - Entries.push_back(Sym); + unsigned RelOff = Target->supportsLazyRelocations() + ? Out<ELFT>::RelaPlt->getRelocOffset() + : Out<ELFT>::RelaDyn->getRelocOffset(); + Entries.push_back(std::make_pair(Sym, RelOff)); } template <class ELFT> @@ -281,6 +288,11 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { } } +template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { + const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); + return EntrySize * Relocs.size(); +} + template <class ELFT> void RelocationSection<ELFT>::finalize() { this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex; this->Header.sh_size = Relocs.size() * this->Header.sh_entsize; |