LLVM 23.0.0git
SelfExecutorProcessControl.cpp
Go to the documentation of this file.
1//===------ SelfExecutorProcessControl.cpp -- EPC for in-process JITs -----===//
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
10
20
21#define DEBUG_TYPE "orc"
22
23namespace llvm::orc {
24
26public:
27 InProcessDylibManager(char GlobalManglingPrefix);
28 Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
29 void
31 DylibManager::SymbolLookupCompleteFn Complete) override;
32
33private:
34 char GlobalManglingPrefix;
35};
36
38 std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
41
42 this->TargetTriple = std::move(TargetTriple);
43 this->PageSize = PageSize;
44 this->JDI = {ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager),
46
48
49#ifdef __APPLE__
50 // FIXME: Don't add an UnwindInfoManager by default -- it's redundant when
51 // the ORC runtime is loaded. We'll need a way to document this and
52 // allow clients to choose.
55#endif // __APPLE__
56}
57
59SelfExecutorProcessControl::Create(std::shared_ptr<SymbolStringPool> SSP,
60 std::unique_ptr<TaskDispatcher> D) {
61
62 if (!SSP)
63 SSP = std::make_shared<SymbolStringPool>();
64
65 if (!D)
66 D = std::make_unique<InPlaceTaskDispatcher>();
67
69 if (!PageSize)
70 return PageSize.takeError();
71
73
74 return std::make_unique<SelfExecutorProcessControl>(
75 std::move(SSP), std::move(D), std::move(TT), *PageSize);
76}
77
81 using MainTy = int (*)(int, char *[]);
82 return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);
83}
84
87 using VoidTy = int (*)();
88 return orc::runAsVoidFunction(VoidFnAddr.toPtr<VoidTy>());
89}
90
93 using IntTy = int (*)(int);
94 return orc::runAsIntFunction(IntFnAddr.toPtr<IntTy>(), Arg);
95}
96
98 IncomingWFRHandler SendResult,
99 ArrayRef<char> ArgBuffer) {
100 using WrapperFnTy =
101 shared::CWrapperFunctionBuffer (*)(const char *Data, size_t Size);
102 auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();
104 WrapperFn(ArgBuffer.data(), ArgBuffer.size())));
105}
106
108 D->shutdown();
109 return Error::success();
110}
111
114 return std::make_unique<jitlink::InProcessMemoryManager>(
116}
117
120 char Prefix = TargetTriple.isOSBinFormatMachO() ? '_' : '\0';
121 return std::make_unique<InProcessDylibManager>(Prefix);
122}
123
126 return std::make_unique<InProcessMemoryAccess>(TargetTriple.isArch64Bit());
127}
128
130SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
131 void *Ctx, const void *FnTag, const char *Data, size_t Size) {
132
133 LLVM_DEBUG({
134 dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
135 << " byte payload.\n";
136 });
137
138 std::promise<shared::WrapperFunctionBuffer> ResultP;
139 auto ResultF = ResultP.get_future();
140 static_cast<SelfExecutorProcessControl *>(Ctx)
143 [ResultP = std::move(ResultP)](
144 shared::WrapperFunctionBuffer Result) mutable {
145 ResultP.set_value(std::move(Result));
146 },
149
150 return ResultF.get().release();
151}
152
154 char GlobalManglingPrefix)
155 : GlobalManglingPrefix(GlobalManglingPrefix) {}
156
159 const char *DylibPath) {
160 std::string ErrMsg;
161 auto Dylib = sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg);
162 if (!Dylib.isValid())
163 return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
164 return ExecutorAddr::fromPtr(Dylib.getOSSpecificHandle());
165}
166
170 std::vector<tpctypes::LookupResult> R;
171
172 for (auto &Elem : Request) {
173 sys::DynamicLibrary Dylib(Elem.Handle.toPtr<void *>());
174 R.push_back(tpctypes::LookupResult());
175 for (auto &KV : Elem.Symbols) {
176 auto &Sym = KV.first;
177 std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
178 (*Sym).size() - !!GlobalManglingPrefix);
179 void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str());
180 if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol)
181 R.back().emplace_back();
182 else
183 // FIXME: determine accurate JITSymbolFlags.
184 R.back().emplace_back(ExecutorSymbolDef(ExecutorAddr::fromPtr(Addr),
186 }
187 }
188 Complete(std::move(R));
189}
190
191} // namespace llvm::orc
Provides a library for accessing information about this process and other processes on the operating ...
#define LLVM_DEBUG(...)
Definition Debug.h:114
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
const T * data() const
Definition ArrayRef.h:139
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
unique_function< void(Expected< std::vector< tpctypes::LookupResult > >)> SymbolLookupCompleteFn
LLVM_ABI void runJITDispatchHandler(SendResultFunction SendResult, ExecutorAddr HandlerFnTagAddr, shared::WrapperFunctionBuffer ArgBytes)
Run a registered jit-side wrapper function.
Definition Core.cpp:1924
Represents an address in the executor process.
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
A handler or incoming WrapperFunctionBuffers – either return values from callWrapper* calls,...
std::unique_ptr< TaskDispatcher > D
std::shared_ptr< SymbolStringPool > SSP
StringMap< ExecutorAddr > BootstrapSymbols
StringMap< std::vector< char > > BootstrapMap
ExecutionSession & getExecutionSession()
Return the ExecutionSession associated with this instance.
ExecutorProcessControl(std::shared_ptr< SymbolStringPool > SSP, std::unique_ptr< TaskDispatcher > D)
Represents a defining location for a JIT symbol.
void lookupSymbolsAsync(ArrayRef< LookupRequest > Request, DylibManager::SymbolLookupCompleteFn Complete) override
Search for symbols in the target process.
Expected< tpctypes::DylibHandle > loadDylib(const char *DylibPath) override
Load the dynamic library at the given path and return a handle to it.
SelfExecutorProcessControl(std::shared_ptr< SymbolStringPool > SSP, std::unique_ptr< TaskDispatcher > D, Triple TargetTriple, unsigned PageSize)
Expected< std::unique_ptr< jitlink::JITLinkMemoryManager > > createDefaultMemoryManager() override
Create a default JITLinkMemoryManager for the target process.
static Expected< std::unique_ptr< SelfExecutorProcessControl > > Create(std::shared_ptr< SymbolStringPool > SSP=nullptr, std::unique_ptr< TaskDispatcher > D=nullptr)
Create a SelfExecutorProcessControl with the given symbol string pool and memory manager.
Expected< std::unique_ptr< MemoryAccess > > createDefaultMemoryAccess() override
Create a default MemoryAccess for the target process.
Error disconnect() override
Disconnect from the target process.
Expected< int32_t > runAsVoidFunction(ExecutorAddr VoidFnAddr) override
Run function with a int (*)(void) signature.
Expected< int32_t > runAsMain(ExecutorAddr MainFnAddr, ArrayRef< std::string > Args) override
Run function with a main-like signature.
void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef< char > ArgBuffer) override
Run a wrapper function in the executor.
Expected< std::unique_ptr< DylibManager > > createDefaultDylibMgr() override
Create a default DylibManager for the target process.
Expected< int32_t > runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override
Run function with a int (*)(int) signature.
static LLVM_ABI bool TryEnable()
If the libunwind find-dynamic-unwind-info callback registration APIs are available then this method w...
static LLVM_ABI void addBootstrapSymbols(StringMap< ExecutorAddr > &M)
C++ wrapper function buffer: Same as CWrapperFunctionBuffer but auto-releases memory.
static WrapperFunctionBuffer copyFrom(const char *Source, size_t Size)
Copy from the given char range.
This class provides a portable interface to dynamic libraries which also might be known as shared lib...
static LLVM_ABI DynamicLibrary getPermanentLibrary(const char *filename, std::string *errMsg=nullptr)
This function permanently loads the dynamic library at the given path using the library load operatio...
LLVM_ABI void * getAddressOfSymbol(const char *symbolName)
Searches through the library for the symbol symbolName.
static LLVM_ABI Expected< unsigned > getPageSize()
Get the process's page size.
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
Definition Process.h:62
std::vector< std::optional< ExecutorSymbolDef > > LookupResult
LLVM_ABI void addDefaultBootstrapValuesForHostProcess(StringMap< std::vector< char > > &BootstrapMap, StringMap< ExecutorAddr > &BootstrapSymbols)
LLVM_ABI int runAsVoidFunction(int(*Func)(void))
LLVM_ABI int runAsIntFunction(int(*Func)(int), int Arg)
LLVM_ABI int runAsMain(int(*Main)(int, char *[]), ArrayRef< std::string > Args, std::optional< StringRef > ProgramName=std::nullopt)
Run a main function, returning the result.
LLVM_ABI std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition Host.cpp:2576
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1916
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870