llvm-6502/tools/lli/RemoteTarget.cpp
Renato Golin 83ece7a499 Sanitize MCJIT remote execution
MCJIT remote execution (ChildTarget+RemoteTargetExternal) protocol was in
dire need of refactoring. It was fail-prone, had no error reporting and
implemented the same message logic on every single function.

This patch rectifies it, and makes it work on ARM, where it was randomly
failing. Other architectures shall profit from this change as well, making
their buildbots and releases more reliable.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199261 91177308-0d34-0410-b5e6-96231b3b80d8
2014-01-14 22:43:43 +00:00

94 lines
2.7 KiB
C++

//===- RemoteTarget.cpp - LLVM Remote process JIT execution --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of the RemoteTarget class which executes JITed code in a
// separate address range from where it was built.
//
//===----------------------------------------------------------------------===//
#include "RemoteTarget.h"
#include "RemoteTargetExternal.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Memory.h"
#include <stdlib.h>
#include <string>
using namespace llvm;
// Static methods
RemoteTarget *RemoteTarget::createRemoteTarget() {
return new RemoteTarget;
}
RemoteTarget *RemoteTarget::createExternalRemoteTarget(std::string &ChildName) {
#ifdef LLVM_ON_UNIX
return new RemoteTargetExternal(ChildName);
#else
return 0;
#endif
}
bool RemoteTarget::hostSupportsExternalRemoteTarget() {
#ifdef LLVM_ON_UNIX
return true;
#else
return false;
#endif
}
////////////////////////////////////////////////////////////////////////////////
// Simulated remote execution
//
// This implementation will simply move generated code and data to a new memory
// location in the current executable and let it run from there.
////////////////////////////////////////////////////////////////////////////////
bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,
uint64_t &Address) {
sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : NULL;
sys::MemoryBlock Mem = sys::Memory::AllocateRWX(Size, Prev, &ErrorMsg);
if (Mem.base() == NULL)
return false;
if ((uintptr_t)Mem.base() % Alignment) {
ErrorMsg = "unable to allocate sufficiently aligned memory";
return false;
}
Address = reinterpret_cast<uint64_t>(Mem.base());
return true;
}
bool RemoteTarget::loadData(uint64_t Address, const void *Data, size_t Size) {
memcpy ((void*)Address, Data, Size);
return true;
}
bool RemoteTarget::loadCode(uint64_t Address, const void *Data, size_t Size) {
memcpy ((void*)Address, Data, Size);
sys::MemoryBlock Mem((void*)Address, Size);
sys::Memory::setExecutable(Mem, &ErrorMsg);
return true;
}
bool RemoteTarget::executeCode(uint64_t Address, int &RetVal) {
int (*fn)(void) = (int(*)(void))Address;
RetVal = fn();
return true;
}
bool RemoteTarget::create() {
return true;
}
void RemoteTarget::stop() {
for (unsigned i = 0, e = Allocations.size(); i != e; ++i)
sys::Memory::ReleaseRWX(Allocations[i]);
}