[MCJIT] Fix PR20656 by teaching MCJIT to honor ExecutionEngine's global mapping.
authorLang Hames <lhames@gmail.com>
Wed, 29 Jul 2015 23:12:33 +0000 (23:12 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 29 Jul 2015 23:12:33 +0000 (23:12 +0000)
This is important for users of the C API who can't supply custom symbol
resolvers yet.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243589 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/MCJIT/MCJIT.cpp
unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp

index 67b843737cd2b6abadd969d48f270ccb96b26c8f..1fc6bb5fe1669811471623c9cb51a907d9c46bd0 100644 (file)
@@ -189,10 +189,17 @@ uint64_t ExecutionEngineState::RemoveMapping(StringRef Name) {
 }
 
 std::string ExecutionEngine::getMangledName(const GlobalValue *GV) {
+  assert(GV->hasName() && "Global must have name.");
+
   MutexGuard locked(lock);
-  Mangler Mang;
   SmallString<128> FullName;
-  Mang.getNameWithPrefix(FullName, GV, false);
+
+  const DataLayout &DL =
+    GV->getParent()->getDataLayout().isDefault()
+      ? getDataLayout()
+      : GV->getParent()->getDataLayout();
+
+  Mangler::getNameWithPrefix(FullName, GV->getName(), DL);
   return FullName.str();
 }
 
index 492478da89f246cf7dd6ee944d8b074d3b98156e..c201f39a375e492c26edf02c93a546198f8b0a57 100644 (file)
@@ -270,6 +270,12 @@ void MCJIT::finalizeModule(Module *M) {
 RuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) {
   SmallString<128> FullName;
   Mangler::getNameWithPrefix(FullName, Name, getDataLayout());
+
+  if (void *Addr = getPointerToGlobalIfAvailable(FullName))
+    return RuntimeDyld::SymbolInfo(static_cast<uint64_t>(
+                                     reinterpret_cast<uintptr_t>(Addr)),
+                                   JITSymbolFlags::Exported);
+
   return Dyld.getSymbol(FullName);
 }
 
index c7d4dd757cf8373a865c5d0d0c94dc3b60e188ed..16530293270f5d5aca1e94cbc222eb2a20dc67f9 100644 (file)
@@ -488,3 +488,36 @@ TEST_F(MCJITCAPITest, yield) {
   EXPECT_TRUE(didCallYield);
 }
 
+static int localTestFunc() {
+  return 42;
+}
+
+TEST_F(MCJITCAPITest, addGlobalMapping) {
+  SKIP_UNSUPPORTED_PLATFORM;
+
+  Module = LLVMModuleCreateWithName("testModule");
+  LLVMTypeRef FunctionType = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0);
+  LLVMValueRef MappedFn = LLVMAddFunction(Module, "mapped_fn", FunctionType);
+
+  Function = LLVMAddFunction(Module, "test_fn", FunctionType);
+  LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "");
+  LLVMBuilderRef Builder = LLVMCreateBuilder();
+  LLVMPositionBuilderAtEnd(Builder, Entry);
+  LLVMValueRef RetVal = LLVMBuildCall(Builder, MappedFn, NULL, 0, "");
+  LLVMBuildRet(Builder, RetVal);
+
+  LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
+  LLVMDisposeMessage(Error);
+
+  buildMCJITOptions();
+  buildMCJITEngine();
+
+  LLVMAddGlobalMapping(Engine, MappedFn, reinterpret_cast<void*>(&localTestFunc));
+
+  buildAndRunPasses();
+
+  uint64_t raw = LLVMGetFunctionAddress(Engine, "test_fn");
+  int (*usable)() = (int (*)()) raw;
+
+  EXPECT_EQ(42, usable());
+}