1 | //===------ InProcessMemoryAccess.cpp - Direct, in-process mem access -----===// |
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 | #include "llvm/ExecutionEngine/Orc/InProcessMemoryAccess.h" |
10 | |
11 | #define DEBUG_TYPE "orc" |
12 | |
13 | namespace llvm::orc { |
14 | |
15 | MemoryAccess::~MemoryAccess() = default; |
16 | |
17 | void InProcessMemoryAccess::writeUInt8sAsync(ArrayRef<tpctypes::UInt8Write> Ws, |
18 | WriteResultFn OnWriteComplete) { |
19 | for (auto &W : Ws) |
20 | *W.Addr.toPtr<uint8_t *>() = W.Value; |
21 | OnWriteComplete(Error::success()); |
22 | } |
23 | |
24 | void InProcessMemoryAccess::writeUInt16sAsync( |
25 | ArrayRef<tpctypes::UInt16Write> Ws, WriteResultFn OnWriteComplete) { |
26 | for (auto &W : Ws) |
27 | *W.Addr.toPtr<uint16_t *>() = W.Value; |
28 | OnWriteComplete(Error::success()); |
29 | } |
30 | |
31 | void InProcessMemoryAccess::writeUInt32sAsync( |
32 | ArrayRef<tpctypes::UInt32Write> Ws, WriteResultFn OnWriteComplete) { |
33 | for (auto &W : Ws) |
34 | *W.Addr.toPtr<uint32_t *>() = W.Value; |
35 | OnWriteComplete(Error::success()); |
36 | } |
37 | |
38 | void InProcessMemoryAccess::writeUInt64sAsync( |
39 | ArrayRef<tpctypes::UInt64Write> Ws, WriteResultFn OnWriteComplete) { |
40 | for (auto &W : Ws) |
41 | *W.Addr.toPtr<uint64_t *>() = W.Value; |
42 | OnWriteComplete(Error::success()); |
43 | } |
44 | |
45 | void InProcessMemoryAccess::writePointersAsync( |
46 | ArrayRef<tpctypes::PointerWrite> Ws, WriteResultFn OnWriteComplete) { |
47 | if (IsArch64Bit) { |
48 | for (auto &W : Ws) |
49 | *W.Addr.toPtr<uint64_t *>() = W.Value.getValue(); |
50 | } else { |
51 | for (auto &W : Ws) |
52 | *W.Addr.toPtr<uint32_t *>() = static_cast<uint32_t>(W.Value.getValue()); |
53 | } |
54 | |
55 | OnWriteComplete(Error::success()); |
56 | } |
57 | |
58 | void InProcessMemoryAccess::writeBuffersAsync( |
59 | ArrayRef<tpctypes::BufferWrite> Ws, WriteResultFn OnWriteComplete) { |
60 | for (auto &W : Ws) |
61 | memcpy(dest: W.Addr.toPtr<char *>(), src: W.Buffer.data(), n: W.Buffer.size()); |
62 | OnWriteComplete(Error::success()); |
63 | } |
64 | |
65 | void InProcessMemoryAccess::readUInt8sAsync( |
66 | ArrayRef<ExecutorAddr> Rs, OnReadUIntsCompleteFn<uint8_t> OnComplete) { |
67 | ReadUIntsResult<uint8_t> Result; |
68 | Result.reserve(n: Rs.size()); |
69 | for (auto &R : Rs) |
70 | Result.push_back(x: *R.toPtr<uint8_t *>()); |
71 | OnComplete(std::move(Result)); |
72 | } |
73 | |
74 | void InProcessMemoryAccess::readUInt16sAsync( |
75 | ArrayRef<ExecutorAddr> Rs, OnReadUIntsCompleteFn<uint16_t> OnComplete) { |
76 | ReadUIntsResult<uint16_t> Result; |
77 | Result.reserve(n: Rs.size()); |
78 | for (auto &R : Rs) |
79 | Result.push_back(x: *R.toPtr<uint16_t *>()); |
80 | OnComplete(std::move(Result)); |
81 | } |
82 | |
83 | void InProcessMemoryAccess::readUInt32sAsync( |
84 | ArrayRef<ExecutorAddr> Rs, OnReadUIntsCompleteFn<uint32_t> OnComplete) { |
85 | ReadUIntsResult<uint32_t> Result; |
86 | Result.reserve(n: Rs.size()); |
87 | for (auto &R : Rs) |
88 | Result.push_back(x: *R.toPtr<uint32_t *>()); |
89 | OnComplete(std::move(Result)); |
90 | } |
91 | |
92 | void InProcessMemoryAccess::readUInt64sAsync( |
93 | ArrayRef<ExecutorAddr> Rs, OnReadUIntsCompleteFn<uint64_t> OnComplete) { |
94 | ReadUIntsResult<uint64_t> Result; |
95 | Result.reserve(n: Rs.size()); |
96 | for (auto &R : Rs) |
97 | Result.push_back(x: *R.toPtr<uint64_t *>()); |
98 | OnComplete(std::move(Result)); |
99 | } |
100 | |
101 | void InProcessMemoryAccess::readPointersAsync( |
102 | ArrayRef<ExecutorAddr> Rs, OnReadPointersCompleteFn OnComplete) { |
103 | ReadPointersResult Result; |
104 | Result.reserve(n: Rs.size()); |
105 | for (auto &R : Rs) |
106 | Result.push_back(x: ExecutorAddr::fromPtr(Ptr: *R.toPtr<void **>())); |
107 | OnComplete(std::move(Result)); |
108 | } |
109 | |
110 | void InProcessMemoryAccess::readBuffersAsync( |
111 | ArrayRef<ExecutorAddrRange> Rs, OnReadBuffersCompleteFn OnComplete) { |
112 | ReadBuffersResult Result; |
113 | Result.reserve(n: Rs.size()); |
114 | for (auto &R : Rs) { |
115 | Result.push_back(x: {}); |
116 | Result.back().resize(new_size: R.size()); |
117 | memcpy(dest: Result.back().data(), src: R.Start.toPtr<char *>(), n: R.size()); |
118 | } |
119 | OnComplete(std::move(Result)); |
120 | } |
121 | |
122 | void InProcessMemoryAccess::readStringsAsync( |
123 | ArrayRef<ExecutorAddr> Rs, OnReadStringsCompleteFn OnComplete) { |
124 | ReadStringsResult Result; |
125 | Result.reserve(n: Rs.size()); |
126 | for (auto &R : Rs) { |
127 | Result.push_back(x: {}); |
128 | for (auto *P = R.toPtr<char *>(); *P; ++P) |
129 | Result.back().push_back(c: *P); |
130 | } |
131 | OnComplete(std::move(Result)); |
132 | } |
133 | |
134 | } // end namespace llvm::orc |
135 | |