xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the C bindings for the ExecutionEngine library.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm-c/ExecutionEngine.h"
140b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h"
150b57cec5SDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h"
160b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITEventListener.h"
170b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
180b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
190b57cec5SDimitry Andric #include "llvm/IR/Module.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include "llvm/Target/CodeGenCWrappers.h"
220b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
230b57cec5SDimitry Andric #include <cstring>
24bdd1243dSDimitry Andric #include <optional>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "jit"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric // Wrapping the C bindings types.
310b57cec5SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric static LLVMTargetMachineRef wrap(const TargetMachine *P) {
350b57cec5SDimitry Andric   return
360b57cec5SDimitry Andric   reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric /*===-- Operations on generic values --------------------------------------===*/
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
420b57cec5SDimitry Andric                                                 unsigned long long N,
430b57cec5SDimitry Andric                                                 LLVMBool IsSigned) {
440b57cec5SDimitry Andric   GenericValue *GenVal = new GenericValue();
450b57cec5SDimitry Andric   GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
460b57cec5SDimitry Andric   return wrap(GenVal);
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
500b57cec5SDimitry Andric   GenericValue *GenVal = new GenericValue();
510b57cec5SDimitry Andric   GenVal->PointerVal = P;
520b57cec5SDimitry Andric   return wrap(GenVal);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
560b57cec5SDimitry Andric   GenericValue *GenVal = new GenericValue();
570b57cec5SDimitry Andric   switch (unwrap(TyRef)->getTypeID()) {
580b57cec5SDimitry Andric   case Type::FloatTyID:
590b57cec5SDimitry Andric     GenVal->FloatVal = N;
600b57cec5SDimitry Andric     break;
610b57cec5SDimitry Andric   case Type::DoubleTyID:
620b57cec5SDimitry Andric     GenVal->DoubleVal = N;
630b57cec5SDimitry Andric     break;
640b57cec5SDimitry Andric   default:
650b57cec5SDimitry Andric     llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
660b57cec5SDimitry Andric   }
670b57cec5SDimitry Andric   return wrap(GenVal);
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
710b57cec5SDimitry Andric   return unwrap(GenValRef)->IntVal.getBitWidth();
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
750b57cec5SDimitry Andric                                          LLVMBool IsSigned) {
760b57cec5SDimitry Andric   GenericValue *GenVal = unwrap(GenValRef);
770b57cec5SDimitry Andric   if (IsSigned)
780b57cec5SDimitry Andric     return GenVal->IntVal.getSExtValue();
790b57cec5SDimitry Andric   else
800b57cec5SDimitry Andric     return GenVal->IntVal.getZExtValue();
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
840b57cec5SDimitry Andric   return unwrap(GenVal)->PointerVal;
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
880b57cec5SDimitry Andric   switch (unwrap(TyRef)->getTypeID()) {
890b57cec5SDimitry Andric   case Type::FloatTyID:
900b57cec5SDimitry Andric     return unwrap(GenVal)->FloatVal;
910b57cec5SDimitry Andric   case Type::DoubleTyID:
920b57cec5SDimitry Andric     return unwrap(GenVal)->DoubleVal;
930b57cec5SDimitry Andric   default:
940b57cec5SDimitry Andric     llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
990b57cec5SDimitry Andric   delete unwrap(GenVal);
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric /*===-- Operations on execution engines -----------------------------------===*/
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
1050b57cec5SDimitry Andric                                             LLVMModuleRef M,
1060b57cec5SDimitry Andric                                             char **OutError) {
1070b57cec5SDimitry Andric   std::string Error;
1080b57cec5SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
1090b57cec5SDimitry Andric   builder.setEngineKind(EngineKind::Either)
1100b57cec5SDimitry Andric          .setErrorStr(&Error);
1110b57cec5SDimitry Andric   if (ExecutionEngine *EE = builder.create()){
1120b57cec5SDimitry Andric     *OutEE = wrap(EE);
1130b57cec5SDimitry Andric     return 0;
1140b57cec5SDimitry Andric   }
1150b57cec5SDimitry Andric   *OutError = strdup(Error.c_str());
1160b57cec5SDimitry Andric   return 1;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
1200b57cec5SDimitry Andric                                         LLVMModuleRef M,
1210b57cec5SDimitry Andric                                         char **OutError) {
1220b57cec5SDimitry Andric   std::string Error;
1230b57cec5SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
1240b57cec5SDimitry Andric   builder.setEngineKind(EngineKind::Interpreter)
1250b57cec5SDimitry Andric          .setErrorStr(&Error);
1260b57cec5SDimitry Andric   if (ExecutionEngine *Interp = builder.create()) {
1270b57cec5SDimitry Andric     *OutInterp = wrap(Interp);
1280b57cec5SDimitry Andric     return 0;
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric   *OutError = strdup(Error.c_str());
1310b57cec5SDimitry Andric   return 1;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
1350b57cec5SDimitry Andric                                         LLVMModuleRef M,
1360b57cec5SDimitry Andric                                         unsigned OptLevel,
1370b57cec5SDimitry Andric                                         char **OutError) {
1380b57cec5SDimitry Andric   std::string Error;
1390b57cec5SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
1400b57cec5SDimitry Andric   builder.setEngineKind(EngineKind::JIT)
1410b57cec5SDimitry Andric       .setErrorStr(&Error)
142*5f757f3fSDimitry Andric       .setOptLevel((CodeGenOptLevel)OptLevel);
1430b57cec5SDimitry Andric   if (ExecutionEngine *JIT = builder.create()) {
1440b57cec5SDimitry Andric     *OutJIT = wrap(JIT);
1450b57cec5SDimitry Andric     return 0;
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric   *OutError = strdup(Error.c_str());
1480b57cec5SDimitry Andric   return 1;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
1520b57cec5SDimitry Andric                                         size_t SizeOfPassedOptions) {
1530b57cec5SDimitry Andric   LLVMMCJITCompilerOptions options;
1540b57cec5SDimitry Andric   memset(&options, 0, sizeof(options)); // Most fields are zero by default.
1550b57cec5SDimitry Andric   options.CodeModel = LLVMCodeModelJITDefault;
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   memcpy(PassedOptions, &options,
1580b57cec5SDimitry Andric          std::min(sizeof(options), SizeOfPassedOptions));
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric LLVMBool LLVMCreateMCJITCompilerForModule(
1620b57cec5SDimitry Andric     LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
1630b57cec5SDimitry Andric     LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
1640b57cec5SDimitry Andric     char **OutError) {
1650b57cec5SDimitry Andric   LLVMMCJITCompilerOptions options;
1660b57cec5SDimitry Andric   // If the user passed a larger sized options struct, then they were compiled
1670b57cec5SDimitry Andric   // against a newer LLVM. Tell them that something is wrong.
1680b57cec5SDimitry Andric   if (SizeOfPassedOptions > sizeof(options)) {
1690b57cec5SDimitry Andric     *OutError = strdup(
1700b57cec5SDimitry Andric       "Refusing to use options struct that is larger than my own; assuming "
1710b57cec5SDimitry Andric       "LLVM library mismatch.");
1720b57cec5SDimitry Andric     return 1;
1730b57cec5SDimitry Andric   }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   // Defend against the user having an old version of the API by ensuring that
1760b57cec5SDimitry Andric   // any fields they didn't see are cleared. We must defend against fields being
1770b57cec5SDimitry Andric   // set to the bitwise equivalent of zero, and assume that this means "do the
1780b57cec5SDimitry Andric   // default" as if that option hadn't been available.
1790b57cec5SDimitry Andric   LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
1800b57cec5SDimitry Andric   memcpy(&options, PassedOptions, SizeOfPassedOptions);
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   TargetOptions targetOptions;
1830b57cec5SDimitry Andric   targetOptions.EnableFastISel = options.EnableFastISel;
1840b57cec5SDimitry Andric   std::unique_ptr<Module> Mod(unwrap(M));
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   if (Mod)
187480093f4SDimitry Andric     // Set function attribute "frame-pointer" based on
1880b57cec5SDimitry Andric     // NoFramePointerElim.
1890b57cec5SDimitry Andric     for (auto &F : *Mod) {
1900b57cec5SDimitry Andric       auto Attrs = F.getAttributes();
191480093f4SDimitry Andric       StringRef Value = options.NoFramePointerElim ? "all" : "none";
192349cc55cSDimitry Andric       Attrs = Attrs.addFnAttribute(F.getContext(), "frame-pointer", Value);
1930b57cec5SDimitry Andric       F.setAttributes(Attrs);
1940b57cec5SDimitry Andric     }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   std::string Error;
1970b57cec5SDimitry Andric   EngineBuilder builder(std::move(Mod));
1980b57cec5SDimitry Andric   builder.setEngineKind(EngineKind::JIT)
1990b57cec5SDimitry Andric       .setErrorStr(&Error)
200*5f757f3fSDimitry Andric       .setOptLevel((CodeGenOptLevel)options.OptLevel)
2010b57cec5SDimitry Andric       .setTargetOptions(targetOptions);
2020b57cec5SDimitry Andric   bool JIT;
203bdd1243dSDimitry Andric   if (std::optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
2040b57cec5SDimitry Andric     builder.setCodeModel(*CM);
2050b57cec5SDimitry Andric   if (options.MCJMM)
2060b57cec5SDimitry Andric     builder.setMCJITMemoryManager(
2070b57cec5SDimitry Andric       std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
2080b57cec5SDimitry Andric   if (ExecutionEngine *JIT = builder.create()) {
2090b57cec5SDimitry Andric     *OutJIT = wrap(JIT);
2100b57cec5SDimitry Andric     return 0;
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric   *OutError = strdup(Error.c_str());
2130b57cec5SDimitry Andric   return 1;
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
2170b57cec5SDimitry Andric   delete unwrap(EE);
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
2210b57cec5SDimitry Andric   unwrap(EE)->finalizeObject();
2220b57cec5SDimitry Andric   unwrap(EE)->runStaticConstructorsDestructors(false);
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
2260b57cec5SDimitry Andric   unwrap(EE)->finalizeObject();
2270b57cec5SDimitry Andric   unwrap(EE)->runStaticConstructorsDestructors(true);
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
2310b57cec5SDimitry Andric                           unsigned ArgC, const char * const *ArgV,
2320b57cec5SDimitry Andric                           const char * const *EnvP) {
2330b57cec5SDimitry Andric   unwrap(EE)->finalizeObject();
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
2360b57cec5SDimitry Andric   return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
2400b57cec5SDimitry Andric                                     unsigned NumArgs,
2410b57cec5SDimitry Andric                                     LLVMGenericValueRef *Args) {
2420b57cec5SDimitry Andric   unwrap(EE)->finalizeObject();
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   std::vector<GenericValue> ArgVec;
2450b57cec5SDimitry Andric   ArgVec.reserve(NumArgs);
2460b57cec5SDimitry Andric   for (unsigned I = 0; I != NumArgs; ++I)
2470b57cec5SDimitry Andric     ArgVec.push_back(*unwrap(Args[I]));
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   GenericValue *Result = new GenericValue();
2500b57cec5SDimitry Andric   *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
2510b57cec5SDimitry Andric   return wrap(Result);
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
2580b57cec5SDimitry Andric   unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
2620b57cec5SDimitry Andric                           LLVMModuleRef *OutMod, char **OutError) {
2630b57cec5SDimitry Andric   Module *Mod = unwrap(M);
2640b57cec5SDimitry Andric   unwrap(EE)->removeModule(Mod);
2650b57cec5SDimitry Andric   *OutMod = wrap(Mod);
2660b57cec5SDimitry Andric   return 0;
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
2700b57cec5SDimitry Andric                           LLVMValueRef *OutFn) {
2710b57cec5SDimitry Andric   if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
2720b57cec5SDimitry Andric     *OutFn = wrap(F);
2730b57cec5SDimitry Andric     return 0;
2740b57cec5SDimitry Andric   }
2750b57cec5SDimitry Andric   return 1;
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
2790b57cec5SDimitry Andric                                      LLVMValueRef Fn) {
2800b57cec5SDimitry Andric   return nullptr;
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
2840b57cec5SDimitry Andric   return wrap(&unwrap(EE)->getDataLayout());
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric LLVMTargetMachineRef
2880b57cec5SDimitry Andric LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
2890b57cec5SDimitry Andric   return wrap(unwrap(EE)->getTargetMachine());
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
2930b57cec5SDimitry Andric                           void* Addr) {
2940b57cec5SDimitry Andric   unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
2980b57cec5SDimitry Andric   unwrap(EE)->finalizeObject();
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
3040b57cec5SDimitry Andric   return unwrap(EE)->getGlobalValueAddress(Name);
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
3080b57cec5SDimitry Andric   return unwrap(EE)->getFunctionAddress(Name);
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3115ffd83dbSDimitry Andric LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
3125ffd83dbSDimitry Andric                                       char **OutError) {
3135ffd83dbSDimitry Andric   assert(OutError && "OutError must be non-null");
3145ffd83dbSDimitry Andric   auto *ExecEngine = unwrap(EE);
3155ffd83dbSDimitry Andric   if (ExecEngine->hasError()) {
3165ffd83dbSDimitry Andric     *OutError = strdup(ExecEngine->getErrorMessage().c_str());
3175ffd83dbSDimitry Andric     ExecEngine->clearErrorMessage();
3185ffd83dbSDimitry Andric     return true;
3195ffd83dbSDimitry Andric   }
3205ffd83dbSDimitry Andric   return false;
3215ffd83dbSDimitry Andric }
3225ffd83dbSDimitry Andric 
3230b57cec5SDimitry Andric /*===-- Operations on memory managers -------------------------------------===*/
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric namespace {
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric struct SimpleBindingMMFunctions {
3280b57cec5SDimitry Andric   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
3290b57cec5SDimitry Andric   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
3300b57cec5SDimitry Andric   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
3310b57cec5SDimitry Andric   LLVMMemoryManagerDestroyCallback Destroy;
3320b57cec5SDimitry Andric };
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric class SimpleBindingMemoryManager : public RTDyldMemoryManager {
3350b57cec5SDimitry Andric public:
3360b57cec5SDimitry Andric   SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
3370b57cec5SDimitry Andric                              void *Opaque);
3380b57cec5SDimitry Andric   ~SimpleBindingMemoryManager() override;
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
3410b57cec5SDimitry Andric                                unsigned SectionID,
3420b57cec5SDimitry Andric                                StringRef SectionName) override;
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
3450b57cec5SDimitry Andric                                unsigned SectionID, StringRef SectionName,
3460b57cec5SDimitry Andric                                bool isReadOnly) override;
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   bool finalizeMemory(std::string *ErrMsg) override;
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric private:
3510b57cec5SDimitry Andric   SimpleBindingMMFunctions Functions;
3520b57cec5SDimitry Andric   void *Opaque;
3530b57cec5SDimitry Andric };
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric SimpleBindingMemoryManager::SimpleBindingMemoryManager(
3560b57cec5SDimitry Andric   const SimpleBindingMMFunctions& Functions,
3570b57cec5SDimitry Andric   void *Opaque)
3580b57cec5SDimitry Andric   : Functions(Functions), Opaque(Opaque) {
3590b57cec5SDimitry Andric   assert(Functions.AllocateCodeSection &&
3600b57cec5SDimitry Andric          "No AllocateCodeSection function provided!");
3610b57cec5SDimitry Andric   assert(Functions.AllocateDataSection &&
3620b57cec5SDimitry Andric          "No AllocateDataSection function provided!");
3630b57cec5SDimitry Andric   assert(Functions.FinalizeMemory &&
3640b57cec5SDimitry Andric          "No FinalizeMemory function provided!");
3650b57cec5SDimitry Andric   assert(Functions.Destroy &&
3660b57cec5SDimitry Andric          "No Destroy function provided!");
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
3700b57cec5SDimitry Andric   Functions.Destroy(Opaque);
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
3740b57cec5SDimitry Andric   uintptr_t Size, unsigned Alignment, unsigned SectionID,
3750b57cec5SDimitry Andric   StringRef SectionName) {
3760b57cec5SDimitry Andric   return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
3770b57cec5SDimitry Andric                                        SectionName.str().c_str());
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateDataSection(
3810b57cec5SDimitry Andric   uintptr_t Size, unsigned Alignment, unsigned SectionID,
3820b57cec5SDimitry Andric   StringRef SectionName, bool isReadOnly) {
3830b57cec5SDimitry Andric   return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
3840b57cec5SDimitry Andric                                        SectionName.str().c_str(),
3850b57cec5SDimitry Andric                                        isReadOnly);
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
3890b57cec5SDimitry Andric   char *errMsgCString = nullptr;
3900b57cec5SDimitry Andric   bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
3910b57cec5SDimitry Andric   assert((result || !errMsgCString) &&
3920b57cec5SDimitry Andric          "Did not expect an error message if FinalizeMemory succeeded");
3930b57cec5SDimitry Andric   if (errMsgCString) {
3940b57cec5SDimitry Andric     if (ErrMsg)
3950b57cec5SDimitry Andric       *ErrMsg = errMsgCString;
3960b57cec5SDimitry Andric     free(errMsgCString);
3970b57cec5SDimitry Andric   }
3980b57cec5SDimitry Andric   return result;
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric } // anonymous namespace
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
4040b57cec5SDimitry Andric   void *Opaque,
4050b57cec5SDimitry Andric   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
4060b57cec5SDimitry Andric   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
4070b57cec5SDimitry Andric   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
4080b57cec5SDimitry Andric   LLVMMemoryManagerDestroyCallback Destroy) {
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
4110b57cec5SDimitry Andric       !Destroy)
4120b57cec5SDimitry Andric     return nullptr;
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   SimpleBindingMMFunctions functions;
4150b57cec5SDimitry Andric   functions.AllocateCodeSection = AllocateCodeSection;
4160b57cec5SDimitry Andric   functions.AllocateDataSection = AllocateDataSection;
4170b57cec5SDimitry Andric   functions.FinalizeMemory = FinalizeMemory;
4180b57cec5SDimitry Andric   functions.Destroy = Destroy;
4190b57cec5SDimitry Andric   return wrap(new SimpleBindingMemoryManager(functions, Opaque));
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
4230b57cec5SDimitry Andric   delete unwrap(MM);
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric /*===-- JIT Event Listener functions -------------------------------------===*/
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric #if !LLVM_USE_INTEL_JITEVENTS
4300b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
4310b57cec5SDimitry Andric {
4320b57cec5SDimitry Andric   return nullptr;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric #endif
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric #if !LLVM_USE_OPROFILE
4370b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
4380b57cec5SDimitry Andric {
4390b57cec5SDimitry Andric   return nullptr;
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric #endif
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric #if !LLVM_USE_PERF
4440b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
4450b57cec5SDimitry Andric {
4460b57cec5SDimitry Andric   return nullptr;
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric #endif
449