Skip to content

Commit f93df5e

Browse files
authored
[ORC] Add read operations to orc::MemoryAccess. (#145834)
This commit adds operations to orc::MemoryAccess for reading basic types (uint8_t, uint16_t, uint32_t, uint64_t, pointers, buffers, and strings) from executor memory. The InProcessMemoryAccess and EPCGenericMemoryAccess implementations are updated to support the new operations.
1 parent 76f3cc9 commit f93df5e

File tree

10 files changed

+748
-105
lines changed

10 files changed

+748
-105
lines changed

llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,15 @@ class EPCGenericMemoryAccess : public MemoryAccess {
3131
ExecutorAddr WriteUInt16s;
3232
ExecutorAddr WriteUInt32s;
3333
ExecutorAddr WriteUInt64s;
34-
ExecutorAddr WriteBuffers;
3534
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;
3643
};
3744

3845
/// Create an EPCGenericMemoryAccess instance from a given set of
@@ -68,18 +75,130 @@ class EPCGenericMemoryAccess : public MemoryAccess {
6875
FAs.WriteUInt64s, std::move(OnWriteComplete), Ws);
6976
}
7077

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+
7185
void writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws,
7286
WriteResultFn OnWriteComplete) override {
7387
using namespace shared;
7488
EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessBufferWrite>)>(
7589
FAs.WriteBuffers, std::move(OnWriteComplete), Ws);
7690
}
7791

78-
void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,
79-
WriteResultFn OnWriteComplete) override {
92+
void readUInt8sAsync(ArrayRef<ExecutorAddr> Rs,
93+
OnReadUIntsCompleteFn<uint8_t> OnComplete) override {
8094
using namespace shared;
81-
EPC.callSPSWrapperAsync<void(SPSSequence<SPSMemoryAccessPointerWrite>)>(
82-
FAs.WritePointers, std::move(OnWriteComplete), Ws);
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+
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+
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+
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+
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+
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+
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);
83202
}
84203

85204
private:

llvm/include/llvm/ExecutionEngine/Orc/InProcessMemoryAccess.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,32 @@ class LLVM_ABI InProcessMemoryAccess : public MemoryAccess {
3232
void writeUInt64sAsync(ArrayRef<tpctypes::UInt64Write> Ws,
3333
WriteResultFn OnWriteComplete) override;
3434

35+
void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,
36+
WriteResultFn OnWriteComplete) override;
37+
3538
void writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws,
3639
WriteResultFn OnWriteComplete) override;
3740

38-
void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,
39-
WriteResultFn OnWriteComplete) override;
41+
void readUInt8sAsync(ArrayRef<ExecutorAddr> Rs,
42+
OnReadUIntsCompleteFn<uint8_t> OnComplete) override;
43+
44+
void readUInt16sAsync(ArrayRef<ExecutorAddr> Rs,
45+
OnReadUIntsCompleteFn<uint16_t> OnComplete) override;
46+
47+
void readUInt32sAsync(ArrayRef<ExecutorAddr> Rs,
48+
OnReadUIntsCompleteFn<uint32_t> OnComplete) override;
49+
50+
void readUInt64sAsync(ArrayRef<ExecutorAddr> Rs,
51+
OnReadUIntsCompleteFn<uint64_t> OnComplete) override;
52+
53+
void readPointersAsync(ArrayRef<ExecutorAddr> Rs,
54+
OnReadPointersCompleteFn OnComplete) override;
55+
56+
void readBuffersAsync(ArrayRef<ExecutorAddrRange> Rs,
57+
OnReadBuffersCompleteFn OnComplete) override;
58+
59+
void readStringsAsync(ArrayRef<ExecutorAddr> Rs,
60+
OnReadStringsCompleteFn OnComplete) override;
4061

4162
private:
4263
bool IsArch64Bit;

