xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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