xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===------------------------ OrcRTBootstrap.cpp --------------------------===//
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 "OrcRTBootstrap.h"
10 
11 #include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
12 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
13 #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
14 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
15 
16 #define DEBUG_TYPE "orc"
17 
18 using namespace llvm::orc::shared;
19 
20 namespace llvm {
21 namespace orc {
22 namespace rt_bootstrap {
23 
24 template <typename WriteT, typename SPSWriteT>
25 static llvm::orc::shared::CWrapperFunctionResult
26 writeUIntsWrapper(const char *ArgData, size_t ArgSize) {
27   return WrapperFunction<void(SPSSequence<SPSWriteT>)>::handle(
28              ArgData, ArgSize,
29              [](std::vector<WriteT> Ws) {
30                for (auto &W : Ws)
31                  *W.Addr.template toPtr<decltype(W.Value) *>() = W.Value;
32              })
33       .release();
34 }
35 
36 static llvm::orc::shared::CWrapperFunctionResult
37 writePointersWrapper(const char *ArgData, size_t ArgSize) {
38   return WrapperFunction<void(SPSSequence<SPSMemoryAccessPointerWrite>)>::
39       handle(ArgData, ArgSize,
40              [](std::vector<tpctypes::PointerWrite> Ws) {
41                for (auto &W : Ws)
42                  *W.Addr.template toPtr<void **>() =
43                      W.Value.template toPtr<void *>();
44              })
45           .release();
46 }
47 
48 static llvm::orc::shared::CWrapperFunctionResult
49 writeBuffersWrapper(const char *ArgData, size_t ArgSize) {
50   return WrapperFunction<void(SPSSequence<SPSMemoryAccessBufferWrite>)>::handle(
51              ArgData, ArgSize,
52              [](std::vector<tpctypes::BufferWrite> Ws) {
53                for (auto &W : Ws)
54                  memcpy(W.Addr.template toPtr<char *>(), W.Buffer.data(),
55                         W.Buffer.size());
56              })
57       .release();
58 }
59 
60 template <typename ReadT>
61 static llvm::orc::shared::CWrapperFunctionResult
62 readUIntsWrapper(const char *ArgData, size_t ArgSize) {
63   using SPSSig = SPSSequence<ReadT>(SPSSequence<SPSExecutorAddr>);
64   return WrapperFunction<SPSSig>::handle(ArgData, ArgSize,
65                                          [](std::vector<ExecutorAddr> Rs) {
66                                            std::vector<ReadT> Result;
67                                            Result.reserve(Rs.size());
68                                            for (auto &R : Rs)
69                                              Result.push_back(
70                                                  *R.toPtr<ReadT *>());
71                                            return Result;
72                                          })
73       .release();
74 }
75 
76 static llvm::orc::shared::CWrapperFunctionResult
77 readPointersWrapper(const char *ArgData, size_t ArgSize) {
78   using SPSSig = SPSSequence<SPSExecutorAddr>(SPSSequence<SPSExecutorAddr>);
79   return WrapperFunction<SPSSig>::handle(
80              ArgData, ArgSize,
81              [](std::vector<ExecutorAddr> Rs) {
82                std::vector<ExecutorAddr> Result;
83                Result.reserve(Rs.size());
84                for (auto &R : Rs)
85                  Result.push_back(ExecutorAddr::fromPtr(*R.toPtr<void **>()));
86                return Result;
87              })
88       .release();
89 }
90 
91 static llvm::orc::shared::CWrapperFunctionResult
92 readBuffersWrapper(const char *ArgData, size_t ArgSize) {
93   using SPSSig =
94       SPSSequence<SPSSequence<uint8_t>>(SPSSequence<SPSExecutorAddrRange>);
95   return WrapperFunction<SPSSig>::handle(
96              ArgData, ArgSize,
97              [](std::vector<ExecutorAddrRange> Rs) {
98                std::vector<std::vector<uint8_t>> Result;
99                Result.reserve(Rs.size());
100                for (auto &R : Rs) {
101                  Result.push_back({});
102                  Result.back().resize(R.size());
103                  memcpy(reinterpret_cast<char *>(Result.back().data()),
104                         R.Start.toPtr<char *>(), R.size());
105                }
106                return Result;
107              })
108       .release();
109 }
110 
111 static llvm::orc::shared::CWrapperFunctionResult
112 readStringsWrapper(const char *ArgData, size_t ArgSize) {
113   using SPSSig = SPSSequence<SPSString>(SPSSequence<SPSExecutorAddr>);
114   return WrapperFunction<SPSSig>::handle(ArgData, ArgSize,
115                                          [](std::vector<ExecutorAddr> Rs) {
116                                            std::vector<std::string> Result;
117                                            Result.reserve(Rs.size());
118                                            for (auto &R : Rs)
119                                              Result.push_back(
120                                                  R.toPtr<char *>());
121                                            return Result;
122                                          })
123       .release();
124 }
125 
126 static llvm::orc::shared::CWrapperFunctionResult
127 runAsMainWrapper(const char *ArgData, size_t ArgSize) {
128   return WrapperFunction<rt::SPSRunAsMainSignature>::handle(
129              ArgData, ArgSize,
130              [](ExecutorAddr MainAddr,
131                 std::vector<std::string> Args) -> int64_t {
132                return runAsMain(MainAddr.toPtr<int (*)(int, char *[])>(), Args);
133              })
134       .release();
135 }
136 
137 static llvm::orc::shared::CWrapperFunctionResult
138 runAsVoidFunctionWrapper(const char *ArgData, size_t ArgSize) {
139   return WrapperFunction<rt::SPSRunAsVoidFunctionSignature>::handle(
140              ArgData, ArgSize,
141              [](ExecutorAddr MainAddr) -> int32_t {
142                return runAsVoidFunction(MainAddr.toPtr<int32_t (*)(void)>());
143              })
144       .release();
145 }
146 
147 static llvm::orc::shared::CWrapperFunctionResult
148 runAsIntFunctionWrapper(const char *ArgData, size_t ArgSize) {
149   return WrapperFunction<rt::SPSRunAsIntFunctionSignature>::handle(
150              ArgData, ArgSize,
151              [](ExecutorAddr MainAddr, int32_t Arg) -> int32_t {
152                return runAsIntFunction(MainAddr.toPtr<int32_t (*)(int32_t)>(),
153                                        Arg);
154              })
155       .release();
156 }
157 
158 void addTo(StringMap<ExecutorAddr> &M) {
159   M[rt::MemoryWriteUInt8sWrapperName] = ExecutorAddr::fromPtr(
160       &writeUIntsWrapper<tpctypes::UInt8Write,
161                          shared::SPSMemoryAccessUInt8Write>);
162   M[rt::MemoryWriteUInt16sWrapperName] = ExecutorAddr::fromPtr(
163       &writeUIntsWrapper<tpctypes::UInt16Write,
164                          shared::SPSMemoryAccessUInt16Write>);
165   M[rt::MemoryWriteUInt32sWrapperName] = ExecutorAddr::fromPtr(
166       &writeUIntsWrapper<tpctypes::UInt32Write,
167                          shared::SPSMemoryAccessUInt32Write>);
168   M[rt::MemoryWriteUInt64sWrapperName] = ExecutorAddr::fromPtr(
169       &writeUIntsWrapper<tpctypes::UInt64Write,
170                          shared::SPSMemoryAccessUInt64Write>);
171   M[rt::MemoryWritePointersWrapperName] =
172       ExecutorAddr::fromPtr(&writePointersWrapper);
173   M[rt::MemoryWriteBuffersWrapperName] =
174       ExecutorAddr::fromPtr(&writeBuffersWrapper);
175   M[rt::MemoryReadUInt8sWrapperName] =
176       ExecutorAddr::fromPtr(&readUIntsWrapper<uint8_t>);
177   M[rt::MemoryReadUInt16sWrapperName] =
178       ExecutorAddr::fromPtr(&readUIntsWrapper<uint16_t>);
179   M[rt::MemoryReadUInt32sWrapperName] =
180       ExecutorAddr::fromPtr(&readUIntsWrapper<uint32_t>);
181   M[rt::MemoryReadUInt64sWrapperName] =
182       ExecutorAddr::fromPtr(&readUIntsWrapper<uint64_t>);
183   M[rt::MemoryReadPointersWrapperName] =
184       ExecutorAddr::fromPtr(&readPointersWrapper);
185   M[rt::MemoryReadBuffersWrapperName] =
186       ExecutorAddr::fromPtr(&readBuffersWrapper);
187   M[rt::MemoryReadStringsWrapperName] =
188       ExecutorAddr::fromPtr(&readStringsWrapper);
189   M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper);
190   M[rt::RunAsVoidFunctionWrapperName] =
191       ExecutorAddr::fromPtr(&runAsVoidFunctionWrapper);
192   M[rt::RunAsIntFunctionWrapperName] =
193       ExecutorAddr::fromPtr(&runAsIntFunctionWrapper);
194 }
195 
196 } // end namespace rt_bootstrap
197 } // end namespace orc
198 } // end namespace llvm
199