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
23namespace llvm::orc {
24
25/// APIs for manipulating memory in the target process.
26class LLVM_ABI MemoryAccess {
27public:
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
89 Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
90 std::promise<MSVCPError> ResultP;
91 auto ResultF = ResultP.get_future();
92 writeUInt8sAsync(Ws, OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
93 return ResultF.get();
94 }
95
96 Error writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws) {
97 std::promise<MSVCPError> ResultP;
98 auto ResultF = ResultP.get_future();
99 writeUInt16sAsync(Ws,
100 OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
101 return ResultF.get();
102 }
103
104 Error writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws) {
105 std::promise<MSVCPError> ResultP;
106 auto ResultF = ResultP.get_future();
107 writeUInt32sAsync(Ws,
108 OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
109 return ResultF.get();
110 }
111
112 Error writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws) {
113 std::promise<MSVCPError> ResultP;
114 auto ResultF = ResultP.get_future();
115 writeUInt64sAsync(Ws,
116 OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
117 return ResultF.get();
118 }
119
120 Error writePointers(ArrayRef<tpctypes::PointerWrite> Ws) {
121 std::promise<MSVCPError> ResultP;
122 auto ResultF = ResultP.get_future();
123 writePointersAsync(Ws,
124 OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
125 return ResultF.get();
126 }
127
128 Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
129 std::promise<MSVCPError> ResultP;
130 auto ResultF = ResultP.get_future();
131 writeBuffersAsync(Ws,
132 OnWriteComplete: [&](Error Err) { ResultP.set_value(std::move(Err)); });
133 return ResultF.get();
134 }
135
136 Expected<ReadUIntsResult<uint8_t>> readUInt8s(ArrayRef<ExecutorAddr> Rs) {
137 std::promise<MSVCPExpected<ReadUIntsResult<uint8_t>>> P;
138 readUInt8sAsync(Rs, OnComplete: [&](Expected<ReadUIntsResult<uint8_t>> Result) {
139 P.set_value(std::move(Result));
140 });
141 return P.get_future().get();
142 }
143
144 Expected<ReadUIntsResult<uint16_t>> readUInt16s(ArrayRef<ExecutorAddr> Rs) {
145 std::promise<MSVCPExpected<ReadUIntsResult<uint16_t>>> P;
146 readUInt16sAsync(Rs, OnComplete: [&](Expected<ReadUIntsResult<uint16_t>> Result) {
147 P.set_value(std::move(Result));
148 });
149 return P.get_future().get();
150 }
151
152 Expected<ReadUIntsResult<uint32_t>> readUInt32s(ArrayRef<ExecutorAddr> Rs) {
153 std::promise<MSVCPExpected<ReadUIntsResult<uint32_t>>> P;
154 readUInt32sAsync(Rs, OnComplete: [&](Expected<ReadUIntsResult<uint32_t>> Result) {
155 P.set_value(std::move(Result));
156 });
157 return P.get_future().get();
158 }
159
160 Expected<ReadUIntsResult<uint64_t>> readUInt64s(ArrayRef<ExecutorAddr> Rs) {
161 std::promise<MSVCPExpected<ReadUIntsResult<uint64_t>>> P;
162 readUInt64sAsync(Rs, OnComplete: [&](Expected<ReadUIntsResult<uint64_t>> Result) {
163 P.set_value(std::move(Result));
164 });
165 return P.get_future().get();
166 }
167
168 Expected<ReadPointersResult> readPointers(ArrayRef<ExecutorAddr> Rs) {
169 std::promise<MSVCPExpected<ReadPointersResult>> P;
170 readPointersAsync(Rs, OnComplete: [&](Expected<ReadPointersResult> Result) {
171 P.set_value(std::move(Result));
172 });
173 return P.get_future().get();
174 }
175
176 Expected<ReadBuffersResult> readBuffers(ArrayRef<ExecutorAddrRange> Rs) {
177 std::promise<MSVCPExpected<ReadBuffersResult>> P;
178 readBuffersAsync(Rs, OnComplete: [&](Expected<ReadBuffersResult> Result) {
179 P.set_value(std::move(Result));
180 });
181 return P.get_future().get();
182 }
183
184 Expected<ReadStringsResult> readStrings(ArrayRef<ExecutorAddr> Rs) {
185 std::promise<MSVCPExpected<ReadStringsResult>> P;
186 readStringsAsync(Rs, OnComplete: [&](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