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