mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
Preliminary support for systems which require changing JIT memory regions privilege from read / write to read / executable.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56303 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
057d0c3535
commit
bc4707a255
@ -69,6 +69,11 @@ namespace sys {
|
|||||||
/// that has been emitted it must invalidate the instruction cache on some
|
/// that has been emitted it must invalidate the instruction cache on some
|
||||||
/// platforms.
|
/// platforms.
|
||||||
static void InvalidateInstructionCache(const void *Addr, size_t Len);
|
static void InvalidateInstructionCache(const void *Addr, size_t Len);
|
||||||
|
|
||||||
|
/// SetRXPrivilege - Before the JIT can run a block of code, it has to be
|
||||||
|
/// given read and executable privilege. Return true if it is already r-x
|
||||||
|
/// or the system is able to change its previlege.
|
||||||
|
static bool SetRXPrivilege(const void *Addr, size_t Size);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
|
|||||||
void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
|
void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
|
||||||
MutexGuard locked(lock);
|
MutexGuard locked(lock);
|
||||||
|
|
||||||
|
DOUT << "Map " << *GV << " to " << Addr << "\n";
|
||||||
void *&CurVal = state.getGlobalAddressMap(locked)[GV];
|
void *&CurVal = state.getGlobalAddressMap(locked)[GV];
|
||||||
assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
|
assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
|
||||||
CurVal = Addr;
|
CurVal = Addr;
|
||||||
|
@ -925,6 +925,9 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
|
|||||||
<< Relocations.size() << " relocations\n";
|
<< Relocations.size() << " relocations\n";
|
||||||
Relocations.clear();
|
Relocations.clear();
|
||||||
|
|
||||||
|
// Mark code region readable and executable if it's not so already.
|
||||||
|
sys::Memory::SetRXPrivilege(FnStart, FnEnd-FnStart);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
DOUT << std::hex;
|
DOUT << std::hex;
|
||||||
|
@ -370,7 +370,11 @@ namespace {
|
|||||||
|
|
||||||
DefaultJITMemoryManager::DefaultJITMemoryManager() {
|
DefaultJITMemoryManager::DefaultJITMemoryManager() {
|
||||||
// Allocate a 16M block of memory for functions.
|
// Allocate a 16M block of memory for functions.
|
||||||
|
#if defined(__APPLE__) && defined(__arm__)
|
||||||
|
sys::MemoryBlock MemBlock = getNewMemoryBlock(4 << 20);
|
||||||
|
#else
|
||||||
sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20);
|
sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20);
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char *MemBase = static_cast<unsigned char*>(MemBlock.base());
|
unsigned char *MemBase = static_cast<unsigned char*>(MemBlock.base());
|
||||||
|
|
||||||
|
@ -58,3 +58,14 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
|
|||||||
#endif // end PPC
|
#endif // end PPC
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool llvm::sys::Memory::SetRXPrivilege(const void *Addr, size_t Size) {
|
||||||
|
#if defined(__APPLE__) && defined(__arm__)
|
||||||
|
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
|
||||||
|
(vm_size_t)Size, 0,
|
||||||
|
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
|
||||||
|
return KERN_SUCCESS == kr;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/// AllocateRWX - Allocate a slab of memory with read/write/execute
|
/// AllocateRWX - Allocate a slab of memory with read/write/execute
|
||||||
/// permissions. This is typically used for JIT applications where we want
|
/// permissions. This is typically used for JIT applications where we want
|
||||||
/// to emit code to the memory then jump to it. Getting this type of memory
|
/// to emit code to the memory then jump to it. Getting this type of memory
|
||||||
@ -52,8 +56,13 @@ llvm::sys::Memory::AllocateRWX(unsigned NumBytes, const MemoryBlock* NearBlock,
|
|||||||
void* start = NearBlock ? (unsigned char*)NearBlock->base() +
|
void* start = NearBlock ? (unsigned char*)NearBlock->base() +
|
||||||
NearBlock->size() : 0;
|
NearBlock->size() : 0;
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__arm__)
|
||||||
|
void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC,
|
||||||
|
flags, fd, 0);
|
||||||
|
#else
|
||||||
void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
|
void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||||
flags, fd, 0);
|
flags, fd, 0);
|
||||||
|
#endif
|
||||||
if (pa == MAP_FAILED) {
|
if (pa == MAP_FAILED) {
|
||||||
if (NearBlock) //Try again without a near hint
|
if (NearBlock) //Try again without a near hint
|
||||||
return AllocateRWX(NumBytes, 0);
|
return AllocateRWX(NumBytes, 0);
|
||||||
@ -61,9 +70,29 @@ llvm::sys::Memory::AllocateRWX(unsigned NumBytes, const MemoryBlock* NearBlock,
|
|||||||
MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
|
MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
|
||||||
return MemoryBlock();
|
return MemoryBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__arm__)
|
||||||
|
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
|
||||||
|
(vm_size_t)(pageSize*NumPages), 0,
|
||||||
|
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
|
||||||
|
if (KERN_SUCCESS != kr) {
|
||||||
|
MakeErrMsg(ErrMsg, "vm_protect max RWX failed\n");
|
||||||
|
return sys::MemoryBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = vm_protect(mach_task_self(), (vm_address_t)pa,
|
||||||
|
(vm_size_t)(pageSize*NumPages), 0,
|
||||||
|
VM_PROT_READ | VM_PROT_WRITE);
|
||||||
|
if (KERN_SUCCESS != kr) {
|
||||||
|
MakeErrMsg(ErrMsg, "vm_protect RW failed\n");
|
||||||
|
return sys::MemoryBlock();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemoryBlock result;
|
MemoryBlock result;
|
||||||
result.Address = pa;
|
result.Address = pa;
|
||||||
result.Size = NumPages*pageSize;
|
result.Size = NumPages*pageSize;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user