94 lines · cpp
1//===-- JITLinkRedirectableSymbolManager.cpp - JITLink redirection in Orc -===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"10#include "llvm/ExecutionEngine/Orc/Core.h"11 12#define DEBUG_TYPE "orc"13 14using namespace llvm;15using namespace llvm::orc;16 17namespace {18constexpr StringRef JumpStubSectionName = "__orc_stubs";19constexpr StringRef StubPtrSectionName = "__orc_stub_ptrs";20constexpr StringRef StubSuffix = "$__stub_ptr";21} // namespace22 23void JITLinkRedirectableSymbolManager::emitRedirectableSymbols(24 std::unique_ptr<MaterializationResponsibility> R, SymbolMap InitialDests) {25 26 auto &ES = ObjLinkingLayer.getExecutionSession();27 auto G = std::make_unique<jitlink::LinkGraph>(28 ("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(),29 ES.getSymbolStringPool(), ES.getTargetTriple(), SubtargetFeatures(),30 jitlink::getGenericEdgeKindName);31 auto &PointerSection =32 G->createSection(StubPtrSectionName, MemProt::Write | MemProt::Read);33 auto &StubsSection =34 G->createSection(JumpStubSectionName, MemProt::Exec | MemProt::Read);35 36 SymbolFlagsMap NewSymbols;37 for (auto &[Name, Def] : InitialDests) {38 jitlink::Symbol *TargetSym = nullptr;39 if (Def.getAddress())40 TargetSym = &G->addAbsoluteSymbol(41 G->allocateName(*Name + "$__init_tgt"), Def.getAddress(), 0,42 jitlink::Linkage::Strong, jitlink::Scope::Local, false);43 44 auto PtrName = ES.intern((*Name + StubSuffix).str());45 auto &Ptr = AnonymousPtrCreator(*G, PointerSection, TargetSym, 0);46 Ptr.setName(PtrName);47 Ptr.setScope(jitlink::Scope::Hidden);48 auto &Stub = PtrJumpStubCreator(*G, StubsSection, Ptr);49 Stub.setName(Name);50 Stub.setScope(Def.getFlags().isExported() ? jitlink::Scope::Default51 : jitlink::Scope::Hidden);52 Stub.setLinkage(!Def.getFlags().isWeak() ? jitlink::Linkage::Strong53 : jitlink::Linkage::Weak);54 NewSymbols[std::move(PtrName)] = JITSymbolFlags();55 }56 57 // Try to claim responsibility for the new stub symbols.58 if (auto Err = R->defineMaterializing(std::move(NewSymbols))) {59 ES.reportError(std::move(Err));60 return R->failMaterialization();61 }62 63 ObjLinkingLayer.emit(std::move(R), std::move(G));64}65 66Error JITLinkRedirectableSymbolManager::redirect(JITDylib &JD,67 const SymbolMap &NewDests) {68 auto &ES = ObjLinkingLayer.getExecutionSession();69 SymbolLookupSet LS;70 DenseMap<NonOwningSymbolStringPtr, SymbolStringPtr> PtrToStub;71 for (auto &[StubName, Sym] : NewDests) {72 auto PtrName = ES.intern((*StubName + StubSuffix).str());73 PtrToStub[NonOwningSymbolStringPtr(PtrName)] = StubName;74 LS.add(std::move(PtrName));75 }76 auto PtrSyms =77 ES.lookup({{&JD, JITDylibLookupFlags::MatchAllSymbols}}, std::move(LS));78 if (!PtrSyms)79 return PtrSyms.takeError();80 81 std::vector<tpctypes::PointerWrite> PtrWrites;82 for (auto &[PtrName, PtrSym] : *PtrSyms) {83 auto DestSymI = NewDests.find(PtrToStub[NonOwningSymbolStringPtr(PtrName)]);84 assert(DestSymI != NewDests.end() && "Bad ptr -> stub mapping");85 auto &DestSym = DestSymI->second;86 PtrWrites.push_back({PtrSym.getAddress(), DestSym.getAddress()});87 }88 89 return ObjLinkingLayer.getExecutionSession()90 .getExecutorProcessControl()91 .getMemoryAccess()92 .writePointers(PtrWrites);93}94