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