xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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.
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 
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 
48 LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
49   GenericValue *GenVal = new GenericValue();
50   GenVal->PointerVal = P;
51   return wrap(GenVal);
52 }
53 
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 
69 unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
70   return unwrap(GenValRef)->IntVal.getBitWidth();
71 }
72 
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 
82 void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
83   return unwrap(GenVal)->PointerVal;
84 }
85 
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 
97 void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
98   delete unwrap(GenVal);
99 }
100 
101 /*===-- Operations on execution engines -----------------------------------===*/
102 
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 
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 
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 
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 
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.addFnAttribute(F.getContext(), "frame-pointer", Value);
192       F.setAttributes(Attrs);
193     }
194 
195   std::string Error;
196   EngineBuilder builder(std::move(Mod));
197   builder.setEngineKind(EngineKind::JIT)
198          .setErrorStr(&Error)
199          .setOptLevel((CodeGenOpt::Level)options.OptLevel)
200          .setTargetOptions(targetOptions);
201   bool JIT;
202   if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
203     builder.setCodeModel(*CM);
204   if (options.MCJMM)
205     builder.setMCJITMemoryManager(
206       std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
207   if (ExecutionEngine *JIT = builder.create()) {
208     *OutJIT = wrap(JIT);
209     return 0;
210   }
211   *OutError = strdup(Error.c_str());
212   return 1;
213 }
214 
215 void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
216   delete unwrap(EE);
217 }
218 
219 void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
220   unwrap(EE)->finalizeObject();
221   unwrap(EE)->runStaticConstructorsDestructors(false);
222 }
223 
224 void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
225   unwrap(EE)->finalizeObject();
226   unwrap(EE)->runStaticConstructorsDestructors(true);
227 }
228 
229 int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
230                           unsigned ArgC, const char * const *ArgV,
231                           const char * const *EnvP) {
232   unwrap(EE)->finalizeObject();
233 
234   std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
235   return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
236 }
237 
238 LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
239                                     unsigned NumArgs,
240                                     LLVMGenericValueRef *Args) {
241   unwrap(EE)->finalizeObject();
242 
243   std::vector<GenericValue> ArgVec;
244   ArgVec.reserve(NumArgs);
245   for (unsigned I = 0; I != NumArgs; ++I)
246     ArgVec.push_back(*unwrap(Args[I]));
247 
248   GenericValue *Result = new GenericValue();
249   *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
250   return wrap(Result);
251 }
252 
253 void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
254 }
255 
256 void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
257   unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
258 }
259 
260 LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
261                           LLVMModuleRef *OutMod, char **OutError) {
262   Module *Mod = unwrap(M);
263   unwrap(EE)->removeModule(Mod);
264   *OutMod = wrap(Mod);
265   return 0;
266 }
267 
268 LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
269                           LLVMValueRef *OutFn) {
270   if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
271     *OutFn = wrap(F);
272     return 0;
273   }
274   return 1;
275 }
276 
277 void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
278                                      LLVMValueRef Fn) {
279   return nullptr;
280 }
281 
282 LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
283   return wrap(&unwrap(EE)->getDataLayout());
284 }
285 
286 LLVMTargetMachineRef
287 LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
288   return wrap(unwrap(EE)->getTargetMachine());
289 }
290 
291 void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
292                           void* Addr) {
293   unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
294 }
295 
296 void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
297   unwrap(EE)->finalizeObject();
298 
299   return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
300 }
301 
302 uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
303   return unwrap(EE)->getGlobalValueAddress(Name);
304 }
305 
306 uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
307   return unwrap(EE)->getFunctionAddress(Name);
308 }
309 
310 LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
311                                       char **OutError) {
312   assert(OutError && "OutError must be non-null");
313   auto *ExecEngine = unwrap(EE);
314   if (ExecEngine->hasError()) {
315     *OutError = strdup(ExecEngine->getErrorMessage().c_str());
316     ExecEngine->clearErrorMessage();
317     return true;
318   }
319   return false;
320 }
321 
322 /*===-- Operations on memory managers -------------------------------------===*/
323 
324 namespace {
325 
326 struct SimpleBindingMMFunctions {
327   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
328   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
329   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
330   LLVMMemoryManagerDestroyCallback Destroy;
331 };
332 
333 class SimpleBindingMemoryManager : public RTDyldMemoryManager {
334 public:
335   SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
336                              void *Opaque);
337   ~SimpleBindingMemoryManager() override;
338 
339   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
340                                unsigned SectionID,
341                                StringRef SectionName) override;
342 
343   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
344                                unsigned SectionID, StringRef SectionName,
345                                bool isReadOnly) override;
346 
347   bool finalizeMemory(std::string *ErrMsg) override;
348 
349 private:
350   SimpleBindingMMFunctions Functions;
351   void *Opaque;
352 };
353 
354 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
355   const SimpleBindingMMFunctions& Functions,
356   void *Opaque)
357   : Functions(Functions), Opaque(Opaque) {
358   assert(Functions.AllocateCodeSection &&
359          "No AllocateCodeSection function provided!");
360   assert(Functions.AllocateDataSection &&
361          "No AllocateDataSection function provided!");
362   assert(Functions.FinalizeMemory &&
363          "No FinalizeMemory function provided!");
364   assert(Functions.Destroy &&
365          "No Destroy function provided!");
366 }
367 
368 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
369   Functions.Destroy(Opaque);
370 }
371 
372 uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
373   uintptr_t Size, unsigned Alignment, unsigned SectionID,
374   StringRef SectionName) {
375   return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
376                                        SectionName.str().c_str());
377 }
378 
379 uint8_t *SimpleBindingMemoryManager::allocateDataSection(
380   uintptr_t Size, unsigned Alignment, unsigned SectionID,
381   StringRef SectionName, bool isReadOnly) {
382   return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
383                                        SectionName.str().c_str(),
384                                        isReadOnly);
385 }
386 
387 bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
388   char *errMsgCString = nullptr;
389   bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
390   assert((result || !errMsgCString) &&
391          "Did not expect an error message if FinalizeMemory succeeded");
392   if (errMsgCString) {
393     if (ErrMsg)
394       *ErrMsg = errMsgCString;
395     free(errMsgCString);
396   }
397   return result;
398 }
399 
400 } // anonymous namespace
401 
402 LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
403   void *Opaque,
404   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
405   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
406   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
407   LLVMMemoryManagerDestroyCallback Destroy) {
408 
409   if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
410       !Destroy)
411     return nullptr;
412 
413   SimpleBindingMMFunctions functions;
414   functions.AllocateCodeSection = AllocateCodeSection;
415   functions.AllocateDataSection = AllocateDataSection;
416   functions.FinalizeMemory = FinalizeMemory;
417   functions.Destroy = Destroy;
418   return wrap(new SimpleBindingMemoryManager(functions, Opaque));
419 }
420 
421 void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
422   delete unwrap(MM);
423 }
424 
425 /*===-- JIT Event Listener functions -------------------------------------===*/
426 
427 
428 #if !LLVM_USE_INTEL_JITEVENTS
429 LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
430 {
431   return nullptr;
432 }
433 #endif
434 
435 #if !LLVM_USE_OPROFILE
436 LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
437 {
438   return nullptr;
439 }
440 #endif
441 
442 #if !LLVM_USE_PERF
443 LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
444 {
445   return nullptr;
446 }
447 #endif
448