Support targets that require stubs for external functions better


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18098 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 52fb2e3..c2c8875 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -151,9 +151,22 @@
   void *&Stub = FunctionToStubMap[F];
   if (Stub) return Stub;
 
+  // Call the lazy resolver function unless we already KNOW it is an external
+  // function, in which case we just skip the lazy resolution step.
+  void *Actual = (void*)LazyResolverFn;
+  if (F->hasExternalLinkage())
+    Actual = TheJIT->getPointerToFunction(F);
+    
   // Otherwise, codegen a new stub.  For now, the stub will call the lazy
   // resolver function.
-  Stub = TheJIT->getJITInfo().emitFunctionStub((void*)LazyResolverFn, MCE);
+  Stub = TheJIT->getJITInfo().emitFunctionStub(Actual, MCE);
+
+  if (F->hasExternalLinkage()) {
+    // If we are getting the stub for an external function, we really want the
+    // address of the stub in the GlobalAddressMap for the JIT, not the address
+    // of the external function.
+    TheJIT->updateGlobalMapping(F, Stub);
+  }
 
   DEBUG(std::cerr << "JIT: Stub emitted at [" << Stub << "] for function '"
                   << F->getName() << "\n");
@@ -274,7 +287,10 @@
   if (F->hasExternalLinkage()) {
     // If this is an external function pointer, we can force the JIT to
     // 'compile' it, which really just adds it to the map.
-    return TheJIT->getPointerToFunction(F);
+    if (DoesntNeedStub)
+      return TheJIT->getPointerToFunction(F);
+
+    return getJITResolver(this).getFunctionStub(F);
   }
 
   // Okay, the function has not been compiled yet, if the target callback