RemoteTargetExternal.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //===----- RemoteTargetExternal.h - 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. // Definition of the RemoteTargetExternal class which executes JITed code in a
  11. // separate process from where it was built.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H
  15. #define LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H
  16. #include "RPCChannel.h"
  17. #include "RemoteTarget.h"
  18. #include "RemoteTargetMessage.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Config/config.h"
  22. #include "llvm/Support/DataTypes.h"
  23. #include "llvm/Support/Memory.h"
  24. #include <stdlib.h>
  25. #include <string>
  26. namespace llvm {
  27. class RemoteTargetExternal : public RemoteTarget {
  28. RPCChannel RPC;
  29. bool WriteBytes(const void *Data, size_t Size) {
  30. return RPC.WriteBytes(Data, Size);
  31. }
  32. bool ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); }
  33. public:
  34. /// Allocate space in the remote target address space.
  35. ///
  36. /// @param Size Amount of space, in bytes, to allocate.
  37. /// @param Alignment Required minimum alignment for allocated space.
  38. /// @param[out] Address Remote address of the allocated memory.
  39. ///
  40. /// @returns True on success. On failure, ErrorMsg is updated with
  41. /// descriptive text of the encountered error.
  42. bool allocateSpace(size_t Size, unsigned Alignment,
  43. uint64_t &Address) override;
  44. /// Load data into the target address space.
  45. ///
  46. /// @param Address Destination address in the target process.
  47. /// @param Data Source address in the host process.
  48. /// @param Size Number of bytes to copy.
  49. ///
  50. /// @returns True on success. On failure, ErrorMsg is updated with
  51. /// descriptive text of the encountered error.
  52. bool loadData(uint64_t Address, const void *Data, size_t Size) override;
  53. /// Load code into the target address space and prepare it for execution.
  54. ///
  55. /// @param Address Destination address in the target process.
  56. /// @param Data Source address in the host process.
  57. /// @param Size Number of bytes to copy.
  58. ///
  59. /// @returns True on success. On failure, ErrorMsg is updated with
  60. /// descriptive text of the encountered error.
  61. bool loadCode(uint64_t Address, const void *Data, size_t Size) override;
  62. /// Execute code in the target process. The called function is required
  63. /// to be of signature int "(*)(void)".
  64. ///
  65. /// @param Address Address of the loaded function in the target
  66. /// process.
  67. /// @param[out] RetVal The integer return value of the called function.
  68. ///
  69. /// @returns True on success. On failure, ErrorMsg is updated with
  70. /// descriptive text of the encountered error.
  71. bool executeCode(uint64_t Address, int &RetVal) override;
  72. /// Minimum alignment for memory permissions. Used to separate code and
  73. /// data regions to make sure data doesn't get marked as code or vice
  74. /// versa.
  75. ///
  76. /// @returns Page alignment return value. Default of 4k.
  77. unsigned getPageAlignment() override { return 4096; }
  78. bool create() override {
  79. RPC.ChildName = ChildName;
  80. if (!RPC.createServer())
  81. return true;
  82. // We must get Ack from the client (blocking read)
  83. if (!Receive(LLI_ChildActive)) {
  84. ErrorMsg += ", (RPCChannel::create) - Stopping process!";
  85. stop();
  86. return false;
  87. }
  88. return true;
  89. }
  90. /// Terminate the remote process.
  91. void stop() override;
  92. RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {}
  93. ~RemoteTargetExternal() override {}
  94. private:
  95. std::string ChildName;
  96. bool SendAllocateSpace(uint32_t Alignment, uint32_t Size);
  97. bool SendLoadSection(uint64_t Addr,
  98. const void *Data,
  99. uint32_t Size,
  100. bool IsCode);
  101. bool SendExecute(uint64_t Addr);
  102. bool SendTerminate();
  103. // High-level wrappers for receiving data
  104. bool Receive(LLIMessageType Msg);
  105. bool Receive(LLIMessageType Msg, int32_t &Data);
  106. bool Receive(LLIMessageType Msg, uint64_t &Data);
  107. // Lower level target-independent read/write to deal with errors
  108. bool ReceiveHeader(LLIMessageType Msg);
  109. bool ReceivePayload();
  110. bool SendHeader(LLIMessageType Msg);
  111. bool SendPayload();
  112. // Functions to append/retrieve data from the payload
  113. SmallVector<const void *, 2> SendData;
  114. SmallVector<void *, 1> ReceiveData; // Future proof
  115. SmallVector<int, 2> Sizes;
  116. void AppendWrite(const void *Data, uint32_t Size);
  117. void AppendRead(void *Data, uint32_t Size);
  118. };
  119. } // end namespace llvm
  120. #endif