[lld] r258753 - ELF: Move code for GNU_IFUNC to one place. NFC.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 25 16:24:57 PST 2016
Author: ruiu
Date: Mon Jan 25 18:24:57 2016
New Revision: 258753
URL: http://llvm.org/viewvc/llvm-project?rev=258753&view=rev
Log:
ELF: Move code for GNU_IFUNC to one place. NFC.
This does not solve the problem that we call isGnuIFunc function
both from RelocationSection and from the Writer::scanRelocs, but
this at least should improve readability. I'm taking an incremental
approach to reduce complexity.
Modified:
lld/trunk/ELF/OutputSections.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=258753&r1=258752&r2=258753&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Jan 25 18:24:57 2016
@@ -300,15 +300,27 @@ template <class ELFT> void RelocationSec
bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body);
bool CBP = canBePreempted(Body, NeedsGot);
+
+ // For a symbol with STT_GNU_IFUNC type, we always create a PLT and
+ // a GOT entry for the symbol, and emit an IRELATIVE reloc rather than
+ // the usual JUMP_SLOT reloc for the GOT entry. For the details, you
+ // want to read http://www.airs.com/blog/archives/403
+ if (!CBP && Body && isGnuIFunc<ELFT>(*Body)) {
+ P->setSymbolAndType(0, Target->getIRelativeReloc(), Config->Mips64EL);
+ if (Out<ELFT>::GotPlt)
+ P->r_offset = Out<ELFT>::GotPlt->getEntryAddr(*Body);
+ else
+ P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+ continue;
+ }
+
bool LazyReloc = Body && Target->supportsLazyRelocations() &&
Target->relocNeedsPlt(Type, *Body);
bool IsDynRelative = Type == Target->getRelativeReloc();
unsigned Sym = CBP ? Body->DynamicSymbolTableIndex : 0;
unsigned Reloc;
- if (!CBP && Body && isGnuIFunc<ELFT>(*Body))
- Reloc = Target->getIRelativeReloc();
- else if (!CBP || IsDynRelative)
+ if (!CBP || IsDynRelative)
Reloc = Target->getRelativeReloc();
else if (LazyReloc)
Reloc = Target->getPltReloc();
More information about the llvm-commits
mailing list