15 #include "llvm/Support/DataTypes.h"
24 DWORD getWindowsProtectionFlags(
unsigned Flags) {
32 return PAGE_READWRITE;
34 return PAGE_READWRITE;
36 return PAGE_EXECUTE_READ;
40 return PAGE_EXECUTE_READWRITE;
50 size_t getAllocationGranularity() {
52 ::GetSystemInfo(&Info);
53 if (Info.dwPageSize > Info.dwAllocationGranularity)
54 return Info.dwPageSize;
56 return Info.dwAllocationGranularity;
70 const MemoryBlock *
const NearBlock,
80 static const size_t Granularity = getAllocationGranularity();
81 const size_t NumBlocks = (NumBytes+Granularity-1)/Granularity;
83 uintptr_t Start = NearBlock ?
reinterpret_cast<uintptr_t
>(NearBlock->base()) +
89 if (Start && Start % Granularity != 0)
90 Start += Granularity - Start % Granularity;
92 DWORD Protect = getWindowsProtectionFlags(Flags);
94 void *PA = ::VirtualAlloc(reinterpret_cast<void*>(Start),
95 NumBlocks*Granularity,
96 MEM_RESERVE | MEM_COMMIT, Protect);
103 return MemoryBlock();
108 Result.Size = NumBlocks*Granularity;
117 if (M.Address == 0 || M.Size == 0)
120 if (!VirtualFree(M.Address, 0, MEM_RELEASE))
131 if (M.Address == 0 || M.Size == 0)
134 DWORD Protect = getWindowsProtectionFlags(Flags);
137 if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags))
150 const void *Addr,
size_t Len) {
151 FlushInstructionCache(GetCurrentProcess(), Addr, Len);
156 const MemoryBlock *NearBlock,
157 std::string *ErrMsg) {
176 static DWORD getProtection(
const void *addr) {
177 MEMORY_BASIC_INFORMATION
info;
178 if (
sizeof(info) == ::VirtualQuery(addr, &info,
sizeof(info))) {
186 return MakeErrMsg(ErrMsg,
"Cannot set memory to writeable: ");
193 return MakeErrMsg(ErrMsg,
"Cannot set memory to executable: ");
199 DWORD prot = getProtection(Addr);
203 if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) {
204 prot = PAGE_EXECUTE_READWRITE;
205 }
else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) {
206 prot = PAGE_READWRITE;
211 return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
216 DWORD prot = getProtection(Addr);
220 if (prot == PAGE_NOACCESS) {
222 }
else if (prot == PAGE_READONLY) {
223 prot = PAGE_EXECUTE_READ;
224 }
else if (prot == PAGE_READWRITE) {
225 prot = PAGE_EXECUTE_READWRITE;
230 return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
const error_category & system_category()
static bool setRangeWritable(const void *Addr, size_t Size)
static void InvalidateInstructionCache(const void *Addr, size_t Len)
#define llvm_unreachable(msg)
static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg=0)
Release Read/Write/Execute memory.
static bool setExecutable(MemoryBlock &M, std::string *ErrMsg=0)
static error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
Set memory protection state.
static bool setRangeExecutable(const void *Addr, size_t Size)
static MemoryBlock AllocateRWX(size_t NumBytes, const MemoryBlock *NearBlock, std::string *ErrMsg=0)
Allocate Read/Write/Execute memory.
static bool setWritable(MemoryBlock &M, std::string *ErrMsg=0)
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, error_code &EC)
Allocate mapped memory.
bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix)
static error_code success()
static error_code releaseMappedMemory(MemoryBlock &Block)
Release mapped memory.