1 //===--- SimpleExecutorDylibManager.cpp - Executor-side dylib management --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h" 10 11 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" 12 #include "llvm/Support/FormatVariadic.h" 13 14 #define DEBUG_TYPE "orc" 15 16 namespace llvm { 17 namespace orc { 18 namespace rt_bootstrap { 19 20 SimpleExecutorDylibManager::~SimpleExecutorDylibManager() { 21 assert(Dylibs.empty() && "shutdown not called?"); 22 } 23 24 Expected<tpctypes::DylibHandle> 25 SimpleExecutorDylibManager::open(const std::string &Path, uint64_t Mode) { 26 if (Mode != 0) 27 return make_error<StringError>("open: non-zero mode bits not yet supported", 28 inconvertibleErrorCode()); 29 30 const char *PathCStr = Path.empty() ? nullptr : Path.c_str(); 31 std::string ErrMsg; 32 33 auto DL = sys::DynamicLibrary::getPermanentLibrary(PathCStr, &ErrMsg); 34 if (!DL.isValid()) 35 return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 36 37 std::lock_guard<std::mutex> Lock(M); 38 auto H = ExecutorAddr::fromPtr(DL.getOSSpecificHandle()); 39 Dylibs.insert(DL.getOSSpecificHandle()); 40 return H; 41 } 42 43 Expected<std::vector<ExecutorSymbolDef>> 44 SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H, 45 const RemoteSymbolLookupSet &L) { 46 std::vector<ExecutorSymbolDef> Result; 47 auto DL = sys::DynamicLibrary(H.toPtr<void *>()); 48 49 for (const auto &E : L) { 50 if (E.Name.empty()) { 51 if (E.Required) 52 return make_error<StringError>("Required address for empty symbol \"\"", 53 inconvertibleErrorCode()); 54 else 55 Result.push_back(ExecutorSymbolDef()); 56 } else { 57 58 const char *DemangledSymName = E.Name.c_str(); 59 #ifdef __APPLE__ 60 if (E.Name.front() != '_') 61 return make_error<StringError>(Twine("MachO symbol \"") + E.Name + 62 "\" missing leading '_'", 63 inconvertibleErrorCode()); 64 ++DemangledSymName; 65 #endif 66 67 void *Addr = DL.getAddressOfSymbol(DemangledSymName); 68 if (!Addr && E.Required) 69 return make_error<StringError>(Twine("Missing definition for ") + 70 DemangledSymName, 71 inconvertibleErrorCode()); 72 73 // FIXME: determine accurate JITSymbolFlags. 74 Result.push_back({ExecutorAddr::fromPtr(Addr), JITSymbolFlags::Exported}); 75 } 76 } 77 78 return Result; 79 } 80 81 Error SimpleExecutorDylibManager::shutdown() { 82 83 DylibSet DS; 84 { 85 std::lock_guard<std::mutex> Lock(M); 86 std::swap(DS, Dylibs); 87 } 88 89 // There is no removal of dylibs at the moment, so nothing to do here. 90 return Error::success(); 91 } 92 93 void SimpleExecutorDylibManager::addBootstrapSymbols( 94 StringMap<ExecutorAddr> &M) { 95 M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this); 96 M[rt::SimpleExecutorDylibManagerOpenWrapperName] = 97 ExecutorAddr::fromPtr(&openWrapper); 98 M[rt::SimpleExecutorDylibManagerLookupWrapperName] = 99 ExecutorAddr::fromPtr(&lookupWrapper); 100 } 101 102 llvm::orc::shared::CWrapperFunctionResult 103 SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) { 104 return shared:: 105 WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle( 106 ArgData, ArgSize, 107 shared::makeMethodWrapperHandler( 108 &SimpleExecutorDylibManager::open)) 109 .release(); 110 } 111 112 llvm::orc::shared::CWrapperFunctionResult 113 SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) { 114 return shared:: 115 WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle( 116 ArgData, ArgSize, 117 shared::makeMethodWrapperHandler( 118 &SimpleExecutorDylibManager::lookup)) 119 .release(); 120 } 121 122 } // namespace rt_bootstrap 123 } // end namespace orc 124 } // end namespace llvm 125