blob: e528c6da84e535db79f4305c4be04a6892964fe1 [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
njnb126f732004-11-22 17:57:07 +0000140Bool SK_(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:
njnb126f732004-11-22 17:57:07 +0000196 VG_(skin_panic)("Shouldn't get LeakErr in SK_(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));
njnb126f732004-11-22 17:57:07 +0000205 VG_(skin_panic)("unknown error code in SK_(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:
njn43c799e2003-04-08 00:08:52 +0000263 VG_(skin_panic)("MAC_(pp_AddrInfo)");
264 }
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:
njnb126f732004-11-22 17:57:07 +0000300 VG_(skin_panic)("SK_(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));
njnb126f732004-11-22 17:57:07 +0000339 VG_(skin_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
433 just_below_esp = is_just_below_ESP( VG_(get_stack_pointer)(), a );
434
435 /* If this is caused by an access immediately below %ESP, and the
436 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000437 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000438 return;
439
njn43c799e2003-04-08 00:08:52 +0000440 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000441 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
442 err_extra.size = size;
443 err_extra.addrinfo.akind = Undescribed;
444 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000445 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000446}
447
448/* These ones are called from non-generated code */
449
450/* This is for memory errors in pthread functions, as opposed to pthread API
451 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000452void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000453{
njn43c799e2003-04-08 00:08:52 +0000454 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000455
njn43c799e2003-04-08 00:08:52 +0000456 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000457 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000458 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000459}
460
nethercote8b76fe52004-11-08 19:20:09 +0000461void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
462 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000463{
njn43c799e2003-04-08 00:08:52 +0000464 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000465
njnca82cc02004-11-22 17:18:48 +0000466 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000467 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000468 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
469 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000470 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000471}
472
njn72718642003-07-24 08:45:32 +0000473void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000474{
njn43c799e2003-04-08 00:08:52 +0000475 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000476
njnca82cc02004-11-22 17:18:48 +0000477 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000478 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000479 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000480 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000481 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000482 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000483}
484
njn72718642003-07-24 08:45:32 +0000485void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000486{
njn43c799e2003-04-08 00:08:52 +0000487 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000488
njnca82cc02004-11-22 17:18:48 +0000489 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000490 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000491 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000492 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000493}
494
rjwalshbc0bb832004-06-19 18:12:36 +0000495void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
496{
497 MAC_Error err_extra;
498
njnca82cc02004-11-22 17:18:48 +0000499 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000500 MAC_(clear_MAC_Error)( &err_extra );
501 err_extra.addrinfo.akind = Undescribed;
502 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
503}
504
njn72718642003-07-24 08:45:32 +0000505void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000506{
njn43c799e2003-04-08 00:08:52 +0000507 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000508
njnca82cc02004-11-22 17:18:48 +0000509 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000510 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000511 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000512 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000513}
514
njn66fe05a2003-07-22 09:12:33 +0000515
njn72718642003-07-24 08:45:32 +0000516// This one not passed a ThreadId, so it grabs it itself.
njnb6cae9f2003-09-04 20:50:47 +0000517void MAC_(record_overlap_error) ( Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000518{
njn72718642003-07-24 08:45:32 +0000519 VG_(maybe_record_error)( VG_(get_current_or_recent_tid)(),
njnb6cae9f2003-09-04 20:50:47 +0000520 OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000521}
522
523
njnb6cae9f2003-09-04 20:50:47 +0000524/* Updates the copy with address info if necessary (but not for all errors). */
njn43c799e2003-04-08 00:08:52 +0000525UInt SK_(update_extra)( Error* err )
526{
njnb6cae9f2003-09-04 20:50:47 +0000527 switch (VG_(get_error_kind)(err)) {
528 case ValueErr:
529 case CoreMemErr:
530 case AddrErr:
531 case ParamErr:
532 case UserErr:
533 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000534 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000535 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000536 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000537 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
538 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
539 }
540 return sizeof(MAC_Error);
541 }
njn43c799e2003-04-08 00:08:52 +0000542 /* Don't need to return the correct size -- LeakErrs are always shown with
543 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000544 case LeakErr: return 0;
545 case OverlapErr: return sizeof(OverlapExtra);
546 default: VG_(skin_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000547 }
njn43c799e2003-04-08 00:08:52 +0000548}
549
550
njn5c004e42002-11-18 11:04:50 +0000551/*------------------------------------------------------------*/
552/*--- Suppressions ---*/
553/*------------------------------------------------------------*/
554
njn43c799e2003-04-08 00:08:52 +0000555Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
556{
557 SuppKind skind;
558
559 if (VG_STREQ(name, "Param")) skind = ParamSupp;
560 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
561 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
562 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
563 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
564 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000565 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000566 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
567 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000568 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000569 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000570 else
571 return False;
572
573 VG_(set_supp_kind)(su, skind);
574 return True;
575}
576
njn5c004e42002-11-18 11:04:50 +0000577Bool SK_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
578{
579 Bool eof;
580
581 if (VG_(get_supp_kind)(su) == ParamSupp) {
582 eof = VG_(get_line) ( fd, buf, nBuf );
583 if (eof) return False;
584 VG_(set_supp_string)(su, VG_(strdup)(buf));
585 }
586 return True;
587}
588
sewardj99aac972002-12-26 01:53:45 +0000589Bool SK_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000590{
sewardj05bcdcb2003-05-18 10:05:38 +0000591 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000592 MAC_Error* err_extra = VG_(get_error_extra)(err);
593 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000594
595 switch (VG_(get_supp_kind)(su)) {
596 case ParamSupp:
597 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000598 && VG_STREQ(VG_(get_error_string)(err),
599 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000600
601 case CoreMemSupp:
602 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000603 && VG_STREQ(VG_(get_error_string)(err),
604 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000605
606 case Value0Supp: su_size = 0; goto value_case;
607 case Value1Supp: su_size = 1; goto value_case;
608 case Value2Supp: su_size = 2; goto value_case;
609 case Value4Supp: su_size = 4; goto value_case;
610 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000611 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000612 value_case:
613 return (ekind == ValueErr && err_extra->size == su_size);
614
615 case Addr1Supp: su_size = 1; goto addr_case;
616 case Addr2Supp: su_size = 2; goto addr_case;
617 case Addr4Supp: su_size = 4; goto addr_case;
618 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000619 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000620 addr_case:
621 return (ekind == AddrErr && err_extra->size == su_size);
622
623 case FreeSupp:
624 return (ekind == FreeErr || ekind == FreeMismatchErr);
625
njn34419c12003-05-02 17:24:29 +0000626 case OverlapSupp:
627 return (ekind = OverlapErr);
628
sewardj4a19e2f2002-12-26 11:50:21 +0000629 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000630 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000631
rjwalshbc0bb832004-06-19 18:12:36 +0000632 case MempoolSupp:
633 return (ekind == IllegalMempoolErr);
634
njn5c004e42002-11-18 11:04:50 +0000635 default:
636 VG_(printf)("Error:\n"
637 " unknown suppression type %d\n",
638 VG_(get_supp_kind)(su));
639 VG_(skin_panic)("unknown suppression type in "
640 "SK_(error_matches_suppression)");
641 }
642}
643
njn43c799e2003-04-08 00:08:52 +0000644Char* SK_(get_error_name) ( Error* err )
645{
646 Char* s;
647 switch (VG_(get_error_kind)(err)) {
648 case ParamErr: return "Param";
649 case UserErr: return NULL; /* Can't suppress User errors */
650 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000651 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000652 case FreeErr: return "Free";
653 case AddrErr:
654 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
655 case 1: return "Addr1";
656 case 2: return "Addr2";
657 case 4: return "Addr4";
658 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000659 case 16: return "Addr16";
njn43c799e2003-04-08 00:08:52 +0000660 default: VG_(skin_panic)("unexpected size for Addr");
661 }
662
663 case ValueErr:
664 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
665 case 0: return "Cond";
666 case 1: return "Value1";
667 case 2: return "Value2";
668 case 4: return "Value4";
669 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000670 case 16: return "Value16";
njn43c799e2003-04-08 00:08:52 +0000671 default: VG_(skin_panic)("unexpected size for Value");
672 }
673 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000674 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000675 case LeakErr: return "Leak";
676 default: VG_(skin_panic)("get_error_name: unexpected type");
677 }
678 VG_(printf)(s);
679}
680
681void SK_(print_extra_suppression_info) ( Error* err )
682{
683 if (ParamErr == VG_(get_error_kind)(err)) {
684 VG_(printf)(" %s\n", VG_(get_error_string)(err));
685 }
686}
njn5c004e42002-11-18 11:04:50 +0000687
688/*------------------------------------------------------------*/
689/*--- Crude profiling machinery. ---*/
690/*------------------------------------------------------------*/
691
692/* Event index. If just the name of the fn is given, this means the
693 number of calls to the fn. Otherwise it is the specified event.
694 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
695 The rest are shared.
696
697 10 alloc_secondary_map
698
699 20 get_abit
700M 21 get_vbyte
701 22 set_abit
702M 23 set_vbyte
703 24 get_abits4_ALIGNED
704M 25 get_vbytes4_ALIGNED
705
706 30 set_address_range_perms
707 31 set_address_range_perms(lower byte loop)
708 32 set_address_range_perms(quadword loop)
709 33 set_address_range_perms(upper byte loop)
710
711 35 make_noaccess
712 36 make_writable
713 37 make_readable
714A 38 make_accessible
715
716 40 copy_address_range_state
717 41 copy_address_range_state(byte loop)
718 42 check_writable
719 43 check_writable(byte loop)
720 44 check_readable
721 45 check_readable(byte loop)
722 46 check_readable_asciiz
723 47 check_readable_asciiz(byte loop)
724A 48 check_accessible
725A 49 check_accessible(byte loop)
726
727 50 make_noaccess_aligned
728 51 make_writable_aligned
729
730M 60 helperc_LOADV4
731M 61 helperc_STOREV4
732M 62 helperc_LOADV2
733M 63 helperc_STOREV2
734M 64 helperc_LOADV1
735M 65 helperc_STOREV1
736
737A 66 helperc_ACCESS4
738A 67 helperc_ACCESS2
739A 68 helperc_ACCESS1
740
741M 70 rim_rd_V4_SLOWLY
742M 71 rim_wr_V4_SLOWLY
743M 72 rim_rd_V2_SLOWLY
744M 73 rim_wr_V2_SLOWLY
745M 74 rim_rd_V1_SLOWLY
746M 75 rim_wr_V1_SLOWLY
747
748A 76 ACCESS4_SLOWLY
749A 77 ACCESS2_SLOWLY
750A 78 ACCESS1_SLOWLY
751
752 80 fpu_read
753 81 fpu_read aligned 4
754 82 fpu_read aligned 8
755 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000756 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000757
758M 85 fpu_write
759M 86 fpu_write aligned 4
760M 87 fpu_write aligned 8
761M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000762M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000763
764 90 fpu_access
765 91 fpu_access aligned 4
766 92 fpu_access aligned 8
767 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000768 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000769
770 100 fpu_access_check_SLOWLY
771 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000772
773 110 new_mem_stack_4
774 111 new_mem_stack_8
775 112 new_mem_stack_12
776 113 new_mem_stack_16
777 114 new_mem_stack_32
778 115 new_mem_stack
779
780 120 die_mem_stack_4
781 121 die_mem_stack_8
782 122 die_mem_stack_12
783 123 die_mem_stack_16
784 124 die_mem_stack_32
785 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000786*/
787
njn43c799e2003-04-08 00:08:52 +0000788#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000789
njn43c799e2003-04-08 00:08:52 +0000790UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000791
njnb4aee052003-04-15 14:09:58 +0000792static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000793{
794 Int i;
795 for (i = 0; i < N_PROF_EVENTS; i++)
njn43c799e2003-04-08 00:08:52 +0000796 MAC_(event_ctr)[i] = 0;
njn5c004e42002-11-18 11:04:50 +0000797}
798
njnb4aee052003-04-15 14:09:58 +0000799static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000800{
801 Int i;
802 for (i = 0; i < N_PROF_EVENTS; i++) {
803 if ((i % 10) == 0)
804 VG_(printf)("\n");
njn43c799e2003-04-08 00:08:52 +0000805 if (MAC_(event_ctr)[i] > 0)
806 VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] );
njn5c004e42002-11-18 11:04:50 +0000807 }
808 VG_(printf)("\n");
809}
810
811#else
812
njnb4aee052003-04-15 14:09:58 +0000813static void init_prof_mem ( void ) { }
814static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000815
njn5c004e42002-11-18 11:04:50 +0000816#endif
817
818/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000819/*--- Common initialisation + finalisation ---*/
820/*------------------------------------------------------------*/
821
822void MAC_(common_pre_clo_init)(void)
823{
824 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000825 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000826 init_prof_mem();
827}
828
829void MAC_(common_fini)(void (*leak_check)(void))
830{
831 MAC_(print_malloc_stats)();
832
833 if (VG_(clo_verbosity) == 1) {
834 if (!MAC_(clo_leak_check))
835 VG_(message)(Vg_UserMsg,
836 "For a detailed leak analysis, rerun with: --leak-check=yes");
837
838 VG_(message)(Vg_UserMsg,
839 "For counts of detected errors, rerun with: -v");
840 }
841 if (MAC_(clo_leak_check)) leak_check();
842
843 done_prof_mem();
844}
845
846/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000847/*--- Common client request handling ---*/
848/*------------------------------------------------------------*/
849
nethercoted1b64b22004-11-04 18:22:28 +0000850Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000851{
njnd7994182003-10-02 13:44:04 +0000852 Char* err =
853 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
854 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
855 " program to incorporate the updates in the Valgrind header files.\n"
856 " You shouldn't need to change the text of your program at all.\n"
857 " Everything should then work as before. Sorry for the bother.\n";
njn72718642003-07-24 08:45:32 +0000858
859 // Not using 'tid' here because MAC_(new_block)() and MAC_(handle_free)()
860 // grab it themselves. But what they grab should match 'tid', check
861 // this.
njnca82cc02004-11-22 17:18:48 +0000862 tl_assert(tid == VG_(get_current_or_recent_tid)());
njn47363ab2003-04-21 13:24:40 +0000863
864 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000865 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000866 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000867 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
868 // if no prior leak checks performed).
869 *argp[1] = MAC_(bytes_leaked);
870 *argp[2] = MAC_(bytes_dubious);
871 *argp[3] = MAC_(bytes_reachable);
872 *argp[4] = MAC_(bytes_suppressed);
njn47363ab2003-04-21 13:24:40 +0000873 *ret = 0;
874 return True;
njn10785452003-05-20 16:38:24 +0000875 }
njnd7994182003-10-02 13:44:04 +0000876 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
877 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
878 VG_(skin_panic)(err);
879
njn10785452003-05-20 16:38:24 +0000880 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000881 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000882 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000883 UInt rzB = arg[3];
884 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000885
nethercote57e36b32004-07-10 14:56:28 +0000886 MAC_(new_block) ( p, sizeB, /*ignored*/0, rzB, is_zeroed,
887 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000888 return True;
889 }
890 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000891 Addr p = (Addr)arg[1];
892 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000893
njn72718642003-07-24 08:45:32 +0000894 MAC_(handle_free) ( p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000895 return True;
896 }
njnd7994182003-10-02 13:44:04 +0000897
nethercotee3a53722004-05-05 10:46:22 +0000898 case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP:
899 *ret = (Addr)MAC_(record_overlap_error);
900 return True;
901
rjwalshbc0bb832004-06-19 18:12:36 +0000902 case VG_USERREQ__CREATE_MEMPOOL: {
903 Addr pool = (Addr)arg[1];
904 UInt rzB = arg[2];
905 Bool is_zeroed = (Bool)arg[3];
906
907 MAC_(create_mempool) ( pool, rzB, is_zeroed );
908 return True;
909 }
910
911 case VG_USERREQ__DESTROY_MEMPOOL: {
912 Addr pool = (Addr)arg[1];
913
914 MAC_(destroy_mempool) ( pool );
915 return True;
916 }
917
918 case VG_USERREQ__MEMPOOL_ALLOC: {
919 Addr pool = (Addr)arg[1];
920 Addr addr = (Addr)arg[2];
921 UInt size = arg[3];
922
923 MAC_(mempool_alloc) ( pool, addr, size );
924 return True;
925 }
926
927 case VG_USERREQ__MEMPOOL_FREE: {
928 Addr pool = (Addr)arg[1];
929 Addr addr = (Addr)arg[2];
930
931 MAC_(mempool_free) ( pool, addr );
932 return True;
933 }
934
njn47363ab2003-04-21 13:24:40 +0000935 default:
936 return False;
937 }
938}
939
940/*------------------------------------------------------------*/
njn5c004e42002-11-18 11:04:50 +0000941/*--- Syscall wrappers ---*/
942/*------------------------------------------------------------*/
943
944void* SK_(pre_syscall) ( ThreadId tid, UInt syscallno, Bool isBlocking )
945{
946 Int sane = SK_(cheap_sanity_check)();
947 return (void*)sane;
948}
949
950void SK_(post_syscall) ( ThreadId tid, UInt syscallno,
951 void* pre_result, Int res, Bool isBlocking )
952{
953 Int sane_before_call = (Int)pre_result;
954 Bool sane_after_call = SK_(cheap_sanity_check)();
955
956 if ((Int)sane_before_call && (!sane_after_call)) {
957 VG_(message)(Vg_DebugMsg, "post-syscall: ");
958 VG_(message)(Vg_DebugMsg,
959 "probable sanity check failure for syscall number %d\n",
960 syscallno );
961 VG_(skin_panic)("aborting due to the above ... bye!");
962 }
963}
964
njn5c004e42002-11-18 11:04:50 +0000965/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000966/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000967/*--------------------------------------------------------------------*/