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
25using namespace llvm;
26
27#define DEBUG_TYPE "jit"
28
29// Wrapping the C bindings types.
30DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
31
32
33static LLVMTargetMachineRef wrap(const TargetMachine *P) {
34  return
35  reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
36}
37
38/*===-- Operations on generic values --------------------------------------===*/
39
40LLVMGenericValueRef 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
48LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
49  GenericValue *GenVal = new GenericValue();
50  GenVal->PointerVal = P;
51  return wrap(GenVal);
52}
53
54LLVMGenericValueRef 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
69unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
70  return unwrap(GenValRef)->IntVal.getBitWidth();
71}
72
73unsigned 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
82void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
83  return unwrap(GenVal)->PointerVal;
84}
85
86double 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
97void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
98  delete unwrap(GenVal);
99}
100
101/*===-- Operations on execution engines -----------------------------------===*/
102
103LLVMBool 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
118LLVMBool 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
133LLVMBool 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
150void 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
160LLVMBool 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
216void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
217  delete unwrap(EE);
218}
219
220void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
221  unwrap(EE)->finalizeObject();
222  unwrap(EE)->runStaticConstructorsDestructors(false);
223}
224
225void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
226  unwrap(EE)->finalizeObject();
227  unwrap(EE)->runStaticConstructorsDestructors(true);
228}
229
230int 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
239LLVMGenericValueRef 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
254void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
255}
256
257void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
258  unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
259}
260
261LLVMBool 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
269LLVMBool 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
278void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
279                                     LLVMValueRef Fn) {
280  return nullptr;
281}
282
283LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
284  return wrap(&unwrap(EE)->getDataLayout());
285}
286
287LLVMTargetMachineRef
288LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
289  return wrap(unwrap(EE)->getTargetMachine());
290}
291
292void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
293                          void* Addr) {
294  unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
295}
296
297void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
298  unwrap(EE)->finalizeObject();
299
300  return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
301}
302
303uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
304  return unwrap(EE)->getGlobalValueAddress(Name);
305}
306
307uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
308  return unwrap(EE)->getFunctionAddress(Name);
309}
310
311/*===-- Operations on memory managers -------------------------------------===*/
312
313namespace {
314
315struct SimpleBindingMMFunctions {
316  LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
317  LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
318  LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
319  LLVMMemoryManagerDestroyCallback Destroy;
320};
321
322class SimpleBindingMemoryManager : public RTDyldMemoryManager {
323public:
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
338private:
339  SimpleBindingMMFunctions Functions;
340  void *Opaque;
341};
342
343SimpleBindingMemoryManager::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
357SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
358  Functions.Destroy(Opaque);
359}
360
361uint8_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
368uint8_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
376bool 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
391LLVMMCJITMemoryManagerRef 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
410void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
411  delete unwrap(MM);
412}
413
414/*===-- JIT Event Listener functions -------------------------------------===*/
415
416
417#if !LLVM_USE_INTEL_JITEVENTS
418LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
419{
420  return nullptr;
421}
422#endif
423
424#if !LLVM_USE_OPROFILE
425LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
426{
427  return nullptr;
428}
429#endif
430
431#if !LLVM_USE_PERF
432LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
433{
434  return nullptr;
435}
436#endif
437