1f22ef01cSRoman Divacky //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file defines the C bindings for the ExecutionEngine library.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "llvm-c/ExecutionEngine.h"
15f22ef01cSRoman Divacky #include "llvm/ExecutionEngine/ExecutionEngine.h"
16139f7f9bSDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h"
17*4ba319b5SDimitry Andric #include "llvm/ExecutionEngine/JITEventListener.h"
18f785676fSDimitry Andric #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
19284c1978SDimitry Andric #include "llvm/IR/DerivedTypes.h"
20284c1978SDimitry Andric #include "llvm/IR/Module.h"
21f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
22*4ba319b5SDimitry Andric #include "llvm/Target/CodeGenCWrappers.h"
2397bc6c73SDimitry Andric #include "llvm/Target/TargetOptions.h"
24f22ef01cSRoman Divacky #include <cstring>
25f22ef01cSRoman Divacky 
26f22ef01cSRoman Divacky using namespace llvm;
27f22ef01cSRoman Divacky 
2891bc56edSDimitry Andric #define DEBUG_TYPE "jit"
2991bc56edSDimitry Andric 
30284c1978SDimitry Andric // Wrapping the C bindings types.
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue,LLVMGenericValueRef)31284c1978SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
32284c1978SDimitry Andric 
33284c1978SDimitry Andric 
347d523365SDimitry Andric static LLVMTargetMachineRef wrap(const TargetMachine *P) {
3591bc56edSDimitry Andric   return
3691bc56edSDimitry Andric   reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
3791bc56edSDimitry Andric }
3891bc56edSDimitry Andric 
39f22ef01cSRoman Divacky /*===-- Operations on generic values --------------------------------------===*/
40f22ef01cSRoman Divacky 
LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,unsigned long long N,LLVMBool IsSigned)41f22ef01cSRoman Divacky LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
42f22ef01cSRoman Divacky                                                 unsigned long long N,
43f22ef01cSRoman Divacky                                                 LLVMBool IsSigned) {
44f22ef01cSRoman Divacky   GenericValue *GenVal = new GenericValue();
45f22ef01cSRoman Divacky   GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
46f22ef01cSRoman Divacky   return wrap(GenVal);
47f22ef01cSRoman Divacky }
48f22ef01cSRoman Divacky 
LLVMCreateGenericValueOfPointer(void * P)49f22ef01cSRoman Divacky LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
50f22ef01cSRoman Divacky   GenericValue *GenVal = new GenericValue();
51f22ef01cSRoman Divacky   GenVal->PointerVal = P;
52f22ef01cSRoman Divacky   return wrap(GenVal);
53f22ef01cSRoman Divacky }
54f22ef01cSRoman Divacky 
LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef,double N)55f22ef01cSRoman Divacky LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
56f22ef01cSRoman Divacky   GenericValue *GenVal = new GenericValue();
57f22ef01cSRoman Divacky   switch (unwrap(TyRef)->getTypeID()) {
58f22ef01cSRoman Divacky   case Type::FloatTyID:
59f22ef01cSRoman Divacky     GenVal->FloatVal = N;
60f22ef01cSRoman Divacky     break;
61f22ef01cSRoman Divacky   case Type::DoubleTyID:
62f22ef01cSRoman Divacky     GenVal->DoubleVal = N;
63f22ef01cSRoman Divacky     break;
64f22ef01cSRoman Divacky   default:
65f22ef01cSRoman Divacky     llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
66f22ef01cSRoman Divacky   }
67f22ef01cSRoman Divacky   return wrap(GenVal);
68f22ef01cSRoman Divacky }
69f22ef01cSRoman Divacky 
LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef)70f22ef01cSRoman Divacky unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
71f22ef01cSRoman Divacky   return unwrap(GenValRef)->IntVal.getBitWidth();
72f22ef01cSRoman Divacky }
73f22ef01cSRoman Divacky 
LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,LLVMBool IsSigned)74f22ef01cSRoman Divacky unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
75f22ef01cSRoman Divacky                                          LLVMBool IsSigned) {
76f22ef01cSRoman Divacky   GenericValue *GenVal = unwrap(GenValRef);
77f22ef01cSRoman Divacky   if (IsSigned)
78f22ef01cSRoman Divacky     return GenVal->IntVal.getSExtValue();
79f22ef01cSRoman Divacky   else
80f22ef01cSRoman Divacky     return GenVal->IntVal.getZExtValue();
81f22ef01cSRoman Divacky }
82f22ef01cSRoman Divacky 
LLVMGenericValueToPointer(LLVMGenericValueRef GenVal)83f22ef01cSRoman Divacky void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
84f22ef01cSRoman Divacky   return unwrap(GenVal)->PointerVal;
85f22ef01cSRoman Divacky }
86f22ef01cSRoman Divacky 
LLVMGenericValueToFloat(LLVMTypeRef TyRef,LLVMGenericValueRef GenVal)87f22ef01cSRoman Divacky double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
88f22ef01cSRoman Divacky   switch (unwrap(TyRef)->getTypeID()) {
89f22ef01cSRoman Divacky   case Type::FloatTyID:
90f22ef01cSRoman Divacky     return unwrap(GenVal)->FloatVal;
91f22ef01cSRoman Divacky   case Type::DoubleTyID:
92f22ef01cSRoman Divacky     return unwrap(GenVal)->DoubleVal;
93f22ef01cSRoman Divacky   default:
94f22ef01cSRoman Divacky     llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
95f22ef01cSRoman Divacky   }
96f22ef01cSRoman Divacky }
97f22ef01cSRoman Divacky 
LLVMDisposeGenericValue(LLVMGenericValueRef GenVal)98f22ef01cSRoman Divacky void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
99f22ef01cSRoman Divacky   delete unwrap(GenVal);
100f22ef01cSRoman Divacky }
101f22ef01cSRoman Divacky 
102f22ef01cSRoman Divacky /*===-- Operations on execution engines -----------------------------------===*/
103f22ef01cSRoman Divacky 
LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef * OutEE,LLVMModuleRef M,char ** OutError)104f22ef01cSRoman Divacky LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
105f22ef01cSRoman Divacky                                             LLVMModuleRef M,
106f22ef01cSRoman Divacky                                             char **OutError) {
107f22ef01cSRoman Divacky   std::string Error;
10839d628a0SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
109f22ef01cSRoman Divacky   builder.setEngineKind(EngineKind::Either)
110f22ef01cSRoman Divacky          .setErrorStr(&Error);
111f22ef01cSRoman Divacky   if (ExecutionEngine *EE = builder.create()){
112f22ef01cSRoman Divacky     *OutEE = wrap(EE);
113f22ef01cSRoman Divacky     return 0;
114f22ef01cSRoman Divacky   }
115f22ef01cSRoman Divacky   *OutError = strdup(Error.c_str());
116f22ef01cSRoman Divacky   return 1;
117f22ef01cSRoman Divacky }
118f22ef01cSRoman Divacky 
LLVMCreateInterpreterForModule(LLVMExecutionEngineRef * OutInterp,LLVMModuleRef M,char ** OutError)119f22ef01cSRoman Divacky LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
120f22ef01cSRoman Divacky                                         LLVMModuleRef M,
121f22ef01cSRoman Divacky                                         char **OutError) {
122f22ef01cSRoman Divacky   std::string Error;
12339d628a0SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
124f22ef01cSRoman Divacky   builder.setEngineKind(EngineKind::Interpreter)
125f22ef01cSRoman Divacky          .setErrorStr(&Error);
126f22ef01cSRoman Divacky   if (ExecutionEngine *Interp = builder.create()) {
127f22ef01cSRoman Divacky     *OutInterp = wrap(Interp);
128f22ef01cSRoman Divacky     return 0;
129f22ef01cSRoman Divacky   }
130f22ef01cSRoman Divacky   *OutError = strdup(Error.c_str());
131f22ef01cSRoman Divacky   return 1;
132f22ef01cSRoman Divacky }
133f22ef01cSRoman Divacky 
LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef * OutJIT,LLVMModuleRef M,unsigned OptLevel,char ** OutError)134f22ef01cSRoman Divacky LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
135f22ef01cSRoman Divacky                                         LLVMModuleRef M,
136f22ef01cSRoman Divacky                                         unsigned OptLevel,
137f22ef01cSRoman Divacky                                         char **OutError) {
138f22ef01cSRoman Divacky   std::string Error;
13939d628a0SDimitry Andric   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
140f22ef01cSRoman Divacky   builder.setEngineKind(EngineKind::JIT)
141f22ef01cSRoman Divacky          .setErrorStr(&Error)
142f22ef01cSRoman Divacky          .setOptLevel((CodeGenOpt::Level)OptLevel);
143f22ef01cSRoman Divacky   if (ExecutionEngine *JIT = builder.create()) {
144f22ef01cSRoman Divacky     *OutJIT = wrap(JIT);
145f22ef01cSRoman Divacky     return 0;
146f22ef01cSRoman Divacky   }
147f22ef01cSRoman Divacky   *OutError = strdup(Error.c_str());
148f22ef01cSRoman Divacky   return 1;
149f22ef01cSRoman Divacky }
150f22ef01cSRoman Divacky 
LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions * PassedOptions,size_t SizeOfPassedOptions)151284c1978SDimitry Andric void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
152284c1978SDimitry Andric                                         size_t SizeOfPassedOptions) {
153284c1978SDimitry Andric   LLVMMCJITCompilerOptions options;
154f785676fSDimitry Andric   memset(&options, 0, sizeof(options)); // Most fields are zero by default.
155284c1978SDimitry Andric   options.CodeModel = LLVMCodeModelJITDefault;
156284c1978SDimitry Andric 
157284c1978SDimitry Andric   memcpy(PassedOptions, &options,
158284c1978SDimitry Andric          std::min(sizeof(options), SizeOfPassedOptions));
159284c1978SDimitry Andric }
160284c1978SDimitry Andric 
LLVMCreateMCJITCompilerForModule(LLVMExecutionEngineRef * OutJIT,LLVMModuleRef M,LLVMMCJITCompilerOptions * PassedOptions,size_t SizeOfPassedOptions,char ** OutError)161284c1978SDimitry Andric LLVMBool LLVMCreateMCJITCompilerForModule(
162284c1978SDimitry Andric     LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
163284c1978SDimitry Andric     LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
164284c1978SDimitry Andric     char **OutError) {
165284c1978SDimitry Andric   LLVMMCJITCompilerOptions options;
166284c1978SDimitry Andric   // If the user passed a larger sized options struct, then they were compiled
167284c1978SDimitry Andric   // against a newer LLVM. Tell them that something is wrong.
168284c1978SDimitry Andric   if (SizeOfPassedOptions > sizeof(options)) {
169284c1978SDimitry Andric     *OutError = strdup(
170284c1978SDimitry Andric       "Refusing to use options struct that is larger than my own; assuming "
171284c1978SDimitry Andric       "LLVM library mismatch.");
172284c1978SDimitry Andric     return 1;
173284c1978SDimitry Andric   }
174284c1978SDimitry Andric 
175284c1978SDimitry Andric   // Defend against the user having an old version of the API by ensuring that
176284c1978SDimitry Andric   // any fields they didn't see are cleared. We must defend against fields being
177284c1978SDimitry Andric   // set to the bitwise equivalent of zero, and assume that this means "do the
178284c1978SDimitry Andric   // default" as if that option hadn't been available.
179284c1978SDimitry Andric   LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
180284c1978SDimitry Andric   memcpy(&options, PassedOptions, SizeOfPassedOptions);
181284c1978SDimitry Andric 
182284c1978SDimitry Andric   TargetOptions targetOptions;
183284c1978SDimitry Andric   targetOptions.EnableFastISel = options.EnableFastISel;
184ff0cc061SDimitry Andric   std::unique_ptr<Module> Mod(unwrap(M));
185ff0cc061SDimitry Andric 
186ff0cc061SDimitry Andric   if (Mod)
187ff0cc061SDimitry Andric     // Set function attribute "no-frame-pointer-elim" based on
188ff0cc061SDimitry Andric     // NoFramePointerElim.
189ff0cc061SDimitry Andric     for (auto &F : *Mod) {
190ff0cc061SDimitry Andric       auto Attrs = F.getAttributes();
191d88c1a5aSDimitry Andric       StringRef Value(options.NoFramePointerElim ? "true" : "false");
1927a7e6055SDimitry Andric       Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
193ff0cc061SDimitry Andric                                  "no-frame-pointer-elim", Value);
194ff0cc061SDimitry Andric       F.setAttributes(Attrs);
195ff0cc061SDimitry Andric     }
196284c1978SDimitry Andric 
197284c1978SDimitry Andric   std::string Error;
198ff0cc061SDimitry Andric   EngineBuilder builder(std::move(Mod));
199284c1978SDimitry Andric   builder.setEngineKind(EngineKind::JIT)
200284c1978SDimitry Andric          .setErrorStr(&Error)
201284c1978SDimitry Andric          .setOptLevel((CodeGenOpt::Level)options.OptLevel)
202284c1978SDimitry Andric          .setTargetOptions(targetOptions);
2032cab237bSDimitry Andric   bool JIT;
2042cab237bSDimitry Andric   if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
2052cab237bSDimitry Andric     builder.setCodeModel(*CM);
206f785676fSDimitry Andric   if (options.MCJMM)
20739d628a0SDimitry Andric     builder.setMCJITMemoryManager(
20839d628a0SDimitry Andric       std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
209284c1978SDimitry Andric   if (ExecutionEngine *JIT = builder.create()) {
210284c1978SDimitry Andric     *OutJIT = wrap(JIT);
211284c1978SDimitry Andric     return 0;
212284c1978SDimitry Andric   }
213284c1978SDimitry Andric   *OutError = strdup(Error.c_str());
214284c1978SDimitry Andric   return 1;
215284c1978SDimitry Andric }
216284c1978SDimitry Andric 
LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE)217f22ef01cSRoman Divacky void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
218f22ef01cSRoman Divacky   delete unwrap(EE);
219f22ef01cSRoman Divacky }
220f22ef01cSRoman Divacky 
LLVMRunStaticConstructors(LLVMExecutionEngineRef EE)221f22ef01cSRoman Divacky void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
2223ca95b02SDimitry Andric   unwrap(EE)->finalizeObject();
223f22ef01cSRoman Divacky   unwrap(EE)->runStaticConstructorsDestructors(false);
224f22ef01cSRoman Divacky }
225f22ef01cSRoman Divacky 
LLVMRunStaticDestructors(LLVMExecutionEngineRef EE)226f22ef01cSRoman Divacky void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
2273ca95b02SDimitry Andric   unwrap(EE)->finalizeObject();
228f22ef01cSRoman Divacky   unwrap(EE)->runStaticConstructorsDestructors(true);
229f22ef01cSRoman Divacky }
230f22ef01cSRoman Divacky 
LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE,LLVMValueRef F,unsigned ArgC,const char * const * ArgV,const char * const * EnvP)231f22ef01cSRoman Divacky int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
232f22ef01cSRoman Divacky                           unsigned ArgC, const char * const *ArgV,
233f22ef01cSRoman Divacky                           const char * const *EnvP) {
234284c1978SDimitry Andric   unwrap(EE)->finalizeObject();
235284c1978SDimitry Andric 
23697bc6c73SDimitry Andric   std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
237f22ef01cSRoman Divacky   return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
238f22ef01cSRoman Divacky }
239f22ef01cSRoman Divacky 
LLVMRunFunction(LLVMExecutionEngineRef EE,LLVMValueRef F,unsigned NumArgs,LLVMGenericValueRef * Args)240f22ef01cSRoman Divacky LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
241f22ef01cSRoman Divacky                                     unsigned NumArgs,
242f22ef01cSRoman Divacky                                     LLVMGenericValueRef *Args) {
243284c1978SDimitry Andric   unwrap(EE)->finalizeObject();
244284c1978SDimitry Andric 
245f22ef01cSRoman Divacky   std::vector<GenericValue> ArgVec;
246f22ef01cSRoman Divacky   ArgVec.reserve(NumArgs);
247f22ef01cSRoman Divacky   for (unsigned I = 0; I != NumArgs; ++I)
248f22ef01cSRoman Divacky     ArgVec.push_back(*unwrap(Args[I]));
249f22ef01cSRoman Divacky 
250f22ef01cSRoman Divacky   GenericValue *Result = new GenericValue();
251f22ef01cSRoman Divacky   *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
252f22ef01cSRoman Divacky   return wrap(Result);
253f22ef01cSRoman Divacky }
254f22ef01cSRoman Divacky 
LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE,LLVMValueRef F)255f22ef01cSRoman Divacky void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
256f22ef01cSRoman Divacky }
257f22ef01cSRoman Divacky 
LLVMAddModule(LLVMExecutionEngineRef EE,LLVMModuleRef M)258f22ef01cSRoman Divacky void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
25939d628a0SDimitry Andric   unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
260f22ef01cSRoman Divacky }
261f22ef01cSRoman Divacky 
LLVMRemoveModule(LLVMExecutionEngineRef EE,LLVMModuleRef M,LLVMModuleRef * OutMod,char ** OutError)262f22ef01cSRoman Divacky LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
263f22ef01cSRoman Divacky                           LLVMModuleRef *OutMod, char **OutError) {
264f22ef01cSRoman Divacky   Module *Mod = unwrap(M);
265f22ef01cSRoman Divacky   unwrap(EE)->removeModule(Mod);
266f22ef01cSRoman Divacky   *OutMod = wrap(Mod);
267f22ef01cSRoman Divacky   return 0;
268f22ef01cSRoman Divacky }
269f22ef01cSRoman Divacky 
LLVMFindFunction(LLVMExecutionEngineRef EE,const char * Name,LLVMValueRef * OutFn)270f22ef01cSRoman Divacky LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
271f22ef01cSRoman Divacky                           LLVMValueRef *OutFn) {
272f22ef01cSRoman Divacky   if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
273f22ef01cSRoman Divacky     *OutFn = wrap(F);
274f22ef01cSRoman Divacky     return 0;
275f22ef01cSRoman Divacky   }
276f22ef01cSRoman Divacky   return 1;
277f22ef01cSRoman Divacky }
278f22ef01cSRoman Divacky 
LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,LLVMValueRef Fn)279284c1978SDimitry Andric void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
280284c1978SDimitry Andric                                      LLVMValueRef Fn) {
28139d628a0SDimitry Andric   return nullptr;
282e580952dSDimitry Andric }
283e580952dSDimitry Andric 
LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE)284f22ef01cSRoman Divacky LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
2857d523365SDimitry Andric   return wrap(&unwrap(EE)->getDataLayout());
286f22ef01cSRoman Divacky }
287f22ef01cSRoman Divacky 
28891bc56edSDimitry Andric LLVMTargetMachineRef
LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE)28991bc56edSDimitry Andric LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
29091bc56edSDimitry Andric   return wrap(unwrap(EE)->getTargetMachine());
29191bc56edSDimitry Andric }
29291bc56edSDimitry Andric 
LLVMAddGlobalMapping(LLVMExecutionEngineRef EE,LLVMValueRef Global,void * Addr)293f22ef01cSRoman Divacky void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
294f22ef01cSRoman Divacky                           void* Addr) {
295f22ef01cSRoman Divacky   unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
296f22ef01cSRoman Divacky }
297f22ef01cSRoman Divacky 
LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE,LLVMValueRef Global)298f22ef01cSRoman Divacky void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
299284c1978SDimitry Andric   unwrap(EE)->finalizeObject();
300284c1978SDimitry Andric 
301f22ef01cSRoman Divacky   return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
302f22ef01cSRoman Divacky }
303f785676fSDimitry Andric 
LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE,const char * Name)30439d628a0SDimitry Andric uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
30539d628a0SDimitry Andric   return unwrap(EE)->getGlobalValueAddress(Name);
30639d628a0SDimitry Andric }
30739d628a0SDimitry Andric 
LLVMGetFunctionAddress(LLVMExecutionEngineRef EE,const char * Name)30839d628a0SDimitry Andric uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
30939d628a0SDimitry Andric   return unwrap(EE)->getFunctionAddress(Name);
31039d628a0SDimitry Andric }
31139d628a0SDimitry Andric 
312f785676fSDimitry Andric /*===-- Operations on memory managers -------------------------------------===*/
313f785676fSDimitry Andric 
314f785676fSDimitry Andric namespace {
315f785676fSDimitry Andric 
316f785676fSDimitry Andric struct SimpleBindingMMFunctions {
317f785676fSDimitry Andric   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
318f785676fSDimitry Andric   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
319f785676fSDimitry Andric   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
320f785676fSDimitry Andric   LLVMMemoryManagerDestroyCallback Destroy;
321f785676fSDimitry Andric };
322f785676fSDimitry Andric 
323f785676fSDimitry Andric class SimpleBindingMemoryManager : public RTDyldMemoryManager {
324f785676fSDimitry Andric public:
325f785676fSDimitry Andric   SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
326f785676fSDimitry Andric                              void *Opaque);
327ff0cc061SDimitry Andric   ~SimpleBindingMemoryManager() override;
328f785676fSDimitry Andric 
32991bc56edSDimitry Andric   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
33091bc56edSDimitry Andric                                unsigned SectionID,
33191bc56edSDimitry Andric                                StringRef SectionName) override;
332f785676fSDimitry Andric 
33391bc56edSDimitry Andric   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
33491bc56edSDimitry Andric                                unsigned SectionID, StringRef SectionName,
33591bc56edSDimitry Andric                                bool isReadOnly) override;
336f785676fSDimitry Andric 
33791bc56edSDimitry Andric   bool finalizeMemory(std::string *ErrMsg) override;
338f785676fSDimitry Andric 
339f785676fSDimitry Andric private:
340f785676fSDimitry Andric   SimpleBindingMMFunctions Functions;
341f785676fSDimitry Andric   void *Opaque;
342f785676fSDimitry Andric };
343f785676fSDimitry Andric 
SimpleBindingMemoryManager(const SimpleBindingMMFunctions & Functions,void * Opaque)344f785676fSDimitry Andric SimpleBindingMemoryManager::SimpleBindingMemoryManager(
345f785676fSDimitry Andric   const SimpleBindingMMFunctions& Functions,
346f785676fSDimitry Andric   void *Opaque)
347f785676fSDimitry Andric   : Functions(Functions), Opaque(Opaque) {
348f785676fSDimitry Andric   assert(Functions.AllocateCodeSection &&
349f785676fSDimitry Andric          "No AllocateCodeSection function provided!");
350f785676fSDimitry Andric   assert(Functions.AllocateDataSection &&
351f785676fSDimitry Andric          "No AllocateDataSection function provided!");
352f785676fSDimitry Andric   assert(Functions.FinalizeMemory &&
353f785676fSDimitry Andric          "No FinalizeMemory function provided!");
354f785676fSDimitry Andric   assert(Functions.Destroy &&
355f785676fSDimitry Andric          "No Destroy function provided!");
356f785676fSDimitry Andric }
357f785676fSDimitry Andric 
~SimpleBindingMemoryManager()358f785676fSDimitry Andric SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
359f785676fSDimitry Andric   Functions.Destroy(Opaque);
360f785676fSDimitry Andric }
361f785676fSDimitry Andric 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)362f785676fSDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
363f785676fSDimitry Andric   uintptr_t Size, unsigned Alignment, unsigned SectionID,
364f785676fSDimitry Andric   StringRef SectionName) {
365f785676fSDimitry Andric   return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
366f785676fSDimitry Andric                                        SectionName.str().c_str());
367f785676fSDimitry Andric }
368f785676fSDimitry Andric 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool isReadOnly)369f785676fSDimitry Andric uint8_t *SimpleBindingMemoryManager::allocateDataSection(
370f785676fSDimitry Andric   uintptr_t Size, unsigned Alignment, unsigned SectionID,
371f785676fSDimitry Andric   StringRef SectionName, bool isReadOnly) {
372f785676fSDimitry Andric   return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
373f785676fSDimitry Andric                                        SectionName.str().c_str(),
374f785676fSDimitry Andric                                        isReadOnly);
375f785676fSDimitry Andric }
376f785676fSDimitry Andric 
finalizeMemory(std::string * ErrMsg)377f785676fSDimitry Andric bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
37891bc56edSDimitry Andric   char *errMsgCString = nullptr;
379f785676fSDimitry Andric   bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
380f785676fSDimitry Andric   assert((result || !errMsgCString) &&
381f785676fSDimitry Andric          "Did not expect an error message if FinalizeMemory succeeded");
382f785676fSDimitry Andric   if (errMsgCString) {
383f785676fSDimitry Andric     if (ErrMsg)
384f785676fSDimitry Andric       *ErrMsg = errMsgCString;
385f785676fSDimitry Andric     free(errMsgCString);
386f785676fSDimitry Andric   }
387f785676fSDimitry Andric   return result;
388f785676fSDimitry Andric }
389f785676fSDimitry Andric 
390f785676fSDimitry Andric } // anonymous namespace
391f785676fSDimitry Andric 
LLVMCreateSimpleMCJITMemoryManager(void * Opaque,LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,LLVMMemoryManagerDestroyCallback Destroy)392f785676fSDimitry Andric LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
393f785676fSDimitry Andric   void *Opaque,
394f785676fSDimitry Andric   LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
395f785676fSDimitry Andric   LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
396f785676fSDimitry Andric   LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
397f785676fSDimitry Andric   LLVMMemoryManagerDestroyCallback Destroy) {
398f785676fSDimitry Andric 
399f785676fSDimitry Andric   if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
400f785676fSDimitry Andric       !Destroy)
40191bc56edSDimitry Andric     return nullptr;
402f785676fSDimitry Andric 
403f785676fSDimitry Andric   SimpleBindingMMFunctions functions;
404f785676fSDimitry Andric   functions.AllocateCodeSection = AllocateCodeSection;
405f785676fSDimitry Andric   functions.AllocateDataSection = AllocateDataSection;
406f785676fSDimitry Andric   functions.FinalizeMemory = FinalizeMemory;
407f785676fSDimitry Andric   functions.Destroy = Destroy;
408f785676fSDimitry Andric   return wrap(new SimpleBindingMemoryManager(functions, Opaque));
409f785676fSDimitry Andric }
410f785676fSDimitry Andric 
LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM)411f785676fSDimitry Andric void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
412f785676fSDimitry Andric   delete unwrap(MM);
413f785676fSDimitry Andric }
414f785676fSDimitry Andric 
415*4ba319b5SDimitry Andric /*===-- JIT Event Listener functions -------------------------------------===*/
416*4ba319b5SDimitry Andric 
417*4ba319b5SDimitry Andric 
418*4ba319b5SDimitry Andric #if !LLVM_USE_INTEL_JITEVENTS
LLVMCreateIntelJITEventListener(void)419*4ba319b5SDimitry Andric LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
420*4ba319b5SDimitry Andric {
421*4ba319b5SDimitry Andric   return nullptr;
422*4ba319b5SDimitry Andric }
423*4ba319b5SDimitry Andric #endif
424*4ba319b5SDimitry Andric 
425*4ba319b5SDimitry Andric #if !LLVM_USE_OPROFILE
LLVMCreateOProfileJITEventListener(void)426*4ba319b5SDimitry Andric LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
427*4ba319b5SDimitry Andric {
428*4ba319b5SDimitry Andric   return nullptr;
429*4ba319b5SDimitry Andric }
430*4ba319b5SDimitry Andric #endif
431*4ba319b5SDimitry Andric 
432*4ba319b5SDimitry Andric #if !LLVM_USE_PERF
LLVMCreatePerfJITEventListener(void)433*4ba319b5SDimitry Andric LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
434*4ba319b5SDimitry Andric {
435*4ba319b5SDimitry Andric   return nullptr;
436*4ba319b5SDimitry Andric }
437*4ba319b5SDimitry Andric #endif
438