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