| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #include "llvm/Config/config.h"
- #include "../RPCChannel.h"
- #include "../RemoteTarget.h"
- #include "../RemoteTargetMessage.h"
- #include "llvm/Support/Memory.h"
- #include <assert.h>
- #include <map>
- #include <stdint.h>
- #include <string>
- #include <vector>
- using namespace llvm;
- class LLIChildTarget {
- public:
- void initialize();
- LLIMessageType waitForIncomingMessage();
- void handleMessage(LLIMessageType messageType);
- RemoteTarget *RT;
- RPCChannel RPC;
- private:
- // Incoming message handlers
- void handleAllocateSpace();
- void handleLoadSection(bool IsCode);
- void handleExecute();
- // Outgoing message handlers
- void sendChildActive();
- void sendAllocationResult(uint64_t Addr);
- void sendLoadStatus(uint32_t Status);
- void sendExecutionComplete(int Result);
- // OS-specific functions
- void initializeConnection();
- int WriteBytes(const void *Data, size_t Size) {
- return RPC.WriteBytes(Data, Size) ? Size : -1;
- }
- int ReadBytes(void *Data, size_t Size) {
- return RPC.ReadBytes(Data, Size) ? Size : -1;
- }
- // Communication handles (OS-specific)
- void *ConnectionData;
- };
- int main() {
- LLIChildTarget ThisChild;
- ThisChild.RT = new RemoteTarget();
- ThisChild.initialize();
- LLIMessageType MsgType;
- do {
- MsgType = ThisChild.waitForIncomingMessage();
- ThisChild.handleMessage(MsgType);
- } while (MsgType != LLI_Terminate &&
- MsgType != LLI_Error);
- delete ThisChild.RT;
- return 0;
- }
- // Public methods
- void LLIChildTarget::initialize() {
- RPC.createClient();
- sendChildActive();
- }
- LLIMessageType LLIChildTarget::waitForIncomingMessage() {
- int32_t MsgType = -1;
- if (ReadBytes(&MsgType, 4) > 0)
- return (LLIMessageType)MsgType;
- return LLI_Error;
- }
- void LLIChildTarget::handleMessage(LLIMessageType messageType) {
- switch (messageType) {
- case LLI_AllocateSpace:
- handleAllocateSpace();
- break;
- case LLI_LoadCodeSection:
- handleLoadSection(true);
- break;
- case LLI_LoadDataSection:
- handleLoadSection(false);
- break;
- case LLI_Execute:
- handleExecute();
- break;
- case LLI_Terminate:
- RT->stop();
- break;
- default:
- // FIXME: Handle error!
- break;
- }
- }
- // Incoming message handlers
- void LLIChildTarget::handleAllocateSpace() {
- // Read and verify the message data size.
- uint32_t DataSize = 0;
- int rc = ReadBytes(&DataSize, 4);
- (void)rc;
- assert(rc == 4);
- assert(DataSize == 8);
- // Read the message arguments.
- uint32_t Alignment = 0;
- uint32_t AllocSize = 0;
- rc = ReadBytes(&Alignment, 4);
- assert(rc == 4);
- rc = ReadBytes(&AllocSize, 4);
- assert(rc == 4);
- // Allocate the memory.
- uint64_t Addr;
- RT->allocateSpace(AllocSize, Alignment, Addr);
- // Send AllocationResult message.
- sendAllocationResult(Addr);
- }
- void LLIChildTarget::handleLoadSection(bool IsCode) {
- // Read the message data size.
- uint32_t DataSize = 0;
- int rc = ReadBytes(&DataSize, 4);
- (void)rc;
- assert(rc == 4);
- // Read the target load address.
- uint64_t Addr = 0;
- rc = ReadBytes(&Addr, 8);
- assert(rc == 8);
- size_t BufferSize = DataSize - 8;
- if (!RT->isAllocatedMemory(Addr, BufferSize))
- return sendLoadStatus(LLI_Status_NotAllocated);
- // Read section data into previously allocated buffer
- rc = ReadBytes((void*)Addr, BufferSize);
- if (rc != (int)(BufferSize))
- return sendLoadStatus(LLI_Status_IncompleteMsg);
- // If IsCode, mark memory executable
- if (IsCode)
- sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
- // Send MarkLoadComplete message.
- sendLoadStatus(LLI_Status_Success);
- }
- void LLIChildTarget::handleExecute() {
- // Read the message data size.
- uint32_t DataSize = 0;
- int rc = ReadBytes(&DataSize, 4);
- (void)rc;
- assert(rc == 4);
- assert(DataSize == 8);
- // Read the target address.
- uint64_t Addr = 0;
- rc = ReadBytes(&Addr, 8);
- assert(rc == 8);
- // Call function
- int32_t Result = -1;
- RT->executeCode(Addr, Result);
- // Send ExecutionResult message.
- sendExecutionComplete(Result);
- }
- // Outgoing message handlers
- void LLIChildTarget::sendChildActive() {
- // Write the message type.
- uint32_t MsgType = (uint32_t)LLI_ChildActive;
- int rc = WriteBytes(&MsgType, 4);
- (void)rc;
- assert(rc == 4);
- // Write the data size.
- uint32_t DataSize = 0;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4);
- }
- void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
- // Write the message type.
- uint32_t MsgType = (uint32_t)LLI_AllocationResult;
- int rc = WriteBytes(&MsgType, 4);
- (void)rc;
- assert(rc == 4);
- // Write the data size.
- uint32_t DataSize = 8;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4);
- // Write the allocated address.
- rc = WriteBytes(&Addr, 8);
- assert(rc == 8);
- }
- void LLIChildTarget::sendLoadStatus(uint32_t Status) {
- // Write the message type.
- uint32_t MsgType = (uint32_t)LLI_LoadResult;
- int rc = WriteBytes(&MsgType, 4);
- (void)rc;
- assert(rc == 4);
- // Write the data size.
- uint32_t DataSize = 4;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4);
- // Write the result.
- rc = WriteBytes(&Status, 4);
- assert(rc == 4);
- }
- void LLIChildTarget::sendExecutionComplete(int Result) {
- // Write the message type.
- uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
- int rc = WriteBytes(&MsgType, 4);
- (void)rc;
- assert(rc == 4);
- // Write the data size.
- uint32_t DataSize = 4;
- rc = WriteBytes(&DataSize, 4);
- assert(rc == 4);
- // Write the result.
- rc = WriteBytes(&Result, 4);
- assert(rc == 4);
- }
- #ifdef LLVM_ON_UNIX
- #include "../Unix/RPCChannel.inc"
- #endif
- #ifdef LLVM_ON_WIN32
- #include "../Windows/RPCChannel.inc"
- #endif
|