/* $Id: alloc-ef.h 56290 2015-06-09 14:01:31Z vboxsync $ */ /** @file * IPRT - Memory Allocation, electric fence. */ /* * Copyright (C) 2006-2015 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ #ifndef ___alloc_ef_h #define ___alloc_ef_h /******************************************************************************* * Defined Constants And Macros * *******************************************************************************/ #if defined(DOXYGEN_RUNNING) # define RTALLOC_USE_EFENCE # define RTALLOC_EFENCE_IN_FRONT # define RTALLOC_EFENCE_FREE_FILL 'f' #endif /** @def RTALLOC_USE_EFENCE * If defined the electric fence put up for ALL allocations by RTMemAlloc(), * RTMemAllocZ(), RTMemRealloc(), RTMemTmpAlloc() and RTMemTmpAllocZ(). */ #if 0 # define RTALLOC_USE_EFENCE #endif /** @def RTALLOC_EFENCE_SIZE * The size of the fence. This must be page aligned. */ #define RTALLOC_EFENCE_SIZE PAGE_SIZE /** @def RTALLOC_EFENCE_ALIGNMENT * The allocation alignment, power of two of course. * * Use this for working around misaligned sizes, usually stemming from * allocating a string or something after the main structure. When you * encounter this, please fix the allocation to RTMemAllocVar or RTMemAllocZVar. */ #if 0 # define RTALLOC_EFENCE_ALIGNMENT (ARCH_BITS / 8) #else # define RTALLOC_EFENCE_ALIGNMENT 1 #endif /** @def RTALLOC_EFENCE_IN_FRONT * Define this to put the fence up in front of the block. * The default (when this isn't defined) is to up it up after the block. */ //# define RTALLOC_EFENCE_IN_FRONT /** @def RTALLOC_EFENCE_TRACE * Define this to support actual free and reallocation of blocks. */ #define RTALLOC_EFENCE_TRACE /** @def RTALLOC_EFENCE_FREE_DELAYED * This define will enable free() delay and protection of the freed data * while it's being delayed. The value of RTALLOC_EFENCE_FREE_DELAYED defines * the threshold of the delayed blocks. * Delayed blocks does not consume any physical memory, only virtual address space. * Requires RTALLOC_EFENCE_TRACE. */ #define RTALLOC_EFENCE_FREE_DELAYED (20 * _1M) /** @def RTALLOC_EFENCE_FREE_FILL * This define will enable memset(,RTALLOC_EFENCE_FREE_FILL,)'ing the user memory * in the block before freeing/decommitting it. This is useful in GDB since GDB * appears to be able to read the content of the page even after it's been * decommitted. * Requires RTALLOC_EFENCE_TRACE. */ #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(DOXYGEN_RUNNING) # define RTALLOC_EFENCE_FREE_FILL 'f' #endif /** @def RTALLOC_EFENCE_FILLER * This define will enable memset(,RTALLOC_EFENCE_FILLER,)'ing the allocated * memory when the API doesn't require it to be zero'd. */ #define RTALLOC_EFENCE_FILLER 0xef /** @def RTALLOC_EFENCE_NOMAN_FILLER * This define will enable memset(,RTALLOC_EFENCE_NOMAN_FILLER,)'ing the * unprotected but not allocated area of memory, the so called no man's land. */ #define RTALLOC_EFENCE_NOMAN_FILLER 0xaa /** @def RTALLOC_EFENCE_FENCE_FILLER * This define will enable memset(,RTALLOC_EFENCE_FENCE_FILLER,)'ing the * fence itself, as debuggers can usually read them. */ #define RTALLOC_EFENCE_FENCE_FILLER 0xcc #if defined(DOXYGEN_RUNNING) /** @def RTALLOC_EFENCE_CPP * This define will enable the new and delete wrappers. */ # define RTALLOC_EFENCE_CPP #endif #if defined(RUNNING_DOXYGEN) /** @def RTALLOC_REPLACE_MALLOC * Replaces the malloc, calloc, realloc, free and friends in libc (experimental). * Set in LocalConfig.kmk. Requires RTALLOC_EFENCE_TRACE to work. */ # define RTALLOC_REPLACE_MALLOC #endif #if defined(RTALLOC_REPLACE_MALLOC) && !defined(RTALLOC_EFENCE_TRACE) # error "RTALLOC_REPLACE_MALLOC requires RTALLOC_EFENCE_TRACE." #endif /******************************************************************************* * Header Files * *******************************************************************************/ #ifdef RT_OS_WINDOWS # include #else # include #endif #include #include /******************************************************************************* * Structures and Typedefs * *******************************************************************************/ /** * Allocation types. */ typedef enum RTMEMTYPE { RTMEMTYPE_RTMEMALLOC, RTMEMTYPE_RTMEMALLOCZ, RTMEMTYPE_RTMEMREALLOC, RTMEMTYPE_RTMEMFREE, RTMEMTYPE_NEW, RTMEMTYPE_NEW_ARRAY, RTMEMTYPE_DELETE, RTMEMTYPE_DELETE_ARRAY } RTMEMTYPE; #ifdef RTALLOC_EFENCE_TRACE /** * Node tracking a memory allocation. */ typedef struct RTMEMBLOCK { /** Avl node code, key is the user block pointer. */ AVLPVNODECORE Core; /** Allocation type. */ RTMEMTYPE enmType; /** The unaligned size of the block. */ size_t cbUnaligned; /** The aligned size of the block. */ size_t cbAligned; /** The allocation tag (read-only string). */ const char *pszTag; /** The return address of the allocator function. */ void *pvCaller; /** Line number of the alloc call. */ unsigned iLine; /** File from within the allocation was made. */ const char *pszFile; /** Function from within the allocation was made. */ const char *pszFunction; } RTMEMBLOCK, *PRTMEMBLOCK; #endif /******************************************************************************* * Internal Functions * ******************************************************************************/ RT_C_DECLS_BEGIN RTDECL(void *) rtR3MemAlloc(const char *pszOp, RTMEMTYPE enmType, size_t cbUnaligned, size_t cbAligned, const char *pszTag, void *pvCaller, RT_SRC_POS_DECL); RTDECL(void *) rtR3MemRealloc(const char *pszOp, RTMEMTYPE enmType, void *pvOld, size_t cbNew, const char *pszTag, void *pvCaller, RT_SRC_POS_DECL); RTDECL(void) rtR3MemFree(const char *pszOp, RTMEMTYPE enmType, void *pv, void *pvCaller, RT_SRC_POS_DECL); RT_C_DECLS_END /******************************************************************************* * Global Variables * *******************************************************************************/ #ifdef RTALLOC_REPLACE_MALLOC RT_C_DECLS_BEGIN extern void * (*g_pfnOrgMalloc)(size_t); extern void * (*g_pfnOrgCalloc)(size_t, size_t); extern void * (*g_pfnOrgRealloc)(void *, size_t); extern void (*g_pfnOrgFree)(void *); RT_C_DECLS_END #endif #endif