From 343f7e5d8dd56180084023b9846d18e97e62ebbf Mon Sep 17 00:00:00 2001
From: Rui Ueyama <ruiu@google.com>
Date: Tue, 2 Feb 2016 06:29:10 +0000
Subject: [PATCH] ELF: Move GNU_IFUNC relocation handler to one place. NFC.

llvm-svn: 259468
---
 lld/ELF/Writer.cpp | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c99d1ed207b8..a09a570384f1 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -306,6 +306,24 @@ void Writer<ELFT>::scanRelocs(
       }
     }
 
+    // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
+    // to the symbol go through the PLT. This is true even for a local
+    // symbol, although local symbols normally do not require PLT entries.
+    if (Body && isGnuIFunc<ELFT>(*Body)) {
+      Body->setUsedInDynamicReloc();
+      if (Body->isInGot())
+        continue;
+      Out<ELFT>::Plt->addEntry(Body);
+      if (Target->UseLazyBinding) {
+        Out<ELFT>::GotPlt->addEntry(Body);
+        Out<ELFT>::RelaPlt->addReloc({&C, &RI});
+      } else {
+        Out<ELFT>::Got->addEntry(Body);
+        Out<ELFT>::RelaDyn->addReloc({&C, &RI});
+      }
+      continue;
+    }
+
     bool NeedsGot = false;
     bool NeedsPlt = false;
 
@@ -328,15 +346,6 @@ void Writer<ELFT>::scanRelocs(
       }
     }
 
-    // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
-    // to the symbol go through the PLT. This is true even for a local
-    // symbol, although local symbols normally do not require PLT entries.
-    if (Body && isGnuIFunc<ELFT>(*Body)) {
-      Body->setUsedInDynamicReloc();
-      Out<ELFT>::RelaPlt->addReloc({&C, &RI});
-      continue;
-    }
-
     if (Config->EMachine == EM_MIPS) {
       if (Type == R_MIPS_LO16)
         // Ignore R_MIPS_LO16 relocation. If it is a pair for R_MIPS_GOT16 we