llvm/include/llvm/ExecutionEngine/Orc/MemoryAccess.h

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ class LLVM_ABI MemoryAccess {
2828
/// Callback function for asynchronous writes.
2929
using WriteResultFn = unique_function<void(Error)>;
3030

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+
3148
virtual ~MemoryAccess();
3249

3350
virtual void writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws,
@@ -42,11 +59,32 @@ class LLVM_ABI MemoryAccess {
4259
virtual void writeUInt64sAsync(ArrayRef<tpctypes::UInt64Write> Ws,
4360
WriteResultFn OnWriteComplete) = 0;
4461

62+
virtual void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,
63+
WriteResultFn OnWriteComplete) = 0;
64+
4565
virtual void writeBuffersAsync(ArrayRef<tpctypes::BufferWrite> Ws,
4666
WriteResultFn OnWriteComplete) = 0;
4767

48-
virtual void writePointersAsync(ArrayRef<tpctypes::PointerWrite> Ws,
49-
WriteResultFn OnWriteComplete) = 0;
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;
5088

5189
Error writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws) {
5290
std::promise<MSVCPError> ResultP;
@@ -79,21 +117,77 @@ class LLVM_ABI MemoryAccess {
79117
return ResultF.get();
80118
}
81119

82-
Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
120+
Error writePointers(ArrayRef<tpctypes::PointerWrite> Ws) {
83121
std::promise<MSVCPError> ResultP;
84122
auto ResultF = ResultP.get_future();
85-
writeBuffersAsync(Ws,
86-
[&](Error Err) { ResultP.set_value(std::move(Err)); });
123+
writePointersAsync(Ws,
124+
[&](Error Err) { ResultP.set_value(std::move(Err)); });
87125
return ResultF.get();
88126
}
89127

90-
Error writePointers(ArrayRef<tpctypes::PointerWrite> Ws) {
128+
Error writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws) {
91129
std::promise<MSVCPError> ResultP;
92130
auto ResultF = ResultP.get_future();
93-
writePointersAsync(Ws,
94-
[&](Error Err) { ResultP.set_value(std::move(Err)); });
131+
writeBuffersAsync(Ws,
132+
[&](Error Err) { ResultP.set_value(std::move(Err)); });
95133
return ResultF.get();
96134
}
135+
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+
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+
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+
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+
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+
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+
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+
}
97191
};
98192

99193
} // namespace llvm::orc

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,16 @@ LLVM_ABI extern const char *MemoryWriteUInt8sWrapperName;
4444
LLVM_ABI extern const char *MemoryWriteUInt16sWrapperName;
4545
LLVM_ABI extern const char *MemoryWriteUInt32sWrapperName;
4646
LLVM_ABI extern const char *MemoryWriteUInt64sWrapperName;
47-
LLVM_ABI extern const char *MemoryWriteBuffersWrapperName;
4847
LLVM_ABI extern const char *MemoryWritePointersWrapperName;
48+
LLVM_ABI extern const char *MemoryWriteBuffersWrapperName;
49+
50+
LLVM_ABI extern const char *MemoryReadUInt8sWrapperName;
51+
LLVM_ABI extern const char *MemoryReadUInt16sWrapperName;
52+
LLVM_ABI extern const char *MemoryReadUInt32sWrapperName;
53+
LLVM_ABI extern const char *MemoryReadUInt64sWrapperName;
54+
LLVM_ABI extern const char *MemoryReadPointersWrapperName;
55+
LLVM_ABI extern const char *MemoryReadBuffersWrapperName;
56+
LLVM_ABI extern const char *MemoryReadStringsWrapperName;
4957

5058
LLVM_ABI extern const char *RegisterEHFrameSectionAllocActionName;
5159
LLVM_ABI extern const char *DeregisterEHFrameSectionAllocActionName;

llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ using UInt64Write = UIntWrite<uint64_t>;
9393
/// For use with TargetProcessControl::MemoryAccess objects.
9494
struct BufferWrite {
9595
BufferWrite() = default;
96-
BufferWrite(ExecutorAddr Addr, StringRef Buffer)
96+
BufferWrite(ExecutorAddr Addr, ArrayRef<char> Buffer)
9797
: Addr(Addr), Buffer(Buffer) {}
9898

9999
ExecutorAddr Addr;
100-
StringRef Buffer;
100+
ArrayRef<char> Buffer;
101101
};
102102

103103
/// Describes a write to a pointer.

0 commit comments

Comments
 (0)