blob: 8612a72ad36f58e2a6b0ae33a3f315aba3c1f7f0 [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
njn53612422005-03-12 16:22:54 +000012 Copyright (C) 2000-2005 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
sewardjb5f6f512005-03-10 23:59:00 +000050Bool MAC_(clo_partial_loads_ok) = True;
51Int MAC_(clo_freelist_vol) = 1000000;
njn6a329422005-03-12 20:38:13 +000052LeakCheckMode MAC_(clo_leak_check) = LC_Summary;
sewardjb5f6f512005-03-10 23:59:00 +000053VgRes 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{
sewardjb5f6f512005-03-10 23:59:00 +000059 VG_BOOL_CLO("--partial-loads-ok", MAC_(clo_partial_loads_ok))
nethercote27fec902004-06-16 21:26:32 +000060 else VG_BOOL_CLO("--show-reachable", MAC_(clo_show_reachable))
61 else VG_BOOL_CLO("--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
62
63 else VG_BNUM_CLO("--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
64
sewardjb5f6f512005-03-10 23:59:00 +000065 else if (VG_CLO_STREQ(arg, "--leak-check=no"))
66 MAC_(clo_leak_check) = LC_Off;
67 else if (VG_CLO_STREQ(arg, "--leak-check=summary"))
68 MAC_(clo_leak_check) = LC_Summary;
69 else if (VG_CLO_STREQ(arg, "--leak-check=yes") ||
70 VG_CLO_STREQ(arg, "--leak-check=full"))
71 MAC_(clo_leak_check) = LC_Full;
72
njn43c799e2003-04-08 00:08:52 +000073 else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
74 MAC_(clo_leak_resolution) = Vg_LowRes;
75 else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
76 MAC_(clo_leak_resolution) = Vg_MedRes;
77 else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
78 MAC_(clo_leak_resolution) = Vg_HighRes;
njn5c004e42002-11-18 11:04:50 +000079
80 else
njn3e884182003-04-15 13:03:23 +000081 return VG_(replacement_malloc_process_cmd_line_option)(arg);
njn5c004e42002-11-18 11:04:50 +000082
83 return True;
njn43c799e2003-04-08 00:08:52 +000084}
njn5c004e42002-11-18 11:04:50 +000085
njn3e884182003-04-15 13:03:23 +000086void MAC_(print_common_usage)(void)
njn43c799e2003-04-08 00:08:52 +000087{
njn3e884182003-04-15 13:03:23 +000088 VG_(printf)(
sewardjb5f6f512005-03-10 23:59:00 +000089" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n"
90" --freelist-vol=<number> volume of freed blocks queue [1000000]\n"
njn6a329422005-03-12 20:38:13 +000091" --leak-check=no|summary|full search for memory leaks at exit? [summary]\n"
sewardjb5f6f512005-03-10 23:59:00 +000092" --leak-resolution=low|med|high how much bt merging in leak check [low]\n"
93" --show-reachable=no|yes show reachable blocks in leak check? [no]\n"
njn3e884182003-04-15 13:03:23 +000094" --workaround-gcc296-bugs=no|yes self explanatory [no]\n"
95 );
96 VG_(replacement_malloc_print_usage)();
njn43c799e2003-04-08 00:08:52 +000097}
98
njn3e884182003-04-15 13:03:23 +000099void MAC_(print_common_debug_usage)(void)
njn43c799e2003-04-08 00:08:52 +0000100{
njn3e884182003-04-15 13:03:23 +0000101 VG_(replacement_malloc_print_debug_usage)();
njn5c004e42002-11-18 11:04:50 +0000102}
103
104/*------------------------------------------------------------*/
105/*--- Comparing and printing errors ---*/
106/*------------------------------------------------------------*/
107
108static __inline__
109void clear_AddrInfo ( AddrInfo* ai )
110{
111 ai->akind = Unknown;
112 ai->blksize = 0;
113 ai->rwoffset = 0;
114 ai->lastchange = NULL;
115 ai->stack_tid = VG_INVALID_THREADID;
116 ai->maybe_gcc = False;
sewardjb5f6f512005-03-10 23:59:00 +0000117 ai->desc = NULL;
njn5c004e42002-11-18 11:04:50 +0000118}
119
njn43c799e2003-04-08 00:08:52 +0000120void MAC_(clear_MAC_Error) ( MAC_Error* err_extra )
njn5c004e42002-11-18 11:04:50 +0000121{
122 err_extra->axskind = ReadAxs;
123 err_extra->size = 0;
124 clear_AddrInfo ( &err_extra->addrinfo );
nethercote8b76fe52004-11-08 19:20:09 +0000125 err_extra->isUnaddr = True;
njn5c004e42002-11-18 11:04:50 +0000126}
127
128__attribute__ ((unused))
129static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
130{
131 if (ai1->akind != Undescribed
132 && ai2->akind != Undescribed
133 && ai1->akind != ai2->akind)
134 return False;
135 if (ai1->akind == Freed || ai1->akind == Mallocd) {
136 if (ai1->blksize != ai2->blksize)
137 return False;
138 if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
139 return False;
140 }
141 return True;
142}
143
144/* Compare error contexts, to detect duplicates. Note that if they
145 are otherwise the same, the faulting addrs and associated rwoffsets
146 are allowed to be different. */
147
njn26f02512004-11-22 18:33:15 +0000148Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
njn5c004e42002-11-18 11:04:50 +0000149{
njn43c799e2003-04-08 00:08:52 +0000150 MAC_Error* e1_extra = VG_(get_error_extra)(e1);
151 MAC_Error* e2_extra = VG_(get_error_extra)(e2);
njn7cc53a82002-11-19 16:19:32 +0000152
153 /* Guaranteed by calling function */
njnca82cc02004-11-22 17:18:48 +0000154 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
njn5c004e42002-11-18 11:04:50 +0000155
156 switch (VG_(get_error_kind)(e1)) {
157 case CoreMemErr: {
158 Char *e1s, *e2s;
nethercote8b76fe52004-11-08 19:20:09 +0000159 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000160 e1s = VG_(get_error_string)(e1);
161 e2s = VG_(get_error_string)(e2);
162 if (e1s == e2s) return True;
163 if (0 == VG_(strcmp)(e1s, e2s)) return True;
164 return False;
165 }
166
167 case UserErr:
168 case ParamErr:
nethercote8b76fe52004-11-08 19:20:09 +0000169 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000170 if (VG_(get_error_kind)(e1) == ParamErr
171 && 0 != VG_(strcmp)(VG_(get_error_string)(e1),
172 VG_(get_error_string)(e2))) return False;
173 return True;
174
175 case FreeErr:
176 case FreeMismatchErr:
177 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
178 cause excessive duplication of errors. Not even AddrErr
179 below does that. So don't compare either the .addr field
180 or the .addrinfo fields. */
181 /* if (e1->addr != e2->addr) return False; */
182 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
183 return False;
184 */
185 return True;
186
187 case AddrErr:
188 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
189 if (e1_extra->size != e2_extra->size) return False;
190 /*
191 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
192 return False;
193 */
194 return True;
195
196 case ValueErr:
197 if (e1_extra->size != e2_extra->size) return False;
198 return True;
199
njn34419c12003-05-02 17:24:29 +0000200 case OverlapErr:
201 return True;
202
njn43c799e2003-04-08 00:08:52 +0000203 case LeakErr:
njn26f02512004-11-22 18:33:15 +0000204 VG_(tool_panic)("Shouldn't get LeakErr in TL_(eq_Error),\n"
njn43c799e2003-04-08 00:08:52 +0000205 "since it's handled with VG_(unique_error)()!");
206
rjwalshbc0bb832004-06-19 18:12:36 +0000207 case IllegalMempoolErr:
208 return True;
209
njn5c004e42002-11-18 11:04:50 +0000210 default:
211 VG_(printf)("Error:\n unknown error code %d\n",
212 VG_(get_error_kind)(e1));
njn26f02512004-11-22 18:33:15 +0000213 VG_(tool_panic)("unknown error code in TL_(eq_Error)");
njn5c004e42002-11-18 11:04:50 +0000214 }
215}
216
njn43c799e2003-04-08 00:08:52 +0000217void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000218{
219 switch (ai->akind) {
220 case Stack:
221 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000222 " Address 0x%x is on thread %d's stack",
njn5c004e42002-11-18 11:04:50 +0000223 a, ai->stack_tid);
224 break;
225 case Unknown:
226 if (ai->maybe_gcc) {
227 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000228 " Address 0x%x is just below %%esp. Possibly a bug in GCC/G++",
njn5c004e42002-11-18 11:04:50 +0000229 a);
230 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000231 " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes");
njn5c004e42002-11-18 11:04:50 +0000232 } else {
233 VG_(message)(Vg_UserMsg,
nethercotef798eee2004-04-13 08:36:35 +0000234 " Address 0x%x is not stack'd, malloc'd or (recently) free'd",a);
njn5c004e42002-11-18 11:04:50 +0000235 }
236 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000237 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000238 SizeT delta;
sewardjb5f6f512005-03-10 23:59:00 +0000239 const Char* relative;
240 const Char* kind;
rjwalshbc0bb832004-06-19 18:12:36 +0000241 if (ai->akind == Mempool) {
242 kind = "mempool";
243 } else {
244 kind = "block";
245 }
sewardjb5f6f512005-03-10 23:59:00 +0000246 if (ai->desc != NULL)
247 kind = ai->desc;
248
njn5c004e42002-11-18 11:04:50 +0000249 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000250 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000251 relative = "before";
252 } else if (ai->rwoffset >= ai->blksize) {
253 delta = ai->rwoffset - ai->blksize;
254 relative = "after";
255 } else {
256 delta = ai->rwoffset;
257 relative = "inside";
258 }
sewardja81709d2002-12-28 12:55:48 +0000259 VG_(message)(Vg_UserMsg,
nethercote50397c22004-11-04 18:03:06 +0000260 " Address 0x%x is %llu bytes %s a %s of size %d %s",
261 a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000262 ai->blksize,
263 ai->akind==Mallocd ? "alloc'd"
264 : ai->akind==Freed ? "free'd"
265 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000266 VG_(pp_ExeContext)(ai->lastchange);
267 break;
268 }
nethercote8b76fe52004-11-08 19:20:09 +0000269 case Register:
270 // print nothing
njnca82cc02004-11-22 17:18:48 +0000271 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000272 break;
njn5c004e42002-11-18 11:04:50 +0000273 default:
njn67993252004-11-22 18:02:32 +0000274 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000275 }
276}
277
278/* This prints out the message for the error types where Memcheck and
279 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000280void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000281{
282 MAC_Error* err_extra = VG_(get_error_extra)(err);
283
284 switch (VG_(get_error_kind)(err)) {
285 case FreeErr:
njn10785452003-05-20 16:38:24 +0000286 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000287 /* fall through */
288 case FreeMismatchErr:
289 if (VG_(get_error_kind)(err) == FreeMismatchErr)
290 VG_(message)(Vg_UserMsg,
291 "Mismatched free() / delete / delete []");
292 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
293 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
294 break;
295
njn89409f82003-09-26 14:55:31 +0000296 case AddrErr:
297 switch (err_extra->axskind) {
298 case ReadAxs:
299 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
300 err_extra->size );
301 break;
302 case WriteAxs:
303 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
304 err_extra->size );
305 break;
306 case ExecAxs:
307 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
308 "stated on the next line");
309 break;
310 default:
njn26f02512004-11-22 18:33:15 +0000311 VG_(tool_panic)("TL_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000312 }
313 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
314 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
315 break;
316
njnb6cae9f2003-09-04 20:50:47 +0000317 case OverlapErr: {
318 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
319 if (ov_extra->len == -1)
320 VG_(message)(Vg_UserMsg,
321 "Source and destination overlap in %s(%p, %p)",
322 VG_(get_error_string)(err),
323 ov_extra->dst, ov_extra->src);
324 else
325 VG_(message)(Vg_UserMsg,
326 "Source and destination overlap in %s(%p, %p, %d)",
327 VG_(get_error_string)(err),
328 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000329 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
330 break;
njnb6cae9f2003-09-04 20:50:47 +0000331 }
njn43c799e2003-04-08 00:08:52 +0000332 case LeakErr: {
333 /* Totally abusing the types of these spare fields... oh well. */
njnc6168192004-11-29 13:54:10 +0000334 UInt n_this_record = (UWord)VG_(get_error_address)(err);
335 UInt n_total_records = (UWord)VG_(get_error_string) (err);
njn43c799e2003-04-08 00:08:52 +0000336
337 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
338 break;
339 }
340
rjwalshbc0bb832004-06-19 18:12:36 +0000341 case IllegalMempoolErr:
342 VG_(message)(Vg_UserMsg, "Illegal memory pool address");
343 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
344 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
345 break;
346
njn43c799e2003-04-08 00:08:52 +0000347 default:
348 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
349 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000350 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000351 }
352}
353
354/*------------------------------------------------------------*/
355/*--- Recording errors ---*/
356/*------------------------------------------------------------*/
357
njn43c799e2003-04-08 00:08:52 +0000358/* Additional description function for describe_addr(); used by
359 MemCheck for user blocks, which Addrcheck doesn't support. */
360Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000361
362/* Callback for searching thread stacks */
363static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
364{
365 Addr a = *(Addr *)ap;
366
367 return (stack_min <= a && a <= stack_max);
368}
369
370/* Callback for searching free'd list */
371static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
372{
373 Addr a = *(Addr *)ap;
374
375 return VG_(addr_is_in_block)( a, mc->data, mc->size );
376}
377
378/* Callback for searching malloc'd lists */
379static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
380{
381 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
382}
383
njn43c799e2003-04-08 00:08:52 +0000384/* Describe an address as best you can, for error messages,
385 putting the result in ai. */
386static void describe_addr ( Addr a, AddrInfo* ai )
387{
njn3e884182003-04-15 13:03:23 +0000388 MAC_Chunk* sc;
389 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000390
njn43c799e2003-04-08 00:08:52 +0000391 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
392 if (NULL != MAC_(describe_addr_supp)) {
393 if (MAC_(describe_addr_supp)( a, ai ))
394 return;
395 }
396 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000397 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000398 if (tid != VG_INVALID_THREADID) {
399 ai->akind = Stack;
400 ai->stack_tid = tid;
401 return;
402 }
403 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000404 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000405 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000406 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000407 ai->blksize = sc->size;
408 ai->rwoffset = (Int)a - (Int)sc->data;
409 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000410 return;
411 }
412 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000413 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000414 if (NULL != sc) {
415 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000416 ai->blksize = sc->size;
417 ai->rwoffset = (Int)(a) - (Int)sc->data;
418 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000419 return;
420 }
421 /* Clueless ... */
422 ai->akind = Unknown;
423 return;
424}
425
njn5c004e42002-11-18 11:04:50 +0000426/* Is this address within some small distance below %ESP? Used only
427 for the --workaround-gcc296-bugs kludge. */
428static Bool is_just_below_ESP( Addr esp, Addr aa )
429{
nethercote50397c22004-11-04 18:03:06 +0000430 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000431 return True;
432 else
433 return False;
434}
435
sewardjaf48a602003-07-06 00:54:47 +0000436/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000437
njn72718642003-07-24 08:45:32 +0000438void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000439 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000440{
njn43c799e2003-04-08 00:08:52 +0000441 MAC_Error err_extra;
442 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000443
njn67516132005-03-22 04:02:43 +0000444 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
njn5c004e42002-11-18 11:04:50 +0000445
446 /* If this is caused by an access immediately below %ESP, and the
447 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000448 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000449 return;
450
njn43c799e2003-04-08 00:08:52 +0000451 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000452 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
453 err_extra.size = size;
454 err_extra.addrinfo.akind = Undescribed;
455 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000456 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000457}
458
459/* These ones are called from non-generated code */
460
461/* This is for memory errors in pthread functions, as opposed to pthread API
462 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000463void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000464{
njn43c799e2003-04-08 00:08:52 +0000465 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000466
njn43c799e2003-04-08 00:08:52 +0000467 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000468 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000469 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000470}
471
nethercote8b76fe52004-11-08 19:20:09 +0000472void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
473 Bool isUnaddr, Char* msg )
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 );
nethercote8b76fe52004-11-08 19:20:09 +0000479 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
480 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000481 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000482}
483
njn72718642003-07-24 08:45:32 +0000484void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000485{
njn43c799e2003-04-08 00:08:52 +0000486 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000487
njnca82cc02004-11-22 17:18:48 +0000488 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000489 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000490 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000491 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000492 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000493 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000494}
495
njn72718642003-07-24 08:45:32 +0000496void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000497{
njn43c799e2003-04-08 00:08:52 +0000498 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000499
njnca82cc02004-11-22 17:18:48 +0000500 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000501 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000502 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000503 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000504}
505
rjwalshbc0bb832004-06-19 18:12:36 +0000506void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
507{
508 MAC_Error err_extra;
509
njnca82cc02004-11-22 17:18:48 +0000510 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000511 MAC_(clear_MAC_Error)( &err_extra );
512 err_extra.addrinfo.akind = Undescribed;
513 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
514}
515
njn72718642003-07-24 08:45:32 +0000516void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000517{
njn43c799e2003-04-08 00:08:52 +0000518 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000519
njnca82cc02004-11-22 17:18:48 +0000520 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000521 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000522 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000523 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000524}
525
sewardj2a99cf62004-11-24 10:44:19 +0000526void MAC_(record_overlap_error) ( ThreadId tid,
527 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000528{
sewardj2a99cf62004-11-24 10:44:19 +0000529 VG_(maybe_record_error)(
530 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000531}
532
533
njnb6cae9f2003-09-04 20:50:47 +0000534/* Updates the copy with address info if necessary (but not for all errors). */
njn26f02512004-11-22 18:33:15 +0000535UInt TL_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000536{
njnb6cae9f2003-09-04 20:50:47 +0000537 switch (VG_(get_error_kind)(err)) {
538 case ValueErr:
539 case CoreMemErr:
540 case AddrErr:
541 case ParamErr:
542 case UserErr:
543 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000544 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000545 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000546 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000547 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
548 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
549 }
550 return sizeof(MAC_Error);
551 }
njn43c799e2003-04-08 00:08:52 +0000552 /* Don't need to return the correct size -- LeakErrs are always shown with
553 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000554 case LeakErr: return 0;
555 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000556 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000557 }
njn43c799e2003-04-08 00:08:52 +0000558}
559
560
njn5c004e42002-11-18 11:04:50 +0000561/*------------------------------------------------------------*/
562/*--- Suppressions ---*/
563/*------------------------------------------------------------*/
564
njn43c799e2003-04-08 00:08:52 +0000565Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
566{
567 SuppKind skind;
568
569 if (VG_STREQ(name, "Param")) skind = ParamSupp;
570 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
571 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
572 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
573 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
574 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000575 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000576 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
577 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000578 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000579 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000580 else
581 return False;
582
583 VG_(set_supp_kind)(su, skind);
584 return True;
585}
586
njn26f02512004-11-22 18:33:15 +0000587Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000588{
589 Bool eof;
590
591 if (VG_(get_supp_kind)(su) == ParamSupp) {
592 eof = VG_(get_line) ( fd, buf, nBuf );
593 if (eof) return False;
594 VG_(set_supp_string)(su, VG_(strdup)(buf));
595 }
596 return True;
597}
598
njn26f02512004-11-22 18:33:15 +0000599Bool TL_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000600{
sewardj05bcdcb2003-05-18 10:05:38 +0000601 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000602 MAC_Error* err_extra = VG_(get_error_extra)(err);
603 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000604
605 switch (VG_(get_supp_kind)(su)) {
606 case ParamSupp:
607 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000608 && VG_STREQ(VG_(get_error_string)(err),
609 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000610
611 case CoreMemSupp:
612 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000613 && VG_STREQ(VG_(get_error_string)(err),
614 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000615
616 case Value0Supp: su_size = 0; goto value_case;
617 case Value1Supp: su_size = 1; goto value_case;
618 case Value2Supp: su_size = 2; goto value_case;
619 case Value4Supp: su_size = 4; goto value_case;
620 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000621 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000622 value_case:
623 return (ekind == ValueErr && err_extra->size == su_size);
624
625 case Addr1Supp: su_size = 1; goto addr_case;
626 case Addr2Supp: su_size = 2; goto addr_case;
627 case Addr4Supp: su_size = 4; goto addr_case;
628 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000629 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000630 addr_case:
631 return (ekind == AddrErr && err_extra->size == su_size);
632
633 case FreeSupp:
634 return (ekind == FreeErr || ekind == FreeMismatchErr);
635
njn34419c12003-05-02 17:24:29 +0000636 case OverlapSupp:
637 return (ekind = OverlapErr);
638
sewardj4a19e2f2002-12-26 11:50:21 +0000639 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000640 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000641
rjwalshbc0bb832004-06-19 18:12:36 +0000642 case MempoolSupp:
643 return (ekind == IllegalMempoolErr);
644
njn5c004e42002-11-18 11:04:50 +0000645 default:
646 VG_(printf)("Error:\n"
647 " unknown suppression type %d\n",
648 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000649 VG_(tool_panic)("unknown suppression type in "
njn26f02512004-11-22 18:33:15 +0000650 "TL_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000651 }
652}
653
njn26f02512004-11-22 18:33:15 +0000654Char* TL_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000655{
656 Char* s;
657 switch (VG_(get_error_kind)(err)) {
658 case ParamErr: return "Param";
659 case UserErr: return NULL; /* Can't suppress User errors */
660 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000661 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000662 case FreeErr: return "Free";
663 case AddrErr:
664 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
665 case 1: return "Addr1";
666 case 2: return "Addr2";
667 case 4: return "Addr4";
668 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000669 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000670 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000671 }
672
673 case ValueErr:
674 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
675 case 0: return "Cond";
676 case 1: return "Value1";
677 case 2: return "Value2";
678 case 4: return "Value4";
679 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000680 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000681 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000682 }
683 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000684 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000685 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000686 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000687 }
688 VG_(printf)(s);
689}
690
njn26f02512004-11-22 18:33:15 +0000691void TL_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000692{
693 if (ParamErr == VG_(get_error_kind)(err)) {
694 VG_(printf)(" %s\n", VG_(get_error_string)(err));
695 }
696}
njn5c004e42002-11-18 11:04:50 +0000697
698/*------------------------------------------------------------*/
699/*--- Crude profiling machinery. ---*/
700/*------------------------------------------------------------*/
701
702/* Event index. If just the name of the fn is given, this means the
703 number of calls to the fn. Otherwise it is the specified event.
704 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
705 The rest are shared.
706
707 10 alloc_secondary_map
708
709 20 get_abit
710M 21 get_vbyte
711 22 set_abit
712M 23 set_vbyte
713 24 get_abits4_ALIGNED
714M 25 get_vbytes4_ALIGNED
715
716 30 set_address_range_perms
717 31 set_address_range_perms(lower byte loop)
718 32 set_address_range_perms(quadword loop)
719 33 set_address_range_perms(upper byte loop)
720
721 35 make_noaccess
722 36 make_writable
723 37 make_readable
724A 38 make_accessible
725
726 40 copy_address_range_state
727 41 copy_address_range_state(byte loop)
728 42 check_writable
729 43 check_writable(byte loop)
730 44 check_readable
731 45 check_readable(byte loop)
732 46 check_readable_asciiz
733 47 check_readable_asciiz(byte loop)
734A 48 check_accessible
735A 49 check_accessible(byte loop)
736
737 50 make_noaccess_aligned
738 51 make_writable_aligned
739
740M 60 helperc_LOADV4
741M 61 helperc_STOREV4
742M 62 helperc_LOADV2
743M 63 helperc_STOREV2
744M 64 helperc_LOADV1
745M 65 helperc_STOREV1
746
747A 66 helperc_ACCESS4
748A 67 helperc_ACCESS2
749A 68 helperc_ACCESS1
750
751M 70 rim_rd_V4_SLOWLY
752M 71 rim_wr_V4_SLOWLY
753M 72 rim_rd_V2_SLOWLY
754M 73 rim_wr_V2_SLOWLY
755M 74 rim_rd_V1_SLOWLY
756M 75 rim_wr_V1_SLOWLY
757
758A 76 ACCESS4_SLOWLY
759A 77 ACCESS2_SLOWLY
760A 78 ACCESS1_SLOWLY
761
762 80 fpu_read
763 81 fpu_read aligned 4
764 82 fpu_read aligned 8
765 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000766 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000767
768M 85 fpu_write
769M 86 fpu_write aligned 4
770M 87 fpu_write aligned 8
771M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000772M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000773
774 90 fpu_access
775 91 fpu_access aligned 4
776 92 fpu_access aligned 8
777 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000778 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000779
780 100 fpu_access_check_SLOWLY
781 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000782
783 110 new_mem_stack_4
784 111 new_mem_stack_8
785 112 new_mem_stack_12
786 113 new_mem_stack_16
787 114 new_mem_stack_32
788 115 new_mem_stack
789
790 120 die_mem_stack_4
791 121 die_mem_stack_8
792 122 die_mem_stack_12
793 123 die_mem_stack_16
794 124 die_mem_stack_32
795 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000796*/
797
njn43c799e2003-04-08 00:08:52 +0000798#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000799
njn43c799e2003-04-08 00:08:52 +0000800UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000801
njnb4aee052003-04-15 14:09:58 +0000802static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000803{
804 Int i;
805 for (i = 0; i < N_PROF_EVENTS; i++)
njn43c799e2003-04-08 00:08:52 +0000806 MAC_(event_ctr)[i] = 0;
njn5c004e42002-11-18 11:04:50 +0000807}
808
njnb4aee052003-04-15 14:09:58 +0000809static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000810{
811 Int i;
812 for (i = 0; i < N_PROF_EVENTS; i++) {
813 if ((i % 10) == 0)
814 VG_(printf)("\n");
njn43c799e2003-04-08 00:08:52 +0000815 if (MAC_(event_ctr)[i] > 0)
816 VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] );
njn5c004e42002-11-18 11:04:50 +0000817 }
818 VG_(printf)("\n");
819}
820
821#else
822
njnb4aee052003-04-15 14:09:58 +0000823static void init_prof_mem ( void ) { }
824static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000825
njn5c004e42002-11-18 11:04:50 +0000826#endif
827
828/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000829/*--- Common initialisation + finalisation ---*/
830/*------------------------------------------------------------*/
831
832void MAC_(common_pre_clo_init)(void)
833{
834 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000835 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000836 init_prof_mem();
837}
838
njnb8dca862005-03-14 02:42:44 +0000839void MAC_(common_fini)(void (*leak_check)(ThreadId tid, LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000840{
njn86f12dc2005-03-14 01:16:05 +0000841 MAC_(print_malloc_stats)();
njn3e884182003-04-15 13:03:23 +0000842
843 if (VG_(clo_verbosity) == 1) {
sewardjb5f6f512005-03-10 23:59:00 +0000844 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000845 VG_(message)(Vg_UserMsg,
846 "For a detailed leak analysis, rerun with: --leak-check=yes");
847
848 VG_(message)(Vg_UserMsg,
849 "For counts of detected errors, rerun with: -v");
850 }
sewardjb5f6f512005-03-10 23:59:00 +0000851 if (MAC_(clo_leak_check) != LC_Off)
njnb8dca862005-03-14 02:42:44 +0000852 leak_check(1/*bogus ThreadId*/, MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000853
854 done_prof_mem();
855}
856
857/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000858/*--- Common client request handling ---*/
859/*------------------------------------------------------------*/
860
nethercoted1b64b22004-11-04 18:22:28 +0000861Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000862{
njnd7994182003-10-02 13:44:04 +0000863 Char* err =
864 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
865 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
866 " program to incorporate the updates in the Valgrind header files.\n"
867 " You shouldn't need to change the text of your program at all.\n"
868 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000869
870 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000871 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000872 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000873 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
874 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000875 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000876 *argp[2] = MAC_(bytes_dubious);
877 *argp[3] = MAC_(bytes_reachable);
878 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000879 // there is no argp[5]
880 //*argp[5] = MAC_(bytes_indirect);
881 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000882 *ret = 0;
883 return True;
njn10785452003-05-20 16:38:24 +0000884 }
njnd7994182003-10-02 13:44:04 +0000885 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
886 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000887 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000888
njn10785452003-05-20 16:38:24 +0000889 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000890 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000891 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000892 UInt rzB = arg[3];
893 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000894
sewardj2a99cf62004-11-24 10:44:19 +0000895 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000896 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000897 return True;
898 }
899 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000900 Addr p = (Addr)arg[1];
901 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000902
sewardj2a99cf62004-11-24 10:44:19 +0000903 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000904 return True;
905 }
njnd7994182003-10-02 13:44:04 +0000906
nethercotee3a53722004-05-05 10:46:22 +0000907 case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP:
908 *ret = (Addr)MAC_(record_overlap_error);
909 return True;
910
rjwalshbc0bb832004-06-19 18:12:36 +0000911 case VG_USERREQ__CREATE_MEMPOOL: {
912 Addr pool = (Addr)arg[1];
913 UInt rzB = arg[2];
914 Bool is_zeroed = (Bool)arg[3];
915
916 MAC_(create_mempool) ( pool, rzB, is_zeroed );
917 return True;
918 }
919
920 case VG_USERREQ__DESTROY_MEMPOOL: {
921 Addr pool = (Addr)arg[1];
922
923 MAC_(destroy_mempool) ( pool );
924 return True;
925 }
926
927 case VG_USERREQ__MEMPOOL_ALLOC: {
928 Addr pool = (Addr)arg[1];
929 Addr addr = (Addr)arg[2];
930 UInt size = arg[3];
931
sewardj2a99cf62004-11-24 10:44:19 +0000932 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000933 return True;
934 }
935
936 case VG_USERREQ__MEMPOOL_FREE: {
937 Addr pool = (Addr)arg[1];
938 Addr addr = (Addr)arg[2];
939
940 MAC_(mempool_free) ( pool, addr );
941 return True;
942 }
943
njn47363ab2003-04-21 13:24:40 +0000944 default:
945 return False;
946 }
947}
948
njn5c004e42002-11-18 11:04:50 +0000949/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000950/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000951/*--------------------------------------------------------------------*/