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