File: duma.h

package info (click to toggle)
duma 2.5.21-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,460 kB
  • sloc: ansic: 5,512; cpp: 2,205; makefile: 441; javascript: 191; sh: 129
file content (352 lines) | stat: -rw-r--r-- 13,771 bytes parent folder | download | duplicates (2)
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*
 * DUMA - Red-Zone memory allocator.
 * Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
 * Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
 * Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
 * License: GNU GPL (GNU General Public License, see COPYING-GPL)
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * FILE CONTENTS:
 * header file for inclusion from YOUR application code
 */

/* explicitly no "#ifndef _DUMA_H_" to allow mutliple inclusions
 * within single source file with inclusion of noduma.h in between
 */

#include <stdlib.h>

/*
 * #include <stdlib.h>
 *
 * You must include <stdlib.h> before including <duma.h> !
 *
 */

/* for enabling inclusion of duma.h after inclusion of efencint.h */
/* remove previous definitions */
#define SKIP_DUMA_NO_CXX
#include "noduma.h"
#undef SKIP_DUMA_NO_CXX

#include "duma_config.h"

#ifdef __cplusplus
  #define DUMA_EXTERN_C   extern "C"
#else
  #define DUMA_EXTERN_C   extern
#endif

#ifdef DUMA_NO_DUMA

  /* enable these macros even in release code, but do nothing */
  #define DUMA_newFrame()             do { } while(0)
  #define DUMA_delFrame()             do { } while(0)

  #define DUMA_SET_ALIGNMENT(V)       do { } while(0)
  #define DUMA_SET_PROTECT_BELOW(V)   do { } while(0)
  #define DUMA_SET_FILL(V)            do { } while(0)

  #define DUMA_ASSERT(EXPR)           do { } while(0)

  #define DUMA_CHECK(BASEADR)         do { } while(0)
  #define DUMA_CHECKALL()             do { } while(0)

  #define CA_DECLARE(NAME,SIZE)       do { } while(0)
  #define CA_DEFINE(TYPE,NAME,SIZE)   TYPE NAME[SIZE]
  #define CA_REF(NAME,INDEX)          NAME[INDEX]

