LLVM API Documentation
00001 //===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the llvm::sys::Memory class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_SUPPORT_MEMORY_H 00015 #define LLVM_SUPPORT_MEMORY_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include <string> 00019 #include <system_error> 00020 00021 namespace llvm { 00022 namespace sys { 00023 00024 /// This class encapsulates the notion of a memory block which has an address 00025 /// and a size. It is used by the Memory class (a friend) as the result of 00026 /// various memory allocation operations. 00027 /// @see Memory 00028 /// @brief Memory block abstraction. 00029 class MemoryBlock { 00030 public: 00031 MemoryBlock() : Address(nullptr), Size(0) { } 00032 MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { } 00033 void *base() const { return Address; } 00034 size_t size() const { return Size; } 00035 private: 00036 void *Address; ///< Address of first byte of memory area 00037 size_t Size; ///< Size, in bytes of the memory area 00038 friend class Memory; 00039 }; 00040 00041 /// This class provides various memory handling functions that manipulate 00042 /// MemoryBlock instances. 00043 /// @since 1.4 00044 /// @brief An abstraction for memory operations. 00045 class Memory { 00046 public: 00047 enum ProtectionFlags { 00048 MF_READ = 0x1000000, 00049 MF_WRITE = 0x2000000, 00050 MF_EXEC = 0x4000000 00051 }; 00052 00053 /// This method allocates a block of memory that is suitable for loading 00054 /// dynamically generated code (e.g. JIT). An attempt to allocate 00055 /// \p NumBytes bytes of virtual memory is made. 00056 /// \p NearBlock may point to an existing allocation in which case 00057 /// an attempt is made to allocate more memory near the existing block. 00058 /// The actual allocated address is not guaranteed to be near the requested 00059 /// address. 00060 /// \p Flags is used to set the initial protection flags for the block 00061 /// of the memory. 00062 /// \p EC [out] returns an object describing any error that occurs. 00063 /// 00064 /// This method may allocate more than the number of bytes requested. The 00065 /// actual number of bytes allocated is indicated in the returned 00066 /// MemoryBlock. 00067 /// 00068 /// The start of the allocated block must be aligned with the 00069 /// system allocation granularity (64K on Windows, page size on Linux). 00070 /// If the address following \p NearBlock is not so aligned, it will be 00071 /// rounded up to the next allocation granularity boundary. 00072 /// 00073 /// \r a non-null MemoryBlock if the function was successful, 00074 /// otherwise a null MemoryBlock is with \p EC describing the error. 00075 /// 00076 /// @brief Allocate mapped memory. 00077 static MemoryBlock allocateMappedMemory(size_t NumBytes, 00078 const MemoryBlock *const NearBlock, 00079 unsigned Flags, 00080 std::error_code &EC); 00081 00082 /// This method releases a block of memory that was allocated with the 00083 /// allocateMappedMemory method. It should not be used to release any 00084 /// memory block allocated any other way. 00085 /// \p Block describes the memory to be released. 00086 /// 00087 /// \r error_success if the function was successful, or an error_code 00088 /// describing the failure if an error occurred. 00089 /// 00090 /// @brief Release mapped memory. 00091 static std::error_code releaseMappedMemory(MemoryBlock &Block); 00092 00093 /// This method sets the protection flags for a block of memory to the 00094 /// state specified by /p Flags. The behavior is not specified if the 00095 /// memory was not allocated using the allocateMappedMemory method. 00096 /// \p Block describes the memory block to be protected. 00097 /// \p Flags specifies the new protection state to be assigned to the block. 00098 /// \p ErrMsg [out] returns a string describing any error that occurred. 00099 /// 00100 /// If \p Flags is MF_WRITE, the actual behavior varies 00101 /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the 00102 /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386). 00103 /// 00104 /// \r error_success if the function was successful, or an error_code 00105 /// describing the failure if an error occurred. 00106 /// 00107 /// @brief Set memory protection state. 00108 static std::error_code protectMappedMemory(const MemoryBlock &Block, 00109 unsigned Flags); 00110 00111 /// This method allocates a block of Read/Write/Execute memory that is 00112 /// suitable for executing dynamically generated code (e.g. JIT). An 00113 /// attempt to allocate \p NumBytes bytes of virtual memory is made. 00114 /// \p NearBlock may point to an existing allocation in which case 00115 /// an attempt is made to allocate more memory near the existing block. 00116 /// 00117 /// On success, this returns a non-null memory block, otherwise it returns 00118 /// a null memory block and fills in *ErrMsg. 00119 /// 00120 /// @brief Allocate Read/Write/Execute memory. 00121 static MemoryBlock AllocateRWX(size_t NumBytes, 00122 const MemoryBlock *NearBlock, 00123 std::string *ErrMsg = nullptr); 00124 00125 /// This method releases a block of Read/Write/Execute memory that was 00126 /// allocated with the AllocateRWX method. It should not be used to 00127 /// release any memory block allocated any other way. 00128 /// 00129 /// On success, this returns false, otherwise it returns true and fills 00130 /// in *ErrMsg. 00131 /// @brief Release Read/Write/Execute memory. 00132 static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr); 00133 00134 00135 /// InvalidateInstructionCache - Before the JIT can run a block of code 00136 /// that has been emitted it must invalidate the instruction cache on some 00137 /// platforms. 00138 static void InvalidateInstructionCache(const void *Addr, size_t Len); 00139 00140 /// setExecutable - Before the JIT can run a block of code, it has to be 00141 /// given read and executable privilege. Return true if it is already r-x 00142 /// or the system is able to change its previlege. 00143 static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = nullptr); 00144 00145 /// setWritable - When adding to a block of code, the JIT may need 00146 /// to mark a block of code as RW since the protections are on page 00147 /// boundaries, and the JIT internal allocations are not page aligned. 00148 static bool setWritable(MemoryBlock &M, std::string *ErrMsg = nullptr); 00149 00150 /// setRangeExecutable - Mark the page containing a range of addresses 00151 /// as executable. 00152 static bool setRangeExecutable(const void *Addr, size_t Size); 00153 00154 /// setRangeWritable - Mark the page containing a range of addresses 00155 /// as writable. 00156 static bool setRangeWritable(const void *Addr, size_t Size); 00157 }; 00158 } 00159 } 00160 00161 #endif