[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