1cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===// 21f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer// 3cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// The LLVM Compiler Infrastructure 4cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 71f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer// 8cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer//===----------------------------------------------------------------------===// 9cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// 10cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// This file provides the Win32 specific implementation of various Memory 11cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// management utilities 12cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer// 13cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer//===----------------------------------------------------------------------===// 14cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h" 16bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor#include "llvm/Support/ErrorHandling.h" 171f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Process.h" 18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Support/WindowsError.h" 198a0ff3a2659e64408c76507ff0514748b6744b06Chandler Carruth 208a0ff3a2659e64408c76507ff0514748b6744b06Chandler Carruth// The Windows.h header must be the last one included. 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "WindowsSupport.h" 22bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 23bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylornamespace { 24bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 25bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew KaylorDWORD getWindowsProtectionFlags(unsigned Flags) { 26bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor switch (Flags) { 27bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // Contrary to what you might expect, the Windows page protection flags 28bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // are not a bitwise combination of RWX values 29bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_READ: 30bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_READONLY; 31bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_WRITE: 32bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // Note: PAGE_WRITE is not supported by VirtualProtect 33bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_READWRITE; 34bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE: 35bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_READWRITE; 36bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC: 37bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_EXECUTE_READ; 38bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_READ | 39bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor llvm::sys::Memory::MF_WRITE | 40bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor llvm::sys::Memory::MF_EXEC: 41bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_EXECUTE_READWRITE; 42bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor case llvm::sys::Memory::MF_EXEC: 43bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_EXECUTE; 44bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor default: 45bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor llvm_unreachable("Illegal memory protection flag specified!"); 46bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor } 47bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // Provide a default return value as required by some compilers. 48bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return PAGE_NOACCESS; 49bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 50bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 51bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylorsize_t getAllocationGranularity() { 52bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor SYSTEM_INFO Info; 53bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor ::GetSystemInfo(&Info); 54bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (Info.dwPageSize > Info.dwAllocationGranularity) 55bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return Info.dwPageSize; 56bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor else 57bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return Info.dwAllocationGranularity; 58bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 59bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 60bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} // namespace 61cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 62cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencernamespace llvm { 63bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylornamespace sys { 64cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 65cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer//===----------------------------------------------------------------------===// 661f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer//=== WARNING: Implementation here must contain only Win32 specific code 67b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer//=== and must not be UNIX code 68cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer//===----------------------------------------------------------------------===// 69cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 70bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew KaylorMemoryBlock Memory::allocateMappedMemory(size_t NumBytes, 71bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor const MemoryBlock *const NearBlock, 72bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor unsigned Flags, 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code &EC) { 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC = std::error_code(); 75bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (NumBytes == 0) 76bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return MemoryBlock(); 77bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 78bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // While we'd be happy to allocate single pages, the Windows allocation 79bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // granularity may be larger than a single page (in practice, it is 64K) 80bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // so mapping less than that will create an unreachable fragment of memory. 81bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor static const size_t Granularity = getAllocationGranularity(); 82bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor const size_t NumBlocks = (NumBytes+Granularity-1)/Granularity; 83cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 84bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) + 85bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor NearBlock->size() 867a7fc90ba3419490c478174d78a3d1fb5373054dAlp Toker : 0; 87b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer 88bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // If the requested address is not aligned to the allocation granularity, 89bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor // round up to get beyond NearBlock. VirtualAlloc would have rounded down. 90bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (Start && Start % Granularity != 0) 91bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Start += Granularity - Start % Granularity; 92a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth 93bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor DWORD Protect = getWindowsProtectionFlags(Flags); 94bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 95bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor void *PA = ::VirtualAlloc(reinterpret_cast<void*>(Start), 96bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor NumBlocks*Granularity, 97bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MEM_RESERVE | MEM_COMMIT, Protect); 98bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (PA == NULL) { 99c5c36765e6ff3207576571e6c75b6e44cd5e9331NAKAMURA Takumi if (NearBlock) { 100c5c36765e6ff3207576571e6c75b6e44cd5e9331NAKAMURA Takumi // Try again without the NearBlock hint 101bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return allocateMappedMemory(NumBytes, NULL, Flags, EC); 102c5c36765e6ff3207576571e6c75b6e44cd5e9331NAKAMURA Takumi } 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC = mapWindowsError(::GetLastError()); 104bed22d89020ea8a46c48bc1aa6128321a445dbb2Chris Lattner return MemoryBlock(); 105cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer } 106b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer 107bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MemoryBlock Result; 108bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Result.Address = PA; 109bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Result.Size = NumBlocks*Granularity; 1107a7fc90ba3419490c478174d78a3d1fb5373054dAlp Toker 111bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (Flags & MF_EXEC) 112bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Memory::InvalidateInstructionCache(Result.Address, Result.Size); 113bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 114bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return Result; 115cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer} 116cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code Memory::releaseMappedMemory(MemoryBlock &M) { 118bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (M.Address == 0 || M.Size == 0) 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::error_code(); 120bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 121bed22d89020ea8a46c48bc1aa6128321a445dbb2Chris Lattner if (!VirtualFree(M.Address, 0, MEM_RELEASE)) 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return mapWindowsError(::GetLastError()); 123bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 124bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor M.Address = 0; 125bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor M.Size = 0; 126bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::error_code(); 128bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 129bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code Memory::protectMappedMemory(const MemoryBlock &M, 131bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor unsigned Flags) { 132bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (M.Address == 0 || M.Size == 0) 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::error_code(); 134bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 135bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor DWORD Protect = getWindowsProtectionFlags(Flags); 136bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 137bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor DWORD OldFlags; 138bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags)) 139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return mapWindowsError(::GetLastError()); 140bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 141bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor if (Flags & MF_EXEC) 142bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Memory::InvalidateInstructionCache(M.Address, M.Size); 143bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return std::error_code(); 145bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 146bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 147bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor/// InvalidateInstructionCache - Before the JIT can run a block of code 148bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor/// that has been emitted it must invalidate the instruction cache on some 149bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor/// platforms. 150bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylorvoid Memory::InvalidateInstructionCache( 151bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor const void *Addr, size_t Len) { 152bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor FlushInstructionCache(GetCurrentProcess(), Addr, Len); 153bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 154bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 155bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 156bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew KaylorMemoryBlock Memory::AllocateRWX(size_t NumBytes, 157bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor const MemoryBlock *NearBlock, 158bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor std::string *ErrMsg) { 159bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MemoryBlock MB; 160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code EC; 161bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MB = allocateMappedMemory(NumBytes, NearBlock, 162bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MF_READ|MF_WRITE|MF_EXEC, EC); 163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (EC != std::error_code() && ErrMsg) { 164bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MakeErrMsg(ErrMsg, EC.message()); 165bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor } 166bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return MB; 167bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} 168bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor 169bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylorbool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { 170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code EC = releaseMappedMemory(M); 171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (EC == std::error_code()) 172bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return false; 173bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor MakeErrMsg(ErrMsg, EC.message()); 174bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor return true; 175cbad701d0b6fd42112e121e2d7af9c70aaee7440Reid Spencer} 176b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer 1772dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencerstatic DWORD getProtection(const void *addr) { 1782dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer MEMORY_BASIC_INFORMATION info; 1792dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (sizeof(info) == ::VirtualQuery(addr, &info, sizeof(info))) { 1802dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return info.Protect; 1812dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } 1822dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return 0; 1832dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer} 1842dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer 185932a32d2512353478d16c4101582adff404a55a5Jim Grosbachbool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) { 1862dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (!setRangeWritable(M.Address, M.Size)) { 1872dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: "); 1882dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } 189c8a07733d3cb1ed13963e9da3e8958bed0e3018dArgyrios Kyrtzidis return true; 190c8a07733d3cb1ed13963e9da3e8958bed0e3018dArgyrios Kyrtzidis} 191c8a07733d3cb1ed13963e9da3e8958bed0e3018dArgyrios Kyrtzidis 192932a32d2512353478d16c4101582adff404a55a5Jim Grosbachbool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) { 1932dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (!setRangeExecutable(M.Address, M.Size)) { 1942dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return MakeErrMsg(ErrMsg, "Cannot set memory to executable: "); 1952dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } 1962dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return true; 197c8a07733d3cb1ed13963e9da3e8958bed0e3018dArgyrios Kyrtzidis} 198c8a07733d3cb1ed13963e9da3e8958bed0e3018dArgyrios Kyrtzidis 199932a32d2512353478d16c4101582adff404a55a5Jim Grosbachbool Memory::setRangeWritable(const void *Addr, size_t Size) { 2002dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer DWORD prot = getProtection(Addr); 2012dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (!prot) 2022dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return false; 2032dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer 2042dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) { 2052dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer prot = PAGE_EXECUTE_READWRITE; 2062dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) { 2072dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer prot = PAGE_READWRITE; 2082dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } 2092dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer 2102dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer DWORD oldProt; 211bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Memory::InvalidateInstructionCache(Addr, Size); 2122dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt) 2132dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer == TRUE; 214b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer} 215b016a376abc0d35ab4e77ea32a5b0421d980482bReid Spencer 216932a32d2512353478d16c4101582adff404a55a5Jim Grosbachbool Memory::setRangeExecutable(const void *Addr, size_t Size) { 2172dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer DWORD prot = getProtection(Addr); 2182dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (!prot) 2192dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return false; 2202dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer 2212dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer if (prot == PAGE_NOACCESS) { 2222dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer prot = PAGE_EXECUTE; 2232dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } else if (prot == PAGE_READONLY) { 2242dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer prot = PAGE_EXECUTE_READ; 2252dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } else if (prot == PAGE_READWRITE) { 2262dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer prot = PAGE_EXECUTE_READWRITE; 2272dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer } 2282dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer 2292dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer DWORD oldProt; 230bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor Memory::InvalidateInstructionCache(Addr, Size); 2312dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt) 2322dd0cfe118dc133721364515f7db4d1f22652ae3Michael J. Spencer == TRUE; 233932a32d2512353478d16c4101582adff404a55a5Jim Grosbach} 234932a32d2512353478d16c4101582adff404a55a5Jim Grosbach 235bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} // namespace sys 236bbf628b6cefc8d817eb9ec04c2a357ad3f27d618Andrew Kaylor} // namespace llvm 237