ELF: Allow GOT relocs pointing to non-preemptable ifunc to resolve to an IRELATIVE where possible.

Non-GOT non-PLT relocations to non-preemptible ifuncs result in the
creation of a canonical PLT, which now takes the identity of the IFUNC
in the symbol table. This (a) ensures address consistency inside and
outside the module, and (b) fixes a bug where some of these relocations
end up pointing to the resolver.

Fixes (at least) PR40474 and PR40501.

Differential Revision: https://reviews.llvm.org/D57371

llvm-svn: 353981
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 52fa72a..96e23b9 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -120,20 +120,24 @@
   return OutVA + Addend;
 }
 
-uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
+uint64_t Symbol::getGotVA() const {
+  if (GotInIgot)
+    return In.IgotPlt->getVA() + getGotPltOffset();
+  return In.Got->getVA() + getGotOffset();
+}
 
 uint64_t Symbol::getGotOffset() const {
   return GotIndex * Target->GotEntrySize;
 }
 
 uint64_t Symbol::getGotPltVA() const {
-  if (this->IsInIgot)
+  if (IsInIplt)
     return In.IgotPlt->getVA() + getGotPltOffset();
   return In.GotPlt->getVA() + getGotPltOffset();
 }
 
 uint64_t Symbol::getGotPltOffset() const {
-  if (IsInIgot)
+  if (IsInIplt)
     return PltIndex * Target->GotPltEntrySize;
   return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
 }