mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
5e0ba8b8db
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. llvm-svn: 199261
94 lines
2.7 KiB
C++
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]);
|
|
}
|