RemoteTargetExternal.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Implementation of the RemoteTargetExternal class which executes JITed code
  11. // in a separate process from where it was built.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Config/config.h"
  15. #include "RemoteTarget.h"
  16. #include "RemoteTargetExternal.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/Support/DataTypes.h"
  19. #include "llvm/Support/Debug.h"
  20. #include "llvm/Support/Format.h"
  21. #include "llvm/Support/Memory.h"
  22. #include "llvm/Support/Program.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. #include <string>
  25. using namespace llvm;
  26. #define DEBUG_TYPE "lli"
  27. bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,
  28. uint64_t &Address) {
  29. DEBUG(dbgs() << "Message [allocate space] size: " << Size <<
  30. ", align: " << Alignment << "\n");
  31. if (!SendAllocateSpace(Alignment, Size)) {
  32. ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";
  33. return false;
  34. }
  35. if (!Receive(LLI_AllocationResult, Address)) {
  36. ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";
  37. return false;
  38. }
  39. if (Address == 0) {
  40. ErrorMsg += "failed allocation, (RemoteTargetExternal::allocateSpace)";
  41. return false;
  42. }
  43. DEBUG(dbgs() << "Message [allocate space] addr: 0x" <<
  44. format("%llx", Address) << "\n");
  45. return true;
  46. }
  47. bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) {
  48. DEBUG(dbgs() << "Message [load data] addr: 0x" << format("%llx", Address) <<
  49. ", size: " << Size << "\n");
  50. if (!SendLoadSection(Address, Data, (uint32_t)Size, false)) {
  51. ErrorMsg += ", (RemoteTargetExternal::loadData)";
  52. return false;
  53. }
  54. int Status = LLI_Status_Success;
  55. if (!Receive(LLI_LoadResult, Status)) {
  56. ErrorMsg += ", (RemoteTargetExternal::loadData)";
  57. return false;
  58. }
  59. if (Status == LLI_Status_IncompleteMsg) {
  60. ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";
  61. return false;
  62. }
  63. if (Status == LLI_Status_NotAllocated) {
  64. ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";
  65. return false;
  66. }
  67. DEBUG(dbgs() << "Message [load data] complete\n");
  68. return true;
  69. }
  70. bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) {
  71. DEBUG(dbgs() << "Message [load code] addr: 0x" << format("%llx", Address) <<
  72. ", size: " << Size << "\n");
  73. if (!SendLoadSection(Address, Data, (uint32_t)Size, true)) {
  74. ErrorMsg += ", (RemoteTargetExternal::loadCode)";
  75. return false;
  76. }
  77. int Status = LLI_Status_Success;
  78. if (!Receive(LLI_LoadResult, Status)) {
  79. ErrorMsg += ", (RemoteTargetExternal::loadCode)";
  80. return false;
  81. }
  82. if (Status == LLI_Status_IncompleteMsg) {
  83. ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";
  84. return false;
  85. }
  86. if (Status == LLI_Status_NotAllocated) {
  87. ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";
  88. return false;
  89. }
  90. DEBUG(dbgs() << "Message [load code] complete\n");
  91. return true;
  92. }
  93. bool RemoteTargetExternal::executeCode(uint64_t Address, int32_t &RetVal) {
  94. DEBUG(dbgs() << "Message [exectue code] addr: " << Address << "\n");
  95. if (!SendExecute(Address)) {
  96. ErrorMsg += ", (RemoteTargetExternal::executeCode)";
  97. return false;
  98. }
  99. if (!Receive(LLI_ExecutionResult, RetVal)) {
  100. ErrorMsg += ", (RemoteTargetExternal::executeCode)";
  101. return false;
  102. }
  103. DEBUG(dbgs() << "Message [exectue code] return: " << RetVal << "\n");
  104. return true;
  105. }
  106. void RemoteTargetExternal::stop() {
  107. SendTerminate();
  108. RPC.Wait();
  109. }
  110. bool RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {
  111. if (!SendHeader(LLI_AllocateSpace)) {
  112. ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";
  113. return false;
  114. }
  115. AppendWrite((const void *)&Alignment, 4);
  116. AppendWrite((const void *)&Size, 4);
  117. if (!SendPayload()) {
  118. ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";
  119. return false;
  120. }
  121. return true;
  122. }
  123. bool RemoteTargetExternal::SendLoadSection(uint64_t Addr,
  124. const void *Data,
  125. uint32_t Size,
  126. bool IsCode) {
  127. LLIMessageType MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;
  128. if (!SendHeader(MsgType)) {
  129. ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";
  130. return false;
  131. }
  132. AppendWrite((const void *)&Addr, 8);
  133. AppendWrite(Data, Size);
  134. if (!SendPayload()) {
  135. ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";
  136. return false;
  137. }
  138. return true;
  139. }
  140. bool RemoteTargetExternal::SendExecute(uint64_t Addr) {
  141. if (!SendHeader(LLI_Execute)) {
  142. ErrorMsg += ", (RemoteTargetExternal::SendExecute)";
  143. return false;
  144. }
  145. AppendWrite((const void *)&Addr, 8);
  146. if (!SendPayload()) {
  147. ErrorMsg += ", (RemoteTargetExternal::SendExecute)";
  148. return false;
  149. }
  150. return true;
  151. }
  152. bool RemoteTargetExternal::SendTerminate() {
  153. return SendHeader(LLI_Terminate);
  154. // No data or data size is sent with Terminate
  155. }
  156. bool RemoteTargetExternal::Receive(LLIMessageType Msg) {
  157. if (!ReceiveHeader(Msg))
  158. return false;
  159. int Unused;
  160. AppendRead(&Unused, 0);
  161. if (!ReceivePayload())
  162. return false;
  163. ReceiveData.clear();
  164. Sizes.clear();
  165. return true;
  166. }
  167. bool RemoteTargetExternal::Receive(LLIMessageType Msg, int32_t &Data) {
  168. if (!ReceiveHeader(Msg))
  169. return false;
  170. AppendRead(&Data, 4);
  171. if (!ReceivePayload())
  172. return false;
  173. ReceiveData.clear();
  174. Sizes.clear();
  175. return true;
  176. }
  177. bool RemoteTargetExternal::Receive(LLIMessageType Msg, uint64_t &Data) {
  178. if (!ReceiveHeader(Msg))
  179. return false;
  180. AppendRead(&Data, 8);
  181. if (!ReceivePayload())
  182. return false;
  183. ReceiveData.clear();
  184. Sizes.clear();
  185. return true;
  186. }
  187. bool RemoteTargetExternal::ReceiveHeader(LLIMessageType ExpectedMsgType) {
  188. assert(ReceiveData.empty() && Sizes.empty() &&
  189. "Payload vector not empty to receive header");
  190. // Message header, with type to follow
  191. uint32_t MsgType;
  192. if (!ReadBytes(&MsgType, 4)) {
  193. ErrorMsg += ", (RemoteTargetExternal::ReceiveHeader)";
  194. return false;
  195. }
  196. if (MsgType != (uint32_t)ExpectedMsgType) {
  197. ErrorMsg = "received unexpected message type";
  198. ErrorMsg += ". Expecting: ";
  199. ErrorMsg += ExpectedMsgType;
  200. ErrorMsg += ", Got: ";
  201. ErrorMsg += MsgType;
  202. return false;
  203. }
  204. return true;
  205. }
  206. bool RemoteTargetExternal::ReceivePayload() {
  207. assert(!ReceiveData.empty() &&
  208. "Payload vector empty to receive");
  209. assert(ReceiveData.size() == Sizes.size() &&
  210. "Unexpected mismatch between data and size");
  211. uint32_t TotalSize = 0;
  212. for (int I=0, E=Sizes.size(); I < E; I++)
  213. TotalSize += Sizes[I];
  214. // Payload size header
  215. uint32_t DataSize;
  216. if (!ReadBytes(&DataSize, 4)) {
  217. ErrorMsg += ", invalid data size";
  218. return false;
  219. }
  220. if (DataSize != TotalSize) {
  221. ErrorMsg = "unexpected data size";
  222. ErrorMsg += ". Expecting: ";
  223. ErrorMsg += TotalSize;
  224. ErrorMsg += ", Got: ";
  225. ErrorMsg += DataSize;
  226. return false;
  227. }
  228. if (DataSize == 0)
  229. return true;
  230. // Payload itself
  231. for (int I=0, E=Sizes.size(); I < E; I++) {
  232. if (!ReadBytes(ReceiveData[I], Sizes[I])) {
  233. ErrorMsg = "unexpected data while reading message";
  234. return false;
  235. }
  236. }
  237. return true;
  238. }
  239. bool RemoteTargetExternal::SendHeader(LLIMessageType MsgType) {
  240. assert(SendData.empty() && Sizes.empty() &&
  241. "Payload vector not empty to send header");
  242. // Message header, with type to follow
  243. if (!WriteBytes(&MsgType, 4)) {
  244. ErrorMsg += ", (RemoteTargetExternal::SendHeader)";
  245. return false;
  246. }
  247. return true;
  248. }
  249. bool RemoteTargetExternal::SendPayload() {
  250. assert(!SendData.empty() && !Sizes.empty() &&
  251. "Payload vector empty to send");
  252. assert(SendData.size() == Sizes.size() &&
  253. "Unexpected mismatch between data and size");
  254. uint32_t TotalSize = 0;
  255. for (int I=0, E=Sizes.size(); I < E; I++)
  256. TotalSize += Sizes[I];
  257. // Payload size header
  258. if (!WriteBytes(&TotalSize, 4)) {
  259. ErrorMsg += ", invalid data size";
  260. return false;
  261. }
  262. if (TotalSize == 0)
  263. return true;
  264. // Payload itself
  265. for (int I=0, E=Sizes.size(); I < E; I++) {
  266. if (!WriteBytes(SendData[I], Sizes[I])) {
  267. ErrorMsg = "unexpected data while writing message";
  268. return false;
  269. }
  270. }
  271. SendData.clear();
  272. Sizes.clear();
  273. return true;
  274. }
  275. void RemoteTargetExternal::AppendWrite(const void *Data, uint32_t Size) {
  276. SendData.push_back(Data);
  277. Sizes.push_back(Size);
  278. }
  279. void RemoteTargetExternal::AppendRead(void *Data, uint32_t Size) {
  280. ReceiveData.push_back(Data);
  281. Sizes.push_back(Size);
  282. }
  283. #ifdef LLVM_ON_UNIX
  284. #include "Unix/RPCChannel.inc"
  285. #endif
  286. #ifdef LLVM_ON_WIN32
  287. #include "Windows/RPCChannel.inc"
  288. #endif