123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- TPCIndirectionUtils.h - TPC based indirection utils ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
- // TargetProcessControl API to interact with the target process.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
- #define LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
- #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
- #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
- #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
- #include <mutex>
- namespace llvm {
- namespace orc {
- class TargetProcessControl;
- /// Provides TargetProcessControl based indirect stubs, trampoline pool and
- /// lazy call through manager.
- class TPCIndirectionUtils {
- friend class TPCIndirectionUtilsAccess;
- public:
- /// ABI support base class. Used to write resolver, stub, and trampoline
- /// blocks.
- class ABISupport {
- protected:
- ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
- unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
- : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
- StubSize(StubSize),
- StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
- ResolverCodeSize(ResolverCodeSize) {}
- public:
- virtual ~ABISupport();
- unsigned getPointerSize() const { return PointerSize; }
- unsigned getTrampolineSize() const { return TrampolineSize; }
- unsigned getStubSize() const { return StubSize; }
- unsigned getStubToPointerMaxDisplacement() const {
- return StubToPointerMaxDisplacement;
- }
- unsigned getResolverCodeSize() const { return ResolverCodeSize; }
- virtual void writeResolverCode(char *ResolverWorkingMem,
- JITTargetAddress ResolverTargetAddr,
- JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr) const = 0;
- virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
- JITTargetAddress TrampolineBlockTragetAddr,
- JITTargetAddress ResolverAddr,
- unsigned NumTrampolines) const = 0;
- virtual void
- writeIndirectStubsBlock(char *StubsBlockWorkingMem,
- JITTargetAddress StubsBlockTargetAddress,
- JITTargetAddress PointersBlockTargetAddress,
- unsigned NumStubs) const = 0;
- private:
- unsigned PointerSize = 0;
- unsigned TrampolineSize = 0;
- unsigned StubSize = 0;
- unsigned StubToPointerMaxDisplacement = 0;
- unsigned ResolverCodeSize = 0;
- };
- /// Create using the given ABI class.
- template <typename ORCABI>
- static std::unique_ptr<TPCIndirectionUtils>
- CreateWithABI(TargetProcessControl &TPC);
- /// Create based on the TargetProcessControl triple.
- static Expected<std::unique_ptr<TPCIndirectionUtils>>
- Create(TargetProcessControl &TPC);
- /// Return a reference to the TargetProcessControl object.
- TargetProcessControl &getTargetProcessControl() const { return TPC; }
- /// Return a reference to the ABISupport object for this instance.
- ABISupport &getABISupport() const { return *ABI; }
- /// Release memory for resources held by this instance. This *must* be called
- /// prior to destruction of the class.
- Error cleanup();
- /// Write resolver code to the target process and return its address.
- /// This must be called before any call to createTrampolinePool or
- /// createLazyCallThroughManager.
- Expected<JITTargetAddress>
- writeResolverBlock(JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr);
- /// Returns the address of the Resolver block. Returns zero if the
- /// writeResolverBlock method has not previously been called.
- JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
- /// Create an IndirectStubsManager for the target process.
- std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
- /// Create a TrampolinePool for the target process.
- TrampolinePool &getTrampolinePool();
- /// Create a LazyCallThroughManager.
- /// This function should only be called once.
- LazyCallThroughManager &
- createLazyCallThroughManager(ExecutionSession &ES,
- JITTargetAddress ErrorHandlerAddr);
- /// Create a LazyCallThroughManager for the target process.
- LazyCallThroughManager &getLazyCallThroughManager() {
- assert(LCTM && "createLazyCallThroughManager must be called first");
- return *LCTM;
- }
- private:
- using Allocation = jitlink::JITLinkMemoryManager::Allocation;
- struct IndirectStubInfo {
- IndirectStubInfo() = default;
- IndirectStubInfo(JITTargetAddress StubAddress,
- JITTargetAddress PointerAddress)
- : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
- JITTargetAddress StubAddress = 0;
- JITTargetAddress PointerAddress = 0;
- };
- using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
- /// Create a TPCIndirectionUtils instance.
- TPCIndirectionUtils(TargetProcessControl &TPC,
- std::unique_ptr<ABISupport> ABI);
- Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
- std::mutex TPCUIMutex;
- TargetProcessControl &TPC;
- std::unique_ptr<ABISupport> ABI;
- JITTargetAddress ResolverBlockAddr;
- std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> ResolverBlock;
- std::unique_ptr<TrampolinePool> TP;
- std::unique_ptr<LazyCallThroughManager> LCTM;
- std::vector<IndirectStubInfo> AvailableIndirectStubs;
- std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
- };
- /// This will call writeResolver on the given TPCIndirectionUtils instance
- /// to set up re-entry via a function that will directly return the trampoline
- /// landing address.
- ///
- /// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
- /// created via TPCIndirectionUtils::createLazyCallThroughManager.
- ///
- /// The TPCIndirectionUtils' writeResolver method must not have been previously
- /// called.
- ///
- /// This function is experimental and likely subject to revision.
- Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);
- namespace detail {
- template <typename ORCABI>
- class ABISupportImpl : public TPCIndirectionUtils::ABISupport {
- public:
- ABISupportImpl()
- : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
- ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
- ORCABI::ResolverCodeSize) {}
- void writeResolverCode(char *ResolverWorkingMem,
- JITTargetAddress ResolverTargetAddr,
- JITTargetAddress ReentryFnAddr,
- JITTargetAddress ReentryCtxAddr) const override {
- ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
- ReentryFnAddr, ReentryCtxAddr);
- }
- void writeTrampolines(char *TrampolineBlockWorkingMem,
- JITTargetAddress TrampolineBlockTargetAddr,
- JITTargetAddress ResolverAddr,
- unsigned NumTrampolines) const override {
- ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
- TrampolineBlockTargetAddr, ResolverAddr,
- NumTrampolines);
- }
- void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
- JITTargetAddress StubsBlockTargetAddress,
- JITTargetAddress PointersBlockTargetAddress,
- unsigned NumStubs) const override {
- ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
- StubsBlockTargetAddress,
- PointersBlockTargetAddress, NumStubs);
- }
- };
- } // end namespace detail
- template <typename ORCABI>
- std::unique_ptr<TPCIndirectionUtils>
- TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) {
- return std::unique_ptr<TPCIndirectionUtils>(new TPCIndirectionUtils(
- TPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
- }
- } // end namespace orc
- } // end namespace llvm
- #endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|