1*e8d8bef9SDimitry Andric //===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- C++ -*-===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // TargetProcessControl types that are used by both the Orc and
10*e8d8bef9SDimitry Andric // OrcTargetProcess libraries.
11*e8d8bef9SDimitry Andric //
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric 
14*e8d8bef9SDimitry Andric #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
15*e8d8bef9SDimitry Andric #define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
16*e8d8bef9SDimitry Andric 
17*e8d8bef9SDimitry Andric #include "llvm/ADT/ArrayRef.h"
18*e8d8bef9SDimitry Andric #include "llvm/ADT/StringRef.h"
19*e8d8bef9SDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h"
20*e8d8bef9SDimitry Andric 
21*e8d8bef9SDimitry Andric #include <vector>
22*e8d8bef9SDimitry Andric 
23*e8d8bef9SDimitry Andric namespace llvm {
24*e8d8bef9SDimitry Andric namespace orc {
25*e8d8bef9SDimitry Andric namespace tpctypes {
26*e8d8bef9SDimitry Andric 
27*e8d8bef9SDimitry Andric template <typename T> struct UIntWrite {
28*e8d8bef9SDimitry Andric   UIntWrite() = default;
29*e8d8bef9SDimitry Andric   UIntWrite(JITTargetAddress Address, T Value)
30*e8d8bef9SDimitry Andric       : Address(Address), Value(Value) {}
31*e8d8bef9SDimitry Andric 
32*e8d8bef9SDimitry Andric   JITTargetAddress Address = 0;
33*e8d8bef9SDimitry Andric   T Value = 0;
34*e8d8bef9SDimitry Andric };
35*e8d8bef9SDimitry Andric 
36*e8d8bef9SDimitry Andric /// Describes a write to a uint8_t.
37*e8d8bef9SDimitry Andric using UInt8Write = UIntWrite<uint8_t>;
38*e8d8bef9SDimitry Andric 
39*e8d8bef9SDimitry Andric /// Describes a write to a uint16_t.
40*e8d8bef9SDimitry Andric using UInt16Write = UIntWrite<uint16_t>;
41*e8d8bef9SDimitry Andric 
42*e8d8bef9SDimitry Andric /// Describes a write to a uint32_t.
43*e8d8bef9SDimitry Andric using UInt32Write = UIntWrite<uint32_t>;
44*e8d8bef9SDimitry Andric 
45*e8d8bef9SDimitry Andric /// Describes a write to a uint64_t.
46*e8d8bef9SDimitry Andric using UInt64Write = UIntWrite<uint64_t>;
47*e8d8bef9SDimitry Andric 
48*e8d8bef9SDimitry Andric /// Describes a write to a buffer.
49*e8d8bef9SDimitry Andric /// For use with TargetProcessControl::MemoryAccess objects.
50*e8d8bef9SDimitry Andric struct BufferWrite {
51*e8d8bef9SDimitry Andric   BufferWrite() = default;
52*e8d8bef9SDimitry Andric   BufferWrite(JITTargetAddress Address, StringRef Buffer)
53*e8d8bef9SDimitry Andric       : Address(Address), Buffer(Buffer) {}
54*e8d8bef9SDimitry Andric 
55*e8d8bef9SDimitry Andric   JITTargetAddress Address = 0;
56*e8d8bef9SDimitry Andric   StringRef Buffer;
57*e8d8bef9SDimitry Andric };
58*e8d8bef9SDimitry Andric 
59*e8d8bef9SDimitry Andric /// A handle used to represent a loaded dylib in the target process.
60*e8d8bef9SDimitry Andric using DylibHandle = JITTargetAddress;
61*e8d8bef9SDimitry Andric 
62*e8d8bef9SDimitry Andric using LookupResult = std::vector<JITTargetAddress>;
63*e8d8bef9SDimitry Andric 
64*e8d8bef9SDimitry Andric /// Either a uint8_t array or a uint8_t*.
65*e8d8bef9SDimitry Andric union CWrapperFunctionResultData {
66*e8d8bef9SDimitry Andric   uint8_t Value[8];
67*e8d8bef9SDimitry Andric   uint8_t *ValuePtr;
68*e8d8bef9SDimitry Andric };
69*e8d8bef9SDimitry Andric 
70*e8d8bef9SDimitry Andric /// C ABI compatible wrapper function result.
71*e8d8bef9SDimitry Andric ///
72*e8d8bef9SDimitry Andric /// This can be safely returned from extern "C" functions, but should be used
73*e8d8bef9SDimitry Andric /// to construct a WrapperFunctionResult for safety.
74*e8d8bef9SDimitry Andric struct CWrapperFunctionResult {
75*e8d8bef9SDimitry Andric   uint64_t Size;
76*e8d8bef9SDimitry Andric   CWrapperFunctionResultData Data;
77*e8d8bef9SDimitry Andric   void (*Destroy)(CWrapperFunctionResultData Data, uint64_t Size);
78*e8d8bef9SDimitry Andric };
79*e8d8bef9SDimitry Andric 
80*e8d8bef9SDimitry Andric /// C++ wrapper function result: Same as CWrapperFunctionResult but
81*e8d8bef9SDimitry Andric /// auto-releases memory.
82*e8d8bef9SDimitry Andric class WrapperFunctionResult {
83*e8d8bef9SDimitry Andric public:
84*e8d8bef9SDimitry Andric   /// Create a default WrapperFunctionResult.
85*e8d8bef9SDimitry Andric   WrapperFunctionResult() { zeroInit(R); }
86*e8d8bef9SDimitry Andric 
87*e8d8bef9SDimitry Andric   /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This
88*e8d8bef9SDimitry Andric   /// instance takes ownership of the result object and will automatically
89*e8d8bef9SDimitry Andric   /// call the Destroy member upon destruction.
90*e8d8bef9SDimitry Andric   WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {}
91*e8d8bef9SDimitry Andric 
92*e8d8bef9SDimitry Andric   WrapperFunctionResult(const WrapperFunctionResult &) = delete;
93*e8d8bef9SDimitry Andric   WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
94*e8d8bef9SDimitry Andric 
95*e8d8bef9SDimitry Andric   WrapperFunctionResult(WrapperFunctionResult &&Other) {
96*e8d8bef9SDimitry Andric     zeroInit(R);
97*e8d8bef9SDimitry Andric     std::swap(R, Other.R);
98*e8d8bef9SDimitry Andric   }
99*e8d8bef9SDimitry Andric 
100*e8d8bef9SDimitry Andric   WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
101*e8d8bef9SDimitry Andric     CWrapperFunctionResult Tmp;
102*e8d8bef9SDimitry Andric     zeroInit(Tmp);
103*e8d8bef9SDimitry Andric     std::swap(Tmp, Other.R);
104*e8d8bef9SDimitry Andric     std::swap(R, Tmp);
105*e8d8bef9SDimitry Andric     return *this;
106*e8d8bef9SDimitry Andric   }
107*e8d8bef9SDimitry Andric 
108*e8d8bef9SDimitry Andric   ~WrapperFunctionResult() {
109*e8d8bef9SDimitry Andric     if (R.Destroy)
110*e8d8bef9SDimitry Andric       R.Destroy(R.Data, R.Size);
111*e8d8bef9SDimitry Andric   }
112*e8d8bef9SDimitry Andric 
113*e8d8bef9SDimitry Andric   /// Relinquish ownership of and return the CWrapperFunctionResult.
114*e8d8bef9SDimitry Andric   CWrapperFunctionResult release() {
115*e8d8bef9SDimitry Andric     CWrapperFunctionResult Tmp;
116*e8d8bef9SDimitry Andric     zeroInit(Tmp);
117*e8d8bef9SDimitry Andric     std::swap(R, Tmp);
118*e8d8bef9SDimitry Andric     return Tmp;
119*e8d8bef9SDimitry Andric   }
120*e8d8bef9SDimitry Andric 
121*e8d8bef9SDimitry Andric   /// Get an ArrayRef covering the data in the result.
122*e8d8bef9SDimitry Andric   ArrayRef<uint8_t> getData() const {
123*e8d8bef9SDimitry Andric     if (R.Size <= 8)
124*e8d8bef9SDimitry Andric       return ArrayRef<uint8_t>(R.Data.Value, R.Size);
125*e8d8bef9SDimitry Andric     return ArrayRef<uint8_t>(R.Data.ValuePtr, R.Size);
126*e8d8bef9SDimitry Andric   }
127*e8d8bef9SDimitry Andric 
128*e8d8bef9SDimitry Andric   /// Create a WrapperFunctionResult from the given integer, provided its
129*e8d8bef9SDimitry Andric   /// size is no greater than 64 bits.
130*e8d8bef9SDimitry Andric   template <typename T,
131*e8d8bef9SDimitry Andric             typename _ = std::enable_if_t<std::is_integral<T>::value &&
132*e8d8bef9SDimitry Andric                                           sizeof(T) <= sizeof(uint64_t)>>
133*e8d8bef9SDimitry Andric   static WrapperFunctionResult from(T Value) {
134*e8d8bef9SDimitry Andric     CWrapperFunctionResult R;
135*e8d8bef9SDimitry Andric     R.Size = sizeof(T);
136*e8d8bef9SDimitry Andric     memcpy(&R.Data.Value, Value, R.Size);
137*e8d8bef9SDimitry Andric     R.Destroy = nullptr;
138*e8d8bef9SDimitry Andric     return R;
139*e8d8bef9SDimitry Andric   }
140*e8d8bef9SDimitry Andric 
141*e8d8bef9SDimitry Andric   /// Create a WrapperFunctionResult from the given string.
142*e8d8bef9SDimitry Andric   static WrapperFunctionResult from(StringRef S);
143*e8d8bef9SDimitry Andric 
144*e8d8bef9SDimitry Andric   /// Always free Data.ValuePtr by calling free on it.
145*e8d8bef9SDimitry Andric   static void destroyWithFree(CWrapperFunctionResultData Data, uint64_t Size);
146*e8d8bef9SDimitry Andric 
147*e8d8bef9SDimitry Andric   /// Always free Data.ValuePtr by calling delete[] on it.
148*e8d8bef9SDimitry Andric   static void destroyWithDeleteArray(CWrapperFunctionResultData Data,
149*e8d8bef9SDimitry Andric                                      uint64_t Size);
150*e8d8bef9SDimitry Andric 
151*e8d8bef9SDimitry Andric private:
152*e8d8bef9SDimitry Andric   static void zeroInit(CWrapperFunctionResult &R) {
153*e8d8bef9SDimitry Andric     R.Size = 0;
154*e8d8bef9SDimitry Andric     R.Data.ValuePtr = nullptr;
155*e8d8bef9SDimitry Andric     R.Destroy = nullptr;
156*e8d8bef9SDimitry Andric   }
157*e8d8bef9SDimitry Andric 
158*e8d8bef9SDimitry Andric   CWrapperFunctionResult R;
159*e8d8bef9SDimitry Andric };
160*e8d8bef9SDimitry Andric 
161*e8d8bef9SDimitry Andric } // end namespace tpctypes
162*e8d8bef9SDimitry Andric } // end namespace orc
163*e8d8bef9SDimitry Andric } // end namespace llvm
164*e8d8bef9SDimitry Andric 
165*e8d8bef9SDimitry Andric #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
166