blob: 14edf23dc27b92112760aef8c12bdeea80d1d145 [file] [log] [blame]
njn5c004e42002-11-18 11:04:50 +00001
2/*--------------------------------------------------------------------*/
3/*--- Code that is shared between MemCheck and AddrCheck. ---*/
njn43c799e2003-04-08 00:08:52 +00004/*--- mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +00005/*--------------------------------------------------------------------*/
6
7/*
nethercote137bc552003-11-14 17:47:54 +00008 This file is part of MemCheck, a heavyweight Valgrind tool for
9 detecting memory errors, and AddrCheck, a lightweight Valgrind tool
njn5c004e42002-11-18 11:04:50 +000010 for detecting memory errors.
11
nethercotebb1c9912004-01-04 16:43:23 +000012 Copyright (C) 2000-2004 Julian Seward
njn5c004e42002-11-18 11:04:50 +000013 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
32
33
njn43c799e2003-04-08 00:08:52 +000034#include "mac_shared.h"
njn5c004e42002-11-18 11:04:50 +000035
njn47363ab2003-04-21 13:24:40 +000036#include "memcheck.h" /* for VG_USERREQ__* */
37
njn5c004e42002-11-18 11:04:50 +000038/*------------------------------------------------------------*/
39/*--- Defns ---*/
40/*------------------------------------------------------------*/
41
42/* These many bytes below %ESP are considered addressible if we're
43 doing the --workaround-gcc296-bugs hack. */
44#define VG_GCC296_BUG_STACK_SLOP 1024
45
46/*------------------------------------------------------------*/
47/*--- Command line options ---*/
48/*------------------------------------------------------------*/
49
njn43c799e2003-04-08 00:08:52 +000050Bool MAC_(clo_partial_loads_ok) = True;
51Int MAC_(clo_freelist_vol) = 1000000;
52Bool MAC_(clo_leak_check) = False;
53VgRes MAC_(clo_leak_resolution) = Vg_LowRes;
54Bool MAC_(clo_show_reachable) = False;
55Bool MAC_(clo_workaround_gcc296_bugs) = False;
njn5c004e42002-11-18 11:04:50 +000056
njn43c799e2003-04-08 00:08:52 +000057Bool MAC_(process_common_cmd_line_option)(Char* arg)
njn5c004e42002-11-18 11:04:50 +000058{
nethercote27fec902004-06-16 21:26:32 +000059 VG_BOOL_CLO("--leak-check", MAC_(clo_leak_check))
60 else VG_BOOL_CLO("--partial-loads-ok", MAC_(clo_partial_loads_ok))
61 else VG_BOOL_CLO("--show-reachable", MAC_(clo_show_reachable))
62 else VG_BOOL_CLO("--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
63
64 else VG_BNUM_CLO("--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
65
njn43c799e2003-04-08 00:08:52 +000066 else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
67 MAC_(clo_leak_resolution) = Vg_LowRes;
68 else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
69 MAC_(clo_leak_resolution) = Vg_MedRes;
70 else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
71 MAC_(clo_leak_resolution) = Vg_HighRes;
njn5c004e42002-11-18 11:04:50 +000072
73 else
njn3e884182003-04-15 13:03:23 +000074 return VG_(replacement_malloc_process_cmd_line_option)(arg);
njn5c004e42002-11-18 11:04:50 +000075
76 return True;
njn43c799e2003-04-08 00:08:52 +000077}
njn5c004e42002-11-18 11:04:50 +000078
njn3e884182003-04-15 13:03:23 +000079void MAC_(print_common_usage)(void)
njn43c799e2003-04-08 00:08:52 +000080{
njn3e884182003-04-15 13:03:23 +000081 VG_(printf)(
82" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n"
83" --freelist-vol=<number> volume of freed blocks queue [1000000]\n"
84" --leak-check=no|yes search for memory leaks at exit? [no]\n"
85" --leak-resolution=low|med|high how much bt merging in leak check [low]\n"
86" --show-reachable=no|yes show reachable blocks in leak check? [no]\n"
87" --workaround-gcc296-bugs=no|yes self explanatory [no]\n"
88 );
89 VG_(replacement_malloc_print_usage)();
njn43c799e2003-04-08 00:08:52 +000090}
91
njn3e884182003-04-15 13:03:23 +000092void MAC_(print_common_debug_usage)(void)
njn43c799e2003-04-08 00:08:52 +000093{
njn3e884182003-04-15 13:03:23 +000094 VG_(replacement_malloc_print_debug_usage)();
njn5c004e42002-11-18 11:04:50 +000095}
96
97/*------------------------------------------------------------*/
98/*--- Comparing and printing errors ---*/
99/*------------------------------------------------------------*/
100
101static __inline__
102void clear_AddrInfo ( AddrInfo* ai )
103{
104 ai->akind = Unknown;
105 ai->blksize = 0;
106 ai->rwoffset = 0;
107 ai->lastchange = NULL;
108 ai->stack_tid = VG_INVALID_THREADID;
109 ai->maybe_gcc = False;
110}
111
njn43c799e2003-04-08 00:08:52 +0000112void MAC_(clear_MAC_Error) ( MAC_Error* err_extra )
njn5c004e42002-11-18 11:04:50 +0000113{
114 err_extra->axskind = ReadAxs;
115 err_extra->size = 0;
116 clear_AddrInfo ( &err_extra->addrinfo );
nethercote8b76fe52004-11-08 19:20:09 +0000117 err_extra->isUnaddr = True;
njn5c004e42002-11-18 11:04:50 +0000118}
119
120__attribute__ ((unused))
121static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
122{
123 if (ai1->akind != Undescribed
124 && ai2->akind != Undescribed
125 && ai1->akind != ai2->akind)
126 return False;
127 if (ai1->akind == Freed || ai1->akind == Mallocd) {
128 if (ai1->blksize != ai2->blksize)
129 return False;
130 if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
131 return False;
132 }
133 return True;
134}
135
136/* Compare error contexts, to detect duplicates. Note that if they
137 are otherwise the same, the faulting addrs and associated rwoffsets
138 are allowed to be different. */
139
njn26f02512004-11-22 18:33:15 +0000140Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
njn5c004e42002-11-18 11:04:50 +0000141{
njn43c799e2003-04-08 00:08:52 +0000142 MAC_Error* e1_extra = VG_(get_error_extra)(e1);
143 MAC_Error* e2_extra = VG_(get_error_extra)(e2);
njn7cc53a82002-11-19 16:19:32 +0000144
145 /* Guaranteed by calling function */
njnca82cc02004-11-22 17:18:48 +0000146 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
njn5c004e42002-11-18 11:04:50 +0000147
148 switch (VG_(get_error_kind)(e1)) {
149 case CoreMemErr: {
150 Char *e1s, *e2s;
nethercote8b76fe52004-11-08 19:20:09 +0000151 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000152 e1s = VG_(get_error_string)(e1);
153 e2s = VG_(get_error_string)(e2);
154 if (e1s == e2s) return True;
155 if (0 == VG_(strcmp)(e1s, e2s)) return True;
156 return False;
157 }
158
159 case UserErr:
160 case ParamErr:
nethercote8b76fe52004-11-08 19:20:09 +0000161 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000162 if (VG_(get_error_kind)(e1) == ParamErr
163 && 0 != VG_(strcmp)(VG_(get_error_string)(e1),
164 VG_(get_error_string)(e2))) return False;
165 return True;
166
167 case FreeErr:
168 case FreeMismatchErr:
169 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
170 cause excessive duplication of errors. Not even AddrErr
171 below does that. So don't compare either the .addr field
172 or the .addrinfo fields. */
173 /* if (e1->addr != e2->addr) return False; */
174 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
175 return False;
176 */
177 return True;
178
179 case AddrErr:
180 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
181 if (e1_extra->size != e2_extra->size) return False;
182 /*
183 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
184 return False;
185 */
186 return True;
187
188 case ValueErr:
189 if (e1_extra->size != e2_extra->size) return False;
190 return True;
191
njn34419c12003-05-02 17:24:29 +0000192 case OverlapErr:
193 return True;
194
njn43c799e2003-04-08 00:08:52 +0000195 case LeakErr:
njn26f02512004-11-22 18:33:15 +0000196 VG_(tool_panic)("Shouldn't get LeakErr in TL_(eq_Error),\n"
njn43c799e2003-04-08 00:08:52 +0000197 "since it's handled with VG_(unique_error)()!");
198
rjwalshbc0bb832004-06-19 18:12:36 +0000199 case IllegalMempoolErr:
200 return True;
201
njn5c004e42002-11-18 11:04:50 +0000202 default:
203 VG_(printf)("Error:\n unknown error code %d\n",
204 VG_(get_error_kind)(e1));
njn26f02512004-11-22 18:33:15 +0000205 VG_(tool_panic)("unknown error code in TL_(eq_Error)");
njn5c004e42002-11-18 11:04:50 +0000206 }
207}
208
njn43c799e2003-04-08 00:08:52 +0000209void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000210{
211 switch (ai->akind) {
212 case Stack:
213 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000214 " Address 0x%x is on thread %d's stack",
njn5c004e42002-11-18 11:04:50 +0000215 a, ai->stack_tid);
216 break;
217 case Unknown:
218 if (ai->maybe_gcc) {
219 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000220 " Address 0x%x is just below %%esp. Possibly a bug in GCC/G++",
njn5c004e42002-11-18 11:04:50 +0000221 a);
222 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000223 " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes");
njn5c004e42002-11-18 11:04:50 +0000224 } else {
225 VG_(message)(Vg_UserMsg,
nethercotef798eee2004-04-13 08:36:35 +0000226 " Address 0x%x is not stack'd, malloc'd or (recently) free'd",a);
njn5c004e42002-11-18 11:04:50 +0000227 }
228 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000229 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000230 SizeT delta;
njn5c004e42002-11-18 11:04:50 +0000231 UChar* relative;
rjwalshbc0bb832004-06-19 18:12:36 +0000232 UChar* kind;
233 if (ai->akind == Mempool) {
234 kind = "mempool";
235 } else {
236 kind = "block";
237 }
njn5c004e42002-11-18 11:04:50 +0000238 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000239 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000240 relative = "before";
241 } else if (ai->rwoffset >= ai->blksize) {
242 delta = ai->rwoffset - ai->blksize;
243 relative = "after";
244 } else {
245 delta = ai->rwoffset;
246 relative = "inside";
247 }
sewardja81709d2002-12-28 12:55:48 +0000248 VG_(message)(Vg_UserMsg,
nethercote50397c22004-11-04 18:03:06 +0000249 " Address 0x%x is %llu bytes %s a %s of size %d %s",
250 a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000251 ai->blksize,
252 ai->akind==Mallocd ? "alloc'd"
253 : ai->akind==Freed ? "free'd"
254 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000255 VG_(pp_ExeContext)(ai->lastchange);
256 break;
257 }
nethercote8b76fe52004-11-08 19:20:09 +0000258 case Register:
259 // print nothing
njnca82cc02004-11-22 17:18:48 +0000260 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000261 break;
njn5c004e42002-11-18 11:04:50 +0000262 default:
njn67993252004-11-22 18:02:32 +0000263 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000264 }
265}
266
267/* This prints out the message for the error types where Memcheck and
268 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000269void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000270{
271 MAC_Error* err_extra = VG_(get_error_extra)(err);
272
273 switch (VG_(get_error_kind)(err)) {
274 case FreeErr:
njn10785452003-05-20 16:38:24 +0000275 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000276 /* fall through */
277 case FreeMismatchErr:
278 if (VG_(get_error_kind)(err) == FreeMismatchErr)
279 VG_(message)(Vg_UserMsg,
280 "Mismatched free() / delete / delete []");
281 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
282 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
283 break;
284
njn89409f82003-09-26 14:55:31 +0000285 case AddrErr:
286 switch (err_extra->axskind) {
287 case ReadAxs:
288 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
289 err_extra->size );
290 break;
291 case WriteAxs:
292 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
293 err_extra->size );
294 break;
295 case ExecAxs:
296 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
297 "stated on the next line");
298 break;
299 default:
njn26f02512004-11-22 18:33:15 +0000300 VG_(tool_panic)("TL_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000301 }
302 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
303 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
304 break;
305
njnb6cae9f2003-09-04 20:50:47 +0000306 case OverlapErr: {
307 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
308 if (ov_extra->len == -1)
309 VG_(message)(Vg_UserMsg,
310 "Source and destination overlap in %s(%p, %p)",
311 VG_(get_error_string)(err),
312 ov_extra->dst, ov_extra->src);
313 else
314 VG_(message)(Vg_UserMsg,
315 "Source and destination overlap in %s(%p, %p, %d)",
316 VG_(get_error_string)(err),
317 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000318 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
319 break;
njnb6cae9f2003-09-04 20:50:47 +0000320 }
njn43c799e2003-04-08 00:08:52 +0000321 case LeakErr: {
322 /* Totally abusing the types of these spare fields... oh well. */
323 UInt n_this_record = (UInt)VG_(get_error_address)(err);
324 UInt n_total_records = (UInt)VG_(get_error_string) (err);
325
326 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
327 break;
328 }
329
rjwalshbc0bb832004-06-19 18:12:36 +0000330 case IllegalMempoolErr:
331 VG_(message)(Vg_UserMsg, "Illegal memory pool address");
332 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
333 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
334 break;
335
njn43c799e2003-04-08 00:08:52 +0000336 default:
337 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
338 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000339 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000340 }
341}
342
343/*------------------------------------------------------------*/
344/*--- Recording errors ---*/
345/*------------------------------------------------------------*/
346
njn43c799e2003-04-08 00:08:52 +0000347/* Additional description function for describe_addr(); used by
348 MemCheck for user blocks, which Addrcheck doesn't support. */
349Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000350
351/* Callback for searching thread stacks */
352static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
353{
354 Addr a = *(Addr *)ap;
355
356 return (stack_min <= a && a <= stack_max);
357}
358
359/* Callback for searching free'd list */
360static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
361{
362 Addr a = *(Addr *)ap;
363
364 return VG_(addr_is_in_block)( a, mc->data, mc->size );
365}
366
367/* Callback for searching malloc'd lists */
368static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
369{
370 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
371}
372
njn43c799e2003-04-08 00:08:52 +0000373/* Describe an address as best you can, for error messages,
374 putting the result in ai. */
375static void describe_addr ( Addr a, AddrInfo* ai )
376{
njn3e884182003-04-15 13:03:23 +0000377 MAC_Chunk* sc;
378 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000379
njn43c799e2003-04-08 00:08:52 +0000380 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
381 if (NULL != MAC_(describe_addr_supp)) {
382 if (MAC_(describe_addr_supp)( a, ai ))
383 return;
384 }
385 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000386 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000387 if (tid != VG_INVALID_THREADID) {
388 ai->akind = Stack;
389 ai->stack_tid = tid;
390 return;
391 }
392 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000393 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000394 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000395 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000396 ai->blksize = sc->size;
397 ai->rwoffset = (Int)a - (Int)sc->data;
398 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000399 return;
400 }
401 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000402 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000403 if (NULL != sc) {
404 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000405 ai->blksize = sc->size;
406 ai->rwoffset = (Int)(a) - (Int)sc->data;
407 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000408 return;
409 }
410 /* Clueless ... */
411 ai->akind = Unknown;
412 return;
413}
414
njn5c004e42002-11-18 11:04:50 +0000415/* Is this address within some small distance below %ESP? Used only
416 for the --workaround-gcc296-bugs kludge. */
417static Bool is_just_below_ESP( Addr esp, Addr aa )
418{
nethercote50397c22004-11-04 18:03:06 +0000419 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000420 return True;
421 else
422 return False;
423}
424
sewardjaf48a602003-07-06 00:54:47 +0000425/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000426
njn72718642003-07-24 08:45:32 +0000427void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000428 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000429{
njn43c799e2003-04-08 00:08:52 +0000430 MAC_Error err_extra;
431 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000432
sewardj2a99cf62004-11-24 10:44:19 +0000433 just_below_esp = is_just_below_ESP(
434 VG_(get_stack_pointer)(tid),
435 a
436 );
njn5c004e42002-11-18 11:04:50 +0000437
438 /* If this is caused by an access immediately below %ESP, and the
439 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000440 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000441 return;
442
njn43c799e2003-04-08 00:08:52 +0000443 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000444 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
445 err_extra.size = size;
446 err_extra.addrinfo.akind = Undescribed;
447 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000448 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000449}
450
451/* These ones are called from non-generated code */
452
453/* This is for memory errors in pthread functions, as opposed to pthread API
454 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000455void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000456{
njn43c799e2003-04-08 00:08:52 +0000457 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000458
njn43c799e2003-04-08 00:08:52 +0000459 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000460 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000461 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000462}
463
nethercote8b76fe52004-11-08 19:20:09 +0000464void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
465 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000466{
njn43c799e2003-04-08 00:08:52 +0000467 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000468
njnca82cc02004-11-22 17:18:48 +0000469 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000470 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000471 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
472 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000473 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000474}
475
njn72718642003-07-24 08:45:32 +0000476void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000477{
njn43c799e2003-04-08 00:08:52 +0000478 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000479
njnca82cc02004-11-22 17:18:48 +0000480 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000481 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000482 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000483 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000484 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000485 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000486}
487
njn72718642003-07-24 08:45:32 +0000488void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000489{
njn43c799e2003-04-08 00:08:52 +0000490 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000491
njnca82cc02004-11-22 17:18:48 +0000492 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000493 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000494 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000495 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000496}
497
rjwalshbc0bb832004-06-19 18:12:36 +0000498void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
499{
500 MAC_Error err_extra;
501
njnca82cc02004-11-22 17:18:48 +0000502 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000503 MAC_(clear_MAC_Error)( &err_extra );
504 err_extra.addrinfo.akind = Undescribed;
505 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
506}
507
njn72718642003-07-24 08:45:32 +0000508void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000509{
njn43c799e2003-04-08 00:08:52 +0000510 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000511
njnca82cc02004-11-22 17:18:48 +0000512 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000513 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000514 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000515 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000516}
517
sewardj2a99cf62004-11-24 10:44:19 +0000518void MAC_(record_overlap_error) ( ThreadId tid,
519 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000520{
sewardj2a99cf62004-11-24 10:44:19 +0000521 VG_(maybe_record_error)(
522 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000523}
524
525
njnb6cae9f2003-09-04 20:50:47 +0000526/* Updates the copy with address info if necessary (but not for all errors). */
njn26f02512004-11-22 18:33:15 +0000527UInt TL_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000528{
njnb6cae9f2003-09-04 20:50:47 +0000529 switch (VG_(get_error_kind)(err)) {
530 case ValueErr:
531 case CoreMemErr:
532 case AddrErr:
533 case ParamErr:
534 case UserErr:
535 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000536 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000537 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000538 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000539 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
540 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
541 }
542 return sizeof(MAC_Error);
543 }
njn43c799e2003-04-08 00:08:52 +0000544 /* Don't need to return the correct size -- LeakErrs are always shown with
545 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000546 case LeakErr: return 0;
547 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000548 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000549 }
njn43c799e2003-04-08 00:08:52 +0000550}
551
552
njn5c004e42002-11-18 11:04:50 +0000553/*------------------------------------------------------------*/
554/*--- Suppressions ---*/
555/*------------------------------------------------------------*/
556
njn43c799e2003-04-08 00:08:52 +0000557Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
558{
559 SuppKind skind;
560
561 if (VG_STREQ(name, "Param")) skind = ParamSupp;
562 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
563 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
564 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
565 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
566 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000567 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000568 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
569 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000570 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000571 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000572 else
573 return False;
574
575 VG_(set_supp_kind)(su, skind);
576 return True;
577}
578
njn26f02512004-11-22 18:33:15 +0000579Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000580{
581 Bool eof;
582
583 if (VG_(get_supp_kind)(su) == ParamSupp) {
584 eof = VG_(get_line) ( fd, buf, nBuf );
585 if (eof) return False;
586 VG_(set_supp_string)(su, VG_(strdup)(buf));
587 }
588 return True;
589}
590
njn26f02512004-11-22 18:33:15 +0000591Bool TL_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000592{
sewardj05bcdcb2003-05-18 10:05:38 +0000593 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000594 MAC_Error* err_extra = VG_(get_error_extra)(err);
595 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000596
597 switch (VG_(get_supp_kind)(su)) {
598 case ParamSupp:
599 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000600 && VG_STREQ(VG_(get_error_string)(err),
601 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000602
603 case CoreMemSupp:
604 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000605 && VG_STREQ(VG_(get_error_string)(err),
606 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000607
608 case Value0Supp: su_size = 0; goto value_case;
609 case Value1Supp: su_size = 1; goto value_case;
610 case Value2Supp: su_size = 2; goto value_case;
611 case Value4Supp: su_size = 4; goto value_case;
612 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000613 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000614 value_case:
615 return (ekind == ValueErr && err_extra->size == su_size);
616
617 case Addr1Supp: su_size = 1; goto addr_case;
618 case Addr2Supp: su_size = 2; goto addr_case;
619 case Addr4Supp: su_size = 4; goto addr_case;
620 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000621 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000622 addr_case:
623 return (ekind == AddrErr && err_extra->size == su_size);
624
625 case FreeSupp:
626 return (ekind == FreeErr || ekind == FreeMismatchErr);
627
njn34419c12003-05-02 17:24:29 +0000628 case OverlapSupp:
629 return (ekind = OverlapErr);
630
sewardj4a19e2f2002-12-26 11:50:21 +0000631 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000632 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000633
rjwalshbc0bb832004-06-19 18:12:36 +0000634 case MempoolSupp:
635 return (ekind == IllegalMempoolErr);
636
njn5c004e42002-11-18 11:04:50 +0000637 default:
638 VG_(printf)("Error:\n"
639 " unknown suppression type %d\n",
640 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000641 VG_(tool_panic)("unknown suppression type in "
njn26f02512004-11-22 18:33:15 +0000642 "TL_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000643 }
644}
645
njn26f02512004-11-22 18:33:15 +0000646Char* TL_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000647{
648 Char* s;
649 switch (VG_(get_error_kind)(err)) {
650 case ParamErr: return "Param";
651 case UserErr: return NULL; /* Can't suppress User errors */
652 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000653 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000654 case FreeErr: return "Free";
655 case AddrErr:
656 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
657 case 1: return "Addr1";
658 case 2: return "Addr2";
659 case 4: return "Addr4";
660 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000661 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000662 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000663 }
664
665 case ValueErr:
666 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
667 case 0: return "Cond";
668 case 1: return "Value1";
669 case 2: return "Value2";
670 case 4: return "Value4";
671 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000672 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000673 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000674 }
675 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000676 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000677 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000678 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000679 }
680 VG_(printf)(s);
681}
682
njn26f02512004-11-22 18:33:15 +0000683void TL_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000684{
685 if (ParamErr == VG_(get_error_kind)(err)) {
686 VG_(printf)(" %s\n", VG_(get_error_string)(err));
687 }
688}
njn5c004e42002-11-18 11:04:50 +0000689
690/*------------------------------------------------------------*/
691/*--- Crude profiling machinery. ---*/
692/*------------------------------------------------------------*/
693
694/* Event index. If just the name of the fn is given, this means the
695 number of calls to the fn. Otherwise it is the specified event.
696 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
697 The rest are shared.
698
699 10 alloc_secondary_map
700
701 20 get_abit
702M 21 get_vbyte
703 22 set_abit
704M 23 set_vbyte
705 24 get_abits4_ALIGNED
706M 25 get_vbytes4_ALIGNED
707
708 30 set_address_range_perms
709 31 set_address_range_perms(lower byte loop)
710 32 set_address_range_perms(quadword loop)
711 33 set_address_range_perms(upper byte loop)
712
713 35 make_noaccess
714 36 make_writable
715 37 make_readable
716A 38 make_accessible
717
718 40 copy_address_range_state
719 41 copy_address_range_state(byte loop)
720 42 check_writable
721 43 check_writable(byte loop)
722 44 check_readable
723 45 check_readable(byte loop)
724 46 check_readable_asciiz
725 47 check_readable_asciiz(byte loop)
726A 48 check_accessible
727A 49 check_accessible(byte loop)
728
729 50 make_noaccess_aligned
730 51 make_writable_aligned
731
732M 60 helperc_LOADV4
733M 61 helperc_STOREV4
734M 62 helperc_LOADV2
735M 63 helperc_STOREV2
736M 64 helperc_LOADV1
737M 65 helperc_STOREV1
738
739A 66 helperc_ACCESS4
740A 67 helperc_ACCESS2
741A 68 helperc_ACCESS1
742
743M 70 rim_rd_V4_SLOWLY
744M 71 rim_wr_V4_SLOWLY
745M 72 rim_rd_V2_SLOWLY
746M 73 rim_wr_V2_SLOWLY
747M 74 rim_rd_V1_SLOWLY
748M 75 rim_wr_V1_SLOWLY
749
750A 76 ACCESS4_SLOWLY
751A 77 ACCESS2_SLOWLY
752A 78 ACCESS1_SLOWLY
753
754 80 fpu_read
755 81 fpu_read aligned 4
756 82 fpu_read aligned 8
757 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000758 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000759
760M 85 fpu_write
761M 86 fpu_write aligned 4
762M 87 fpu_write aligned 8
763M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000764M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000765
766 90 fpu_access
767 91 fpu_access aligned 4
768 92 fpu_access aligned 8
769 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000770 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000771
772 100 fpu_access_check_SLOWLY
773 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000774
775 110 new_mem_stack_4
776 111 new_mem_stack_8
777 112 new_mem_stack_12
778 113 new_mem_stack_16
779 114 new_mem_stack_32
780 115 new_mem_stack
781
782 120 die_mem_stack_4
783 121 die_mem_stack_8
784 122 die_mem_stack_12
785 123 die_mem_stack_16
786 124 die_mem_stack_32
787 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000788*/
789
njn43c799e2003-04-08 00:08:52 +0000790#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000791
njn43c799e2003-04-08 00:08:52 +0000792UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000793
njnb4aee052003-04-15 14:09:58 +0000794static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000795{
796 Int i;
797 for (i = 0; i < N_PROF_EVENTS; i++)
njn43c799e2003-04-08 00:08:52 +0000798 MAC_(event_ctr)[i] = 0;
njn5c004e42002-11-18 11:04:50 +0000799}
800
njnb4aee052003-04-15 14:09:58 +0000801static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000802{
803 Int i;
804 for (i = 0; i < N_PROF_EVENTS; i++) {
805 if ((i % 10) == 0)
806 VG_(printf)("\n");
njn43c799e2003-04-08 00:08:52 +0000807 if (MAC_(event_ctr)[i] > 0)
808 VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] );
njn5c004e42002-11-18 11:04:50 +0000809 }
810 VG_(printf)("\n");
811}
812
813#else
814
njnb4aee052003-04-15 14:09:58 +0000815static void init_prof_mem ( void ) { }
816static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000817
njn5c004e42002-11-18 11:04:50 +0000818#endif
819
820/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000821/*--- Common initialisation + finalisation ---*/
822/*------------------------------------------------------------*/
823
824void MAC_(common_pre_clo_init)(void)
825{
826 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000827 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000828 init_prof_mem();
829}
830
sewardj2a99cf62004-11-24 10:44:19 +0000831void MAC_(common_fini)(void (*leak_check)(ThreadId))
njn3e884182003-04-15 13:03:23 +0000832{
833 MAC_(print_malloc_stats)();
834
835 if (VG_(clo_verbosity) == 1) {
836 if (!MAC_(clo_leak_check))
837 VG_(message)(Vg_UserMsg,
838 "For a detailed leak analysis, rerun with: --leak-check=yes");
839
840 VG_(message)(Vg_UserMsg,
841 "For counts of detected errors, rerun with: -v");
842 }
sewardj2a99cf62004-11-24 10:44:19 +0000843 if (MAC_(clo_leak_check))
844 leak_check( 1/*bogus ThreadID*/ );
njn3e884182003-04-15 13:03:23 +0000845
846 done_prof_mem();
847}
848
849/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000850/*--- Common client request handling ---*/
851/*------------------------------------------------------------*/
852
nethercoted1b64b22004-11-04 18:22:28 +0000853Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000854{
njnd7994182003-10-02 13:44:04 +0000855 Char* err =
856 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
857 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
858 " program to incorporate the updates in the Valgrind header files.\n"
859 " You shouldn't need to change the text of your program at all.\n"
860 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000861
862 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000863 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000864 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000865 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
866 // if no prior leak checks performed).
867 *argp[1] = MAC_(bytes_leaked);
868 *argp[2] = MAC_(bytes_dubious);
869 *argp[3] = MAC_(bytes_reachable);
870 *argp[4] = MAC_(bytes_suppressed);
njn47363ab2003-04-21 13:24:40 +0000871 *ret = 0;
872 return True;
njn10785452003-05-20 16:38:24 +0000873 }
njnd7994182003-10-02 13:44:04 +0000874 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
875 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000876 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000877
njn10785452003-05-20 16:38:24 +0000878 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000879 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000880 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000881 UInt rzB = arg[3];
882 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000883
sewardj2a99cf62004-11-24 10:44:19 +0000884 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000885 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000886 return True;
887 }
888 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000889 Addr p = (Addr)arg[1];
890 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000891
sewardj2a99cf62004-11-24 10:44:19 +0000892 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000893 return True;
894 }
njnd7994182003-10-02 13:44:04 +0000895
nethercotee3a53722004-05-05 10:46:22 +0000896 case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP:
897 *ret = (Addr)MAC_(record_overlap_error);
898 return True;
899
rjwalshbc0bb832004-06-19 18:12:36 +0000900 case VG_USERREQ__CREATE_MEMPOOL: {
901 Addr pool = (Addr)arg[1];
902 UInt rzB = arg[2];
903 Bool is_zeroed = (Bool)arg[3];
904
905 MAC_(create_mempool) ( pool, rzB, is_zeroed );
906 return True;
907 }
908
909 case VG_USERREQ__DESTROY_MEMPOOL: {
910 Addr pool = (Addr)arg[1];
911
912 MAC_(destroy_mempool) ( pool );
913 return True;
914 }
915
916 case VG_USERREQ__MEMPOOL_ALLOC: {
917 Addr pool = (Addr)arg[1];
918 Addr addr = (Addr)arg[2];
919 UInt size = arg[3];
920
sewardj2a99cf62004-11-24 10:44:19 +0000921 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000922 return True;
923 }
924
925 case VG_USERREQ__MEMPOOL_FREE: {
926 Addr pool = (Addr)arg[1];
927 Addr addr = (Addr)arg[2];
928
929 MAC_(mempool_free) ( pool, addr );
930 return True;
931 }
932
njn47363ab2003-04-21 13:24:40 +0000933 default:
934 return False;
935 }
936}
937
njn5c004e42002-11-18 11:04:50 +0000938/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000939/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000940/*--------------------------------------------------------------------*/