#else /* ifndef DUMA_NO_DUMA */

  #ifndef DUMA_EXTERNS_DECLARED
  #define DUMA_EXTERNS_DECLARED
  /* global DUMA variables */
  DUMA_EXTERN_C int DUMA_OUTPUT_DEBUG;
  DUMA_EXTERN_C int DUMA_OUTPUT_STDOUT;
  DUMA_EXTERN_C int DUMA_OUTPUT_STDERR;
  DUMA_EXTERN_C char* DUMA_OUTPUT_FILE;
  DUMA_EXTERN_C int DUMA_OUTPUT_STACKTRACE;
  #endif /* DUMA_EXTERNS_DECLARED */



  /* set Maximum Delete Depth (depth of recursive destructor calls) */
  #ifndef DUMA_MAX_DEL_DEPTH
	#define DUMA_MAX_DEL_DEPTH    256
  #endif


  #ifndef DUMA_TLSVARTYPE_DEFINED
  #define DUMA_TLSVARTYPE_DEFINED
	/* TODO following variables should exist per thread ("thread-local") */
	typedef struct
	{
	  /*
	   * ALIGNMENT is a global variable used to control the default alignment
	   * of buffers returned by malloc(), calloc(), and realloc(). It is all-caps
	   * so that its name matches the name of the environment variable that is used
	   * to set it. This gives the programmer one less name to remember.
	   */
	  int           ALIGNMENT;

	  /*
	   * PROTECT_BELOW is used to modify the behavior of the allocator. When
	   * its value is non-zero, the allocator will place an inaccessable page
	   * immediately _before_ the malloc buffer in the address space, instead
	   * of _after_ it. Use this to detect malloc buffer under-runs, rather than
	   * over-runs. It won't detect both at the same time, so you should test your
	   * software twice, once with this value clear, and once with it set.
	   */
	  int           PROTECT_BELOW;

	  /*
	   * FILL is set to 0-255 if DUMA should fill all new allocated
	   * memory with the specified value. Set to -1 when DUMA should not
	   * initialise allocated memory.
	   * default is set to initialise with 255, cause many programs rely on
	   * initialisation to 0!
	   */
	  int           FILL;

	#if !defined(DUMA_NO_CPP_SUPPORT) && !defined(DUMA_NO_LEAKDETECTION)
	  int           Magic;
	  int           DelPtr;
	  const char *  DelFile[DUMA_MAX_DEL_DEPTH];
	  int           DelLine[DUMA_MAX_DEL_DEPTH];
	#endif
	} DUMA_TLSVARS_T;
  #endif


  #ifndef DUMA_GLOBALS_DEFINED
  #define DUMA_GLOBALS_DEFINED

	typedef struct
	{
	  /* Protection Space A */
	  char  acSpaceA[2 * DUMA_PAGE_SIZE];

	  /* Variable: _duma_allocList
	   *
	   * _DUMA_allocList points to the array of slot structures used to manage the
	   * malloc arena.
	   */
	  struct _DUMA_Slot * allocList;

	  /* Variable: _duma_null_addr
	   *
	   * _duma_null_addr is the address malloc() or C++ operator new returns, when size is 0
	   * two pages get reserved and protected
	   */
	  void * null_addr;


	  /* Variable */
	  DUMA_TLSVARS_T TLS;


	  /* Protection Space B */
	  char  acSpaceB[2 * DUMA_PAGE_SIZE];

	} DUMA_GLOBALVARS_T;

	DUMA_EXTERN_C DUMA_GLOBALVARS_T _duma_g;

  #endif /* DUMA_GLOBALS_DEFINED */



  #define GET_DUMA_TLSVARS()  (&_duma_g.TLS)


  #ifndef DUMA_SET_ALIGNMENT
	#define DUMA_SET_ALIGNMENT(V)      GET_DUMA_TLSVARS()->ALIGNMENT = (V)
  #endif
  #ifndef DUMA_SET_PROTECT_BELOW
	#define DUMA_SET_PROTECT_BELOW(V)  GET_DUMA_TLSVARS()->PROTECT_BELOW = (V)
  #endif
  #ifndef DUMA_SET_FILL
	#define DUMA_SET_FILL(V)           GET_DUMA_TLSVARS()->FILL = (V)
  #endif


  #ifndef DUMA_ENUMS_DECLARED
  #define DUMA_ENUMS_DECLARED

	/* allocator defines the type of calling allocator/deallocator function */
	enum _DUMA_Allocator
	{
	  EFA_INT_ALLOC
	, EFA_INT_DEALLOC
	, EFA_MALLOC
	, EFA_CALLOC
	, EFA_FREE
	, EFA_MEMALIGN
	, EFA_POSIX_MEMALIGN
	, EFA_REALLOC
	, EFA_VALLOC
	, EFA_STRDUP
	, EFA_NEW_ELEM
	, EFA_DEL_ELEM
	, EFA_NEW_ARRAY
	, EFA_DEL_ARRAY

	/* use following enums when calling _duma_allocate()/_duma_deallocate()
	 * from user defined member operators
	 */
	, EFA_MEMBER_NEW_ELEM
	, EFA_MEMBER_DEL_ELEM
	, EFA_MEMBER_NEW_ARRAY
	, EFA_MEMBER_DEL_ARRAY
	};

	enum _DUMA_FailReturn
	{
	  DUMA_FAIL_NULL
	, DUMA_FAIL_ENV
	};

  #endif /* DUMA_ENUMS_DECLARED */


  #ifndef DUMA_FUNCTIONS_DECLARED
  #define DUMA_FUNCTIONS_DECLARED

	DUMA_EXTERN_C void _duma_init(void);
	DUMA_EXTERN_C void _duma_assert(const char * exprstr, const char * filename, int lineno);

	DUMA_EXTERN_C void duma_check(void * address);
	DUMA_EXTERN_C void duma_checkAll();

	DUMA_EXTERN_C void * duma_alloc_return( void * address );

	#ifdef DUMA_EXPLICIT_INIT
	  DUMA_EXTERN_C void   duma_init(void);
	#endif

	#ifndef DUMA_NO_LEAKDETECTION
	  DUMA_EXTERN_C void * _duma_allocate(size_t alignment, size_t userSize, int protectBelow, int fillByte, int protectAllocList, enum _DUMA_Allocator allocator, enum _DUMA_FailReturn fail, const char * filename, int lineno);
	  DUMA_EXTERN_C void   _duma_deallocate(void * baseAdr, int protectAllocList, enum _DUMA_Allocator allocator, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_malloc(size_t size, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_calloc(size_t elemCount, size_t elemSize, const char * filename, int lineno);
	  DUMA_EXTERN_C void   _duma_free(void * baseAdr, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_memalign(size_t alignment, size_t userSize, const char * filename, int lineno);
	  DUMA_EXTERN_C int    _duma_posix_memalign(void **memptr, size_t alignment, size_t userSize, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_realloc(void * baseAdr, size_t newSize, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_valloc(size_t size, const char * filename, int lineno);
	  DUMA_EXTERN_C char * _duma_strdup(const char *str, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_memcpy(void *dest, const void *src, size_t size, const char * filename, int lineno);
	  DUMA_EXTERN_C void * _duma_memmove(void *dest, const void *src, size_t size);
	  DUMA_EXTERN_C char * _duma_strcpy(char *dest, const char *src, const char * filename, int lineno);
	  DUMA_EXTERN_C char * _duma_strncpy(char *dest, const char *src, size_t size, const char * filename, int lineno);
	  DUMA_EXTERN_C char * _duma_strcat(char *dest, const char *src, const char * filename, int lineno);
	  DUMA_EXTERN_C char * _duma_strncat(char *dest, const char *src, size_t size, const char * filename, int lineno);
	  DUMA_EXTERN_C void  DUMA_newFrame(void);
	  DUMA_EXTERN_C void  DUMA_delFrame(void);
	#else /* DUMA_NO_LEAKDETECTION */
	  DUMA_EXTERN_C void * _duma_allocate(size_t alignment, size_t userSize, int protectBelow, int fillByte, int protectAllocList, enum _DUMA_Allocator allocator, enum _DUMA_FailReturn fail);
	  DUMA_EXTERN_C void   _duma_deallocate(void * baseAdr, int protectAllocList, enum _DUMA_Allocator allocator);
	  DUMA_EXTERN_C void * _duma_malloc(size_t size);
	  DUMA_EXTERN_C void * _duma_calloc(size_t elemCount, size_t elemSize);
	  DUMA_EXTERN_C void   _duma_free(void * baseAdr);
	  DUMA_EXTERN_C void * _duma_memalign(size_t alignment, size_t userSize);
	  DUMA_EXTERN_C int    _duma_posix_memalign(void **memptr, size_t alignment, size_t userSize);
	  DUMA_EXTERN_C void * _duma_realloc(void * baseAdr, size_t newSize);
	  DUMA_EXTERN_C void * _duma_valloc(size_t size);
	  DUMA_EXTERN_C char * _duma_strdup(const char *str);
	  DUMA_EXTERN_C void * _duma_memcpy(void *dest, const void *src, size_t size);
	  DUMA_EXTERN_C void * _duma_memmove(void *dest, const void *src, size_t size);
	  DUMA_EXTERN_C char * _duma_strcpy(char *dest, const char *src);
	  DUMA_EXTERN_C char * _duma_strncpy(char *dest, const char *src, size_t size);
	  DUMA_EXTERN_C char * _duma_strcat(char *dest, const char *src);
	  DUMA_EXTERN_C char * _duma_strncat(char *dest, const char *src, size_t size);
	#endif /* DUMA_NO_LEAKDETECTION */

  #endif /* DUMA_FUNCTIONS_DECLARED */


  #ifndef DUMA_SKIP_SETUP
	#ifndef DUMA_NO_LEAKDETECTION
	  #define malloc(SIZE)                _duma_malloc(SIZE, __FILE__, __LINE__)
	  #define calloc(ELEMCOUNT, ELEMSIZE) _duma_calloc(ELEMCOUNT, ELEMSIZE, __FILE__, __LINE__)
	  #define free(BASEADR)               _duma_free(BASEADR, __FILE__, __LINE__)
	  #define memalign(ALIGNMENT, SIZE)   _duma_memalign(ALIGNMENT, SIZE, __FILE__, __LINE__)
	  #define posix_memalign(MEMPTR, ALIGNMENT, SIZE)  _duma_posix_memalign(MEMPTR, ALIGNMENT, SIZE, __FILE__, __LINE__)
	  #define realloc(BASEADR, NEWSIZE)   _duma_realloc(BASEADR, NEWSIZE, __FILE__, __LINE__)
	  #define valloc(SIZE)                _duma_valloc(SIZE, __FILE__, __LINE__)
	  #define strdup(STR)                 _duma_strdup(STR, __FILE__, __LINE__)
	  #define memcpy(DEST, SRC, SIZE)     _duma_memcpy(DEST, SRC, SIZE, __FILE__, __LINE__)
	  #define memmove(DEST, SRC, SIZE)    _duma_memmove(DEST, SRC, SIZE)
	  #define strcpy(DEST, SRC)           _duma_strcpy(DEST, SRC, __FILE__, __LINE__)
	  #define strncpy(DEST, SRC, SIZE)    _duma_strncpy(DEST, SRC, SIZE, __FILE__, __LINE__)
	  #define strcat(DEST, SRC)           _duma_strcat(DEST, SRC, __FILE__, __LINE__)
	  #define strncat(DEST, SRC, SIZE)    _duma_strncat(DEST, SRC, SIZE, __FILE__, __LINE__)
	#else /* DUMA_NO_LEAKDETECTION */
	  #define DUMA_newFrame()             do { } while(0)
	  #define DUMA_delFrame()             do { } while(0)
	#endif /* DUMA_NO_LEAKDETECTION */
  #endif // DUMA_SKIP_SETUP


  #ifndef DUMA_ASSERT
	#define DUMA_ASSERT(EXPR)    (  (EXPR) || ( _duma_assert(#EXPR, __FILE__, __LINE__), 0 )  )
  #endif
  #ifndef DUMA_CHECK
	#define DUMA_CHECK(BASEADR)         duma_check(BASEADR)
  #endif
  #ifndef DUMA_CHECKALL
	#define DUMA_CHECKALL()             duma_checkAll()
  #endif


  /*
   * protection of functions return address
   */
  #ifdef __GNUC__
	#define DUMA_FN_PROT_START      const void * DUMA_RET_ADDR = __builtin_return_address(0); {
	#define DUMA_FN_PROT_END        } DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR );

	#define DUMA_FN_PROT_RET(EXPR)  do {  DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR );  return( EXPR ); }  while (0)
	#define DUMA_FN_PROT_RET_VOID() do {  DUMA_ASSERT( __builtin_return_address(0) == DUMA_RET_ADDR );  return;         }  while (0)
  #else
	#define DUMA_FN_PROT_START      int aiDUMA_PROT[ 4 ] = { 'E', 'F', 'P', 'R' }; {
	#define DUMA_FN_PROT_END        } DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] );
	#define DUMA_FN_PROT_RET(EXPR)  do {  DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] );  return( EXPR ); }  while (0)
	#define DUMA_FN_PROT_RET_VOID() do {  DUMA_ASSERT( 'E'==aiDUMA_PROT[0] && 'F'==aiDUMA_PROT[1] && 'P'==aiDUMA_PROT[2] && 'R'==aiDUMA_PROT[3] );  return;         }  while (0)
  #endif

  /* declaration of an already defined array to enable checking at every reference
   * when using CA_REF()
   */
  #define CA_DECLARE(NAME,SIZE) \
	const unsigned long NAME ## _checkedsize = (SIZE); \
	unsigned long NAME ## _checkedidx

  /* definition of a checked array adds definitions for its size and an extra temporary.
   * every array gets its own temporary to avoid problems with threading
   * a global temporary would have.
   */
  #define CA_DEFINE(TYPE,NAME,SIZE)  TYPE NAME[SIZE]; CA_DECLARE(NAME,SIZE)

  /* every access to a checked array is preceded an assert() on the index;
   * the index parameter is stored to a temporary to avoid double execution of index,
   * when index contains f.e. a "++".
   */
  #define CA_REF(NAME,INDEX) \
	NAME[ DUMA_ASSERT( (NAME ## _checkedidx = (INDEX)) < NAME ## _checkedsize ), NAME ## _checkedidx ]

#endif /* end ifdef DUMA_NO_DUMA */