1218885Sdim//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file declares the llvm::sys::Memory class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14249423Sdim#ifndef LLVM_SUPPORT_MEMORY_H 15249423Sdim#define LLVM_SUPPORT_MEMORY_H 16218885Sdim 17218885Sdim#include "llvm/Support/DataTypes.h" 18243830Sdim#include "llvm/Support/system_error.h" 19218885Sdim#include <string> 20218885Sdim 21218885Sdimnamespace llvm { 22218885Sdimnamespace sys { 23218885Sdim 24218885Sdim /// This class encapsulates the notion of a memory block which has an address 25218885Sdim /// and a size. It is used by the Memory class (a friend) as the result of 26218885Sdim /// various memory allocation operations. 27218885Sdim /// @see Memory 28218885Sdim /// @brief Memory block abstraction. 29218885Sdim class MemoryBlock { 30218885Sdim public: 31218885Sdim MemoryBlock() : Address(0), Size(0) { } 32218885Sdim MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { } 33218885Sdim void *base() const { return Address; } 34218885Sdim size_t size() const { return Size; } 35218885Sdim private: 36218885Sdim void *Address; ///< Address of first byte of memory area 37218885Sdim size_t Size; ///< Size, in bytes of the memory area 38218885Sdim friend class Memory; 39218885Sdim }; 40218885Sdim 41218885Sdim /// This class provides various memory handling functions that manipulate 42218885Sdim /// MemoryBlock instances. 43218885Sdim /// @since 1.4 44218885Sdim /// @brief An abstraction for memory operations. 45218885Sdim class Memory { 46218885Sdim public: 47243830Sdim enum ProtectionFlags { 48243830Sdim MF_READ = 0x1000000, 49243830Sdim MF_WRITE = 0x2000000, 50243830Sdim MF_EXEC = 0x4000000 51243830Sdim }; 52243830Sdim 53243830Sdim /// This method allocates a block of memory that is suitable for loading 54243830Sdim /// dynamically generated code (e.g. JIT). An attempt to allocate 55243830Sdim /// \p NumBytes bytes of virtual memory is made. 56243830Sdim /// \p NearBlock may point to an existing allocation in which case 57243830Sdim /// an attempt is made to allocate more memory near the existing block. 58243830Sdim /// The actual allocated address is not guaranteed to be near the requested 59243830Sdim /// address. 60243830Sdim /// \p Flags is used to set the initial protection flags for the block 61243830Sdim /// of the memory. 62243830Sdim /// \p EC [out] returns an object describing any error that occurs. 63243830Sdim /// 64243830Sdim /// This method may allocate more than the number of bytes requested. The 65243830Sdim /// actual number of bytes allocated is indicated in the returned 66243830Sdim /// MemoryBlock. 67243830Sdim /// 68243830Sdim /// The start of the allocated block must be aligned with the 69243830Sdim /// system allocation granularity (64K on Windows, page size on Linux). 70243830Sdim /// If the address following \p NearBlock is not so aligned, it will be 71243830Sdim /// rounded up to the next allocation granularity boundary. 72243830Sdim /// 73243830Sdim /// \r a non-null MemoryBlock if the function was successful, 74243830Sdim /// otherwise a null MemoryBlock is with \p EC describing the error. 75243830Sdim /// 76243830Sdim /// @brief Allocate mapped memory. 77243830Sdim static MemoryBlock allocateMappedMemory(size_t NumBytes, 78243830Sdim const MemoryBlock *const NearBlock, 79243830Sdim unsigned Flags, 80243830Sdim error_code &EC); 81243830Sdim 82243830Sdim /// This method releases a block of memory that was allocated with the 83243830Sdim /// allocateMappedMemory method. It should not be used to release any 84243830Sdim /// memory block allocated any other way. 85243830Sdim /// \p Block describes the memory to be released. 86243830Sdim /// 87243830Sdim /// \r error_success if the function was successful, or an error_code 88243830Sdim /// describing the failure if an error occurred. 89243830Sdim /// 90243830Sdim /// @brief Release mapped memory. 91243830Sdim static error_code releaseMappedMemory(MemoryBlock &Block); 92243830Sdim 93243830Sdim /// This method sets the protection flags for a block of memory to the 94243830Sdim /// state specified by /p Flags. The behavior is not specified if the 95243830Sdim /// memory was not allocated using the allocateMappedMemory method. 96243830Sdim /// \p Block describes the memory block to be protected. 97243830Sdim /// \p Flags specifies the new protection state to be assigned to the block. 98243830Sdim /// \p ErrMsg [out] returns a string describing any error that occured. 99243830Sdim /// 100243830Sdim /// If \p Flags is MF_WRITE, the actual behavior varies 101243830Sdim /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the 102243830Sdim /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386). 103243830Sdim /// 104243830Sdim /// \r error_success if the function was successful, or an error_code 105243830Sdim /// describing the failure if an error occurred. 106243830Sdim /// 107243830Sdim /// @brief Set memory protection state. 108243830Sdim static error_code protectMappedMemory(const MemoryBlock &Block, 109243830Sdim unsigned Flags); 110243830Sdim 111218885Sdim /// This method allocates a block of Read/Write/Execute memory that is 112218885Sdim /// suitable for executing dynamically generated code (e.g. JIT). An 113218885Sdim /// attempt to allocate \p NumBytes bytes of virtual memory is made. 114218885Sdim /// \p NearBlock may point to an existing allocation in which case 115218885Sdim /// an attempt is made to allocate more memory near the existing block. 116218885Sdim /// 117218885Sdim /// On success, this returns a non-null memory block, otherwise it returns 118218885Sdim /// a null memory block and fills in *ErrMsg. 119218885Sdim /// 120218885Sdim /// @brief Allocate Read/Write/Execute memory. 121218885Sdim static MemoryBlock AllocateRWX(size_t NumBytes, 122218885Sdim const MemoryBlock *NearBlock, 123218885Sdim std::string *ErrMsg = 0); 124218885Sdim 125218885Sdim /// This method releases a block of Read/Write/Execute memory that was 126218885Sdim /// allocated with the AllocateRWX method. It should not be used to 127218885Sdim /// release any memory block allocated any other way. 128218885Sdim /// 129218885Sdim /// On success, this returns false, otherwise it returns true and fills 130218885Sdim /// in *ErrMsg. 131218885Sdim /// @brief Release Read/Write/Execute memory. 132218885Sdim static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0); 133218885Sdim 134218885Sdim 135218885Sdim /// InvalidateInstructionCache - Before the JIT can run a block of code 136218885Sdim /// that has been emitted it must invalidate the instruction cache on some 137218885Sdim /// platforms. 138218885Sdim static void InvalidateInstructionCache(const void *Addr, size_t Len); 139218885Sdim 140218885Sdim /// setExecutable - Before the JIT can run a block of code, it has to be 141218885Sdim /// given read and executable privilege. Return true if it is already r-x 142218885Sdim /// or the system is able to change its previlege. 143221345Sdim static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0); 144218885Sdim 145218885Sdim /// setWritable - When adding to a block of code, the JIT may need 146218885Sdim /// to mark a block of code as RW since the protections are on page 147218885Sdim /// boundaries, and the JIT internal allocations are not page aligned. 148221345Sdim static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0); 149218885Sdim 150218885Sdim /// setRangeExecutable - Mark the page containing a range of addresses 151218885Sdim /// as executable. 152218885Sdim static bool setRangeExecutable(const void *Addr, size_t Size); 153218885Sdim 154218885Sdim /// setRangeWritable - Mark the page containing a range of addresses 155218885Sdim /// as writable. 156218885Sdim static bool setRangeWritable(const void *Addr, size_t Size); 157218885Sdim }; 158218885Sdim} 159218885Sdim} 160218885Sdim 161218885Sdim#endif 162