12c01b278SSunho Kim //===-- JITLinkRedirectableSymbolManager.cpp - JITLink redirection in Orc -===// 22c01b278SSunho Kim // 32c01b278SSunho Kim // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42c01b278SSunho Kim // See https://llvm.org/LICENSE.txt for license information. 52c01b278SSunho Kim // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62c01b278SSunho Kim // 72c01b278SSunho Kim //===----------------------------------------------------------------------===// 82c01b278SSunho Kim 92c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h" 102c01b278SSunho Kim #include "llvm/ExecutionEngine/Orc/Core.h" 112c01b278SSunho Kim 122c01b278SSunho Kim #define DEBUG_TYPE "orc" 132c01b278SSunho Kim 142c01b278SSunho Kim using namespace llvm; 152c01b278SSunho Kim using namespace llvm::orc; 162c01b278SSunho Kim 17529c0913SLang Hames namespace { 18529c0913SLang Hames constexpr StringRef JumpStubSectionName = "__orc_stubs"; 19529c0913SLang Hames constexpr StringRef StubPtrSectionName = "__orc_stub_ptrs"; 20529c0913SLang Hames constexpr StringRef StubSuffix = "$__stub_ptr"; 21529c0913SLang Hames } // namespace 22529c0913SLang Hames 232c01b278SSunho Kim void JITLinkRedirectableSymbolManager::emitRedirectableSymbols( 245e75f294SLang Hames std::unique_ptr<MaterializationResponsibility> R, SymbolMap InitialDests) { 25529c0913SLang Hames 26188ede28SSunho Kim auto &ES = ObjLinkingLayer.getExecutionSession(); 27529c0913SLang Hames auto G = std::make_unique<jitlink::LinkGraph>( 282ccf7ed2SJared Wyles ("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(), 29*4eaff6c5SLang Hames ES.getSymbolStringPool(), ES.getTargetTriple(), SubtargetFeatures(), 30529c0913SLang Hames jitlink::getGenericEdgeKindName); 31529c0913SLang Hames auto &PointerSection = 32529c0913SLang Hames G->createSection(StubPtrSectionName, MemProt::Write | MemProt::Read); 33529c0913SLang Hames auto &StubsSection = 34529c0913SLang Hames G->createSection(JumpStubSectionName, MemProt::Exec | MemProt::Read); 35529c0913SLang Hames 36529c0913SLang Hames SymbolFlagsMap NewSymbols; 37529c0913SLang Hames for (auto &[Name, Def] : InitialDests) { 38529c0913SLang Hames jitlink::Symbol *TargetSym = nullptr; 39529c0913SLang Hames if (Def.getAddress()) 40529c0913SLang Hames TargetSym = &G->addAbsoluteSymbol( 41529c0913SLang Hames G->allocateName(*Name + "$__init_tgt"), Def.getAddress(), 0, 42529c0913SLang Hames jitlink::Linkage::Strong, jitlink::Scope::Local, false); 43529c0913SLang Hames 44529c0913SLang Hames auto PtrName = ES.intern((*Name + StubSuffix).str()); 45529c0913SLang Hames auto &Ptr = AnonymousPtrCreator(*G, PointerSection, TargetSym, 0); 462ccf7ed2SJared Wyles Ptr.setName(PtrName); 47529c0913SLang Hames Ptr.setScope(jitlink::Scope::Hidden); 48529c0913SLang Hames auto &Stub = PtrJumpStubCreator(*G, StubsSection, Ptr); 492ccf7ed2SJared Wyles Stub.setName(Name); 50529c0913SLang Hames Stub.setScope(jitlink::Scope::Default); 51529c0913SLang Hames NewSymbols[std::move(PtrName)] = JITSymbolFlags(); 522c01b278SSunho Kim } 532c01b278SSunho Kim 54529c0913SLang Hames // Try to claim responsibility for the new stub symbols. 55529c0913SLang Hames if (auto Err = R->defineMaterializing(std::move(NewSymbols))) { 56529c0913SLang Hames ES.reportError(std::move(Err)); 57529c0913SLang Hames return R->failMaterialization(); 582c01b278SSunho Kim } 592c01b278SSunho Kim 60529c0913SLang Hames ObjLinkingLayer.emit(std::move(R), std::move(G)); 612c01b278SSunho Kim } 622c01b278SSunho Kim 635e75f294SLang Hames Error JITLinkRedirectableSymbolManager::redirect(JITDylib &JD, 645e75f294SLang Hames const SymbolMap &NewDests) { 65529c0913SLang Hames auto &ES = ObjLinkingLayer.getExecutionSession(); 66529c0913SLang Hames SymbolLookupSet LS; 67529c0913SLang Hames DenseMap<NonOwningSymbolStringPtr, SymbolStringPtr> PtrToStub; 68529c0913SLang Hames for (auto &[StubName, Sym] : NewDests) { 69529c0913SLang Hames auto PtrName = ES.intern((*StubName + StubSuffix).str()); 70529c0913SLang Hames PtrToStub[NonOwningSymbolStringPtr(PtrName)] = StubName; 71529c0913SLang Hames LS.add(std::move(PtrName)); 72529c0913SLang Hames } 733fb4b6f0SLang Hames auto PtrSyms = 743fb4b6f0SLang Hames ES.lookup({{&JD, JITDylibLookupFlags::MatchAllSymbols}}, std::move(LS)); 75529c0913SLang Hames if (!PtrSyms) 76529c0913SLang Hames return PtrSyms.takeError(); 77529c0913SLang Hames 78529c0913SLang Hames std::vector<tpctypes::PointerWrite> PtrWrites; 79529c0913SLang Hames for (auto &[PtrName, PtrSym] : *PtrSyms) { 80529c0913SLang Hames auto DestSymI = NewDests.find(PtrToStub[NonOwningSymbolStringPtr(PtrName)]); 81529c0913SLang Hames assert(DestSymI != NewDests.end() && "Bad ptr -> stub mapping"); 82529c0913SLang Hames auto &DestSym = DestSymI->second; 83529c0913SLang Hames PtrWrites.push_back({PtrSym.getAddress(), DestSym.getAddress()}); 842c01b278SSunho Kim } 852c01b278SSunho Kim 86188ede28SSunho Kim return ObjLinkingLayer.getExecutionSession() 87188ede28SSunho Kim .getExecutorProcessControl() 88188ede28SSunho Kim .getMemoryAccess() 89188ede28SSunho Kim .writePointers(PtrWrites); 902c01b278SSunho Kim } 91