1 | //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===// |
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 | // This file defines the C bindings for the ExecutionEngine library. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm-c/ExecutionEngine.h" |
14 | #include "llvm/ExecutionEngine/ExecutionEngine.h" |
15 | #include "llvm/ExecutionEngine/GenericValue.h" |
16 | #include "llvm/ExecutionEngine/JITEventListener.h" |
17 | #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" |
18 | #include "llvm/IR/DerivedTypes.h" |
19 | #include "llvm/IR/Module.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Target/CodeGenCWrappers.h" |
22 | #include "llvm/Target/TargetOptions.h" |
23 | #include <cstring> |
24 | #include <optional> |
25 | |
26 | using namespace llvm; |
27 | |
28 | #define DEBUG_TYPE "jit" |
29 | |
30 | // Wrapping the C bindings types. |
31 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef) |
32 | |
33 | |
34 | static LLVMTargetMachineRef wrap(const TargetMachine *P) { |
35 | return |
36 | reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P)); |
37 | } |
38 | |
39 | /*===-- Operations on generic values --------------------------------------===*/ |
40 | |
41 | LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty, |
42 | unsigned long long N, |
43 | LLVMBool IsSigned) { |
44 | GenericValue *GenVal = new GenericValue(); |
45 | GenVal->IntVal = APInt(unwrap<IntegerType>(P: Ty)->getBitWidth(), N, IsSigned); |
46 | return wrap(P: GenVal); |
47 | } |
48 | |
49 | LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) { |
50 | GenericValue *GenVal = new GenericValue(); |
51 | GenVal->PointerVal = P; |
52 | return wrap(P: GenVal); |
53 | } |
54 | |
55 | LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) { |
56 | GenericValue *GenVal = new GenericValue(); |
57 | switch (unwrap(P: TyRef)->getTypeID()) { |
58 | case Type::FloatTyID: |
59 | GenVal->FloatVal = N; |
60 | break; |
61 | case Type::DoubleTyID: |
62 | GenVal->DoubleVal = N; |
63 | break; |
64 | default: |
65 | llvm_unreachable("LLVMGenericValueToFloat supports only float and double." ); |
66 | } |
67 | return wrap(P: GenVal); |
68 | } |
69 | |
70 | unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) { |
71 | return unwrap(P: GenValRef)->IntVal.getBitWidth(); |
72 | } |
73 | |
74 | unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef, |
75 | LLVMBool IsSigned) { |
76 | GenericValue *GenVal = unwrap(P: GenValRef); |
77 | if (IsSigned) |
78 | return GenVal->IntVal.getSExtValue(); |
79 | else |
80 | return GenVal->IntVal.getZExtValue(); |
81 | } |
82 | |
83 | void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) { |
84 | return unwrap(P: GenVal)->PointerVal; |
85 | } |
86 | |
87 | double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) { |
88 | switch (unwrap(P: TyRef)->getTypeID()) { |
89 | case Type::FloatTyID: |
90 | return unwrap(P: GenVal)->FloatVal; |
91 | case Type::DoubleTyID: |
92 | return unwrap(P: GenVal)->DoubleVal; |
93 | default: |
94 | llvm_unreachable("LLVMGenericValueToFloat supports only float and double." ); |
95 | } |
96 | } |
97 | |
98 | void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) { |
99 | delete unwrap(P: GenVal); |
100 | } |
101 | |
102 | /*===-- Operations on execution engines -----------------------------------===*/ |
103 | |
104 | LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE, |
105 | LLVMModuleRef M, |
106 | char **OutError) { |
107 | std::string Error; |
108 | EngineBuilder builder(std::unique_ptr<Module>(unwrap(P: M))); |
109 | builder.setEngineKind(EngineKind::Either) |
110 | .setErrorStr(&Error); |
111 | if (ExecutionEngine *EE = builder.create()){ |
112 | *OutEE = wrap(P: EE); |
113 | return 0; |
114 | } |
115 | *OutError = strdup(s: Error.c_str()); |
116 | return 1; |
117 | } |
118 | |
119 | LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, |
120 | LLVMModuleRef M, |
121 | char **OutError) { |
122 | std::string Error; |
123 | EngineBuilder builder(std::unique_ptr<Module>(unwrap(P: M))); |
124 | builder.setEngineKind(EngineKind::Interpreter) |
125 | .setErrorStr(&Error); |
126 | if (ExecutionEngine *Interp = builder.create()) { |
127 | *OutInterp = wrap(P: Interp); |
128 | return 0; |
129 | } |
130 | *OutError = strdup(s: Error.c_str()); |
131 | return 1; |
132 | } |
133 | |
134 | LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, |
135 | LLVMModuleRef M, |
136 | unsigned OptLevel, |
137 | char **OutError) { |
138 | std::string Error; |
139 | EngineBuilder builder(std::unique_ptr<Module>(unwrap(P: M))); |
140 | builder.setEngineKind(EngineKind::JIT) |
141 | .setErrorStr(&Error) |
142 | .setOptLevel((CodeGenOptLevel)OptLevel); |
143 | if (ExecutionEngine *JIT = builder.create()) { |
144 | *OutJIT = wrap(P: JIT); |
145 | return 0; |
146 | } |
147 | *OutError = strdup(s: Error.c_str()); |
148 | return 1; |
149 | } |
150 | |
151 | void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions, |
152 | size_t SizeOfPassedOptions) { |
153 | LLVMMCJITCompilerOptions options; |
154 | memset(s: &options, c: 0, n: sizeof(options)); // Most fields are zero by default. |
155 | options.CodeModel = LLVMCodeModelJITDefault; |
156 | |
157 | memcpy(dest: PassedOptions, src: &options, |
158 | n: std::min(a: sizeof(options), b: SizeOfPassedOptions)); |
159 | } |
160 | |
161 | LLVMBool LLVMCreateMCJITCompilerForModule( |
162 | LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, |
163 | LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions, |
164 | char **OutError) { |
165 | LLVMMCJITCompilerOptions options; |
166 | // If the user passed a larger sized options struct, then they were compiled |
167 | // against a newer LLVM. Tell them that something is wrong. |
168 | if (SizeOfPassedOptions > sizeof(options)) { |
169 | *OutError = strdup( |
170 | s: "Refusing to use options struct that is larger than my own; assuming " |
171 | "LLVM library mismatch." ); |
172 | return 1; |
173 | } |
174 | |
175 | // Defend against the user having an old version of the API by ensuring that |
176 | // any fields they didn't see are cleared. We must defend against fields being |
177 | // set to the bitwise equivalent of zero, and assume that this means "do the |
178 | // default" as if that option hadn't been available. |
179 | LLVMInitializeMCJITCompilerOptions(PassedOptions: &options, SizeOfPassedOptions: sizeof(options)); |
180 | memcpy(dest: &options, src: PassedOptions, n: SizeOfPassedOptions); |
181 | |
182 | TargetOptions targetOptions; |
183 | targetOptions.EnableFastISel = options.EnableFastISel; |
184 | std::unique_ptr<Module> Mod(unwrap(P: M)); |
185 | |
186 | if (Mod) |
187 | // Set function attribute "frame-pointer" based on |
188 | // NoFramePointerElim. |
189 | for (auto &F : *Mod) { |
190 | auto Attrs = F.getAttributes(); |
191 | StringRef Value = options.NoFramePointerElim ? "all" : "none" ; |
192 | Attrs = Attrs.addFnAttribute(C&: F.getContext(), Kind: "frame-pointer" , Value); |
193 | F.setAttributes(Attrs); |
194 | } |
195 | |
196 | std::string Error; |
197 | EngineBuilder builder(std::move(Mod)); |
198 | builder.setEngineKind(EngineKind::JIT) |
199 | .setErrorStr(&Error) |
200 | .setOptLevel((CodeGenOptLevel)options.OptLevel) |
201 | .setTargetOptions(targetOptions); |
202 | bool JIT; |
203 | if (std::optional<CodeModel::Model> CM = unwrap(Model: options.CodeModel, JIT)) |
204 | builder.setCodeModel(*CM); |
205 | if (options.MCJMM) |
206 | builder.setMCJITMemoryManager( |
207 | std::unique_ptr<RTDyldMemoryManager>(unwrap(P: options.MCJMM))); |
208 | if (ExecutionEngine *JIT = builder.create()) { |
209 | *OutJIT = wrap(P: JIT); |
210 | return 0; |
211 | } |
212 | *OutError = strdup(s: Error.c_str()); |
213 | return 1; |
214 | } |
215 | |
216 | void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) { |
217 | delete unwrap(P: EE); |
218 | } |
219 | |
220 | void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) { |
221 | unwrap(P: EE)->finalizeObject(); |
222 | unwrap(P: EE)->runStaticConstructorsDestructors(isDtors: false); |
223 | } |
224 | |
225 | void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) { |
226 | unwrap(P: EE)->finalizeObject(); |
227 | unwrap(P: EE)->runStaticConstructorsDestructors(isDtors: true); |
228 | } |
229 | |
230 | int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F, |
231 | unsigned ArgC, const char * const *ArgV, |
232 | const char * const *EnvP) { |
233 | unwrap(P: EE)->finalizeObject(); |
234 | |
235 | std::vector<std::string> ArgVec(ArgV, ArgV + ArgC); |
236 | return unwrap(P: EE)->runFunctionAsMain(Fn: unwrap<Function>(P: F), argv: ArgVec, envp: EnvP); |
237 | } |
238 | |
239 | LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F, |
240 | unsigned NumArgs, |
241 | LLVMGenericValueRef *Args) { |
242 | unwrap(P: EE)->finalizeObject(); |
243 | |
244 | std::vector<GenericValue> ArgVec; |
245 | ArgVec.reserve(n: NumArgs); |
246 | for (unsigned I = 0; I != NumArgs; ++I) |
247 | ArgVec.push_back(x: *unwrap(P: Args[I])); |
248 | |
249 | GenericValue *Result = new GenericValue(); |
250 | *Result = unwrap(P: EE)->runFunction(F: unwrap<Function>(P: F), ArgValues: ArgVec); |
251 | return wrap(P: Result); |
252 | } |
253 | |
254 | void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) { |
255 | } |
256 | |
257 | void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){ |
258 | unwrap(P: EE)->addModule(M: std::unique_ptr<Module>(unwrap(P: M))); |
259 | } |
260 | |
261 | LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M, |
262 | LLVMModuleRef *OutMod, char **OutError) { |
263 | Module *Mod = unwrap(P: M); |
264 | unwrap(P: EE)->removeModule(M: Mod); |
265 | *OutMod = wrap(P: Mod); |
266 | return 0; |
267 | } |
268 | |
269 | LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, |
270 | LLVMValueRef *OutFn) { |
271 | if (Function *F = unwrap(P: EE)->FindFunctionNamed(FnName: Name)) { |
272 | *OutFn = wrap(P: F); |
273 | return 0; |
274 | } |
275 | return 1; |
276 | } |
277 | |
278 | void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, |
279 | LLVMValueRef Fn) { |
280 | return nullptr; |
281 | } |
282 | |
283 | LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) { |
284 | return wrap(P: &unwrap(P: EE)->getDataLayout()); |
285 | } |
286 | |
287 | LLVMTargetMachineRef |
288 | LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) { |
289 | return wrap(P: unwrap(P: EE)->getTargetMachine()); |
290 | } |
291 | |
292 | void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, |
293 | void* Addr) { |
294 | unwrap(P: EE)->addGlobalMapping(GV: unwrap<GlobalValue>(P: Global), Addr); |
295 | } |
296 | |
297 | void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) { |
298 | unwrap(P: EE)->finalizeObject(); |
299 | |
300 | return unwrap(P: EE)->getPointerToGlobal(GV: unwrap<GlobalValue>(P: Global)); |
301 | } |
302 | |
303 | uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) { |
304 | return unwrap(P: EE)->getGlobalValueAddress(Name); |
305 | } |
306 | |
307 | uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) { |
308 | return unwrap(P: EE)->getFunctionAddress(Name); |
309 | } |
310 | |
311 | LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE, |
312 | char **OutError) { |
313 | assert(OutError && "OutError must be non-null" ); |
314 | auto *ExecEngine = unwrap(P: EE); |
315 | if (ExecEngine->hasError()) { |
316 | *OutError = strdup(s: ExecEngine->getErrorMessage().c_str()); |
317 | ExecEngine->clearErrorMessage(); |
318 | return true; |
319 | } |
320 | return false; |
321 | } |
322 | |
323 | /*===-- Operations on memory managers -------------------------------------===*/ |
324 | |
325 | namespace { |
326 | |
327 | struct SimpleBindingMMFunctions { |
328 | LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection; |
329 | LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection; |
330 | LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory; |
331 | LLVMMemoryManagerDestroyCallback Destroy; |
332 | }; |
333 | |
334 | class SimpleBindingMemoryManager : public RTDyldMemoryManager { |
335 | public: |
336 | SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions, |
337 | void *Opaque); |
338 | ~SimpleBindingMemoryManager() override; |
339 | |
340 | uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, |
341 | unsigned SectionID, |
342 | StringRef SectionName) override; |
343 | |
344 | uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, |
345 | unsigned SectionID, StringRef SectionName, |
346 | bool isReadOnly) override; |
347 | |
348 | bool finalizeMemory(std::string *ErrMsg) override; |
349 | |
350 | private: |
351 | SimpleBindingMMFunctions Functions; |
352 | void *Opaque; |
353 | }; |
354 | |
355 | SimpleBindingMemoryManager::SimpleBindingMemoryManager( |
356 | const SimpleBindingMMFunctions& Functions, |
357 | void *Opaque) |
358 | : Functions(Functions), Opaque(Opaque) { |
359 | assert(Functions.AllocateCodeSection && |
360 | "No AllocateCodeSection function provided!" ); |
361 | assert(Functions.AllocateDataSection && |
362 | "No AllocateDataSection function provided!" ); |
363 | assert(Functions.FinalizeMemory && |
364 | "No FinalizeMemory function provided!" ); |
365 | assert(Functions.Destroy && |
366 | "No Destroy function provided!" ); |
367 | } |
368 | |
369 | SimpleBindingMemoryManager::~SimpleBindingMemoryManager() { |
370 | Functions.Destroy(Opaque); |
371 | } |
372 | |
373 | uint8_t *SimpleBindingMemoryManager::allocateCodeSection( |
374 | uintptr_t Size, unsigned Alignment, unsigned SectionID, |
375 | StringRef SectionName) { |
376 | return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID, |
377 | SectionName.str().c_str()); |
378 | } |
379 | |
380 | uint8_t *SimpleBindingMemoryManager::allocateDataSection( |
381 | uintptr_t Size, unsigned Alignment, unsigned SectionID, |
382 | StringRef SectionName, bool isReadOnly) { |
383 | return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID, |
384 | SectionName.str().c_str(), |
385 | isReadOnly); |
386 | } |
387 | |
388 | bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) { |
389 | char *errMsgCString = nullptr; |
390 | bool result = Functions.FinalizeMemory(Opaque, &errMsgCString); |
391 | assert((result || !errMsgCString) && |
392 | "Did not expect an error message if FinalizeMemory succeeded" ); |
393 | if (errMsgCString) { |
394 | if (ErrMsg) |
395 | *ErrMsg = errMsgCString; |
396 | free(ptr: errMsgCString); |
397 | } |
398 | return result; |
399 | } |
400 | |
401 | } // anonymous namespace |
402 | |
403 | LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager( |
404 | void *Opaque, |
405 | LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, |
406 | LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, |
407 | LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, |
408 | LLVMMemoryManagerDestroyCallback Destroy) { |
409 | |
410 | if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory || |
411 | !Destroy) |
412 | return nullptr; |
413 | |
414 | SimpleBindingMMFunctions functions; |
415 | functions.AllocateCodeSection = AllocateCodeSection; |
416 | functions.AllocateDataSection = AllocateDataSection; |
417 | functions.FinalizeMemory = FinalizeMemory; |
418 | functions.Destroy = Destroy; |
419 | return wrap(P: new SimpleBindingMemoryManager(functions, Opaque)); |
420 | } |
421 | |
422 | void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) { |
423 | delete unwrap(P: MM); |
424 | } |
425 | |
426 | /*===-- JIT Event Listener functions -------------------------------------===*/ |
427 | |
428 | |
429 | #if !LLVM_USE_INTEL_JITEVENTS |
430 | LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void) |
431 | { |
432 | return nullptr; |
433 | } |
434 | #endif |
435 | |
436 | #if !LLVM_USE_OPROFILE |
437 | LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void) |
438 | { |
439 | return nullptr; |
440 | } |
441 | #endif |
442 | |
443 | #if !LLVM_USE_PERF |
444 | LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void) |
445 | { |
446 | return nullptr; |
447 | } |
448 | #endif |
449 | |