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