xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp (revision 84e404763fa5a7e00105ff86e6caff5aebe0e55e)
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 "no-frame-pointer-elim" based on
187      // NoFramePointerElim.
188      for (auto &F : *Mod) {
189        auto Attrs = F.getAttributes();
190        StringRef Value(options.NoFramePointerElim ? "true" : "false");
191        Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
192                                   "no-frame-pointer-elim", 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  
216  void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
217    delete unwrap(EE);
218  }
219  
220  void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
221    unwrap(EE)->finalizeObject();
222    unwrap(EE)->runStaticConstructorsDestructors(false);
223  }
224  
225  void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
226    unwrap(EE)->finalizeObject();
227    unwrap(EE)->runStaticConstructorsDestructors(true);
228  }
229  
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  
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  
254  void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
255  }
256  
257  void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
258    unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
259  }
260  
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  
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  
278  void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
279                                       LLVMValueRef Fn) {
280    return nullptr;
281  }
282  
283  LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
284    return wrap(&unwrap(EE)->getDataLayout());
285  }
286  
287  LLVMTargetMachineRef
288  LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
289    return wrap(unwrap(EE)->getTargetMachine());
290  }
291  
292  void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
293                            void* Addr) {
294    unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
295  }
296  
297  void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
298    unwrap(EE)->finalizeObject();
299  
300    return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
301  }
302  
303  uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
304    return unwrap(EE)->getGlobalValueAddress(Name);
305  }
306  
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  
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  
357  SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
358    Functions.Destroy(Opaque);
359  }
360  
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  
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  
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  
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  
410  void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
411    delete unwrap(MM);
412  }
413  
414  /*===-- JIT Event Listener functions -------------------------------------===*/
415  
416  
417  #if !LLVM_USE_INTEL_JITEVENTS
418  LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
419  {
420    return nullptr;
421  }
422  #endif
423  
424  #if !LLVM_USE_OPROFILE
425  LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
426  {
427    return nullptr;
428  }
429  #endif
430  
431  #if !LLVM_USE_PERF
432  LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
433  {
434    return nullptr;
435  }
436  #endif
437