dawn@0
|
1 /*
|
dawn@0
|
2 19 Dec 94 - Sept 95
|
dawn@0
|
3 Alain de Cheveigne, LLF, CNRS/Universite Paris 7.
|
dawn@0
|
4 Modified: Sept 2000
|
dawn@0
|
5
|
dawn@0
|
6 file mwrap.h
|
dawn@0
|
7
|
dawn@0
|
8 To use the malloc wrappers:
|
dawn@0
|
9 - include this file in all source files that call malloc routines,
|
dawn@0
|
10 - link with mwrap.o,
|
dawn@0
|
11 - compile all files with -DMWRAP to turn on wrapping and checking.
|
dawn@0
|
12
|
dawn@0
|
13 */
|
dawn@0
|
14
|
dawn@0
|
15 #ifndef MWRAP_H
|
dawn@0
|
16 #define MWRAP_H
|
dawn@0
|
17
|
dawn@0
|
18 #include <stdio.h>
|
dawn@0
|
19 #include <stdlib.h>
|
dawn@0
|
20
|
dawn@0
|
21 /* NOTE: (char *) is used for pointer arithmetic.
|
dawn@0
|
22 Pointer arguments of all macros are cast to (char *). */
|
dawn@0
|
23
|
dawn@0
|
24 /* node structure for binary splay tree */
|
dawn@0
|
25 typedef struct mwrap_node_struct *mwrap_node ;
|
dawn@0
|
26 struct mwrap_node_struct {
|
dawn@0
|
27 char *lo; /* base of block */
|
dawn@0
|
28 char *hi; /* one beyond last address in block */
|
dawn@0
|
29 mwrap_node up;
|
dawn@0
|
30 mwrap_node left;
|
dawn@0
|
31 mwrap_node right;
|
dawn@0
|
32 };
|
dawn@0
|
33
|
dawn@0
|
34
|
dawn@0
|
35 /* Abbreviations for macros. Change in case of conflict.
|
dawn@0
|
36
|
dawn@0
|
37 Assignment macros:
|
dawn@0
|
38 GET(x) equivalent to 'x' on a rhs, but memory address is checked before access
|
dawn@0
|
39 SET(x) equivalent to 'x' on a lhs, but memory address is checked before assignment
|
dawn@0
|
40 CPY(p,q,n) copy n values starting from p to n values starting from q, after checking both
|
dawn@0
|
41
|
dawn@0
|
42 Test macros:
|
dawn@0
|
43 POK(p) pointer p is within an allocated block.
|
dawn@0
|
44 BOK(b) pointer b is the base of an allocated block.
|
dawn@0
|
45 PQOK(p, q) pointers p and q are in same allocated block.
|
dawn@0
|
46 PBOK(p, b) pointer p is in block of base b.
|
dawn@0
|
47
|
dawn@0
|
48 MWRAPOK() check internal tree for sanity (slow)
|
dawn@0
|
49
|
dawn@0
|
50 Query macros:
|
dawn@0
|
51 PBASE(p) base of block containing p, NULL if there is none.
|
dawn@0
|
52 PBUMP(p) one beyond last byte of block.
|
dawn@0
|
53 PSIZE(p) size of block containing p, -1 if none.
|
dawn@0
|
54
|
dawn@0
|
55 Explicit block registering macros.
|
dawn@0
|
56 CHECKIN(lo, hi) register block of bounds lo, hi
|
dawn@0
|
57 CHECKOUT(lo) unregister block of base lo
|
dawn@0
|
58
|
dawn@0
|
59 */
|
dawn@0
|
60
|
dawn@0
|
61 #define GET(x) MWRAP_GET(x)
|
dawn@0
|
62 #define SET(x) MWRAP_SET(x)
|
dawn@0
|
63 #define CPY(p,q,n) MWRAP_CPY(p,q,n)
|
dawn@0
|
64 #define POK(p) MWRAP_POK(p)
|
dawn@0
|
65 #define BOK(b) MWRAP_BOK(b)
|
dawn@0
|
66 #define PQOK(p,q) MWRAP_PQOK((p),(q))
|
dawn@0
|
67 #define PBOK(p,b) MWRAP_PBOK((p),(b))
|
dawn@0
|
68 #define MWRAPOK() MWRAP_MWRAPOK()
|
dawn@0
|
69 #define PBASE(p) MWRAP_PBASE(p)
|
dawn@0
|
70 #define PSIZE(p) MWRAP_PSIZE(p)
|
dawn@0
|
71 #define CHECKIN(lo, hi) MWRAP_CHECKIN((lo), (hi))
|
dawn@0
|
72 #define CHECKOUT(lo) MWRAP_CHECKOUT(lo)
|
dawn@0
|
73
|
dawn@0
|
74
|
dawn@0
|
75 /* Definitions of macros.
|
dawn@0
|
76 All are conditional on MWRAP being defined.
|
dawn@0
|
77 For speed, macros check for a "lucky" hit (block already
|
dawn@0
|
78 at root) before handing over to functions. */
|
dawn@0
|
79
|
dawn@0
|
80 #ifdef MWRAP
|
dawn@0
|
81
|
dawn@0
|
82 #define MWRAP_GET(x) \
|
dawn@0
|
83 ( (MWRAP_POK(&x)) ? (x) : (x) )
|
dawn@0
|
84
|
dawn@0
|
85 #define MWRAP_SET(x) \
|
dawn@0
|
86 MWRAP_POK(&x) ; (x)
|
dawn@0
|
87
|
dawn@0
|
88 #define MWRAP_CPY(p, q, n) \
|
dawn@0
|
89 do {int i; \
|
dawn@0
|
90 MWRAP_PQOK((p),(p)+(n-1)); \
|
dawn@0
|
91 MWRAP_PQOK((q),(q)+(n-1)); \
|
dawn@0
|
92 for(i=0;i<n;i++) (q)[i]=(p)[i]; \
|
dawn@0
|
93 } while(0)
|
dawn@0
|
94
|
dawn@0
|
95 /* #define MWRAP_POK(p) \
|
dawn@0
|
96 do { if (mwrap_tree \
|
dawn@0
|
97 && (char *) (p) >= mwrap_tree->lo \
|
dawn@0
|
98 && (char *) (p) < mwrap_tree->hi) break; \
|
dawn@0
|
99 mwrap_pok((char *) (p), __FILE__, __LINE__); } while (0) */
|
dawn@0
|
100
|
dawn@0
|
101 #define MWRAP_POK(p) \
|
dawn@0
|
102 ((mwrap_tree && (char *) (p) >= mwrap_tree->lo && (char *) (p) <mwrap_tree->hi) ? \
|
dawn@0
|
103 1 : mwrap_pok((char *) (p), __FILE__, __LINE__))
|
dawn@0
|
104
|
dawn@0
|
105
|
dawn@0
|
106 /* #define MWRAP_BOK(b) \
|
dawn@0
|
107 do { if (mwrap_tree \
|
dawn@0
|
108 && (char *) (b) == mwrap_tree->lo) break; \
|
dawn@0
|
109 mwrap_bok((char *) (b), __FILE__, __LINE__); } while (0) */
|
dawn@0
|
110
|
dawn@0
|
111 #define MWRAP_BOK(b) \
|
dawn@0
|
112 ((mwrap_tree && (char *) (b) == mwrap_tree->lo) ? 1 : mwrap_bok((char *) (b), __FILE__, __LINE__))
|
dawn@0
|
113
|
dawn@0
|
114
|
dawn@0
|
115 /* #define MWRAP_PQOK(p, q) \
|
dawn@0
|
116 do { if (mwrap_tree \
|
dawn@0
|
117 && (char *) (p) >= mwrap_tree->lo \
|
dawn@0
|
118 && (char *) (p) < mwrap_tree->hi \
|
dawn@0
|
119 && (char *) (q) >= mwrap_tree->lo \
|
dawn@0
|
120 && (char *) (q) < mwrap_tree->lo) break; \
|
dawn@0
|
121 mwrap_pqok((char *)(p), (char *)(q), __FILE__, __LINE__); } while (0) */
|
dawn@0
|
122
|
dawn@0
|
123 #define MWRAP_PQOK(p,q) \
|
dawn@0
|
124 ((mwrap_tree \
|
dawn@0
|
125 && (char *) (p) >= mwrap_tree->lo \
|
dawn@0
|
126 && (char *) (p) < mwrap_tree->hi \
|
dawn@0
|
127 && (char *) (q) >= mwrap_tree->lo \
|
dawn@0
|
128 && (char *) (q) < mwrap_tree->lo ) ? \
|
dawn@0
|
129 1 : mwrap_pqok((char *)(p), (char *)(q), __FILE__, __LINE__))
|
dawn@0
|
130
|
dawn@0
|
131 /* #define MWRAP_PBOK(p, b) \
|
dawn@0
|
132 do { if (mwrap_tree \
|
dawn@0
|
133 && (char *) (b) == mwrap_tree->lo \
|
dawn@0
|
134 && (char *) (p) >= mwrap_tree->lo \
|
dawn@0
|
135 && (char *) (p) < mwrap_tree->lo) break; \
|
dawn@0
|
136 mwrap_pbok((char *)(p), (char *)(b), __FILE__, __LINE__); } while (0) */
|
dawn@0
|
137
|
dawn@0
|
138 #define MWRAP_PBOK(p, b) \
|
dawn@0
|
139 (( mwrap_tree \
|
dawn@0
|
140 && (char *) (b) == mwrap_tree->lo \
|
dawn@0
|
141 && (char *) (p) >= mwrap_tree->lo \
|
dawn@0
|
142 && (char *) (p) < mwrap_tree->lo) ? \
|
dawn@0
|
143 1 : mwrap_pbok((char *)(p), (char *)(b), __FILE__, __LINE__))
|
dawn@0
|
144
|
dawn@0
|
145 #define MWRAP_MWRAPOK() mwrap_checktree(__FILE__, __LINE__)
|
dawn@0
|
146
|
dawn@0
|
147 #define MWRAP_PBASE(p) mwrap_pbase((char *) p)
|
dawn@0
|
148 #define MWRAP_PBUMP(p) mwrap_pbump((char *) p)
|
dawn@0
|
149 #define MWRAP_PSIZE(p) mwrap_psize((char *) p)
|
dawn@0
|
150 #define MWRAP_CHECKIN(lo, hi) \
|
dawn@0
|
151 mwrap_checkin((char *) (lo), (char *) (hi), __FILE__, __LINE__)
|
dawn@0
|
152 #define MWRAP_CHECKOUT(lo) \
|
dawn@0
|
153 mwrap_checkout( (char *) (lo), __FILE__, __LINE__)
|
dawn@0
|
154
|
dawn@0
|
155 #else
|
dawn@0
|
156
|
dawn@0
|
157 #define MWRAP_GET(x) (x)
|
dawn@0
|
158 #define MWRAP_SET(x) (x)
|
dawn@0
|
159 #define MWRAP_CPY(p,q,n)
|
dawn@0
|
160 #define MWRAP_POK(p)
|
dawn@0
|
161 #define MWRAP_BOK(p)
|
dawn@0
|
162 #define MWRAP_PBOK(p,b)
|
dawn@0
|
163 #define MWRAP_PQOK(p,q)
|
dawn@0
|
164 #define MWRAP_MWRAPOK()
|
dawn@0
|
165 #define MWRAP_PBASE(p) (void *) mwrap_squeal(__FILE__, __LINE__)
|
dawn@0
|
166 #define MWRAP_PBUMP(p) (void *) mwrap_squeal(__FILE__, __LINE__)
|
dawn@0
|
167 #define MWRAP_PSIZE(p) (long) mwrap_squeal(__FILE__, __LINE__)
|
dawn@0
|
168 #define MWRAP_CHECKIN(lo, hi)
|
dawn@0
|
169 #define MWRAP_CHECKOUT(lo)
|
dawn@0
|
170 #endif
|
dawn@0
|
171
|
dawn@0
|
172
|
dawn@0
|
173 /* Wrapping macros.
|
dawn@0
|
174
|
dawn@0
|
175 If MWRAP is defined, all malloc routines are wrapped and the
|
dawn@0
|
176 original routines are available as "nowrap_malloc()", etc..
|
dawn@0
|
177
|
dawn@0
|
178 If MWRAP is not defined, malloc routines are not wrapped
|
dawn@0
|
179 and "nowrap_malloc()", etc. are #defined to "malloc()", etc.
|
dawn@0
|
180 */
|
dawn@0
|
181
|
dawn@0
|
182 #ifdef MWRAP
|
dawn@0
|
183
|
dawn@0
|
184 #ifndef MWRAP_C
|
dawn@0
|
185 #define malloc(size) mwrap_malloc((size), __FILE__, __LINE__)
|
dawn@0
|
186 #define free(p) mwrap_free((p), __FILE__, __LINE__)
|
dawn@0
|
187 #define realloc(p, size) mwrap_realloc((p), (size), __FILE__, __LINE__)
|
dawn@0
|
188 #define calloc(n, size) mwrap_calloc((n), (size), __FILE__, __LINE__)
|
dawn@0
|
189 #define cfree(p) mwrap_cfree((p), __FILE__, __LINE__)
|
dawn@0
|
190 #define valloc(size) mwrap_valloc((size), __FILE__, __LINE__)
|
dawn@0
|
191 #define vfree(p) mwrap_vfree((p), __FILE__, __LINE__)
|
dawn@0
|
192 #define memalign(a, p) mwrap_memalign((a), (p), __FILE__, __LINE__)
|
dawn@0
|
193 #endif /* MWRAP_C */
|
dawn@0
|
194
|
dawn@0
|
195 #else
|
dawn@0
|
196
|
dawn@0
|
197 #ifndef MWRAP_C
|
dawn@0
|
198 #define nowrap_malloc(size) malloc(size)
|
dawn@0
|
199 #define nowrap_free(p) free(p)
|
dawn@0
|
200 #define nowrap_realloc(p, size) realloc(p)
|
dawn@0
|
201 #define nowrap_calloc(n, size) calloc((n), (size))
|
dawn@0
|
202 #define nowrap_cfree(p) cfree(p)
|
dawn@0
|
203 #define nowrap_valloc(size) valloc(size)
|
dawn@0
|
204 #define nowrap_vfree(p) vfree(p)
|
dawn@0
|
205 #define nowrap_memalign(a, p) memalign((a), (p))
|
dawn@0
|
206 #endif /* MWRAP_C */
|
dawn@0
|
207
|
dawn@0
|
208 #endif /* MWRAP */
|
dawn@0
|
209
|
dawn@0
|
210
|
dawn@0
|
211 /* three global variables */
|
dawn@0
|
212
|
dawn@0
|
213 #ifndef MWRAP_C
|
dawn@0
|
214 extern mwrap_node mwrap_tree; /* the tree */
|
dawn@0
|
215 extern char *mwrap_file; /* caller source file */
|
dawn@0
|
216 extern long mwrap_line; /* line in caller source file */
|
dawn@0
|
217 #endif
|
dawn@0
|
218
|
dawn@0
|
219
|
dawn@0
|
220 /* Data types used by malloc library. Modify if necessary */
|
dawn@0
|
221 typedef void DATATYPE; /* returned by malloc(), etc. */
|
dawn@0
|
222 typedef size_t SIZETYPE; /* fed to malloc(), etc. */
|
dawn@0
|
223 typedef void VOIDTYPE; /* returned by free(), etc. */
|
dawn@0
|
224
|
dawn@0
|
225
|
dawn@0
|
226 /* prototypes of routines made public */
|
dawn@0
|
227
|
dawn@0
|
228 /* malloc wrappers */
|
dawn@0
|
229 DATATYPE *mwrap_malloc(SIZETYPE size, char *file, long line);
|
dawn@0
|
230 VOIDTYPE mwrap_free(DATATYPE *p, char *file, long line);
|
dawn@0
|
231 DATATYPE *mwrap_realloc(DATATYPE *p, SIZETYPE size, char *file, long line);
|
dawn@0
|
232 DATATYPE *mwrap_calloc(SIZETYPE n, SIZETYPE size, char *file, long line);
|
dawn@0
|
233 VOIDTYPE mwrap_cfree(DATATYPE *p, char *file, long line);
|
dawn@0
|
234 DATATYPE *mwrap_valloc(SIZETYPE size, char *file, long line);
|
dawn@0
|
235 VOIDTYPE mwrap_vfree(DATATYPE *p, char *file, long line);
|
dawn@0
|
236 DATATYPE *mwrap_memalign(SIZETYPE alignment, SIZETYPE size, char *file, long line);
|
dawn@0
|
237
|
dawn@0
|
238 /* unwrapped versions */
|
dawn@0
|
239 #ifdef MWRAP
|
dawn@0
|
240 DATATYPE *nowrap_malloc(SIZETYPE size);
|
dawn@0
|
241 VOIDTYPE nowrap_free(DATATYPE *p);
|
dawn@0
|
242 DATATYPE *nowrap_realloc(DATATYPE *p, SIZETYPE size);
|
dawn@0
|
243 DATATYPE *nowrap_calloc(SIZETYPE n, SIZETYPE size);
|
dawn@0
|
244 VOIDTYPE nowrap_cfree(DATATYPE *p);
|
dawn@0
|
245 DATATYPE *nowrap_valloc(SIZETYPE size);
|
dawn@0
|
246 VOIDTYPE nowrap_vfree(DATATYPE *p);
|
dawn@0
|
247 DATATYPE *nowrap_memalign(SIZETYPE alignment, SIZETYPE size);
|
dawn@0
|
248 #endif
|
dawn@0
|
249
|
dawn@0
|
250 /* explicit block registering */
|
dawn@0
|
251 void mwrap_checkin(char *lo, char *hi, char *file, long line);
|
dawn@0
|
252 void mwrap_checkout(char *lo, char *file, long line);
|
dawn@0
|
253
|
dawn@0
|
254 /* tests & queries */
|
dawn@0
|
255 int mwrap_pok(char *p, char *file, long line);
|
dawn@0
|
256 int mwrap_bok(char *b, char *file, long line);
|
dawn@0
|
257 int mwrap_pqok(char *p, char *q, char *file, long line);
|
dawn@0
|
258 int mwrap_pbok(char *p, char *b, char *file, long line);
|
dawn@0
|
259 char *mwrap_pbase(char *p);
|
dawn@0
|
260 char *mwrap_pbump(char *p);
|
dawn@0
|
261 long mwrap_psize(char *p);
|
dawn@0
|
262 long mwrap_squeal(char *file, long line);
|
dawn@0
|
263
|
dawn@0
|
264 /* change default functions */
|
dawn@0
|
265 void mwrap_set_errorfunction(void (*f)(int level));
|
dawn@0
|
266 void mwrap_set_messagefunction(void (*f)(int level, char * message));
|
dawn@0
|
267
|
dawn@0
|
268 #endif
|