1 //===- EPCGenericMemoryAccess.h - Generic EPC MemoryAccess impl -*- 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 // Implements ExecutorProcessControl::MemoryAccess by making calls to 10 // ExecutorProcessControl::callWrapperAsync. 11 // 12 // This simplifies the implementaton of new ExecutorProcessControl instances, 13 // as this implementation will always work (at the cost of some performance 14 // overhead for the calls). 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H 19 #define LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H 20 21 #include "llvm/ExecutionEngine/Orc/Core.h" 22 23 namespace llvm { 24 namespace orc { 25 26 class EPCGenericMemoryAccess : public MemoryAccess { 27 public: 28 /// Function addresses for memory access. 29 struct FuncAddrs { 30 ExecutorAddr WriteUInt8s; 31 ExecutorAddr WriteUInt16s; 32 ExecutorAddr WriteUInt32s; 33 ExecutorAddr WriteUInt64s; 34 ExecutorAddr WritePointers; 35 ExecutorAddr WriteBuffers; 36 ExecutorAddr ReadUInt8s; 37 ExecutorAddr ReadUInt16s; 38 ExecutorAddr ReadUInt32s; 39 ExecutorAddr ReadUInt64s; 40 ExecutorAddr ReadPointers; 41 ExecutorAddr ReadBuffers; 42 ExecutorAddr ReadStrings; 43 }; 44 45 /// Create an EPCGenericMemoryAccess instance from a given set of 46 /// function addrs. EPCGenericMemoryAccess(ExecutorProcessControl & EPC,FuncAddrs FAs)47 EPCGenericMemoryAccess(ExecutorProcessControl &EPC, FuncAddrs FAs) 48 : EPC(EPC), FAs(FAs) {} 49 writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws,WriteResultFn OnWriteComplete)50 void writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws, 51 WriteResultFn OnWriteComplete) override { 52 using namespace shared; 53 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessUInt8Write>)>( 54 FAs.WriteUInt8s, std::move(OnWriteComplete), Ws); 55 } 56 writeUInt16sAsync(ArrayRef<tpctypes::UInt16Write> Ws,WriteResultFn OnWriteComplete)57 void writeUInt16sAsync(ArrayRef<tpctypes::UInt16Write> Ws, 58 WriteResultFn OnWriteComplete) override { 59 using namespace shared; 60 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessUInt16Write>)>( 61 FAs.WriteUInt16s, std::move(OnWriteComplete), Ws); 62 } 63 writeUInt32sAsync(ArrayRef<tpctypes::UInt32Write> Ws,WriteResultFn OnWriteComplete)64 void writeUInt32sAsync(ArrayRef<tpctypes::UInt32Write> Ws, 65 WriteResultFn OnWriteComplete) override { 66 using namespace shared; 67 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessUInt32Write>)>( 68 FAs.WriteUInt32s, std::move(OnWriteComplete), Ws); 69 } 70 writeUInt64sAsync(ArrayRef<tpctypes::UInt64Write> Ws,WriteResultFn OnWriteComplete)71 void writeUInt64sAsync(ArrayRef<tpctypes::UInt64Write> Ws, 72 WriteResultFn OnWriteComplete) override { 73 using namespace shared; 74 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessUInt64Write>)>( 75 FAs.WriteUInt64s, std::move(OnWriteComplete), Ws); 76 } 77 writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,WriteResultFn OnWriteComplete)78 void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws, 79 WriteResultFn OnWriteComplete) override { 80 using namespace shared; 81 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessPointerWrite>)>( 82 FAs.WritePointers, std::move(OnWriteComplete), Ws); 83 } 84 writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws,WriteResultFn OnWriteComplete)85 void writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws, 86 WriteResultFn OnWriteComplete) override { 87 using namespace shared; 88 EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessBufferWrite>)>( 89 FAs.WriteBuffers, std::move(OnWriteComplete), Ws); 90 } 91 readUInt8sAsync(ArrayRef<ExecutorAddr> Rs,OnReadUIntsCompleteFn<uint8_t> OnComplete)92 void readUInt8sAsync(ArrayRef<ExecutorAddr> Rs, 93 OnReadUIntsCompleteFn<uint8_t> OnComplete) override { 94 using namespace shared; 95 EPC.callSPSWrapperAsync<SPSSequence<uint8_t>(SPSSequence<SPSExecutorAddr>)>( 96 FAs.ReadUInt8s, 97 [OnComplete = std::move(OnComplete)]( 98 Error Err, ReadUIntsResult<uint8_t> Result) mutable { 99 if (Err) 100 OnComplete(std::move(Err)); 101 else 102 OnComplete(std::move(Result)); 103 }, 104 Rs); 105 } 106 readUInt16sAsync(ArrayRef<ExecutorAddr> Rs,OnReadUIntsCompleteFn<uint16_t> OnComplete)107 void readUInt16sAsync(ArrayRef<ExecutorAddr> Rs, 108 OnReadUIntsCompleteFn<uint16_t> OnComplete) override { 109 using namespace shared; 110 EPC.callSPSWrapperAsync<SPSSequence<uint16_t>( 111 SPSSequence<SPSExecutorAddr>)>( 112 FAs.ReadUInt16s, 113 [OnComplete = std::move(OnComplete)]( 114 Error Err, ReadUIntsResult<uint16_t> Result) mutable { 115 if (Err) 116 OnComplete(std::move(Err)); 117 else 118 OnComplete(std::move(Result)); 119 }, 120 Rs); 121 } 122 readUInt32sAsync(ArrayRef<ExecutorAddr> Rs,OnReadUIntsCompleteFn<uint32_t> OnComplete)123 void readUInt32sAsync(ArrayRef<ExecutorAddr> Rs, 124 OnReadUIntsCompleteFn<uint32_t> OnComplete) override { 125 using namespace shared; 126 EPC.callSPSWrapperAsync<SPSSequence<uint32_t>( 127 SPSSequence<SPSExecutorAddr>)>( 128 FAs.ReadUInt32s, 129 [OnComplete = std::move(OnComplete)]( 130 Error Err, ReadUIntsResult<uint32_t> Result) mutable { 131 if (Err) 132 OnComplete(std::move(Err)); 133 else 134 OnComplete(std::move(Result)); 135 }, 136 Rs); 137 } 138 readUInt64sAsync(ArrayRef<ExecutorAddr> Rs,OnReadUIntsCompleteFn<uint64_t> OnComplete)139 void readUInt64sAsync(ArrayRef<ExecutorAddr> Rs, 140 OnReadUIntsCompleteFn<uint64_t> OnComplete) override { 141 using namespace shared; 142 EPC.callSPSWrapperAsync<SPSSequence<uint64_t>( 143 SPSSequence<SPSExecutorAddr>)>( 144 FAs.ReadUInt64s, 145 [OnComplete = std::move(OnComplete)]( 146 Error Err, ReadUIntsResult<uint64_t> Result) mutable { 147 if (Err) 148 OnComplete(std::move(Err)); 149 else 150 OnComplete(std::move(Result)); 151 }, 152 Rs); 153 } 154 readPointersAsync(ArrayRef<ExecutorAddr> Rs,OnReadPointersCompleteFn OnComplete)155 void readPointersAsync(ArrayRef<ExecutorAddr> Rs, 156 OnReadPointersCompleteFn OnComplete) override { 157 using namespace shared; 158 using SPSSig = SPSSequence<SPSExecutorAddr>(SPSSequence<SPSExecutorAddr>); 159 EPC.callSPSWrapperAsync<SPSSig>( 160 FAs.ReadPointers, 161 [OnComplete = std::move(OnComplete)]( 162 Error Err, ReadPointersResult Result) mutable { 163 if (Err) 164 OnComplete(std::move(Err)); 165 else 166 OnComplete(std::move(Result)); 167 }, 168 Rs); 169 } 170 readBuffersAsync(ArrayRef<ExecutorAddrRange> Rs,OnReadBuffersCompleteFn OnComplete)171 void readBuffersAsync(ArrayRef<ExecutorAddrRange> Rs, 172 OnReadBuffersCompleteFn OnComplete) override { 173 using namespace shared; 174 using SPSSig = 175 SPSSequence<SPSSequence<uint8_t>>(SPSSequence<SPSExecutorAddrRange>); 176 EPC.callSPSWrapperAsync<SPSSig>( 177 FAs.ReadBuffers, 178 [OnComplete = std::move(OnComplete)](Error Err, 179 ReadBuffersResult Result) mutable { 180 if (Err) 181 OnComplete(std::move(Err)); 182 else 183 OnComplete(std::move(Result)); 184 }, 185 Rs); 186 } 187 readStringsAsync(ArrayRef<ExecutorAddr> Rs,OnReadStringsCompleteFn OnComplete)188 void readStringsAsync(ArrayRef<ExecutorAddr> Rs, 189 OnReadStringsCompleteFn OnComplete) override { 190 using namespace shared; 191 using SPSSig = SPSSequence<SPSString>(SPSSequence<SPSExecutorAddr>); 192 EPC.callSPSWrapperAsync<SPSSig>( 193 FAs.ReadStrings, 194 [OnComplete = std::move(OnComplete)](Error Err, 195 ReadStringsResult Result) mutable { 196 if (Err) 197 OnComplete(std::move(Err)); 198 else 199 OnComplete(std::move(Result)); 200 }, 201 Rs); 202 } 203 204 private: 205 ExecutorProcessControl &EPC; 206 FuncAddrs FAs; 207 }; 208 209 } // end namespace orc 210 } // end namespace llvm 211 212 #endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H 213