Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- EPCIndirectionUtils.h - EPC based indirection utils ----*- C++ -*-===//
  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. // Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
  10. // ExecutorProcessControl API to interact with the executor process.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
  15. #define LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
  16.  
  17. #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
  18. #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
  19. #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
  20.  
  21. #include <mutex>
  22.  
  23. namespace llvm {
  24. namespace orc {
  25.  
  26. class ExecutorProcessControl;
  27.  
  28. /// Provides ExecutorProcessControl based indirect stubs, trampoline pool and
  29. /// lazy call through manager.
  30. class EPCIndirectionUtils {
  31.   friend class EPCIndirectionUtilsAccess;
  32.  
  33. public:
  34.   /// ABI support base class. Used to write resolver, stub, and trampoline
  35.   /// blocks.
  36.   class ABISupport {
  37.   protected:
  38.     ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
  39.                unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
  40.         : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
  41.           StubSize(StubSize),
  42.           StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
  43.           ResolverCodeSize(ResolverCodeSize) {}
  44.  
  45.   public:
  46.     virtual ~ABISupport();
  47.  
  48.     unsigned getPointerSize() const { return PointerSize; }
  49.     unsigned getTrampolineSize() const { return TrampolineSize; }
  50.     unsigned getStubSize() const { return StubSize; }
  51.     unsigned getStubToPointerMaxDisplacement() const {
  52.       return StubToPointerMaxDisplacement;
  53.     }
  54.     unsigned getResolverCodeSize() const { return ResolverCodeSize; }
  55.  
  56.     virtual void writeResolverCode(char *ResolverWorkingMem,
  57.                                    JITTargetAddress ResolverTargetAddr,
  58.                                    JITTargetAddress ReentryFnAddr,
  59.                                    JITTargetAddress ReentryCtxAddr) const = 0;
  60.  
  61.     virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
  62.                                   JITTargetAddress TrampolineBlockTragetAddr,
  63.                                   JITTargetAddress ResolverAddr,
  64.                                   unsigned NumTrampolines) const = 0;
  65.  
  66.     virtual void
  67.     writeIndirectStubsBlock(char *StubsBlockWorkingMem,
  68.                             JITTargetAddress StubsBlockTargetAddress,
  69.                             JITTargetAddress PointersBlockTargetAddress,
  70.                             unsigned NumStubs) const = 0;
  71.  
  72.   private:
  73.     unsigned PointerSize = 0;
  74.     unsigned TrampolineSize = 0;
  75.     unsigned StubSize = 0;
  76.     unsigned StubToPointerMaxDisplacement = 0;
  77.     unsigned ResolverCodeSize = 0;
  78.   };
  79.  
  80.   /// Create using the given ABI class.
  81.   template <typename ORCABI>
  82.   static std::unique_ptr<EPCIndirectionUtils>
  83.   CreateWithABI(ExecutorProcessControl &EPC);
  84.  
  85.   /// Create based on the ExecutorProcessControl triple.
  86.   static Expected<std::unique_ptr<EPCIndirectionUtils>>
  87.   Create(ExecutorProcessControl &EPC);
  88.  
  89.   /// Return a reference to the ExecutorProcessControl object.
  90.   ExecutorProcessControl &getExecutorProcessControl() const { return EPC; }
  91.  
  92.   /// Return a reference to the ABISupport object for this instance.
  93.   ABISupport &getABISupport() const { return *ABI; }
  94.  
  95.   /// Release memory for resources held by this instance. This *must* be called
  96.   /// prior to destruction of the class.
  97.   Error cleanup();
  98.  
  99.   /// Write resolver code to the executor process and return its address.
  100.   /// This must be called before any call to createTrampolinePool or
  101.   /// createLazyCallThroughManager.
  102.   Expected<JITTargetAddress>
  103.   writeResolverBlock(JITTargetAddress ReentryFnAddr,
  104.                      JITTargetAddress ReentryCtxAddr);
  105.  
  106.   /// Returns the address of the Resolver block. Returns zero if the
  107.   /// writeResolverBlock method has not previously been called.
  108.   JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
  109.  
  110.   /// Create an IndirectStubsManager for the executor process.
  111.   std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
  112.  
  113.   /// Create a TrampolinePool for the executor process.
  114.   TrampolinePool &getTrampolinePool();
  115.  
  116.   /// Create a LazyCallThroughManager.
  117.   /// This function should only be called once.
  118.   LazyCallThroughManager &
  119.   createLazyCallThroughManager(ExecutionSession &ES,
  120.                                JITTargetAddress ErrorHandlerAddr);
  121.  
  122.   /// Create a LazyCallThroughManager for the executor process.
  123.   LazyCallThroughManager &getLazyCallThroughManager() {
  124.     assert(LCTM && "createLazyCallThroughManager must be called first");
  125.     return *LCTM;
  126.   }
  127.  
  128. private:
  129.   using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
  130.  
  131.   struct IndirectStubInfo {
  132.     IndirectStubInfo() = default;
  133.     IndirectStubInfo(JITTargetAddress StubAddress,
  134.                      JITTargetAddress PointerAddress)
  135.         : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
  136.     JITTargetAddress StubAddress = 0;
  137.     JITTargetAddress PointerAddress = 0;
  138.   };
  139.  
  140.   using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
  141.  
  142.   /// Create an EPCIndirectionUtils instance.
  143.   EPCIndirectionUtils(ExecutorProcessControl &EPC,
  144.                       std::unique_ptr<ABISupport> ABI);
  145.  
  146.   Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
  147.  
  148.   std::mutex EPCUIMutex;
  149.   ExecutorProcessControl &EPC;
  150.   std::unique_ptr<ABISupport> ABI;
  151.   JITTargetAddress ResolverBlockAddr = 0;
  152.   FinalizedAlloc ResolverBlock;
  153.   std::unique_ptr<TrampolinePool> TP;
  154.   std::unique_ptr<LazyCallThroughManager> LCTM;
  155.  
  156.   std::vector<IndirectStubInfo> AvailableIndirectStubs;
  157.   std::vector<FinalizedAlloc> IndirectStubAllocs;
  158. };
  159.  
  160. /// This will call writeResolver on the given EPCIndirectionUtils instance
  161. /// to set up re-entry via a function that will directly return the trampoline
  162. /// landing address.
  163. ///
  164. /// The EPCIndirectionUtils' LazyCallThroughManager must have been previously
  165. /// created via EPCIndirectionUtils::createLazyCallThroughManager.
  166. ///
  167. /// The EPCIndirectionUtils' writeResolver method must not have been previously
  168. /// called.
  169. ///
  170. /// This function is experimental and likely subject to revision.
  171. Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU);
  172.  
  173. namespace detail {
  174.  
  175. template <typename ORCABI>
  176. class ABISupportImpl : public EPCIndirectionUtils::ABISupport {
  177. public:
  178.   ABISupportImpl()
  179.       : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
  180.                    ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
  181.                    ORCABI::ResolverCodeSize) {}
  182.  
  183.   void writeResolverCode(char *ResolverWorkingMem,
  184.                          JITTargetAddress ResolverTargetAddr,
  185.                          JITTargetAddress ReentryFnAddr,
  186.                          JITTargetAddress ReentryCtxAddr) const override {
  187.     ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
  188.                               ReentryFnAddr, ReentryCtxAddr);
  189.   }
  190.  
  191.   void writeTrampolines(char *TrampolineBlockWorkingMem,
  192.                         JITTargetAddress TrampolineBlockTargetAddr,
  193.                         JITTargetAddress ResolverAddr,
  194.                         unsigned NumTrampolines) const override {
  195.     ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
  196.                              TrampolineBlockTargetAddr, ResolverAddr,
  197.                              NumTrampolines);
  198.   }
  199.  
  200.   void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
  201.                                JITTargetAddress StubsBlockTargetAddress,
  202.                                JITTargetAddress PointersBlockTargetAddress,
  203.                                unsigned NumStubs) const override {
  204.     ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
  205.                                     StubsBlockTargetAddress,
  206.                                     PointersBlockTargetAddress, NumStubs);
  207.   }
  208. };
  209.  
  210. } // end namespace detail
  211.  
  212. template <typename ORCABI>
  213. std::unique_ptr<EPCIndirectionUtils>
  214. EPCIndirectionUtils::CreateWithABI(ExecutorProcessControl &EPC) {
  215.   return std::unique_ptr<EPCIndirectionUtils>(new EPCIndirectionUtils(
  216.       EPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
  217. }
  218.  
  219. } // end namespace orc
  220. } // end namespace llvm
  221.  
  222. #endif // LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
  223.