1*0b57cec5SDimitry Andric //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines the C bindings for the ExecutionEngine library. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm-c/ExecutionEngine.h" 14*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h" 15*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h" 16*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITEventListener.h" 17*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 18*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 19*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 20*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 21*0b57cec5SDimitry Andric #include "llvm/Target/CodeGenCWrappers.h" 22*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 23*0b57cec5SDimitry Andric #include <cstring> 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric using namespace llvm; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric #define DEBUG_TYPE "jit" 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric // Wrapping the C bindings types. 30*0b57cec5SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef) 31*0b57cec5SDimitry Andric 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric static LLVMTargetMachineRef wrap(const TargetMachine *P) { 34*0b57cec5SDimitry Andric return 35*0b57cec5SDimitry Andric reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P)); 36*0b57cec5SDimitry Andric } 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric /*===-- Operations on generic values --------------------------------------===*/ 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty, 41*0b57cec5SDimitry Andric unsigned long long N, 42*0b57cec5SDimitry Andric LLVMBool IsSigned) { 43*0b57cec5SDimitry Andric GenericValue *GenVal = new GenericValue(); 44*0b57cec5SDimitry Andric GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned); 45*0b57cec5SDimitry Andric return wrap(GenVal); 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) { 49*0b57cec5SDimitry Andric GenericValue *GenVal = new GenericValue(); 50*0b57cec5SDimitry Andric GenVal->PointerVal = P; 51*0b57cec5SDimitry Andric return wrap(GenVal); 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) { 55*0b57cec5SDimitry Andric GenericValue *GenVal = new GenericValue(); 56*0b57cec5SDimitry Andric switch (unwrap(TyRef)->getTypeID()) { 57*0b57cec5SDimitry Andric case Type::FloatTyID: 58*0b57cec5SDimitry Andric GenVal->FloatVal = N; 59*0b57cec5SDimitry Andric break; 60*0b57cec5SDimitry Andric case Type::DoubleTyID: 61*0b57cec5SDimitry Andric GenVal->DoubleVal = N; 62*0b57cec5SDimitry Andric break; 63*0b57cec5SDimitry Andric default: 64*0b57cec5SDimitry Andric llvm_unreachable("LLVMGenericValueToFloat supports only float and double."); 65*0b57cec5SDimitry Andric } 66*0b57cec5SDimitry Andric return wrap(GenVal); 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) { 70*0b57cec5SDimitry Andric return unwrap(GenValRef)->IntVal.getBitWidth(); 71*0b57cec5SDimitry Andric } 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef, 74*0b57cec5SDimitry Andric LLVMBool IsSigned) { 75*0b57cec5SDimitry Andric GenericValue *GenVal = unwrap(GenValRef); 76*0b57cec5SDimitry Andric if (IsSigned) 77*0b57cec5SDimitry Andric return GenVal->IntVal.getSExtValue(); 78*0b57cec5SDimitry Andric else 79*0b57cec5SDimitry Andric return GenVal->IntVal.getZExtValue(); 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) { 83*0b57cec5SDimitry Andric return unwrap(GenVal)->PointerVal; 84*0b57cec5SDimitry Andric } 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) { 87*0b57cec5SDimitry Andric switch (unwrap(TyRef)->getTypeID()) { 88*0b57cec5SDimitry Andric case Type::FloatTyID: 89*0b57cec5SDimitry Andric return unwrap(GenVal)->FloatVal; 90*0b57cec5SDimitry Andric case Type::DoubleTyID: 91*0b57cec5SDimitry Andric return unwrap(GenVal)->DoubleVal; 92*0b57cec5SDimitry Andric default: 93*0b57cec5SDimitry Andric llvm_unreachable("LLVMGenericValueToFloat supports only float and double."); 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric } 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) { 98*0b57cec5SDimitry Andric delete unwrap(GenVal); 99*0b57cec5SDimitry Andric } 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric /*===-- Operations on execution engines -----------------------------------===*/ 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE, 104*0b57cec5SDimitry Andric LLVMModuleRef M, 105*0b57cec5SDimitry Andric char **OutError) { 106*0b57cec5SDimitry Andric std::string Error; 107*0b57cec5SDimitry Andric EngineBuilder builder(std::unique_ptr<Module>(unwrap(M))); 108*0b57cec5SDimitry Andric builder.setEngineKind(EngineKind::Either) 109*0b57cec5SDimitry Andric .setErrorStr(&Error); 110*0b57cec5SDimitry Andric if (ExecutionEngine *EE = builder.create()){ 111*0b57cec5SDimitry Andric *OutEE = wrap(EE); 112*0b57cec5SDimitry Andric return 0; 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric *OutError = strdup(Error.c_str()); 115*0b57cec5SDimitry Andric return 1; 116*0b57cec5SDimitry Andric } 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp, 119*0b57cec5SDimitry Andric LLVMModuleRef M, 120*0b57cec5SDimitry Andric char **OutError) { 121*0b57cec5SDimitry Andric std::string Error; 122*0b57cec5SDimitry Andric EngineBuilder builder(std::unique_ptr<Module>(unwrap(M))); 123*0b57cec5SDimitry Andric builder.setEngineKind(EngineKind::Interpreter) 124*0b57cec5SDimitry Andric .setErrorStr(&Error); 125*0b57cec5SDimitry Andric if (ExecutionEngine *Interp = builder.create()) { 126*0b57cec5SDimitry Andric *OutInterp = wrap(Interp); 127*0b57cec5SDimitry Andric return 0; 128*0b57cec5SDimitry Andric } 129*0b57cec5SDimitry Andric *OutError = strdup(Error.c_str()); 130*0b57cec5SDimitry Andric return 1; 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, 134*0b57cec5SDimitry Andric LLVMModuleRef M, 135*0b57cec5SDimitry Andric unsigned OptLevel, 136*0b57cec5SDimitry Andric char **OutError) { 137*0b57cec5SDimitry Andric std::string Error; 138*0b57cec5SDimitry Andric EngineBuilder builder(std::unique_ptr<Module>(unwrap(M))); 139*0b57cec5SDimitry Andric builder.setEngineKind(EngineKind::JIT) 140*0b57cec5SDimitry Andric .setErrorStr(&Error) 141*0b57cec5SDimitry Andric .setOptLevel((CodeGenOpt::Level)OptLevel); 142*0b57cec5SDimitry Andric if (ExecutionEngine *JIT = builder.create()) { 143*0b57cec5SDimitry Andric *OutJIT = wrap(JIT); 144*0b57cec5SDimitry Andric return 0; 145*0b57cec5SDimitry Andric } 146*0b57cec5SDimitry Andric *OutError = strdup(Error.c_str()); 147*0b57cec5SDimitry Andric return 1; 148*0b57cec5SDimitry Andric } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions, 151*0b57cec5SDimitry Andric size_t SizeOfPassedOptions) { 152*0b57cec5SDimitry Andric LLVMMCJITCompilerOptions options; 153*0b57cec5SDimitry Andric memset(&options, 0, sizeof(options)); // Most fields are zero by default. 154*0b57cec5SDimitry Andric options.CodeModel = LLVMCodeModelJITDefault; 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric memcpy(PassedOptions, &options, 157*0b57cec5SDimitry Andric std::min(sizeof(options), SizeOfPassedOptions)); 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric LLVMBool LLVMCreateMCJITCompilerForModule( 161*0b57cec5SDimitry Andric LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, 162*0b57cec5SDimitry Andric LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions, 163*0b57cec5SDimitry Andric char **OutError) { 164*0b57cec5SDimitry Andric LLVMMCJITCompilerOptions options; 165*0b57cec5SDimitry Andric // If the user passed a larger sized options struct, then they were compiled 166*0b57cec5SDimitry Andric // against a newer LLVM. Tell them that something is wrong. 167*0b57cec5SDimitry Andric if (SizeOfPassedOptions > sizeof(options)) { 168*0b57cec5SDimitry Andric *OutError = strdup( 169*0b57cec5SDimitry Andric "Refusing to use options struct that is larger than my own; assuming " 170*0b57cec5SDimitry Andric "LLVM library mismatch."); 171*0b57cec5SDimitry Andric return 1; 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric // Defend against the user having an old version of the API by ensuring that 175*0b57cec5SDimitry Andric // any fields they didn't see are cleared. We must defend against fields being 176*0b57cec5SDimitry Andric // set to the bitwise equivalent of zero, and assume that this means "do the 177*0b57cec5SDimitry Andric // default" as if that option hadn't been available. 178*0b57cec5SDimitry Andric LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); 179*0b57cec5SDimitry Andric memcpy(&options, PassedOptions, SizeOfPassedOptions); 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric TargetOptions targetOptions; 182*0b57cec5SDimitry Andric targetOptions.EnableFastISel = options.EnableFastISel; 183*0b57cec5SDimitry Andric std::unique_ptr<Module> Mod(unwrap(M)); 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric if (Mod) 186*0b57cec5SDimitry Andric // Set function attribute "no-frame-pointer-elim" based on 187*0b57cec5SDimitry Andric // NoFramePointerElim. 188*0b57cec5SDimitry Andric for (auto &F : *Mod) { 189*0b57cec5SDimitry Andric auto Attrs = F.getAttributes(); 190*0b57cec5SDimitry Andric StringRef Value(options.NoFramePointerElim ? "true" : "false"); 191*0b57cec5SDimitry Andric Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex, 192*0b57cec5SDimitry Andric "no-frame-pointer-elim", Value); 193*0b57cec5SDimitry Andric F.setAttributes(Attrs); 194*0b57cec5SDimitry Andric } 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric std::string Error; 197*0b57cec5SDimitry Andric EngineBuilder builder(std::move(Mod)); 198*0b57cec5SDimitry Andric builder.setEngineKind(EngineKind::JIT) 199*0b57cec5SDimitry Andric .setErrorStr(&Error) 200*0b57cec5SDimitry Andric .setOptLevel((CodeGenOpt::Level)options.OptLevel) 201*0b57cec5SDimitry Andric .setTargetOptions(targetOptions); 202*0b57cec5SDimitry Andric bool JIT; 203*0b57cec5SDimitry Andric if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT)) 204*0b57cec5SDimitry Andric builder.setCodeModel(*CM); 205*0b57cec5SDimitry Andric if (options.MCJMM) 206*0b57cec5SDimitry Andric builder.setMCJITMemoryManager( 207*0b57cec5SDimitry Andric std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM))); 208*0b57cec5SDimitry Andric if (ExecutionEngine *JIT = builder.create()) { 209*0b57cec5SDimitry Andric *OutJIT = wrap(JIT); 210*0b57cec5SDimitry Andric return 0; 211*0b57cec5SDimitry Andric } 212*0b57cec5SDimitry Andric *OutError = strdup(Error.c_str()); 213*0b57cec5SDimitry Andric return 1; 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) { 217*0b57cec5SDimitry Andric delete unwrap(EE); 218*0b57cec5SDimitry Andric } 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) { 221*0b57cec5SDimitry Andric unwrap(EE)->finalizeObject(); 222*0b57cec5SDimitry Andric unwrap(EE)->runStaticConstructorsDestructors(false); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) { 226*0b57cec5SDimitry Andric unwrap(EE)->finalizeObject(); 227*0b57cec5SDimitry Andric unwrap(EE)->runStaticConstructorsDestructors(true); 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F, 231*0b57cec5SDimitry Andric unsigned ArgC, const char * const *ArgV, 232*0b57cec5SDimitry Andric const char * const *EnvP) { 233*0b57cec5SDimitry Andric unwrap(EE)->finalizeObject(); 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric std::vector<std::string> ArgVec(ArgV, ArgV + ArgC); 236*0b57cec5SDimitry Andric return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP); 237*0b57cec5SDimitry Andric } 238*0b57cec5SDimitry Andric 239*0b57cec5SDimitry Andric LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F, 240*0b57cec5SDimitry Andric unsigned NumArgs, 241*0b57cec5SDimitry Andric LLVMGenericValueRef *Args) { 242*0b57cec5SDimitry Andric unwrap(EE)->finalizeObject(); 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric std::vector<GenericValue> ArgVec; 245*0b57cec5SDimitry Andric ArgVec.reserve(NumArgs); 246*0b57cec5SDimitry Andric for (unsigned I = 0; I != NumArgs; ++I) 247*0b57cec5SDimitry Andric ArgVec.push_back(*unwrap(Args[I])); 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andric GenericValue *Result = new GenericValue(); 250*0b57cec5SDimitry Andric *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec); 251*0b57cec5SDimitry Andric return wrap(Result); 252*0b57cec5SDimitry Andric } 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) { 255*0b57cec5SDimitry Andric } 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){ 258*0b57cec5SDimitry Andric unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M))); 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M, 262*0b57cec5SDimitry Andric LLVMModuleRef *OutMod, char **OutError) { 263*0b57cec5SDimitry Andric Module *Mod = unwrap(M); 264*0b57cec5SDimitry Andric unwrap(EE)->removeModule(Mod); 265*0b57cec5SDimitry Andric *OutMod = wrap(Mod); 266*0b57cec5SDimitry Andric return 0; 267*0b57cec5SDimitry Andric } 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andric LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, 270*0b57cec5SDimitry Andric LLVMValueRef *OutFn) { 271*0b57cec5SDimitry Andric if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) { 272*0b57cec5SDimitry Andric *OutFn = wrap(F); 273*0b57cec5SDimitry Andric return 0; 274*0b57cec5SDimitry Andric } 275*0b57cec5SDimitry Andric return 1; 276*0b57cec5SDimitry Andric } 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, 279*0b57cec5SDimitry Andric LLVMValueRef Fn) { 280*0b57cec5SDimitry Andric return nullptr; 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) { 284*0b57cec5SDimitry Andric return wrap(&unwrap(EE)->getDataLayout()); 285*0b57cec5SDimitry Andric } 286*0b57cec5SDimitry Andric 287*0b57cec5SDimitry Andric LLVMTargetMachineRef 288*0b57cec5SDimitry Andric LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) { 289*0b57cec5SDimitry Andric return wrap(unwrap(EE)->getTargetMachine()); 290*0b57cec5SDimitry Andric } 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, 293*0b57cec5SDimitry Andric void* Addr) { 294*0b57cec5SDimitry Andric unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr); 295*0b57cec5SDimitry Andric } 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) { 298*0b57cec5SDimitry Andric unwrap(EE)->finalizeObject(); 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andric return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global)); 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) { 304*0b57cec5SDimitry Andric return unwrap(EE)->getGlobalValueAddress(Name); 305*0b57cec5SDimitry Andric } 306*0b57cec5SDimitry Andric 307*0b57cec5SDimitry Andric uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) { 308*0b57cec5SDimitry Andric return unwrap(EE)->getFunctionAddress(Name); 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric 311*0b57cec5SDimitry Andric /*===-- Operations on memory managers -------------------------------------===*/ 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric namespace { 314*0b57cec5SDimitry Andric 315*0b57cec5SDimitry Andric struct SimpleBindingMMFunctions { 316*0b57cec5SDimitry Andric LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection; 317*0b57cec5SDimitry Andric LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection; 318*0b57cec5SDimitry Andric LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory; 319*0b57cec5SDimitry Andric LLVMMemoryManagerDestroyCallback Destroy; 320*0b57cec5SDimitry Andric }; 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric class SimpleBindingMemoryManager : public RTDyldMemoryManager { 323*0b57cec5SDimitry Andric public: 324*0b57cec5SDimitry Andric SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions, 325*0b57cec5SDimitry Andric void *Opaque); 326*0b57cec5SDimitry Andric ~SimpleBindingMemoryManager() override; 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 329*0b57cec5SDimitry Andric unsigned SectionID, 330*0b57cec5SDimitry Andric StringRef SectionName) override; 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 333*0b57cec5SDimitry Andric unsigned SectionID, StringRef SectionName, 334*0b57cec5SDimitry Andric bool isReadOnly) override; 335*0b57cec5SDimitry Andric 336*0b57cec5SDimitry Andric bool finalizeMemory(std::string *ErrMsg) override; 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric private: 339*0b57cec5SDimitry Andric SimpleBindingMMFunctions Functions; 340*0b57cec5SDimitry Andric void *Opaque; 341*0b57cec5SDimitry Andric }; 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric SimpleBindingMemoryManager::SimpleBindingMemoryManager( 344*0b57cec5SDimitry Andric const SimpleBindingMMFunctions& Functions, 345*0b57cec5SDimitry Andric void *Opaque) 346*0b57cec5SDimitry Andric : Functions(Functions), Opaque(Opaque) { 347*0b57cec5SDimitry Andric assert(Functions.AllocateCodeSection && 348*0b57cec5SDimitry Andric "No AllocateCodeSection function provided!"); 349*0b57cec5SDimitry Andric assert(Functions.AllocateDataSection && 350*0b57cec5SDimitry Andric "No AllocateDataSection function provided!"); 351*0b57cec5SDimitry Andric assert(Functions.FinalizeMemory && 352*0b57cec5SDimitry Andric "No FinalizeMemory function provided!"); 353*0b57cec5SDimitry Andric assert(Functions.Destroy && 354*0b57cec5SDimitry Andric "No Destroy function provided!"); 355*0b57cec5SDimitry Andric } 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric SimpleBindingMemoryManager::~SimpleBindingMemoryManager() { 358*0b57cec5SDimitry Andric Functions.Destroy(Opaque); 359*0b57cec5SDimitry Andric } 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateCodeSection( 362*0b57cec5SDimitry Andric uintptr_t Size, unsigned Alignment, unsigned SectionID, 363*0b57cec5SDimitry Andric StringRef SectionName) { 364*0b57cec5SDimitry Andric return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID, 365*0b57cec5SDimitry Andric SectionName.str().c_str()); 366*0b57cec5SDimitry Andric } 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateDataSection( 369*0b57cec5SDimitry Andric uintptr_t Size, unsigned Alignment, unsigned SectionID, 370*0b57cec5SDimitry Andric StringRef SectionName, bool isReadOnly) { 371*0b57cec5SDimitry Andric return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID, 372*0b57cec5SDimitry Andric SectionName.str().c_str(), 373*0b57cec5SDimitry Andric isReadOnly); 374*0b57cec5SDimitry Andric } 375*0b57cec5SDimitry Andric 376*0b57cec5SDimitry Andric bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) { 377*0b57cec5SDimitry Andric char *errMsgCString = nullptr; 378*0b57cec5SDimitry Andric bool result = Functions.FinalizeMemory(Opaque, &errMsgCString); 379*0b57cec5SDimitry Andric assert((result || !errMsgCString) && 380*0b57cec5SDimitry Andric "Did not expect an error message if FinalizeMemory succeeded"); 381*0b57cec5SDimitry Andric if (errMsgCString) { 382*0b57cec5SDimitry Andric if (ErrMsg) 383*0b57cec5SDimitry Andric *ErrMsg = errMsgCString; 384*0b57cec5SDimitry Andric free(errMsgCString); 385*0b57cec5SDimitry Andric } 386*0b57cec5SDimitry Andric return result; 387*0b57cec5SDimitry Andric } 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric } // anonymous namespace 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager( 392*0b57cec5SDimitry Andric void *Opaque, 393*0b57cec5SDimitry Andric LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, 394*0b57cec5SDimitry Andric LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, 395*0b57cec5SDimitry Andric LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, 396*0b57cec5SDimitry Andric LLVMMemoryManagerDestroyCallback Destroy) { 397*0b57cec5SDimitry Andric 398*0b57cec5SDimitry Andric if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory || 399*0b57cec5SDimitry Andric !Destroy) 400*0b57cec5SDimitry Andric return nullptr; 401*0b57cec5SDimitry Andric 402*0b57cec5SDimitry Andric SimpleBindingMMFunctions functions; 403*0b57cec5SDimitry Andric functions.AllocateCodeSection = AllocateCodeSection; 404*0b57cec5SDimitry Andric functions.AllocateDataSection = AllocateDataSection; 405*0b57cec5SDimitry Andric functions.FinalizeMemory = FinalizeMemory; 406*0b57cec5SDimitry Andric functions.Destroy = Destroy; 407*0b57cec5SDimitry Andric return wrap(new SimpleBindingMemoryManager(functions, Opaque)); 408*0b57cec5SDimitry Andric } 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) { 411*0b57cec5SDimitry Andric delete unwrap(MM); 412*0b57cec5SDimitry Andric } 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric /*===-- JIT Event Listener functions -------------------------------------===*/ 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andric 417*0b57cec5SDimitry Andric #if !LLVM_USE_INTEL_JITEVENTS 418*0b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void) 419*0b57cec5SDimitry Andric { 420*0b57cec5SDimitry Andric return nullptr; 421*0b57cec5SDimitry Andric } 422*0b57cec5SDimitry Andric #endif 423*0b57cec5SDimitry Andric 424*0b57cec5SDimitry Andric #if !LLVM_USE_OPROFILE 425*0b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void) 426*0b57cec5SDimitry Andric { 427*0b57cec5SDimitry Andric return nullptr; 428*0b57cec5SDimitry Andric } 429*0b57cec5SDimitry Andric #endif 430*0b57cec5SDimitry Andric 431*0b57cec5SDimitry Andric #if !LLVM_USE_PERF 432*0b57cec5SDimitry Andric LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void) 433*0b57cec5SDimitry Andric { 434*0b57cec5SDimitry Andric return nullptr; 435*0b57cec5SDimitry Andric } 436*0b57cec5SDimitry Andric #endif 437