ChildTarget.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "llvm/Config/config.h"
  2. #include "../RPCChannel.h"
  3. #include "../RemoteTarget.h"
  4. #include "../RemoteTargetMessage.h"
  5. #include "llvm/Support/Memory.h"
  6. #include <assert.h>
  7. #include <map>
  8. #include <stdint.h>
  9. #include <string>
  10. #include <vector>
  11. using namespace llvm;
  12. class LLIChildTarget {
  13. public:
  14. void initialize();
  15. LLIMessageType waitForIncomingMessage();
  16. void handleMessage(LLIMessageType messageType);
  17. RemoteTarget *RT;
  18. RPCChannel RPC;
  19. private:
  20. // Incoming message handlers
  21. void handleAllocateSpace();
  22. void handleLoadSection(bool IsCode);
  23. void handleExecute();
  24. // Outgoing message handlers
  25. void sendChildActive();
  26. void sendAllocationResult(uint64_t Addr);
  27. void sendLoadStatus(uint32_t Status);
  28. void sendExecutionComplete(int Result);
  29. // OS-specific functions
  30. void initializeConnection();
  31. int WriteBytes(const void *Data, size_t Size) {
  32. return RPC.WriteBytes(Data, Size) ? Size : -1;
  33. }
  34. int ReadBytes(void *Data, size_t Size) {
  35. return RPC.ReadBytes(Data, Size) ? Size : -1;
  36. }
  37. // Communication handles (OS-specific)
  38. void *ConnectionData;
  39. };
  40. int main() {
  41. LLIChildTarget ThisChild;
  42. ThisChild.RT = new RemoteTarget();
  43. ThisChild.initialize();
  44. LLIMessageType MsgType;
  45. do {
  46. MsgType = ThisChild.waitForIncomingMessage();
  47. ThisChild.handleMessage(MsgType);
  48. } while (MsgType != LLI_Terminate &&
  49. MsgType != LLI_Error);
  50. delete ThisChild.RT;
  51. return 0;
  52. }
  53. // Public methods
  54. void LLIChildTarget::initialize() {
  55. RPC.createClient();
  56. sendChildActive();
  57. }
  58. LLIMessageType LLIChildTarget::waitForIncomingMessage() {
  59. int32_t MsgType = -1;
  60. if (ReadBytes(&MsgType, 4) > 0)
  61. return (LLIMessageType)MsgType;
  62. return LLI_Error;
  63. }
  64. void LLIChildTarget::handleMessage(LLIMessageType messageType) {
  65. switch (messageType) {
  66. case LLI_AllocateSpace:
  67. handleAllocateSpace();
  68. break;
  69. case LLI_LoadCodeSection:
  70. handleLoadSection(true);
  71. break;
  72. case LLI_LoadDataSection:
  73. handleLoadSection(false);
  74. break;
  75. case LLI_Execute:
  76. handleExecute();
  77. break;
  78. case LLI_Terminate:
  79. RT->stop();
  80. break;
  81. default:
  82. // FIXME: Handle error!
  83. break;
  84. }
  85. }
  86. // Incoming message handlers
  87. void LLIChildTarget::handleAllocateSpace() {
  88. // Read and verify the message data size.
  89. uint32_t DataSize = 0;
  90. int rc = ReadBytes(&DataSize, 4);
  91. (void)rc;
  92. assert(rc == 4);
  93. assert(DataSize == 8);
  94. // Read the message arguments.
  95. uint32_t Alignment = 0;
  96. uint32_t AllocSize = 0;
  97. rc = ReadBytes(&Alignment, 4);
  98. assert(rc == 4);
  99. rc = ReadBytes(&AllocSize, 4);
  100. assert(rc == 4);
  101. // Allocate the memory.
  102. uint64_t Addr;
  103. RT->allocateSpace(AllocSize, Alignment, Addr);
  104. // Send AllocationResult message.
  105. sendAllocationResult(Addr);
  106. }
  107. void LLIChildTarget::handleLoadSection(bool IsCode) {
  108. // Read the message data size.
  109. uint32_t DataSize = 0;
  110. int rc = ReadBytes(&DataSize, 4);
  111. (void)rc;
  112. assert(rc == 4);
  113. // Read the target load address.
  114. uint64_t Addr = 0;
  115. rc = ReadBytes(&Addr, 8);
  116. assert(rc == 8);
  117. size_t BufferSize = DataSize - 8;
  118. if (!RT->isAllocatedMemory(Addr, BufferSize))
  119. return sendLoadStatus(LLI_Status_NotAllocated);
  120. // Read section data into previously allocated buffer
  121. rc = ReadBytes((void*)Addr, BufferSize);
  122. if (rc != (int)(BufferSize))
  123. return sendLoadStatus(LLI_Status_IncompleteMsg);
  124. // If IsCode, mark memory executable
  125. if (IsCode)
  126. sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
  127. // Send MarkLoadComplete message.
  128. sendLoadStatus(LLI_Status_Success);
  129. }
  130. void LLIChildTarget::handleExecute() {
  131. // Read the message data size.
  132. uint32_t DataSize = 0;
  133. int rc = ReadBytes(&DataSize, 4);
  134. (void)rc;
  135. assert(rc == 4);
  136. assert(DataSize == 8);
  137. // Read the target address.
  138. uint64_t Addr = 0;
  139. rc = ReadBytes(&Addr, 8);
  140. assert(rc == 8);
  141. // Call function
  142. int32_t Result = -1;
  143. RT->executeCode(Addr, Result);
  144. // Send ExecutionResult message.
  145. sendExecutionComplete(Result);
  146. }
  147. // Outgoing message handlers
  148. void LLIChildTarget::sendChildActive() {
  149. // Write the message type.
  150. uint32_t MsgType = (uint32_t)LLI_ChildActive;
  151. int rc = WriteBytes(&MsgType, 4);
  152. (void)rc;
  153. assert(rc == 4);
  154. // Write the data size.
  155. uint32_t DataSize = 0;
  156. rc = WriteBytes(&DataSize, 4);
  157. assert(rc == 4);
  158. }
  159. void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
  160. // Write the message type.
  161. uint32_t MsgType = (uint32_t)LLI_AllocationResult;
  162. int rc = WriteBytes(&MsgType, 4);
  163. (void)rc;
  164. assert(rc == 4);
  165. // Write the data size.
  166. uint32_t DataSize = 8;
  167. rc = WriteBytes(&DataSize, 4);
  168. assert(rc == 4);
  169. // Write the allocated address.
  170. rc = WriteBytes(&Addr, 8);
  171. assert(rc == 8);
  172. }
  173. void LLIChildTarget::sendLoadStatus(uint32_t Status) {
  174. // Write the message type.
  175. uint32_t MsgType = (uint32_t)LLI_LoadResult;
  176. int rc = WriteBytes(&MsgType, 4);
  177. (void)rc;
  178. assert(rc == 4);
  179. // Write the data size.
  180. uint32_t DataSize = 4;
  181. rc = WriteBytes(&DataSize, 4);
  182. assert(rc == 4);
  183. // Write the result.
  184. rc = WriteBytes(&Status, 4);
  185. assert(rc == 4);
  186. }
  187. void LLIChildTarget::sendExecutionComplete(int Result) {
  188. // Write the message type.
  189. uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
  190. int rc = WriteBytes(&MsgType, 4);
  191. (void)rc;
  192. assert(rc == 4);
  193. // Write the data size.
  194. uint32_t DataSize = 4;
  195. rc = WriteBytes(&DataSize, 4);
  196. assert(rc == 4);
  197. // Write the result.
  198. rc = WriteBytes(&Result, 4);
  199. assert(rc == 4);
  200. }
  201. #ifdef LLVM_ON_UNIX
  202. #include "../Unix/RPCChannel.inc"
  203. #endif
  204. #ifdef LLVM_ON_WIN32
  205. #include "../Windows/RPCChannel.inc"
  206. #endif