1243789Sdim//===- RemoteTarget.cpp - LLVM Remote process JIT execution --------------===// 2243789Sdim// 3243789Sdim// The LLVM Compiler Infrastructure 4243789Sdim// 5243789Sdim// This file is distributed under the University of Illinois Open Source 6243789Sdim// License. See LICENSE.TXT for details. 7243789Sdim// 8243789Sdim//===----------------------------------------------------------------------===// 9243789Sdim// 10243789Sdim// Implementation of the RemoteTarget class which executes JITed code in a 11243789Sdim// separate address range from where it was built. 12243789Sdim// 13243789Sdim//===----------------------------------------------------------------------===// 14243789Sdim 15243789Sdim#include "RemoteTarget.h" 16263509Sdim#include "RemoteTargetExternal.h" 17243789Sdim#include "llvm/ADT/StringRef.h" 18243789Sdim#include "llvm/Support/DataTypes.h" 19243789Sdim#include "llvm/Support/Memory.h" 20243789Sdim#include <stdlib.h> 21243789Sdim#include <string> 22263509Sdim 23243789Sdimusing namespace llvm; 24243789Sdim 25263509Sdim// Static methods 26263509SdimRemoteTarget *RemoteTarget::createRemoteTarget() { 27263509Sdim return new RemoteTarget; 28263509Sdim} 29263509Sdim 30263509SdimRemoteTarget *RemoteTarget::createExternalRemoteTarget(std::string &ChildName) { 31263509Sdim#ifdef LLVM_ON_UNIX 32263509Sdim return new RemoteTargetExternal(ChildName); 33263509Sdim#else 34263509Sdim return 0; 35263509Sdim#endif 36263509Sdim} 37263509Sdim 38263509Sdimbool RemoteTarget::hostSupportsExternalRemoteTarget() { 39263509Sdim#ifdef LLVM_ON_UNIX 40263509Sdim return true; 41263509Sdim#else 42263509Sdim return false; 43263509Sdim#endif 44263509Sdim} 45263509Sdim 46263509Sdim 47263509Sdim//////////////////////////////////////////////////////////////////////////////// 48263509Sdim// Simulated remote execution 49263509Sdim// 50263509Sdim// This implementation will simply move generated code and data to a new memory 51263509Sdim// location in the current executable and let it run from there. 52263509Sdim//////////////////////////////////////////////////////////////////////////////// 53263509Sdim 54243789Sdimbool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment, 55243789Sdim uint64_t &Address) { 56243789Sdim sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : NULL; 57243789Sdim sys::MemoryBlock Mem = sys::Memory::AllocateRWX(Size, Prev, &ErrorMsg); 58243789Sdim if (Mem.base() == NULL) 59243789Sdim return true; 60243789Sdim if ((uintptr_t)Mem.base() % Alignment) { 61243789Sdim ErrorMsg = "unable to allocate sufficiently aligned memory"; 62243789Sdim return true; 63243789Sdim } 64243789Sdim Address = reinterpret_cast<uint64_t>(Mem.base()); 65243789Sdim return false; 66243789Sdim} 67243789Sdim 68243789Sdimbool RemoteTarget::loadData(uint64_t Address, const void *Data, size_t Size) { 69243789Sdim memcpy ((void*)Address, Data, Size); 70243789Sdim return false; 71243789Sdim} 72243789Sdim 73243789Sdimbool RemoteTarget::loadCode(uint64_t Address, const void *Data, size_t Size) { 74243789Sdim memcpy ((void*)Address, Data, Size); 75243789Sdim sys::MemoryBlock Mem((void*)Address, Size); 76243789Sdim sys::Memory::setExecutable(Mem, &ErrorMsg); 77243789Sdim return false; 78243789Sdim} 79243789Sdim 80243789Sdimbool RemoteTarget::executeCode(uint64_t Address, int &RetVal) { 81243789Sdim int (*fn)(void) = (int(*)(void))Address; 82243789Sdim RetVal = fn(); 83243789Sdim return false; 84243789Sdim} 85243789Sdim 86243789Sdimvoid RemoteTarget::create() { 87243789Sdim} 88243789Sdim 89243789Sdimvoid RemoteTarget::stop() { 90243789Sdim for (unsigned i = 0, e = Allocations.size(); i != e; ++i) 91243789Sdim sys::Memory::ReleaseRWX(Allocations[i]); 92243789Sdim} 93