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 Dylibs[NextId] = std::move(DL); 39 return NextId++; 40 } 41 42 Expected<std::vector<ExecutorAddr>> 43 SimpleExecutorDylibManager::lookup(tpctypes::DylibHandle H, 44 const RemoteSymbolLookupSet &L) { 45 std::vector<ExecutorAddr> Result; 46 47 std::lock_guard<std::mutex> Lock(M); 48 auto I = Dylibs.find(H); 49 if (I == Dylibs.end()) 50 return make_error<StringError>("No dylib for handle " + formatv("{0:x}", H), 51 inconvertibleErrorCode()); 52 auto &DL = I->second; 53 54 for (const auto &E : L) { 55 56 if (E.Name.empty()) { 57 if (E.Required) 58 return make_error<StringError>("Required address for empty symbol \"\"", 59 inconvertibleErrorCode()); 60 else 61 Result.push_back(ExecutorAddr()); 62 } else { 63 64 const char *DemangledSymName = E.Name.c_str(); 65 #ifdef __APPLE__ 66 if (E.Name.front() != '_') 67 return make_error<StringError>(Twine("MachO symbol \"") + E.Name + 68 "\" missing leading '_'", 69 inconvertibleErrorCode()); 70 ++DemangledSymName; 71 #endif 72 73 void *Addr = DL.getAddressOfSymbol(DemangledSymName); 74 if (!Addr && E.Required) 75 return make_error<StringError>(Twine("Missing definition for ") + 76 DemangledSymName, 77 inconvertibleErrorCode()); 78 79 Result.push_back(ExecutorAddr::fromPtr(Addr)); 80 } 81 } 82 83 return Result; 84 } 85 86 Error SimpleExecutorDylibManager::shutdown() { 87 88 DylibsMap DM; 89 { 90 std::lock_guard<std::mutex> Lock(M); 91 std::swap(DM, Dylibs); 92 } 93 94 // There is no removal of dylibs at the moment, so nothing to do here. 95 return Error::success(); 96 } 97 98 void SimpleExecutorDylibManager::addBootstrapSymbols( 99 StringMap<ExecutorAddr> &M) { 100 M[rt::SimpleExecutorDylibManagerInstanceName] = ExecutorAddr::fromPtr(this); 101 M[rt::SimpleExecutorDylibManagerOpenWrapperName] = 102 ExecutorAddr::fromPtr(&openWrapper); 103 M[rt::SimpleExecutorDylibManagerLookupWrapperName] = 104 ExecutorAddr::fromPtr(&lookupWrapper); 105 } 106 107 llvm::orc::shared::CWrapperFunctionResult 108 SimpleExecutorDylibManager::openWrapper(const char *ArgData, size_t ArgSize) { 109 return shared:: 110 WrapperFunction<rt::SPSSimpleExecutorDylibManagerOpenSignature>::handle( 111 ArgData, ArgSize, 112 shared::makeMethodWrapperHandler( 113 &SimpleExecutorDylibManager::open)) 114 .release(); 115 } 116 117 llvm::orc::shared::CWrapperFunctionResult 118 SimpleExecutorDylibManager::lookupWrapper(const char *ArgData, size_t ArgSize) { 119 return shared:: 120 WrapperFunction<rt::SPSSimpleExecutorDylibManagerLookupSignature>::handle( 121 ArgData, ArgSize, 122 shared::makeMethodWrapperHandler( 123 &SimpleExecutorDylibManager::lookup)) 124 .release(); 125 } 126 127 } // namespace rt_bootstrap 128 } // end namespace orc 129 } // end namespace llvm 130