1 //===-- OrcTargetSupport.h - Code to support specific targets  --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Target specific code for Orc, e.g. callback assembly.
11 //
12 // Target classes should be part of the JIT *target* process, not the host
13 // process (except where you're doing hosted JITing and the two are one and the
14 // same).
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H
19 #define LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H
20 
21 #include "IndirectionUtils.h"
22 #include "llvm/Support/Memory.h"
23 
24 namespace llvm {
25 namespace orc {
26 
27 class OrcX86_64 {
28 public:
29   static const unsigned PageSize = 4096;
30   static const unsigned PointerSize = 8;
31   static const unsigned TrampolineSize = 8;
32   static const unsigned ResolverCodeSize = 0x78;
33 
34   typedef TargetAddress (*JITReentryFn)(void *CallbackMgr,
35                                         void *TrampolineId);
36 
37   /// @brief Write the resolver code into the given memory. The user is be
38   ///        responsible for allocating the memory and setting permissions.
39   static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
40                                 void *CallbackMgr);
41 
42   /// @brief Write the requsted number of trampolines into the given memory,
43   ///        which must be big enough to hold 1 pointer, plus NumTrampolines
44   ///        trampolines.
45   static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
46                                unsigned NumTrampolines);
47 
48   /// @brief Provide information about stub blocks generated by the
49   ///        makeIndirectStubsBlock function.
50   class IndirectStubsInfo {
51     friend class OrcX86_64;
52   public:
53     const static unsigned StubSize = 8;
54     const static unsigned PtrSize = 8;
55 
IndirectStubsInfo()56     IndirectStubsInfo() : NumStubs(0) {}
IndirectStubsInfo(IndirectStubsInfo && Other)57     IndirectStubsInfo(IndirectStubsInfo &&Other)
58         : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
59       Other.NumStubs = 0;
60     }
61     IndirectStubsInfo& operator=(IndirectStubsInfo &&Other) {
62       NumStubs = Other.NumStubs;
63       Other.NumStubs = 0;
64       StubsMem = std::move(Other.StubsMem);
65       return *this;
66     }
67 
68     /// @brief Number of stubs in this block.
getNumStubs()69     unsigned getNumStubs() const { return NumStubs; }
70 
71     /// @brief Get a pointer to the stub at the given index, which must be in
72     ///        the range 0 .. getNumStubs() - 1.
getStub(unsigned Idx)73     void* getStub(unsigned Idx) const {
74       return static_cast<uint64_t*>(StubsMem.base()) + Idx;
75     }
76 
77     /// @brief Get a pointer to the implementation-pointer at the given index,
78     ///        which must be in the range 0 .. getNumStubs() - 1.
getPtr(unsigned Idx)79     void** getPtr(unsigned Idx) const {
80       char *PtrsBase =
81         static_cast<char*>(StubsMem.base()) + NumStubs * StubSize;
82       return reinterpret_cast<void**>(PtrsBase) + Idx;
83     }
84   private:
85     unsigned NumStubs;
86     sys::OwningMemoryBlock StubsMem;
87   };
88 
89   /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
90   ///        the nearest page size.
91   ///
92   ///   E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
93   /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
94   /// will return a block of 1024 (2-pages worth).
95   static std::error_code emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
96                                                 unsigned MinStubs,
97                                                 void *InitialPtrVal);
98 };
99 
100 } // End namespace orc.
101 } // End namespace llvm.
102 
103 #endif // LLVM_EXECUTIONENGINE_ORC_ORCTARGETSUPPORT_H
104