1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// 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 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 10 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" 11 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" 12 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 13 #include "llvm/ExecutionEngine/Orc/OrcError.h" 14 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 15 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 16 #include "llvm/IR/GlobalVariable.h" 17 #include "llvm/IR/IRBuilder.h" 18 #include "llvm/IR/Mangler.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/Support/DynamicLibrary.h" 21 22 #include <map> 23 24 using namespace llvm; 25 using namespace llvm::orc; 26 27 namespace { 28 29 /// Add a reference to the __dso_handle global to the given module. 30 /// Returns a reference to the __dso_handle IR decl. 31 GlobalVariable *addDSOHandleDecl(Module &M) { 32 auto DSOHandleTy = StructType::create(M.getContext(), "lljit.dso_handle"); 33 return new GlobalVariable(M, DSOHandleTy, true, GlobalValue::ExternalLinkage, 34 nullptr, "__dso_handle"); 35 } 36 37 /// Adds helper function decls and wrapper functions that call the helper with 38 /// some additional prefix arguments. 39 /// 40 /// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix 41 /// args i32 4 and i16 12345, this function will add: 42 /// 43 /// declare i8 @bar(i32, i16, i8, i64) 44 /// 45 /// define i8 @foo(i8, i64) { 46 /// entry: 47 /// %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1) 48 /// ret i8 %2 49 /// } 50 /// 51 Function *addHelperAndWrapper(Module &M, StringRef WrapperName, 52 FunctionType *WrapperFnType, 53 GlobalValue::VisibilityTypes WrapperVisibility, 54 StringRef HelperName, 55 ArrayRef<Value *> HelperPrefixArgs) { 56 std::vector<Type *> HelperArgTypes; 57 for (auto *Arg : HelperPrefixArgs) 58 HelperArgTypes.push_back(Arg->getType()); 59 for (auto *T : WrapperFnType->params()) 60 HelperArgTypes.push_back(T); 61 auto *HelperFnType = 62 FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false); 63 auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage, 64 HelperName, M); 65 66 auto *WrapperFn = Function::Create( 67 WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M); 68 WrapperFn->setVisibility(WrapperVisibility); 69 70 auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn); 71 IRBuilder<> IB(EntryBlock); 72 73 std::vector<Value *> HelperArgs; 74 for (auto *Arg : HelperPrefixArgs) 75 HelperArgs.push_back(Arg); 76 for (auto &Arg : WrapperFn->args()) 77 HelperArgs.push_back(&Arg); 78 auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs); 79 if (HelperFn->getReturnType()->isVoidTy()) 80 IB.CreateRetVoid(); 81 else 82 IB.CreateRet(HelperResult); 83 84 return WrapperFn; 85 } 86 87 class GenericLLVMIRPlatformSupport; 88 89 /// orc::Platform component of Generic LLVM IR Platform support. 90 /// Just forwards calls to the GenericLLVMIRPlatformSupport class below. 91 class GenericLLVMIRPlatform : public Platform { 92 public: 93 GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {} 94 Error setupJITDylib(JITDylib &JD) override; 95 Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) override; 96 Error notifyRemoving(JITDylib &JD, VModuleKey K) override { 97 // Noop -- Nothing to do (yet). 98 return Error::success(); 99 } 100 101 private: 102 GenericLLVMIRPlatformSupport &S; 103 }; 104 105 /// This transform parses llvm.global_ctors to produce a single initialization 106 /// function for the module, records the function, then deletes 107 /// llvm.global_ctors. 108 class GlobalCtorDtorScraper { 109 public: 110 111 GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS, 112 StringRef InitFunctionPrefix) 113 : PS(PS), InitFunctionPrefix(InitFunctionPrefix) {} 114 Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM, 115 MaterializationResponsibility &R); 116 117 private: 118 GenericLLVMIRPlatformSupport &PS; 119 StringRef InitFunctionPrefix; 120 }; 121 122 /// Generic IR Platform Support 123 /// 124 /// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with 125 /// specially named 'init' and 'deinit'. Injects definitions / interposes for 126 /// some runtime API, including __cxa_atexit, dlopen, and dlclose. 127 class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { 128 public: 129 // GenericLLVMIRPlatform &P) : P(P) { 130 GenericLLVMIRPlatformSupport(LLJIT &J) : J(J) { 131 132 MangleAndInterner Mangle(getExecutionSession(), J.getDataLayout()); 133 InitFunctionPrefix = Mangle("__orc_init_func."); 134 135 getExecutionSession().setPlatform( 136 std::make_unique<GenericLLVMIRPlatform>(*this)); 137 138 setInitTransform(J, GlobalCtorDtorScraper(*this, *InitFunctionPrefix)); 139 140 SymbolMap StdInterposes; 141 142 StdInterposes[Mangle("__lljit.platform_support_instance")] = 143 JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags()); 144 StdInterposes[Mangle("__lljit.cxa_atexit_helper")] = JITEvaluatedSymbol( 145 pointerToJITTargetAddress(registerAtExitHelper), JITSymbolFlags()); 146 StdInterposes[Mangle("__lljit.run_atexits_helper")] = JITEvaluatedSymbol( 147 pointerToJITTargetAddress(runAtExitsHelper), JITSymbolFlags()); 148 149 cantFail( 150 J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes)))); 151 cantFail(setupJITDylib(J.getMainJITDylib())); 152 cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule())); 153 } 154 155 ExecutionSession &getExecutionSession() { return J.getExecutionSession(); } 156 157 /// Adds a module that defines the __dso_handle global. 158 Error setupJITDylib(JITDylib &JD) { 159 auto Ctx = std::make_unique<LLVMContext>(); 160 auto M = std::make_unique<Module>("__standard_lib", *Ctx); 161 M->setDataLayout(J.getDataLayout()); 162 163 auto *Int64Ty = Type::getInt64Ty(*Ctx); 164 auto *DSOHandle = new GlobalVariable( 165 *M, Int64Ty, true, GlobalValue::ExternalLinkage, 166 ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)), 167 "__dso_handle"); 168 DSOHandle->setVisibility(GlobalValue::HiddenVisibility); 169 DSOHandle->setInitializer( 170 ConstantInt::get(Int64Ty, pointerToJITTargetAddress(&JD))); 171 return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx))); 172 } 173 174 Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) { 175 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 176 if (auto &InitSym = MU.getInitializerSymbol()) 177 InitSymbols[&JD].add(InitSym); 178 else { 179 // If there's no identified init symbol attached, but there is a symbol 180 // with the GenericIRPlatform::InitFunctionPrefix, then treat that as 181 // an init function. Add the symbol to both the InitSymbols map (which 182 // will trigger a lookup to materialize the module) and the InitFunctions 183 // map (which holds the names of the symbols to execute). 184 for (auto &KV : MU.getSymbols()) 185 if ((*KV.first).startswith(*InitFunctionPrefix)) { 186 InitSymbols[&JD].add(KV.first); 187 InitFunctions[&JD].add(KV.first); 188 } 189 } 190 return Error::success(); 191 } 192 193 Error initialize(JITDylib &JD) override { 194 if (auto Initializers = getInitializers(JD)) { 195 for (auto InitFnAddr : *Initializers) { 196 auto *InitFn = jitTargetAddressToFunction<void (*)()>(InitFnAddr); 197 InitFn(); 198 } 199 } else 200 return Initializers.takeError(); 201 return Error::success(); 202 } 203 204 Error deinitialize(JITDylib &JD) override { 205 if (auto Deinitializers = getDeinitializers(JD)) { 206 for (auto DeinitFnAddr : *Deinitializers) { 207 auto *DeinitFn = jitTargetAddressToFunction<void (*)()>(DeinitFnAddr); 208 DeinitFn(); 209 } 210 } else 211 return Deinitializers.takeError(); 212 213 return Error::success(); 214 } 215 216 void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) { 217 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 218 InitFunctions[&JD].add(InitName); 219 } 220 221 private: 222 Expected<std::vector<JITTargetAddress>> getInitializers(JITDylib &JD) { 223 if (auto Err = issueInitLookups(JD)) 224 return std::move(Err); 225 226 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 227 std::vector<JITDylib *> DFSLinkOrder; 228 229 { 230 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 231 DFSLinkOrder = getDFSLinkOrder(JD); 232 233 for (auto *NextJD : DFSLinkOrder) { 234 auto IFItr = InitFunctions.find(NextJD); 235 if (IFItr != InitFunctions.end()) { 236 LookupSymbols[NextJD] = std::move(IFItr->second); 237 InitFunctions.erase(IFItr); 238 } 239 } 240 } 241 242 auto &ES = getExecutionSession(); 243 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 244 245 if (!LookupResult) 246 return LookupResult.takeError(); 247 248 std::vector<JITTargetAddress> Initializers; 249 while (!DFSLinkOrder.empty()) { 250 auto &NextJD = *DFSLinkOrder.back(); 251 DFSLinkOrder.pop_back(); 252 auto InitsItr = LookupResult->find(&NextJD); 253 if (InitsItr == LookupResult->end()) 254 continue; 255 for (auto &KV : InitsItr->second) 256 Initializers.push_back(KV.second.getAddress()); 257 } 258 259 return Initializers; 260 } 261 262 Expected<std::vector<JITTargetAddress>> getDeinitializers(JITDylib &JD) { 263 auto &ES = getExecutionSession(); 264 265 MangleAndInterner Mangle(getExecutionSession(), J.getDataLayout()); 266 auto LLJITRunAtExits = Mangle("__lljit_run_atexits"); 267 268 DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols; 269 std::vector<JITDylib *> DFSLinkOrder; 270 271 { 272 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 273 DFSLinkOrder = getDFSLinkOrder(JD); 274 275 for (auto *NextJD : DFSLinkOrder) { 276 auto &JDLookupSymbols = LookupSymbols[NextJD]; 277 auto DIFItr = DeInitFunctions.find(NextJD); 278 if (DIFItr != DeInitFunctions.end()) { 279 LookupSymbols[NextJD] = std::move(DIFItr->second); 280 DeInitFunctions.erase(DIFItr); 281 } 282 JDLookupSymbols.add(LLJITRunAtExits, 283 SymbolLookupFlags::WeaklyReferencedSymbol); 284 } 285 } 286 287 auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols); 288 289 if (!LookupResult) 290 return LookupResult.takeError(); 291 292 std::vector<JITTargetAddress> DeInitializers; 293 for (auto *NextJD : DFSLinkOrder) { 294 auto DeInitsItr = LookupResult->find(NextJD); 295 assert(DeInitsItr != LookupResult->end() && 296 "Every JD should have at least __lljit_run_atexits"); 297 298 auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits); 299 if (RunAtExitsItr != DeInitsItr->second.end()) 300 DeInitializers.push_back(RunAtExitsItr->second.getAddress()); 301 302 for (auto &KV : DeInitsItr->second) 303 if (KV.first != LLJITRunAtExits) 304 DeInitializers.push_back(KV.second.getAddress()); 305 } 306 307 return DeInitializers; 308 } 309 310 // Returns a DFS traversal order of the JITDylibs reachable (via 311 // links-against edges) from JD, starting with JD itself. 312 static std::vector<JITDylib *> getDFSLinkOrder(JITDylib &JD) { 313 std::vector<JITDylib *> DFSLinkOrder; 314 std::vector<JITDylib *> WorkStack({&JD}); 315 DenseSet<JITDylib *> Visited; 316 317 while (!WorkStack.empty()) { 318 auto &NextJD = *WorkStack.back(); 319 WorkStack.pop_back(); 320 if (Visited.count(&NextJD)) 321 continue; 322 Visited.insert(&NextJD); 323 DFSLinkOrder.push_back(&NextJD); 324 NextJD.withSearchOrderDo([&](const JITDylibSearchOrder &SearchOrder) { 325 for (auto &KV : SearchOrder) 326 WorkStack.push_back(KV.first); 327 }); 328 } 329 330 return DFSLinkOrder; 331 } 332 333 /// Issue lookups for all init symbols required to initialize JD (and any 334 /// JITDylibs that it depends on). 335 Error issueInitLookups(JITDylib &JD) { 336 DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols; 337 338 { 339 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 340 341 auto DFSLinkOrder = getDFSLinkOrder(JD); 342 343 for (auto *NextJD : DFSLinkOrder) { 344 auto ISItr = InitSymbols.find(NextJD); 345 if (ISItr != InitSymbols.end()) { 346 RequiredInitSymbols[NextJD] = std::move(ISItr->second); 347 InitSymbols.erase(ISItr); 348 } 349 } 350 } 351 352 return Platform::lookupInitSymbols(getExecutionSession(), 353 RequiredInitSymbols) 354 .takeError(); 355 } 356 357 static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx, 358 void *DSOHandle) { 359 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 360 F, Ctx, DSOHandle); 361 } 362 363 static void runAtExitsHelper(void *Self, void *DSOHandle) { 364 static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits( 365 DSOHandle); 366 } 367 368 // Constructs an LLVM IR module containing platform runtime globals, 369 // functions, and interposes. 370 ThreadSafeModule createPlatformRuntimeModule() { 371 auto Ctx = std::make_unique<LLVMContext>(); 372 auto M = std::make_unique<Module>("__standard_lib", *Ctx); 373 M->setDataLayout(J.getDataLayout()); 374 375 auto *GenericIRPlatformSupportTy = 376 StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport"); 377 378 auto *PlatformInstanceDecl = new GlobalVariable( 379 *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage, 380 nullptr, "__lljit.platform_support_instance"); 381 382 auto *DSOHandleDecl = addDSOHandleDecl(*M); 383 384 auto *Int8Ty = Type::getInt8Ty(*Ctx); 385 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 386 auto *VoidTy = Type::getVoidTy(*Ctx); 387 auto *BytePtrTy = PointerType::getUnqual(Int8Ty); 388 auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); 389 auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); 390 391 addHelperAndWrapper( 392 *M, "__cxa_atexit", 393 FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, 394 false), 395 GlobalValue::HiddenVisibility, "__lljit.cxa_atexit_helper", 396 {PlatformInstanceDecl}); 397 398 addHelperAndWrapper( 399 *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false), 400 GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper", 401 {PlatformInstanceDecl, DSOHandleDecl}); 402 403 return ThreadSafeModule(std::move(M), std::move(Ctx)); 404 } 405 406 std::mutex PlatformSupportMutex; 407 LLJIT &J; 408 SymbolStringPtr InitFunctionPrefix; 409 DenseMap<JITDylib *, SymbolLookupSet> InitSymbols; 410 DenseMap<JITDylib *, SymbolLookupSet> InitFunctions; 411 DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions; 412 ItaniumCXAAtExitSupport AtExitMgr; 413 }; 414 415 Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) { 416 return S.setupJITDylib(JD); 417 } 418 419 Error GenericLLVMIRPlatform::notifyAdding(JITDylib &JD, 420 const MaterializationUnit &MU) { 421 return S.notifyAdding(JD, MU); 422 } 423 424 Expected<ThreadSafeModule> 425 GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM, 426 MaterializationResponsibility &R) { 427 auto Err = TSM.withModuleDo([&](Module &M) -> Error { 428 auto &Ctx = M.getContext(); 429 auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors"); 430 431 // If there's no llvm.global_ctors or it's just a decl then skip. 432 if (!GlobalCtors || GlobalCtors->isDeclaration()) 433 return Error::success(); 434 435 std::string InitFunctionName; 436 raw_string_ostream(InitFunctionName) 437 << InitFunctionPrefix << M.getModuleIdentifier(); 438 439 MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout()); 440 auto InternedName = Mangle(InitFunctionName); 441 if (auto Err = 442 R.defineMaterializing({{InternedName, JITSymbolFlags::Callable}})) 443 return Err; 444 445 auto *InitFunc = 446 Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {}, false), 447 GlobalValue::ExternalLinkage, InitFunctionName, &M); 448 InitFunc->setVisibility(GlobalValue::HiddenVisibility); 449 std::vector<std::pair<Function *, unsigned>> Inits; 450 for (auto E : getConstructors(M)) 451 Inits.push_back(std::make_pair(E.Func, E.Priority)); 452 llvm::sort(Inits, [](const std::pair<Function *, unsigned> &LHS, 453 const std::pair<Function *, unsigned> &RHS) { 454 return LHS.first < RHS.first; 455 }); 456 auto *EntryBlock = BasicBlock::Create(Ctx, "entry", InitFunc); 457 IRBuilder<> IB(EntryBlock); 458 for (auto &KV : Inits) 459 IB.CreateCall(KV.first); 460 IB.CreateRetVoid(); 461 462 PS.registerInitFunc(R.getTargetJITDylib(), InternedName); 463 GlobalCtors->eraseFromParent(); 464 return Error::success(); 465 }); 466 467 if (Err) 468 return std::move(Err); 469 470 return std::move(TSM); 471 } 472 473 class MachOPlatformSupport : public LLJIT::PlatformSupport { 474 public: 475 using DLOpenType = void *(*)(const char *Name, int Mode); 476 using DLCloseType = int (*)(void *Handle); 477 using DLSymType = void *(*)(void *Handle, const char *Name); 478 using DLErrorType = const char *(*)(); 479 480 struct DlFcnValues { 481 Optional<void *> RTLDDefault; 482 DLOpenType dlopen = nullptr; 483 DLCloseType dlclose = nullptr; 484 DLSymType dlsym = nullptr; 485 DLErrorType dlerror = nullptr; 486 }; 487 488 static Expected<std::unique_ptr<MachOPlatformSupport>> 489 Create(LLJIT &J, JITDylib &PlatformJITDylib) { 490 491 // Make process symbols visible. 492 { 493 std::string ErrMsg; 494 auto Lib = sys::DynamicLibrary::getPermanentLibrary(nullptr, &ErrMsg); 495 if (!Lib.isValid()) 496 return make_error<StringError>(std::move(ErrMsg), 497 inconvertibleErrorCode()); 498 } 499 500 DlFcnValues DlFcn; 501 502 // Add support for RTLDDefault on known platforms. 503 #ifdef __APPLE__ 504 DlFcn.RTLDDefault = reinterpret_cast<void *>(-2); 505 #endif // __APPLE__ 506 507 if (auto Err = hookUpFunction(DlFcn.dlopen, "dlopen")) 508 return std::move(Err); 509 if (auto Err = hookUpFunction(DlFcn.dlclose, "dlclose")) 510 return std::move(Err); 511 if (auto Err = hookUpFunction(DlFcn.dlsym, "dlsym")) 512 return std::move(Err); 513 if (auto Err = hookUpFunction(DlFcn.dlerror, "dlerror")) 514 return std::move(Err); 515 516 std::unique_ptr<MachOPlatformSupport> MP( 517 new MachOPlatformSupport(J, PlatformJITDylib, DlFcn)); 518 return std::move(MP); 519 } 520 521 Error initialize(JITDylib &JD) override { 522 if (auto InitSeq = MP.getInitializerSequence(JD)) { 523 for (auto &KV : *InitSeq) { 524 KV.second.registerObjCSelectors(); 525 if (auto Err = KV.second.registerObjCClasses()) { 526 // FIXME: Roll back registrations on error? 527 return Err; 528 } 529 } 530 for (auto &KV : *InitSeq) 531 KV.second.runModInits(); 532 } else 533 return InitSeq.takeError(); 534 return Error::success(); 535 } 536 537 Error deinitialize(JITDylib &JD) override { 538 auto &ES = J.getExecutionSession(); 539 if (auto DeinitSeq = MP.getDeinitializerSequence(JD)) { 540 for (auto &KV : *DeinitSeq) { 541 auto DSOHandleName = ES.intern("___dso_handle"); 542 543 // FIXME: Run DeInits here. 544 auto Result = ES.lookup( 545 {{KV.first, JITDylibLookupFlags::MatchAllSymbols}}, 546 SymbolLookupSet(DSOHandleName, 547 SymbolLookupFlags::WeaklyReferencedSymbol)); 548 if (!Result) 549 return Result.takeError(); 550 if (Result->empty()) 551 continue; 552 assert(Result->count(DSOHandleName) && 553 "Result does not contain __dso_handle"); 554 auto *DSOHandle = jitTargetAddressToPointer<void *>( 555 Result->begin()->second.getAddress()); 556 AtExitMgr.runAtExits(DSOHandle); 557 } 558 } else 559 return DeinitSeq.takeError(); 560 return Error::success(); 561 } 562 563 private: 564 template <typename FunctionPtrTy> 565 static Error hookUpFunction(FunctionPtrTy &Fn, const char *Name) { 566 if (auto *FnAddr = sys::DynamicLibrary::SearchForAddressOfSymbol(Name)) { 567 Fn = reinterpret_cast<FunctionPtrTy>(Fn); 568 return Error::success(); 569 } 570 571 return make_error<StringError>((Twine("Can not enable MachO JIT Platform: " 572 "missing function: ") + 573 Name) 574 .str(), 575 inconvertibleErrorCode()); 576 } 577 578 MachOPlatformSupport(LLJIT &J, JITDylib &PlatformJITDylib, DlFcnValues DlFcn) 579 : J(J), MP(setupPlatform(J)), DlFcn(std::move(DlFcn)) { 580 581 MangleAndInterner Mangle(J.getExecutionSession(), J.getDataLayout()); 582 SymbolMap HelperSymbols; 583 584 // platform and atexit helpers. 585 HelperSymbols[Mangle("__lljit.platform_support_instance")] = 586 JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags()); 587 HelperSymbols[Mangle("__lljit.cxa_atexit_helper")] = JITEvaluatedSymbol( 588 pointerToJITTargetAddress(registerAtExitHelper), JITSymbolFlags()); 589 HelperSymbols[Mangle("__lljit.run_atexits_helper")] = JITEvaluatedSymbol( 590 pointerToJITTargetAddress(runAtExitsHelper), JITSymbolFlags()); 591 592 // dlfcn helpers. 593 HelperSymbols[Mangle("__lljit.dlopen_helper")] = JITEvaluatedSymbol( 594 pointerToJITTargetAddress(dlopenHelper), JITSymbolFlags()); 595 HelperSymbols[Mangle("__lljit.dlclose_helper")] = JITEvaluatedSymbol( 596 pointerToJITTargetAddress(dlcloseHelper), JITSymbolFlags()); 597 HelperSymbols[Mangle("__lljit.dlsym_helper")] = JITEvaluatedSymbol( 598 pointerToJITTargetAddress(dlsymHelper), JITSymbolFlags()); 599 HelperSymbols[Mangle("__lljit.dlerror_helper")] = JITEvaluatedSymbol( 600 pointerToJITTargetAddress(dlerrorHelper), JITSymbolFlags()); 601 602 cantFail( 603 PlatformJITDylib.define(absoluteSymbols(std::move(HelperSymbols)))); 604 cantFail(MP.setupJITDylib(J.getMainJITDylib())); 605 cantFail(J.addIRModule(PlatformJITDylib, createPlatformRuntimeModule())); 606 } 607 608 static MachOPlatform &setupPlatform(LLJIT &J) { 609 auto Tmp = std::make_unique<MachOPlatform>( 610 J.getExecutionSession(), 611 static_cast<ObjectLinkingLayer &>(J.getObjLinkingLayer()), 612 createStandardSymbolsObject(J)); 613 auto &MP = *Tmp; 614 J.getExecutionSession().setPlatform(std::move(Tmp)); 615 return MP; 616 } 617 618 static std::unique_ptr<MemoryBuffer> createStandardSymbolsObject(LLJIT &J) { 619 LLVMContext Ctx; 620 Module M("__standard_symbols", Ctx); 621 M.setDataLayout(J.getDataLayout()); 622 623 auto *Int64Ty = Type::getInt64Ty(Ctx); 624 625 auto *DSOHandle = 626 new GlobalVariable(M, Int64Ty, true, GlobalValue::ExternalLinkage, 627 ConstantInt::get(Int64Ty, 0), "__dso_handle"); 628 DSOHandle->setVisibility(GlobalValue::HiddenVisibility); 629 630 return cantFail(J.getIRCompileLayer().getCompiler()(M)); 631 } 632 633 ThreadSafeModule createPlatformRuntimeModule() { 634 auto Ctx = std::make_unique<LLVMContext>(); 635 auto M = std::make_unique<Module>("__standard_lib", *Ctx); 636 M->setDataLayout(J.getDataLayout()); 637 638 auto *MachOPlatformSupportTy = 639 StructType::create(*Ctx, "lljit.MachOPlatformSupport"); 640 641 auto *PlatformInstanceDecl = new GlobalVariable( 642 *M, MachOPlatformSupportTy, true, GlobalValue::ExternalLinkage, nullptr, 643 "__lljit.platform_support_instance"); 644 645 auto *Int8Ty = Type::getInt8Ty(*Ctx); 646 auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); 647 auto *VoidTy = Type::getVoidTy(*Ctx); 648 auto *BytePtrTy = PointerType::getUnqual(Int8Ty); 649 auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); 650 auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); 651 652 addHelperAndWrapper( 653 *M, "__cxa_atexit", 654 FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, 655 false), 656 GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper", 657 {PlatformInstanceDecl}); 658 659 addHelperAndWrapper(*M, "dlopen", 660 FunctionType::get(BytePtrTy, {BytePtrTy, IntTy}, false), 661 GlobalValue::DefaultVisibility, "__lljit.dlopen_helper", 662 {PlatformInstanceDecl}); 663 664 addHelperAndWrapper(*M, "dlclose", 665 FunctionType::get(IntTy, {BytePtrTy}, false), 666 GlobalValue::DefaultVisibility, 667 "__lljit.dlclose_helper", {PlatformInstanceDecl}); 668 669 addHelperAndWrapper( 670 *M, "dlsym", 671 FunctionType::get(BytePtrTy, {BytePtrTy, BytePtrTy}, false), 672 GlobalValue::DefaultVisibility, "__lljit.dlsym_helper", 673 {PlatformInstanceDecl}); 674 675 addHelperAndWrapper(*M, "dlerror", FunctionType::get(BytePtrTy, {}, false), 676 GlobalValue::DefaultVisibility, 677 "__lljit.dlerror_helper", {PlatformInstanceDecl}); 678 679 return ThreadSafeModule(std::move(M), std::move(Ctx)); 680 } 681 682 static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx, 683 void *DSOHandle) { 684 static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.registerAtExit( 685 F, Ctx, DSOHandle); 686 } 687 688 static void runAtExitsHelper(void *Self, void *DSOHandle) { 689 static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.runAtExits(DSOHandle); 690 } 691 692 void *jit_dlopen(const char *Path, int Mode) { 693 JITDylib *JDToOpen = nullptr; 694 // FIXME: Do the right thing with Mode flags. 695 { 696 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 697 698 // Clear any existing error messages. 699 dlErrorMsgs.erase(std::this_thread::get_id()); 700 701 if (auto *JD = J.getExecutionSession().getJITDylibByName(Path)) { 702 auto I = JDRefCounts.find(JD); 703 if (I != JDRefCounts.end()) { 704 ++I->second; 705 return JD; 706 } 707 708 JDRefCounts[JD] = 1; 709 JDToOpen = JD; 710 } 711 } 712 713 if (JDToOpen) { 714 if (auto Err = initialize(*JDToOpen)) { 715 recordError(std::move(Err)); 716 return 0; 717 } 718 } 719 720 // Fall through to dlopen if no JITDylib found for Path. 721 return DlFcn.dlopen(Path, Mode); 722 } 723 724 static void *dlopenHelper(void *Self, const char *Path, int Mode) { 725 return static_cast<MachOPlatformSupport *>(Self)->jit_dlopen(Path, Mode); 726 } 727 728 int jit_dlclose(void *Handle) { 729 JITDylib *JDToClose = nullptr; 730 731 { 732 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 733 734 // Clear any existing error messages. 735 dlErrorMsgs.erase(std::this_thread::get_id()); 736 737 auto I = JDRefCounts.find(Handle); 738 if (I != JDRefCounts.end()) { 739 --I->second; 740 if (I->second == 0) { 741 JDRefCounts.erase(I); 742 JDToClose = static_cast<JITDylib *>(Handle); 743 } else 744 return 0; 745 } 746 } 747 748 if (JDToClose) { 749 if (auto Err = deinitialize(*JDToClose)) { 750 recordError(std::move(Err)); 751 return -1; 752 } 753 return 0; 754 } 755 756 // Fall through to dlclose if no JITDylib found for Path. 757 return DlFcn.dlclose(Handle); 758 } 759 760 static int dlcloseHelper(void *Self, void *Handle) { 761 return static_cast<MachOPlatformSupport *>(Self)->jit_dlclose(Handle); 762 } 763 764 void *jit_dlsym(void *Handle, const char *Name) { 765 JITDylibSearchOrder JITSymSearchOrder; 766 767 // FIXME: RTLD_NEXT, RTLD_SELF not supported. 768 { 769 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 770 771 // Clear any existing error messages. 772 dlErrorMsgs.erase(std::this_thread::get_id()); 773 774 if (JDRefCounts.count(Handle)) { 775 JITSymSearchOrder.push_back( 776 {static_cast<JITDylib *>(Handle), 777 JITDylibLookupFlags::MatchExportedSymbolsOnly}); 778 } else if (Handle == DlFcn.RTLDDefault) { 779 for (auto &KV : JDRefCounts) 780 JITSymSearchOrder.push_back( 781 {static_cast<JITDylib *>(KV.first), 782 JITDylibLookupFlags::MatchExportedSymbolsOnly}); 783 } 784 } 785 786 if (!JITSymSearchOrder.empty()) { 787 MangleAndInterner Mangle(J.getExecutionSession(), J.getDataLayout()); 788 auto MangledName = Mangle(Name); 789 SymbolLookupSet Syms(MangledName, 790 SymbolLookupFlags::WeaklyReferencedSymbol); 791 if (auto Result = J.getExecutionSession().lookup(JITSymSearchOrder, Syms, 792 LookupKind::DLSym)) { 793 auto I = Result->find(MangledName); 794 if (I != Result->end()) 795 return jitTargetAddressToPointer<void *>(I->second.getAddress()); 796 } else { 797 recordError(Result.takeError()); 798 return 0; 799 } 800 } 801 802 // Fall through to dlsym. 803 return DlFcn.dlsym(Handle, Name); 804 } 805 806 static void *dlsymHelper(void *Self, void *Handle, const char *Name) { 807 return static_cast<MachOPlatformSupport *>(Self)->jit_dlsym(Handle, Name); 808 } 809 810 const char *jit_dlerror() { 811 { 812 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 813 auto I = dlErrorMsgs.find(std::this_thread::get_id()); 814 if (I != dlErrorMsgs.end()) 815 return I->second->c_str(); 816 } 817 return DlFcn.dlerror(); 818 } 819 820 static const char *dlerrorHelper(void *Self) { 821 return static_cast<MachOPlatformSupport *>(Self)->jit_dlerror(); 822 } 823 824 void recordError(Error Err) { 825 std::lock_guard<std::mutex> Lock(PlatformSupportMutex); 826 dlErrorMsgs[std::this_thread::get_id()] = 827 std::make_unique<std::string>(toString(std::move(Err))); 828 } 829 830 std::mutex PlatformSupportMutex; 831 LLJIT &J; 832 MachOPlatform &MP; 833 DlFcnValues DlFcn; 834 ItaniumCXAAtExitSupport AtExitMgr; 835 DenseMap<void *, unsigned> JDRefCounts; 836 std::map<std::thread::id, std::unique_ptr<std::string>> dlErrorMsgs; 837 }; 838 839 } // end anonymous namespace 840 841 namespace llvm { 842 namespace orc { 843 844 void LLJIT::PlatformSupport::setInitTransform( 845 LLJIT &J, IRTransformLayer::TransformFunction T) { 846 J.InitHelperTransformLayer->setTransform(std::move(T)); 847 } 848 849 LLJIT::PlatformSupport::~PlatformSupport() {} 850 851 Error LLJITBuilderState::prepareForConstruction() { 852 853 if (!JTMB) { 854 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost()) 855 JTMB = std::move(*JTMBOrErr); 856 else 857 return JTMBOrErr.takeError(); 858 } 859 860 // If the client didn't configure any linker options then auto-configure the 861 // JIT linker. 862 if (!CreateObjectLinkingLayer && JTMB->getCodeModel() == None && 863 JTMB->getRelocationModel() == None) { 864 865 auto &TT = JTMB->getTargetTriple(); 866 if (TT.isOSBinFormatMachO() && 867 (TT.getArch() == Triple::aarch64 || TT.getArch() == Triple::x86_64)) { 868 869 JTMB->setRelocationModel(Reloc::PIC_); 870 JTMB->setCodeModel(CodeModel::Small); 871 CreateObjectLinkingLayer = 872 [](ExecutionSession &ES, 873 const Triple &) -> std::unique_ptr<ObjectLayer> { 874 return std::make_unique<ObjectLinkingLayer>( 875 ES, std::make_unique<jitlink::InProcessMemoryManager>()); 876 }; 877 } 878 } 879 880 return Error::success(); 881 } 882 883 LLJIT::~LLJIT() { 884 if (CompileThreads) 885 CompileThreads->wait(); 886 } 887 888 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) { 889 auto InternedName = ES->intern(Name); 890 SymbolMap Symbols({{InternedName, Sym}}); 891 return Main->define(absoluteSymbols(std::move(Symbols))); 892 } 893 894 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { 895 assert(TSM && "Can not add null module"); 896 897 if (auto Err = 898 TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); })) 899 return Err; 900 901 return InitHelperTransformLayer->add(JD, std::move(TSM), 902 ES->allocateVModule()); 903 } 904 905 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { 906 assert(Obj && "Can not add null object"); 907 908 return ObjTransformLayer.add(JD, std::move(Obj), ES->allocateVModule()); 909 } 910 911 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD, 912 StringRef Name) { 913 return ES->lookup( 914 makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 915 ES->intern(Name)); 916 } 917 918 std::unique_ptr<ObjectLayer> 919 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { 920 921 // If the config state provided an ObjectLinkingLayer factory then use it. 922 if (S.CreateObjectLinkingLayer) 923 return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple()); 924 925 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs 926 // a new SectionMemoryManager for each object. 927 auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); }; 928 auto ObjLinkingLayer = 929 std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); 930 931 if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) { 932 ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true); 933 ObjLinkingLayer->setAutoClaimResponsibilityForObjectSymbols(true); 934 } 935 936 // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence 937 // errors from some GCC / libstdc++ bots. Remove this conversion (i.e. 938 // just return ObjLinkingLayer) once those bots are upgraded. 939 return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer)); 940 } 941 942 Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> 943 LLJIT::createCompileFunction(LLJITBuilderState &S, 944 JITTargetMachineBuilder JTMB) { 945 946 /// If there is a custom compile function creator set then use it. 947 if (S.CreateCompileFunction) 948 return S.CreateCompileFunction(std::move(JTMB)); 949 950 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler, 951 // depending on the number of threads requested. 952 if (S.NumCompileThreads > 0) 953 return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB)); 954 955 auto TM = JTMB.createTargetMachine(); 956 if (!TM) 957 return TM.takeError(); 958 959 return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM)); 960 } 961 962 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) 963 : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()), Main(), 964 DL(""), TT(S.JTMB->getTargetTriple()), 965 ObjLinkingLayer(createObjectLinkingLayer(S, *ES)), 966 ObjTransformLayer(*this->ES, *ObjLinkingLayer) { 967 968 ErrorAsOutParameter _(&Err); 969 970 if (auto MainOrErr = this->ES->createJITDylib("main")) 971 Main = &*MainOrErr; 972 else { 973 Err = MainOrErr.takeError(); 974 return; 975 } 976 977 if (S.DL) 978 DL = std::move(*S.DL); 979 else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget()) 980 DL = std::move(*DLOrErr); 981 else { 982 Err = DLOrErr.takeError(); 983 return; 984 } 985 986 { 987 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB)); 988 if (!CompileFunction) { 989 Err = CompileFunction.takeError(); 990 return; 991 } 992 CompileLayer = std::make_unique<IRCompileLayer>( 993 *ES, ObjTransformLayer, std::move(*CompileFunction)); 994 TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer); 995 InitHelperTransformLayer = 996 std::make_unique<IRTransformLayer>(*ES, *TransformLayer); 997 } 998 999 if (S.NumCompileThreads > 0) { 1000 InitHelperTransformLayer->setCloneToNewContextOnEmit(true); 1001 CompileThreads = 1002 std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads)); 1003 ES->setDispatchMaterialization( 1004 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) { 1005 // FIXME: Switch to move capture once we have c++14. 1006 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU)); 1007 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); }; 1008 CompileThreads->async(std::move(Work)); 1009 }); 1010 } 1011 1012 if (S.SetUpPlatform) 1013 Err = S.SetUpPlatform(*this); 1014 else 1015 setUpGenericLLVMIRPlatform(*this); 1016 } 1017 1018 std::string LLJIT::mangle(StringRef UnmangledName) { 1019 std::string MangledName; 1020 { 1021 raw_string_ostream MangledNameStream(MangledName); 1022 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 1023 } 1024 return MangledName; 1025 } 1026 1027 Error LLJIT::applyDataLayout(Module &M) { 1028 if (M.getDataLayout().isDefault()) 1029 M.setDataLayout(DL); 1030 1031 if (M.getDataLayout() != DL) 1032 return make_error<StringError>( 1033 "Added modules have incompatible data layouts: " + 1034 M.getDataLayout().getStringRepresentation() + " (module) vs " + 1035 DL.getStringRepresentation() + " (jit)", 1036 inconvertibleErrorCode()); 1037 1038 return Error::success(); 1039 } 1040 1041 void setUpGenericLLVMIRPlatform(LLJIT &J) { 1042 J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J)); 1043 } 1044 1045 Error setUpMachOPlatform(LLJIT &J) { 1046 auto MP = MachOPlatformSupport::Create(J, J.getMainJITDylib()); 1047 if (!MP) 1048 return MP.takeError(); 1049 J.setPlatformSupport(std::move(*MP)); 1050 return Error::success(); 1051 } 1052 1053 Error LLLazyJITBuilderState::prepareForConstruction() { 1054 if (auto Err = LLJITBuilderState::prepareForConstruction()) 1055 return Err; 1056 TT = JTMB->getTargetTriple(); 1057 return Error::success(); 1058 } 1059 1060 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { 1061 assert(TSM && "Can not add null module"); 1062 1063 if (auto Err = TSM.withModuleDo( 1064 [&](Module &M) -> Error { return applyDataLayout(M); })) 1065 return Err; 1066 1067 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule()); 1068 } 1069 1070 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) { 1071 1072 // If LLJIT construction failed then bail out. 1073 if (Err) 1074 return; 1075 1076 ErrorAsOutParameter _(&Err); 1077 1078 /// Take/Create the lazy-compile callthrough manager. 1079 if (S.LCTMgr) 1080 LCTMgr = std::move(S.LCTMgr); 1081 else { 1082 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager( 1083 S.TT, *ES, S.LazyCompileFailureAddr)) 1084 LCTMgr = std::move(*LCTMgrOrErr); 1085 else { 1086 Err = LCTMgrOrErr.takeError(); 1087 return; 1088 } 1089 } 1090 1091 // Take/Create the indirect stubs manager builder. 1092 auto ISMBuilder = std::move(S.ISMBuilder); 1093 1094 // If none was provided, try to build one. 1095 if (!ISMBuilder) 1096 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT); 1097 1098 // No luck. Bail out. 1099 if (!ISMBuilder) { 1100 Err = make_error<StringError>("Could not construct " 1101 "IndirectStubsManagerBuilder for target " + 1102 S.TT.str(), 1103 inconvertibleErrorCode()); 1104 return; 1105 } 1106 1107 // Create the COD layer. 1108 CODLayer = std::make_unique<CompileOnDemandLayer>( 1109 *ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder)); 1110 1111 if (S.NumCompileThreads > 0) 1112 CODLayer->setCloneToNewContextOnEmit(true); 1113 } 1114 1115 } // End namespace orc. 1116 } // End namespace llvm. 1117