Index: include/llvm-c/OrcBindings.h =================================================================== --- include/llvm-c/OrcBindings.h +++ include/llvm-c/OrcBindings.h @@ -140,6 +140,15 @@ LLVMOrcTargetAddress *RetAddr, const char *SymbolName); +/** + * Get symbol address from JIT instance, searching only the specified + * handle. + */ +LLVMOrcErrorCode LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, + LLVMOrcTargetAddress *RetAddr, + LLVMOrcModuleHandle H, + const char *SymbolName); + /** * Dispose of an ORC JIT stack. */ Index: lib/ExecutionEngine/Orc/OrcCBindings.cpp =================================================================== --- lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ lib/ExecutionEngine/Orc/OrcCBindings.cpp @@ -112,6 +112,14 @@ return J.findSymbolAddress(*RetAddr, SymbolName, true); } +LLVMOrcErrorCode LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, + LLVMOrcTargetAddress *RetAddr, + LLVMOrcModuleHandle H, + const char *SymbolName) { + OrcCBindingsStack &J = *unwrap(JITStack); + return J.findSymbolAddressIn(*RetAddr, H, SymbolName, true); +} + LLVMOrcErrorCode LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) { auto *J = unwrap(JITStack); auto Err = J->shutdown(); Index: lib/ExecutionEngine/Orc/OrcCBindingsStack.h =================================================================== --- lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -377,6 +377,7 @@ JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, bool ExportedSymbolsOnly) { + assert(KeyLayers.count(K) && "looking up symbol in unknown module"); return KeyLayers[K]->findSymbolIn(K, Name, ExportedSymbolsOnly); } @@ -400,6 +401,27 @@ return LLVMOrcErrSuccess; } + LLVMOrcErrorCode findSymbolAddressIn(JITTargetAddress &RetAddr, + orc::VModuleKey K, + const std::string &Name, + bool ExportedSymbolsOnly) { + RetAddr = 0; + if (auto Sym = findSymbolIn(K, Name, ExportedSymbolsOnly)) { + // Successful lookup, non-null symbol: + if (auto AddrOrErr = Sym.getAddress()) { + RetAddr = *AddrOrErr; + return LLVMOrcErrSuccess; + } else + return mapError(AddrOrErr.takeError()); + } else if (auto Err = Sym.takeError()) { + // Lookup failure - report error. + return mapError(std::move(Err)); + } + // Otherwise we had a successful lookup but got a null result. We already + // set RetAddr to '0' above, so just return success. + return LLVMOrcErrSuccess; + } + const std::string &getErrorMessage() const { return ErrMsg; } private: Index: unittests/ExecutionEngine/Orc/OrcCAPITest.cpp =================================================================== --- unittests/ExecutionEngine/Orc/OrcCAPITest.cpp +++ unittests/ExecutionEngine/Orc/OrcCAPITest.cpp @@ -98,12 +98,26 @@ LLVMOrcModuleHandle H; LLVMOrcAddEagerlyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr); - LLVMOrcTargetAddress MainAddr; - LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main"); - MainFnTy MainFn = (MainFnTy)MainAddr; - int Result = MainFn(); - EXPECT_EQ(Result, 42) - << "Eagerly JIT'd code did not return expected result"; + + // get symbol address searching the entire stack + { + LLVMOrcTargetAddress MainAddr; + LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main"); + MainFnTy MainFn = (MainFnTy)MainAddr; + int Result = MainFn(); + EXPECT_EQ(Result, 42) + << "Eagerly JIT'd code did not return expected result"; + } + + // and then just searching a single handle + { + LLVMOrcTargetAddress MainAddr; + LLVMOrcGetSymbolAddressIn(JIT, &MainAddr, H, "main"); + MainFnTy MainFn = (MainFnTy)MainAddr; + int Result = MainFn(); + EXPECT_EQ(Result, 42) + << "Eagerly JIT'd code did not return expected result"; + } LLVMOrcRemoveModule(JIT, H);