aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lli/ChildTarget
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lli/ChildTarget')
-rw-r--r--tools/lli/ChildTarget/CMakeLists.txt9
-rw-r--r--tools/lli/ChildTarget/ChildTarget.cpp96
-rw-r--r--tools/lli/ChildTarget/Makefile4
-rw-r--r--tools/lli/ChildTarget/Unix/ChildTarget.inc166
-rw-r--r--tools/lli/ChildTarget/Windows/ChildTarget.inc44
5 files changed, 59 insertions, 260 deletions
diff --git a/tools/lli/ChildTarget/CMakeLists.txt b/tools/lli/ChildTarget/CMakeLists.txt
index fd1ac24..9f88b2c 100644
--- a/tools/lli/ChildTarget/CMakeLists.txt
+++ b/tools/lli/ChildTarget/CMakeLists.txt
@@ -1,3 +1,8 @@
-add_llvm_tool(lli-child-target
+set(LLVM_LINK_COMPONENTS support)
+
+add_llvm_executable(lli-child-target
ChildTarget.cpp
- )
+ ../RemoteTarget.cpp
+)
+
+set_target_properties(lli-child-target PROPERTIES FOLDER "Misc")
diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp
index 55fcae9..0d71b17 100644
--- a/tools/lli/ChildTarget/ChildTarget.cpp
+++ b/tools/lli/ChildTarget/ChildTarget.cpp
@@ -1,6 +1,8 @@
#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>
@@ -11,36 +13,32 @@ using namespace llvm;
class LLIChildTarget {
public:
- ~LLIChildTarget(); // OS-specific destructor
void initialize();
LLIMessageType waitForIncomingMessage();
void handleMessage(LLIMessageType messageType);
+ RemoteTarget *RT;
+ RPCChannel RPC;
private:
// Incoming message handlers
void handleAllocateSpace();
void handleLoadSection(bool IsCode);
void handleExecute();
- void handleTerminate();
// Outgoing message handlers
void sendChildActive();
void sendAllocationResult(uint64_t Addr);
- void sendLoadComplete();
- void sendExecutionComplete(uint64_t Result);
+ void sendLoadStatus(uint32_t Status);
+ void sendExecutionComplete(int Result);
// OS-specific functions
void initializeConnection();
- int WriteBytes(const void *Data, size_t Size);
- int ReadBytes(void *Data, size_t Size);
- uint64_t allocate(uint32_t Alignment, uint32_t Size);
- void makeSectionExecutable(uint64_t Addr, uint32_t Size);
- void InvalidateInstructionCache(const void *Addr, size_t Len);
- void releaseMemory(uint64_t Addr, uint32_t Size);
-
- // Store a map of allocated buffers to sizes.
- typedef std::map<uint64_t, uint32_t> AllocMapType;
- AllocMapType m_AllocatedBufferMap;
+ 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;
@@ -48,6 +46,7 @@ private:
int main() {
LLIChildTarget ThisChild;
+ ThisChild.RT = new RemoteTarget();
ThisChild.initialize();
LLIMessageType MsgType;
do {
@@ -55,12 +54,13 @@ int main() {
ThisChild.handleMessage(MsgType);
} while (MsgType != LLI_Terminate &&
MsgType != LLI_Error);
+ delete ThisChild.RT;
return 0;
}
// Public methods
void LLIChildTarget::initialize() {
- initializeConnection();
+ RPC.createClient();
sendChildActive();
}
@@ -86,7 +86,7 @@ void LLIChildTarget::handleMessage(LLIMessageType messageType) {
handleExecute();
break;
case LLI_Terminate:
- handleTerminate();
+ RT->stop();
break;
default:
// FIXME: Handle error!
@@ -99,6 +99,7 @@ void LLIChildTarget::handleAllocateSpace() {
// Read and verify the message data size.
uint32_t DataSize;
int rc = ReadBytes(&DataSize, 4);
+ (void)rc;
assert(rc == 4);
assert(DataSize == 8);
@@ -111,7 +112,8 @@ void LLIChildTarget::handleAllocateSpace() {
assert(rc == 4);
// Allocate the memory.
- uint64_t Addr = allocate(Alignment, AllocSize);
+ uint64_t Addr;
+ RT->allocateSpace(AllocSize, Alignment, Addr);
// Send AllocationResult message.
sendAllocationResult(Addr);
@@ -121,33 +123,36 @@ void LLIChildTarget::handleLoadSection(bool IsCode) {
// Read the message data size.
uint32_t DataSize;
int rc = ReadBytes(&DataSize, 4);
+ (void)rc;
assert(rc == 4);
// Read the target load address.
uint64_t Addr;
rc = ReadBytes(&Addr, 8);
assert(rc == 8);
-
size_t BufferSize = DataSize - 8;
- // FIXME: Verify that this is in allocated space
+ if (!RT->isAllocatedMemory(Addr, BufferSize))
+ return sendLoadStatus(LLI_Status_NotAllocated);
// Read section data into previously allocated buffer
- rc = ReadBytes((void*)Addr, DataSize - 8);
- assert(rc == (int)(BufferSize));
+ rc = ReadBytes((void*)Addr, BufferSize);
+ if (rc != (int)(BufferSize))
+ return sendLoadStatus(LLI_Status_IncompleteMsg);
// If IsCode, mark memory executable
if (IsCode)
- makeSectionExecutable(Addr, BufferSize);
+ sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
// Send MarkLoadComplete message.
- sendLoadComplete();
+ sendLoadStatus(LLI_Status_Success);
}
void LLIChildTarget::handleExecute() {
// Read the message data size.
uint32_t DataSize;
int rc = ReadBytes(&DataSize, 4);
+ (void)rc;
assert(rc == 4);
assert(DataSize == 8);
@@ -157,22 +162,11 @@ void LLIChildTarget::handleExecute() {
assert(rc == 8);
// Call function
- int Result;
- int (*fn)(void) = (int(*)(void))Addr;
- Result = fn();
+ int32_t Result = -1;
+ RT->executeCode(Addr, Result);
// Send ExecutionResult message.
- sendExecutionComplete((int64_t)Result);
-}
-
-void LLIChildTarget::handleTerminate() {
- // Release all allocated memory
- AllocMapType::iterator Begin = m_AllocatedBufferMap.begin();
- AllocMapType::iterator End = m_AllocatedBufferMap.end();
- for (AllocMapType::iterator It = Begin; It != End; ++It) {
- releaseMemory(It->first, It->second);
- }
- m_AllocatedBufferMap.clear();
+ sendExecutionComplete(Result);
}
// Outgoing message handlers
@@ -180,6 +174,7 @@ 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.
@@ -192,6 +187,7 @@ 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.
@@ -204,39 +200,45 @@ void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
assert(rc == 8);
}
-void LLIChildTarget::sendLoadComplete() {
+void LLIChildTarget::sendLoadStatus(uint32_t Status) {
// Write the message type.
- uint32_t MsgType = (uint32_t)LLI_LoadComplete;
+ uint32_t MsgType = (uint32_t)LLI_LoadResult;
int rc = WriteBytes(&MsgType, 4);
+ (void)rc;
assert(rc == 4);
// Write the data size.
- uint32_t DataSize = 0;
+ uint32_t DataSize = 4;
rc = WriteBytes(&DataSize, 4);
assert(rc == 4);
+
+ // Write the result.
+ rc = WriteBytes(&Status, 4);
+ assert(rc == 4);
}
-void LLIChildTarget::sendExecutionComplete(uint64_t Result) {
+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 = 8;
+ uint32_t DataSize = 4;
rc = WriteBytes(&DataSize, 4);
assert(rc == 4);
// Write the result.
- rc = WriteBytes(&Result, 8);
- assert(rc == 8);
+ rc = WriteBytes(&Result, 4);
+ assert(rc == 4);
}
#ifdef LLVM_ON_UNIX
-#include "Unix/ChildTarget.inc"
+#include "../Unix/RPCChannel.inc"
#endif
#ifdef LLVM_ON_WIN32
-#include "Windows/ChildTarget.inc"
+#include "../Windows/RPCChannel.inc"
#endif
diff --git a/tools/lli/ChildTarget/Makefile b/tools/lli/ChildTarget/Makefile
index f77b144..6f4ddef 100644
--- a/tools/lli/ChildTarget/Makefile
+++ b/tools/lli/ChildTarget/Makefile
@@ -12,6 +12,8 @@ TOOLNAME := lli-child-target
include $(LEVEL)/Makefile.config
-LINK_COMPONENTS :=
+LINK_COMPONENTS := support
+
+SOURCES := ChildTarget.cpp ../RemoteTarget.cpp
include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/lli/ChildTarget/Unix/ChildTarget.inc b/tools/lli/ChildTarget/Unix/ChildTarget.inc
deleted file mode 100644
index cc95810..0000000
--- a/tools/lli/ChildTarget/Unix/ChildTarget.inc
+++ /dev/null
@@ -1,166 +0,0 @@
-//===- ChildTarget.inc - Child process for external JIT execution for Unix -==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implementation of the Unix-specific parts of the ChildTarget class
-// which executes JITed code in a separate process from where it was built.
-//
-//===----------------------------------------------------------------------===//
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#ifdef __APPLE__
-#include <mach/mach.h>
-#endif
-
-#if defined(__mips__)
-# if defined(__OpenBSD__)
-# include <mips64/sysarch.h>
-# else
-# include <sys/cachectl.h>
-# endif
-#endif
-
-#ifdef __APPLE__
-extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
-#else
-extern "C" void __clear_cache(void *, void*);
-#endif
-
-namespace {
-
-struct ConnectionData_t {
- int InputPipe;
- int OutputPipe;
-
- ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {}
-};
-
-} // namespace
-
-LLIChildTarget::~LLIChildTarget() {
- delete static_cast<ConnectionData_t *>(ConnectionData);
-}
-
-// OS-specific methods
-void LLIChildTarget::initializeConnection() {
- // Store the parent ends of the pipes
- ConnectionData = (void*)new ConnectionData_t(STDIN_FILENO, STDOUT_FILENO);
-}
-
-int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
- return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size);
-}
-
-int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
- return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
-}
-
-// The functions below duplicate functionality that is implemented in
-// Support/Memory.cpp with the goal of avoiding a dependency on any
-// llvm libraries.
-
-uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) {
- if (!Alignment)
- Alignment = 16;
-
- static const size_t PageSize = getpagesize();
- const size_t NumPages = (Size+PageSize-1)/PageSize;
- Size = NumPages*PageSize;
-
- int fd = -1;
-#ifdef NEED_DEV_ZERO_FOR_MMAP
- static int zero_fd = open("/dev/zero", O_RDWR);
- if (zero_fd == -1)
- return 0;
- fd = zero_fd;
-#endif
-
- int MMFlags = MAP_PRIVATE |
-#ifdef HAVE_MMAP_ANONYMOUS
- MAP_ANONYMOUS
-#else
- MAP_ANON
-#endif
- ; // Ends statement above
-
- uint64_t Addr = (uint64_t)::mmap(0, Size, PROT_READ | PROT_WRITE, MMFlags, fd, 0);
- if (Addr == (uint64_t)MAP_FAILED)
- return 0;
-
- // Align the address.
- Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
-
- m_AllocatedBufferMap[Addr] = Size;
-
- // Return aligned address
- return Addr;
-}
-
-void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) {
- // FIXME: We have to mark the memory as RWX because multiple code chunks may
- // be on the same page. The RemoteTarget interface should be changed to
- // work around that.
- int Result = ::mprotect((void*)Addr, Size, PROT_READ | PROT_WRITE | PROT_EXEC);
- if (Result != 0)
- InvalidateInstructionCache((const void *)Addr, Size);
-}
-
-/// InvalidateInstructionCache - Before the JIT can run a block of code
-/// that has been emitted it must invalidate the instruction cache on some
-/// platforms.
-void LLIChildTarget::InvalidateInstructionCache(const void *Addr,
- size_t Len) {
-
-// icache invalidation for PPC and ARM.
-#if defined(__APPLE__)
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
- sys_icache_invalidate(const_cast<void *>(Addr), Len);
-# endif
-
-#else
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
- const size_t LineSize = 32;
-
- const intptr_t Mask = ~(LineSize - 1);
- const intptr_t StartLine = ((intptr_t) Addr) & Mask;
- const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("dcbf 0, %0" : : "r"(Line));
- asm volatile("sync");
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("icbi 0, %0" : : "r"(Line));
- asm volatile("isync");
-# elif defined(__arm__) && defined(__GNUC__)
- // FIXME: Can we safely always call this for __GNUC__ everywhere?
- const char *Start = static_cast<const char *>(Addr);
- const char *End = Start + Len;
- __clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
-# elif defined(__mips__)
- const char *Start = static_cast<const char *>(Addr);
- cacheflush(const_cast<char *>(Start), Len, BCACHE);
-# endif
-
-#endif // end apple
-}
-
-void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) {
- ::munmap((void*)Addr, Size);
-}
diff --git a/tools/lli/ChildTarget/Windows/ChildTarget.inc b/tools/lli/ChildTarget/Windows/ChildTarget.inc
deleted file mode 100644
index 45db2b0..0000000
--- a/tools/lli/ChildTarget/Windows/ChildTarget.inc
+++ /dev/null
@@ -1,44 +0,0 @@
-//=- ChildTarget.inc - Child process for external JIT execution for Windows -=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Non-implementation of the Windows-specific parts of the ChildTarget class
-// which executes JITed code in a separate process from where it was built.
-//
-//===----------------------------------------------------------------------===//
-
-LLIChildTarget::~LLIChildTarget() {
-}
-
-// The RemoteTargetExternal implementation should prevent us from ever getting
-// here on Windows, but nothing prevents a user from running this directly.
-void LLIChildTarget::initializeConnection() {
- assert(0 && "lli-child-target is not implemented for Windows");
-}
-
-int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
- return 0;
-}
-
-int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
- return 0;
-}
-
-uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) {
- return 0;
-}
-
-void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) {
-}
-
-void LLIChildTarget::InvalidateInstructionCache(const void *Addr,
- size_t Len) {
-}
-
-void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) {
-}