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