1 //===------- MemoryAccess.h - Executor memory access APIs -------*- 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 // Utilities for accessing memory in the executor processes. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_ORC_MEMORYACCESS_H 14 #define LLVM_EXECUTIONENGINE_ORC_MEMORYACCESS_H 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/FunctionExtras.h" 18 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h" 19 #include "llvm/Support/MSVCErrorWorkarounds.h" 20 21 #include <future> 22 23 namespace llvm::orc { 24 25 /// APIs for manipulating memory in the target process. 26 class LLVM_ABI MemoryAccess { 27 public: 28 /// Callback function for asynchronous writes. 29 using WriteResultFn = unique_function<void(Error)>; 30 31 template <typename T> using ReadUIntsResult = std::vector<T>; 32 template <typename T> 33 using OnReadUIntsCompleteFn = 34 unique_function<void(Expected<ReadUIntsResult<T>>)>; 35 36 using ReadPointersResult = std::vector<ExecutorAddr>; 37 using OnReadPointersCompleteFn = 38 unique_function<void(Expected<ReadPointersResult>)>; 39 40 using ReadBuffersResult = std::vector<std::vector<uint8_t>>; 41 using OnReadBuffersCompleteFn = 42 unique_function<void(Expected<ReadBuffersResult>)>; 43 44 using ReadStringsResult = std::vector<std::string>; 45 using OnReadStringsCompleteFn = 46 unique_function<void(Expected<ReadStringsResult>)>; 47 48 virtual ~MemoryAccess(); 49 50 virtual void writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws, 51 WriteResultFn OnWriteComplete) = 0; 52 53 virtual void writeUInt16sAsync(ArrayRef<tpctypes::UInt16Write> Ws, 54 WriteResultFn OnWriteComplete) = 0; 55 56 virtual void writeUInt32sAsync(ArrayRef<tpctypes::UInt32Write> Ws, 57 WriteResultFn OnWriteComplete) = 0; 58 59 virtual void writeUInt64sAsync(ArrayRef<tpctypes::UInt64Write> Ws, 60 WriteResultFn OnWriteComplete) = 0; 61 62 virtual void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws, 63 WriteResultFn OnWriteComplete) = 0; 64 65 virtual void writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws, 66 WriteResultFn OnWriteComplete) = 0; 67 68 virtual void readUInt8sAsync(ArrayRef<ExecutorAddr> Rs, 69 OnReadUIntsCompleteFn<uint8_t> OnComplete) = 0; 70 71 virtual void readUInt16sAsync(ArrayRef<ExecutorAddr> Rs, 72 OnReadUIntsCompleteFn<uint16_t> OnComplete) = 0; 73 74 virtual void readUInt32sAsync(ArrayRef<ExecutorAddr> Rs, 75 OnReadUIntsCompleteFn<uint32_t> OnComplete) = 0; 76 77 virtual void readUInt64sAsync(ArrayRef<ExecutorAddr> Rs, 78 OnReadUIntsCompleteFn<uint64_t> OnComplete) = 0; 79 80 virtual void readPointersAsync(ArrayRef<ExecutorAddr> Rs, 81 OnReadPointersCompleteFn OnComplete) = 0; 82 83 virtual void readBuffersAsync(ArrayRef<ExecutorAddrRange> Rs, 84 OnReadBuffersCompleteFn OnComplete) = 0; 85 86 virtual void readStringsAsync(ArrayRef<ExecutorAddr> Rs, 87 OnReadStringsCompleteFn OnComplete) = 0; 88 writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws)89 Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) { 90 std::promise<MSVCPError> ResultP; 91 auto ResultF = ResultP.get_future(); 92 writeUInt8sAsync(Ws, [&](Error Err) { ResultP.set_value(std::move(Err)); }); 93 return ResultF.get(); 94 } 95 writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws)96 Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) { 97 std::promise<MSVCPError> ResultP; 98 auto ResultF = ResultP.get_future(); 99 writeUInt16sAsync(Ws, 100 [&](Error Err) { ResultP.set_value(std::move(Err)); }); 101 return ResultF.get(); 102 } 103 writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws)104 Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) { 105 std::promise<MSVCPError> ResultP; 106 auto ResultF = ResultP.get_future(); 107 writeUInt32sAsync(Ws, 108 [&](Error Err) { ResultP.set_value(std::move(Err)); }); 109 return ResultF.get(); 110 } 111 writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws)112 Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) { 113 std::promise<MSVCPError> ResultP; 114 auto ResultF = ResultP.get_future(); 115 writeUInt64sAsync(Ws, 116 [&](Error Err) { ResultP.set_value(std::move(Err)); }); 117 return ResultF.get(); 118 } 119 writePointers(ArrayRef<tpctypes::PointerWrite> Ws)120 Error writePointers(ArrayRef<tpctypes::PointerWrite> Ws) { 121 std::promise<MSVCPError> ResultP; 122 auto ResultF = ResultP.get_future(); 123 writePointersAsync(Ws, 124 [&](Error Err) { ResultP.set_value(std::move(Err)); }); 125 return ResultF.get(); 126 } 127 writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws)128 Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) { 129 std::promise<MSVCPError> ResultP; 130 auto ResultF = ResultP.get_future(); 131 writeBuffersAsync(Ws, 132 [&](Error Err) { ResultP.set_value(std::move(Err)); }); 133 return ResultF.get(); 134 } 135 readUInt8s(ArrayRef<ExecutorAddr> Rs)136 Expected<ReadUIntsResult<uint8_t>> readUInt8s(ArrayRef<ExecutorAddr> Rs) { 137 std::promise<MSVCPExpected<ReadUIntsResult<uint8_t>>> P; 138 readUInt8sAsync(Rs, [&](Expected<ReadUIntsResult<uint8_t>> Result) { 139 P.set_value(std::move(Result)); 140 }); 141 return P.get_future().get(); 142 } 143 readUInt16s(ArrayRef<ExecutorAddr> Rs)144 Expected<ReadUIntsResult<uint16_t>> readUInt16s(ArrayRef<ExecutorAddr> Rs) { 145 std::promise<MSVCPExpected<ReadUIntsResult<uint16_t>>> P; 146 readUInt16sAsync(Rs, [&](Expected<ReadUIntsResult<uint16_t>> Result) { 147 P.set_value(std::move(Result)); 148 }); 149 return P.get_future().get(); 150 } 151 readUInt32s(ArrayRef<ExecutorAddr> Rs)152 Expected<ReadUIntsResult<uint32_t>> readUInt32s(ArrayRef<ExecutorAddr> Rs) { 153 std::promise<MSVCPExpected<ReadUIntsResult<uint32_t>>> P; 154 readUInt32sAsync(Rs, [&](Expected<ReadUIntsResult<uint32_t>> Result) { 155 P.set_value(std::move(Result)); 156 }); 157 return P.get_future().get(); 158 } 159 readUInt64s(ArrayRef<ExecutorAddr> Rs)160 Expected<ReadUIntsResult<uint64_t>> readUInt64s(ArrayRef<ExecutorAddr> Rs) { 161 std::promise<MSVCPExpected<ReadUIntsResult<uint64_t>>> P; 162 readUInt64sAsync(Rs, [&](Expected<ReadUIntsResult<uint64_t>> Result) { 163 P.set_value(std::move(Result)); 164 }); 165 return P.get_future().get(); 166 } 167 readPointers(ArrayRef<ExecutorAddr> Rs)168 Expected<ReadPointersResult> readPointers(ArrayRef<ExecutorAddr> Rs) { 169 std::promise<MSVCPExpected<ReadPointersResult>> P; 170 readPointersAsync(Rs, [&](Expected<ReadPointersResult> Result) { 171 P.set_value(std::move(Result)); 172 }); 173 return P.get_future().get(); 174 } 175 readBuffers(ArrayRef<ExecutorAddrRange> Rs)176 Expected<ReadBuffersResult> readBuffers(ArrayRef<ExecutorAddrRange> Rs) { 177 std::promise<MSVCPExpected<ReadBuffersResult>> P; 178 readBuffersAsync(Rs, [&](Expected<ReadBuffersResult> Result) { 179 P.set_value(std::move(Result)); 180 }); 181 return P.get_future().get(); 182 } 183 readStrings(ArrayRef<ExecutorAddr> Rs)184 Expected<ReadStringsResult> readStrings(ArrayRef<ExecutorAddr> Rs) { 185 std::promise<MSVCPExpected<ReadStringsResult>> P; 186 readStringsAsync(Rs, [&](Expected<ReadStringsResult> Result) { 187 P.set_value(std::move(Result)); 188 }); 189 return P.get_future().get(); 190 } 191 }; 192 193 } // namespace llvm::orc 194 195 #endif // LLVM_EXECUTIONENGINE_ORC_MEMORYACCESS_H 196