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