// bdls_memoryutil.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BDLS_MEMORYUTIL #define INCLUDED_BDLS_MEMORYUTIL #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a set of portable utilities for memory manipulation. // //@CLASSES: // bdls::MemoryUtil: struct which scopes memory system utilities. // //@DESCRIPTION: This component, 'bdls::MemoryUtil', defines a // platform-independent interface for memory manipulation, providing utilities // for querying page size, allocating/deallocating page-aligned memory, and // utility to change memory protection. // ///Usage ///----- // First, allocate one page of memory. //.. // int pageSize = bdls::MemoryUtil::pageSize(); // char *data = (char*)bdls::MemoryUtil::allocate(pageSize); //.. // Write into the allocated buffer. //.. // data[0] = '1'; //.. // // Make the memory write protected //.. // bdls::MemoryUtil::protect(data, pageSize, // bdls::MemoryUtil::k_ACCESS_READ); //.. // // Verify that data still could be read. //.. // assert('1' == data[0]); //.. // // Once again, try writing into the buffer. This should crash our process. //.. // data[0] = '2'; //.. // // Restore read/write access and free the allocated memory. Actually, this // will never be executed, as the process has already crashed. //.. // bdls::MemoryUtil::protect(data, pageSize, // bdls::MemoryUtil::k_ACCESS_READ_WRITE); // bdls::MemoryUtil::free(data); //.. #include <bdlscm_version.h> namespace BloombergLP { namespace bdls { // ================= // struct MemoryUtil // ================= struct MemoryUtil { // TYPES enum Access { k_ACCESS_NONE = 0, k_ACCESS_READ = 0x1, k_ACCESS_WRITE = 0x2, k_ACCESS_EXECUTE = 0x4, k_ACCESS_READ_WRITE = k_ACCESS_READ | k_ACCESS_WRITE, k_ACCESS_READ_EXECUTE = k_ACCESS_READ | k_ACCESS_EXECUTE, k_ACCESS_WRITE_EXECUTE = k_ACCESS_WRITE | k_ACCESS_EXECUTE, k_ACCESS_READ_WRITE_EXECUTE = k_ACCESS_READ | k_ACCESS_WRITE | k_ACCESS_EXECUTE #ifndef BDE_OMIT_INTERNAL_DEPRECATED , BDESU_ACCESS_NONE = k_ACCESS_NONE , BDESU_ACCESS_READ = k_ACCESS_READ , BDESU_ACCESS_WRITE = k_ACCESS_WRITE , BDESU_ACCESS_EXECUTE = k_ACCESS_EXECUTE , BDESU_ACCESS_READ_WRITE = k_ACCESS_READ_WRITE , BDESU_ACCESS_READ_EXECUTE = k_ACCESS_READ_EXECUTE , BDESU_ACCESS_WRITE_EXECUTE = k_ACCESS_WRITE_EXECUTE , BDESU_ACCESS_READ_WRITE_EXECUTE = k_ACCESS_READ_WRITE_EXECUTE , ACCESS_READ = k_ACCESS_READ , ACCESS_WRITE = k_ACCESS_WRITE , ACCESS_EXECUTE = k_ACCESS_EXECUTE , ACCESS_NONE = k_ACCESS_NONE , ACCESS_READ_WRITE = k_ACCESS_READ_WRITE , ACCESS_READ_EXECUTE = k_ACCESS_READ_EXECUTE , ACCESS_WRITE_EXECUTE = k_ACCESS_WRITE_EXECUTE , ACCESS_READ_WRITE_EXECUTE = k_ACCESS_READ_WRITE_EXECUTE #endif // BDE_OMIT_INTERNAL_DEPRECATED }; // CLASS METHODS static int pageSize(); // Return the memory page size of the platform. static int protect(void *address, int numBytes, int mode); // Change the access protection on a region of memory starting at the // specified 'address' and 'numBytes' long, according to specified // 'mode', making memory readable if '(mode & ACCESS_READ)' is nonzero // and writable if '(mode & ACCESS_WRITE)' is nonzero. Return 0 on // success, and a nonzero value otherwise. The behavior is undefined // if 'addr' is not aligned on a page boundary, if 'numBytes' is not a // multiple of 'pageSize()', or if 'numBytes' is 0. Note that some // platforms do not support certain protection modes, e.g., on some // platforms the memory cannot be made writable but unreadable, or // readable but non-executable. On these platforms the actual access // protection set on the region might be more permissive than the // specified one. Also note that most memory allocators do not expect // memory protection on allocated memory to be changed, so you must // reset protection back to ACCESS_READ_WRITE before releasing the // memory. static void *allocate(int numBytes); // Allocate an area of memory of the specified size 'numBytes', aligned // on a page boundary. Return a pointer to allocated memory on // success, and a null pointer otherwise. Note that the allocated // memory is readable and writable, and read/write access to this // memory, if revoked, must be restored before deallocation. static int deallocate(void *address); // Deallocate a memory area at the specified 'address' previously // allocated with the 'allocate' method. Return 0 on success, and a // nonzero value otherwise. The behavior is undefined if read or write // access to any memory in this area has been revoked and not restored. // Note that deallocating memory does not change memory protection. }; } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------