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"
16263508Sdim#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>
22263508Sdim
23243789Sdimusing namespace llvm;
24243789Sdim
25263508Sdim// Static methods
26263508SdimRemoteTarget *RemoteTarget::createRemoteTarget() {
27263508Sdim  return new RemoteTarget;
28263508Sdim}
29263508Sdim
30263508SdimRemoteTarget *RemoteTarget::createExternalRemoteTarget(std::string &ChildName) {
31263508Sdim#ifdef LLVM_ON_UNIX
32263508Sdim  return new RemoteTargetExternal(ChildName);
33263508Sdim#else
34263508Sdim  return 0;
35263508Sdim#endif
36263508Sdim}
37263508Sdim
38263508Sdimbool RemoteTarget::hostSupportsExternalRemoteTarget() {
39263508Sdim#ifdef LLVM_ON_UNIX
40263508Sdim  return true;
41263508Sdim#else
42263508Sdim  return false;
43263508Sdim#endif
44263508Sdim}
45263508Sdim
46263508Sdim
47263508Sdim////////////////////////////////////////////////////////////////////////////////
48263508Sdim// Simulated remote execution
49263508Sdim//
50263508Sdim// This implementation will simply move generated code and data to a new memory
51263508Sdim// location in the current executable and let it run from there.
52263508Sdim////////////////////////////////////////////////////////////////////////////////
53263508Sdim
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