1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
/* $Id: alloc-ef.h $ */
/** @file
* IPRT - Memory Allocation, electric fence.
*/
/*
* Copyright (C) 2006-2022 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses>.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
* in the VirtualBox 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.
*
* SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
*/
#ifndef IPRT_INCLUDED_SRC_r3_alloc_ef_h
#define IPRT_INCLUDED_SRC_r3_alloc_ef_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
/*******************************************************************************
* 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 <iprt/win/windows.h>
#else
# include <sys/mman.h>
#endif
#include <iprt/avl.h>
#include <iprt/thread.h>
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* Allocation types.
*/
typedef enum RTMEMTYPE
{
RTMEMTYPE_RTMEMALLOC,
RTMEMTYPE_RTMEMALLOCZ,
RTMEMTYPE_RTMEMREALLOC,
RTMEMTYPE_RTMEMFREE,
RTMEMTYPE_RTMEMFREEZ,
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, size_t cbUser, 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 /* !IPRT_INCLUDED_SRC_r3_alloc_ef_h */
|