summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/tools/lli/ChildTarget/CMakeLists.txt7
-rw-r--r--llvm/tools/lli/ChildTarget/ChildTarget.cpp53
-rw-r--r--llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc120
-rw-r--r--llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc10
-rw-r--r--llvm/tools/lli/RemoteTarget.cpp1
-rw-r--r--llvm/tools/lli/RemoteTarget.h15
6 files changed, 32 insertions, 174 deletions
diff --git a/llvm/tools/lli/ChildTarget/CMakeLists.txt b/llvm/tools/lli/ChildTarget/CMakeLists.txt
index fd1ac24f044..6191fd60166 100644
--- a/llvm/tools/lli/ChildTarget/CMakeLists.txt
+++ b/llvm/tools/lli/ChildTarget/CMakeLists.txt
@@ -1,3 +1,6 @@
-add_llvm_tool(lli-child-target
+set(LLVM_LINK_COMPONENTS support)
+
+add_llvm_executable(lli-child-target
ChildTarget.cpp
- )
+ ../RemoteTarget.cpp
+)
diff --git a/llvm/tools/lli/ChildTarget/ChildTarget.cpp b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
index ca75beb8422..de264af2cdd 100644
--- a/llvm/tools/lli/ChildTarget/ChildTarget.cpp
+++ b/llvm/tools/lli/ChildTarget/ChildTarget.cpp
@@ -1,4 +1,6 @@
#include "llvm/Config/config.h"
+#include "llvm/Support/Memory.h"
+#include "../RemoteTarget.h"
#include "../RemoteTargetMessage.h"
#include <assert.h>
#include <map>
@@ -14,13 +16,13 @@ public:
void initialize();
LLIMessageType waitForIncomingMessage();
void handleMessage(LLIMessageType messageType);
+ RemoteTarget *RT;
private:
// Incoming message handlers
void handleAllocateSpace();
void handleLoadSection(bool IsCode);
void handleExecute();
- void handleTerminate();
// Outgoing message handlers
void sendChildActive();
@@ -32,15 +34,6 @@ private:
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);
- bool isAllocatedMemory(uint64_t Address, uint32_t Size);
-
- // Store a map of allocated buffers to sizes.
- typedef std::map<uint64_t, uint32_t> AllocMapType;
- AllocMapType m_AllocatedBufferMap;
// Communication handles (OS-specific)
void *ConnectionData;
@@ -48,6 +41,7 @@ private:
int main() {
LLIChildTarget ThisChild;
+ ThisChild.RT = new RemoteTarget();
ThisChild.initialize();
LLIMessageType MsgType;
do {
@@ -55,6 +49,7 @@ int main() {
ThisChild.handleMessage(MsgType);
} while (MsgType != LLI_Terminate &&
MsgType != LLI_Error);
+ delete ThisChild.RT;
return 0;
}
@@ -86,7 +81,7 @@ void LLIChildTarget::handleMessage(LLIMessageType messageType) {
handleExecute();
break;
case LLI_Terminate:
- handleTerminate();
+ RT->stop();
break;
default:
// FIXME: Handle error!
@@ -112,7 +107,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);
@@ -131,7 +127,7 @@ void LLIChildTarget::handleLoadSection(bool IsCode) {
assert(rc == 8);
size_t BufferSize = DataSize - 8;
- if (!isAllocatedMemory(Addr, BufferSize))
+ if (!RT->isAllocatedMemory(Addr, BufferSize))
return sendLoadStatus(LLI_Status_NotAllocated);
// Read section data into previously allocated buffer
@@ -141,7 +137,7 @@ void LLIChildTarget::handleLoadSection(bool IsCode) {
// If IsCode, mark memory executable
if (IsCode)
- makeSectionExecutable(Addr, BufferSize);
+ sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
// Send MarkLoadComplete message.
sendLoadStatus(LLI_Status_Success);
@@ -161,38 +157,13 @@ 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(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();
-}
-
-bool LLIChildTarget::isAllocatedMemory(uint64_t Address, uint32_t Size) {
- uint64_t End = Address+Size;
- AllocMapType::iterator ItBegin = m_AllocatedBufferMap.begin();
- AllocMapType::iterator ItEnd = m_AllocatedBufferMap.end();
- for (AllocMapType::iterator It = ItBegin; It != ItEnd; ++It) {
- uint64_t A = It->first;
- uint64_t E = A + It->second;
- // Starts and finishes inside allocated region
- if (Address >= A && End <= E)
- return true;
- }
- return false;
-}
-
// Outgoing message handlers
void LLIChildTarget::sendChildActive() {
// Write the message type.
diff --git a/llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc b/llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc
index c71e422c1ac..67a24ece965 100644
--- a/llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc
+++ b/llvm/tools/lli/ChildTarget/Unix/ChildTarget.inc
@@ -16,28 +16,6 @@
#include <stdlib.h>
#include <unistd.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 {
@@ -66,101 +44,3 @@ int LLIChildTarget::WriteBytes(const void *Data, size_t 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/llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc b/llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc
index 45db2b0a808..bea0947b7ec 100644
--- a/llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc
+++ b/llvm/tools/lli/ChildTarget/Windows/ChildTarget.inc
@@ -32,13 +32,3 @@ int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
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) {
-}
diff --git a/llvm/tools/lli/RemoteTarget.cpp b/llvm/tools/lli/RemoteTarget.cpp
index 9631ef7aac2..f07534d161a 100644
--- a/llvm/tools/lli/RemoteTarget.cpp
+++ b/llvm/tools/lli/RemoteTarget.cpp
@@ -62,6 +62,7 @@ bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,
return false;
}
Address = reinterpret_cast<uint64_t>(Mem.base());
+ Allocations.push_back(Mem);
return true;
}
diff --git a/llvm/tools/lli/RemoteTarget.h b/llvm/tools/lli/RemoteTarget.h
index a7d4e59e3bf..44e649e6e14 100644
--- a/llvm/tools/lli/RemoteTarget.h
+++ b/llvm/tools/lli/RemoteTarget.h
@@ -27,7 +27,8 @@ namespace llvm {
class RemoteTarget {
bool IsRunning;
- SmallVector<sys::MemoryBlock, 16> Allocations;
+ typedef SmallVector<sys::MemoryBlock, 16> AllocMapType;
+ AllocMapType Allocations;
protected:
std::string ErrorMsg;
@@ -47,6 +48,18 @@ public:
unsigned Alignment,
uint64_t &Address);
+ bool isAllocatedMemory(uint64_t Address, uint32_t Size) {
+ uint64_t AddressEnd = Address + Size;
+ for (AllocMapType::const_iterator I = Allocations.begin(),
+ E = Allocations.end();
+ I != E; ++I) {
+ if (Address >= (uint64_t)I->base() &&
+ AddressEnd <= (uint64_t)I->base() + I->size())
+ return true;
+ }
+ return false;
+ }
+
/// Load data into the target address space.
///
/// @param Address Destination address in the target process.
OpenPOWER on IntegriCloud