blob: 60264cd64a284149346aa783ae195703ed6cfe29 [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{
njn45270a22005-03-27 01:00:11 +000059 VG_BOOL_CLO(arg, "--partial-loads-ok", MAC_(clo_partial_loads_ok))
60 else VG_BOOL_CLO(arg, "--show-reachable", MAC_(clo_show_reachable))
61 else VG_BOOL_CLO(arg, "--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
nethercote27fec902004-06-16 21:26:32 +000062
njn45270a22005-03-27 01:00:11 +000063 else VG_BNUM_CLO(arg, "--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
nethercote27fec902004-06-16 21:26:32 +000064
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,
tom14ea6852005-05-03 18:16:12 +0000222 " Address 0x%lx is on thread %d's stack",
223 (ULong)a, ai->stack_tid);
njn5c004e42002-11-18 11:04:50 +0000224 break;
225 case Unknown:
226 if (ai->maybe_gcc) {
227 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000228 " Address 0x%lx is just below %%esp. Possibly a bug in GCC/G++",
229 (ULong)a);
njn5c004e42002-11-18 11:04:50 +0000230 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,
tom14ea6852005-05-03 18:16:12 +0000234 " Address 0x%lx is not stack'd, malloc'd or (recently) free'd",
235 (ULong)a);
njn5c004e42002-11-18 11:04:50 +0000236 }
237 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000238 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000239 SizeT delta;
sewardjb5f6f512005-03-10 23:59:00 +0000240 const Char* relative;
241 const Char* kind;
rjwalshbc0bb832004-06-19 18:12:36 +0000242 if (ai->akind == Mempool) {
243 kind = "mempool";
244 } else {
245 kind = "block";
246 }
sewardjb5f6f512005-03-10 23:59:00 +0000247 if (ai->desc != NULL)
248 kind = ai->desc;
249
njn5c004e42002-11-18 11:04:50 +0000250 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000251 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000252 relative = "before";
253 } else if (ai->rwoffset >= ai->blksize) {
254 delta = ai->rwoffset - ai->blksize;
255 relative = "after";
256 } else {
257 delta = ai->rwoffset;
258 relative = "inside";
259 }
sewardja81709d2002-12-28 12:55:48 +0000260 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000261 " Address 0x%lx is %llu bytes %s a %s of size %d %s",
262 (ULong)a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000263 ai->blksize,
264 ai->akind==Mallocd ? "alloc'd"
265 : ai->akind==Freed ? "free'd"
266 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000267 VG_(pp_ExeContext)(ai->lastchange);
268 break;
269 }
nethercote8b76fe52004-11-08 19:20:09 +0000270 case Register:
271 // print nothing
njnca82cc02004-11-22 17:18:48 +0000272 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000273 break;
njn5c004e42002-11-18 11:04:50 +0000274 default:
njn67993252004-11-22 18:02:32 +0000275 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000276 }
277}
278
279/* This prints out the message for the error types where Memcheck and
280 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000281void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000282{
283 MAC_Error* err_extra = VG_(get_error_extra)(err);
284
285 switch (VG_(get_error_kind)(err)) {
286 case FreeErr:
njn10785452003-05-20 16:38:24 +0000287 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000288 /* fall through */
289 case FreeMismatchErr:
290 if (VG_(get_error_kind)(err) == FreeMismatchErr)
291 VG_(message)(Vg_UserMsg,
292 "Mismatched free() / delete / delete []");
293 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
294 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
295 break;
296
njn89409f82003-09-26 14:55:31 +0000297 case AddrErr:
298 switch (err_extra->axskind) {
299 case ReadAxs:
300 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
301 err_extra->size );
302 break;
303 case WriteAxs:
304 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
305 err_extra->size );
306 break;
307 case ExecAxs:
308 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
309 "stated on the next line");
310 break;
311 default:
njn26f02512004-11-22 18:33:15 +0000312 VG_(tool_panic)("TL_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000313 }
314 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
315 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
316 break;
317
njnb6cae9f2003-09-04 20:50:47 +0000318 case OverlapErr: {
319 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
320 if (ov_extra->len == -1)
321 VG_(message)(Vg_UserMsg,
322 "Source and destination overlap in %s(%p, %p)",
323 VG_(get_error_string)(err),
324 ov_extra->dst, ov_extra->src);
325 else
326 VG_(message)(Vg_UserMsg,
327 "Source and destination overlap in %s(%p, %p, %d)",
328 VG_(get_error_string)(err),
329 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000330 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
331 break;
njnb6cae9f2003-09-04 20:50:47 +0000332 }
njn43c799e2003-04-08 00:08:52 +0000333 case LeakErr: {
334 /* Totally abusing the types of these spare fields... oh well. */
njnc6168192004-11-29 13:54:10 +0000335 UInt n_this_record = (UWord)VG_(get_error_address)(err);
336 UInt n_total_records = (UWord)VG_(get_error_string) (err);
njn43c799e2003-04-08 00:08:52 +0000337
338 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
339 break;
340 }
341
rjwalshbc0bb832004-06-19 18:12:36 +0000342 case IllegalMempoolErr:
343 VG_(message)(Vg_UserMsg, "Illegal memory pool address");
344 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
345 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
346 break;
347
njn43c799e2003-04-08 00:08:52 +0000348 default:
349 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
350 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000351 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000352 }
353}
354
355/*------------------------------------------------------------*/
356/*--- Recording errors ---*/
357/*------------------------------------------------------------*/
358
njn43c799e2003-04-08 00:08:52 +0000359/* Additional description function for describe_addr(); used by
360 MemCheck for user blocks, which Addrcheck doesn't support. */
361Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000362
363/* Callback for searching thread stacks */
364static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
365{
366 Addr a = *(Addr *)ap;
367
368 return (stack_min <= a && a <= stack_max);
369}
370
371/* Callback for searching free'd list */
372static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
373{
374 Addr a = *(Addr *)ap;
375
376 return VG_(addr_is_in_block)( a, mc->data, mc->size );
377}
378
379/* Callback for searching malloc'd lists */
380static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
381{
382 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
383}
384
njn43c799e2003-04-08 00:08:52 +0000385/* Describe an address as best you can, for error messages,
386 putting the result in ai. */
387static void describe_addr ( Addr a, AddrInfo* ai )
388{
njn3e884182003-04-15 13:03:23 +0000389 MAC_Chunk* sc;
390 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000391
njn43c799e2003-04-08 00:08:52 +0000392 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
393 if (NULL != MAC_(describe_addr_supp)) {
394 if (MAC_(describe_addr_supp)( a, ai ))
395 return;
396 }
397 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000398 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000399 if (tid != VG_INVALID_THREADID) {
400 ai->akind = Stack;
401 ai->stack_tid = tid;
402 return;
403 }
404 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000405 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000406 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000407 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000408 ai->blksize = sc->size;
409 ai->rwoffset = (Int)a - (Int)sc->data;
410 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000411 return;
412 }
413 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000414 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000415 if (NULL != sc) {
416 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000417 ai->blksize = sc->size;
418 ai->rwoffset = (Int)(a) - (Int)sc->data;
419 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000420 return;
421 }
422 /* Clueless ... */
423 ai->akind = Unknown;
424 return;
425}
426
njn5c004e42002-11-18 11:04:50 +0000427/* Is this address within some small distance below %ESP? Used only
428 for the --workaround-gcc296-bugs kludge. */
429static Bool is_just_below_ESP( Addr esp, Addr aa )
430{
nethercote50397c22004-11-04 18:03:06 +0000431 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000432 return True;
433 else
434 return False;
435}
436
sewardjaf48a602003-07-06 00:54:47 +0000437/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000438
njn72718642003-07-24 08:45:32 +0000439void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000440 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000441{
njn43c799e2003-04-08 00:08:52 +0000442 MAC_Error err_extra;
443 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000444
njn67516132005-03-22 04:02:43 +0000445 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
njn5c004e42002-11-18 11:04:50 +0000446
447 /* If this is caused by an access immediately below %ESP, and the
448 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000449 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000450 return;
451
njn43c799e2003-04-08 00:08:52 +0000452 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000453 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
454 err_extra.size = size;
455 err_extra.addrinfo.akind = Undescribed;
456 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000457 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000458}
459
460/* These ones are called from non-generated code */
461
462/* This is for memory errors in pthread functions, as opposed to pthread API
463 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000464void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000465{
njn43c799e2003-04-08 00:08:52 +0000466 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000467
njn43c799e2003-04-08 00:08:52 +0000468 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000469 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000470 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000471}
472
nethercote8b76fe52004-11-08 19:20:09 +0000473void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
474 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000475{
njn43c799e2003-04-08 00:08:52 +0000476 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000477
njnca82cc02004-11-22 17:18:48 +0000478 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000479 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000480 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
481 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000482 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000483}
484
njn72718642003-07-24 08:45:32 +0000485void MAC_(record_jump_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.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000492 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000493 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000494 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000495}
496
njn72718642003-07-24 08:45:32 +0000497void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000498{
njn43c799e2003-04-08 00:08:52 +0000499 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000500
njnca82cc02004-11-22 17:18:48 +0000501 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000502 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000503 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000504 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000505}
506
rjwalshbc0bb832004-06-19 18:12:36 +0000507void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
508{
509 MAC_Error err_extra;
510
njnca82cc02004-11-22 17:18:48 +0000511 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000512 MAC_(clear_MAC_Error)( &err_extra );
513 err_extra.addrinfo.akind = Undescribed;
514 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
515}
516
njn72718642003-07-24 08:45:32 +0000517void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000518{
njn43c799e2003-04-08 00:08:52 +0000519 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000520
njnca82cc02004-11-22 17:18:48 +0000521 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000522 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000523 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000524 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000525}
526
sewardj2a99cf62004-11-24 10:44:19 +0000527void MAC_(record_overlap_error) ( ThreadId tid,
528 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000529{
sewardj2a99cf62004-11-24 10:44:19 +0000530 VG_(maybe_record_error)(
531 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000532}
533
534
njnb6cae9f2003-09-04 20:50:47 +0000535/* Updates the copy with address info if necessary (but not for all errors). */
njn26f02512004-11-22 18:33:15 +0000536UInt TL_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000537{
njnb6cae9f2003-09-04 20:50:47 +0000538 switch (VG_(get_error_kind)(err)) {
539 case ValueErr:
540 case CoreMemErr:
541 case AddrErr:
542 case ParamErr:
543 case UserErr:
544 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000545 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000546 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000547 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000548 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
549 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
550 }
551 return sizeof(MAC_Error);
552 }
njn43c799e2003-04-08 00:08:52 +0000553 /* Don't need to return the correct size -- LeakErrs are always shown with
554 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000555 case LeakErr: return 0;
556 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000557 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000558 }
njn43c799e2003-04-08 00:08:52 +0000559}
560
561
njn5c004e42002-11-18 11:04:50 +0000562/*------------------------------------------------------------*/
563/*--- Suppressions ---*/
564/*------------------------------------------------------------*/
565
njn43c799e2003-04-08 00:08:52 +0000566Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
567{
568 SuppKind skind;
569
570 if (VG_STREQ(name, "Param")) skind = ParamSupp;
571 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
572 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
573 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
574 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
575 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000576 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000577 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
578 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000579 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000580 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000581 else
582 return False;
583
584 VG_(set_supp_kind)(su, skind);
585 return True;
586}
587
njn26f02512004-11-22 18:33:15 +0000588Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000589{
590 Bool eof;
591
592 if (VG_(get_supp_kind)(su) == ParamSupp) {
593 eof = VG_(get_line) ( fd, buf, nBuf );
594 if (eof) return False;
595 VG_(set_supp_string)(su, VG_(strdup)(buf));
596 }
597 return True;
598}
599
njn26f02512004-11-22 18:33:15 +0000600Bool TL_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000601{
sewardj05bcdcb2003-05-18 10:05:38 +0000602 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000603 MAC_Error* err_extra = VG_(get_error_extra)(err);
604 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000605
606 switch (VG_(get_supp_kind)(su)) {
607 case ParamSupp:
608 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000609 && VG_STREQ(VG_(get_error_string)(err),
610 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000611
612 case CoreMemSupp:
613 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000614 && VG_STREQ(VG_(get_error_string)(err),
615 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000616
617 case Value0Supp: su_size = 0; goto value_case;
618 case Value1Supp: su_size = 1; goto value_case;
619 case Value2Supp: su_size = 2; goto value_case;
620 case Value4Supp: su_size = 4; goto value_case;
621 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000622 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000623 value_case:
624 return (ekind == ValueErr && err_extra->size == su_size);
625
626 case Addr1Supp: su_size = 1; goto addr_case;
627 case Addr2Supp: su_size = 2; goto addr_case;
628 case Addr4Supp: su_size = 4; goto addr_case;
629 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000630 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000631 addr_case:
632 return (ekind == AddrErr && err_extra->size == su_size);
633
634 case FreeSupp:
635 return (ekind == FreeErr || ekind == FreeMismatchErr);
636
njn34419c12003-05-02 17:24:29 +0000637 case OverlapSupp:
638 return (ekind = OverlapErr);
639
sewardj4a19e2f2002-12-26 11:50:21 +0000640 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000641 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000642
rjwalshbc0bb832004-06-19 18:12:36 +0000643 case MempoolSupp:
644 return (ekind == IllegalMempoolErr);
645
njn5c004e42002-11-18 11:04:50 +0000646 default:
647 VG_(printf)("Error:\n"
648 " unknown suppression type %d\n",
649 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000650 VG_(tool_panic)("unknown suppression type in "
njn26f02512004-11-22 18:33:15 +0000651 "TL_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000652 }
653}
654
njn26f02512004-11-22 18:33:15 +0000655Char* TL_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000656{
657 Char* s;
658 switch (VG_(get_error_kind)(err)) {
659 case ParamErr: return "Param";
660 case UserErr: return NULL; /* Can't suppress User errors */
661 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000662 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000663 case FreeErr: return "Free";
664 case AddrErr:
665 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
666 case 1: return "Addr1";
667 case 2: return "Addr2";
668 case 4: return "Addr4";
669 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000670 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000671 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000672 }
673
674 case ValueErr:
675 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
676 case 0: return "Cond";
677 case 1: return "Value1";
678 case 2: return "Value2";
679 case 4: return "Value4";
680 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000681 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000682 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000683 }
684 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000685 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000686 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000687 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000688 }
689 VG_(printf)(s);
690}
691
njn26f02512004-11-22 18:33:15 +0000692void TL_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000693{
694 if (ParamErr == VG_(get_error_kind)(err)) {
695 VG_(printf)(" %s\n", VG_(get_error_string)(err));
696 }
697}
njn5c004e42002-11-18 11:04:50 +0000698
699/*------------------------------------------------------------*/
700/*--- Crude profiling machinery. ---*/
701/*------------------------------------------------------------*/
702
703/* Event index. If just the name of the fn is given, this means the
704 number of calls to the fn. Otherwise it is the specified event.
705 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
706 The rest are shared.
707
708 10 alloc_secondary_map
709
710 20 get_abit
711M 21 get_vbyte
712 22 set_abit
713M 23 set_vbyte
714 24 get_abits4_ALIGNED
715M 25 get_vbytes4_ALIGNED
716
717 30 set_address_range_perms
718 31 set_address_range_perms(lower byte loop)
719 32 set_address_range_perms(quadword loop)
720 33 set_address_range_perms(upper byte loop)
721
722 35 make_noaccess
723 36 make_writable
724 37 make_readable
725A 38 make_accessible
726
727 40 copy_address_range_state
728 41 copy_address_range_state(byte loop)
729 42 check_writable
730 43 check_writable(byte loop)
731 44 check_readable
732 45 check_readable(byte loop)
733 46 check_readable_asciiz
734 47 check_readable_asciiz(byte loop)
735A 48 check_accessible
736A 49 check_accessible(byte loop)
737
738 50 make_noaccess_aligned
739 51 make_writable_aligned
740
741M 60 helperc_LOADV4
742M 61 helperc_STOREV4
743M 62 helperc_LOADV2
744M 63 helperc_STOREV2
745M 64 helperc_LOADV1
746M 65 helperc_STOREV1
747
748A 66 helperc_ACCESS4
749A 67 helperc_ACCESS2
750A 68 helperc_ACCESS1
751
752M 70 rim_rd_V4_SLOWLY
753M 71 rim_wr_V4_SLOWLY
754M 72 rim_rd_V2_SLOWLY
755M 73 rim_wr_V2_SLOWLY
756M 74 rim_rd_V1_SLOWLY
757M 75 rim_wr_V1_SLOWLY
758
759A 76 ACCESS4_SLOWLY
760A 77 ACCESS2_SLOWLY
761A 78 ACCESS1_SLOWLY
762
763 80 fpu_read
764 81 fpu_read aligned 4
765 82 fpu_read aligned 8
766 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000767 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000768
769M 85 fpu_write
770M 86 fpu_write aligned 4
771M 87 fpu_write aligned 8
772M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000773M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000774
775 90 fpu_access
776 91 fpu_access aligned 4
777 92 fpu_access aligned 8
778 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000779 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000780
781 100 fpu_access_check_SLOWLY
782 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000783
784 110 new_mem_stack_4
785 111 new_mem_stack_8
786 112 new_mem_stack_12
787 113 new_mem_stack_16
788 114 new_mem_stack_32
789 115 new_mem_stack
790
791 120 die_mem_stack_4
792 121 die_mem_stack_8
793 122 die_mem_stack_12
794 123 die_mem_stack_16
795 124 die_mem_stack_32
796 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000797*/
798
njn43c799e2003-04-08 00:08:52 +0000799#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000800
sewardjc1a2cda2005-04-21 17:34:00 +0000801UInt MAC_(event_ctr)[N_PROF_EVENTS];
802HChar* MAC_(event_ctr_name)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000803
njnb4aee052003-04-15 14:09:58 +0000804static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000805{
806 Int i;
sewardjc1a2cda2005-04-21 17:34:00 +0000807 for (i = 0; i < N_PROF_EVENTS; i++) {
njn43c799e2003-04-08 00:08:52 +0000808 MAC_(event_ctr)[i] = 0;
sewardjc1a2cda2005-04-21 17:34:00 +0000809 MAC_(event_ctr_name)[i] = NULL;
810 }
njn5c004e42002-11-18 11:04:50 +0000811}
812
njnb4aee052003-04-15 14:09:58 +0000813static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000814{
sewardjc1a2cda2005-04-21 17:34:00 +0000815 Int i;
816 Bool spaced = False;
njn5c004e42002-11-18 11:04:50 +0000817 for (i = 0; i < N_PROF_EVENTS; i++) {
sewardjc1a2cda2005-04-21 17:34:00 +0000818 if (!spaced && (i % 10) == 0) {
njn5c004e42002-11-18 11:04:50 +0000819 VG_(printf)("\n");
sewardjc1a2cda2005-04-21 17:34:00 +0000820 spaced = True;
821 }
822 if (MAC_(event_ctr)[i] > 0) {
823 spaced = False;
824 VG_(printf)( "prof mem event %3d: %9d %s\n",
825 i, MAC_(event_ctr)[i],
826 MAC_(event_ctr_name)[i]
827 ? MAC_(event_ctr_name)[i] : "unnamed");
828 }
njn5c004e42002-11-18 11:04:50 +0000829 }
njn5c004e42002-11-18 11:04:50 +0000830}
831
832#else
833
njnb4aee052003-04-15 14:09:58 +0000834static void init_prof_mem ( void ) { }
835static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000836
njn5c004e42002-11-18 11:04:50 +0000837#endif
838
839/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000840/*--- Common initialisation + finalisation ---*/
841/*------------------------------------------------------------*/
842
843void MAC_(common_pre_clo_init)(void)
844{
845 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000846 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000847 init_prof_mem();
848}
849
njnb8dca862005-03-14 02:42:44 +0000850void MAC_(common_fini)(void (*leak_check)(ThreadId tid, LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000851{
njn86f12dc2005-03-14 01:16:05 +0000852 MAC_(print_malloc_stats)();
njn3e884182003-04-15 13:03:23 +0000853
854 if (VG_(clo_verbosity) == 1) {
sewardjb5f6f512005-03-10 23:59:00 +0000855 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000856 VG_(message)(Vg_UserMsg,
857 "For a detailed leak analysis, rerun with: --leak-check=yes");
858
859 VG_(message)(Vg_UserMsg,
860 "For counts of detected errors, rerun with: -v");
861 }
sewardjb5f6f512005-03-10 23:59:00 +0000862 if (MAC_(clo_leak_check) != LC_Off)
njnb8dca862005-03-14 02:42:44 +0000863 leak_check(1/*bogus ThreadId*/, MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000864
865 done_prof_mem();
866}
867
868/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000869/*--- Common client request handling ---*/
870/*------------------------------------------------------------*/
871
nethercoted1b64b22004-11-04 18:22:28 +0000872Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000873{
njnd7994182003-10-02 13:44:04 +0000874 Char* err =
875 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
876 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
877 " program to incorporate the updates in the Valgrind header files.\n"
878 " You shouldn't need to change the text of your program at all.\n"
879 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000880
881 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000882 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000883 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000884 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
885 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000886 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000887 *argp[2] = MAC_(bytes_dubious);
888 *argp[3] = MAC_(bytes_reachable);
889 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000890 // there is no argp[5]
891 //*argp[5] = MAC_(bytes_indirect);
892 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000893 *ret = 0;
894 return True;
njn10785452003-05-20 16:38:24 +0000895 }
njnd7994182003-10-02 13:44:04 +0000896 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
897 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000898 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000899
njn10785452003-05-20 16:38:24 +0000900 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000901 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000902 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000903 UInt rzB = arg[3];
904 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000905
sewardj2a99cf62004-11-24 10:44:19 +0000906 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000907 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000908 return True;
909 }
910 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000911 Addr p = (Addr)arg[1];
912 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000913
sewardj2a99cf62004-11-24 10:44:19 +0000914 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000915 return True;
916 }
njnd7994182003-10-02 13:44:04 +0000917
njn1f8b3e72005-03-22 04:27:14 +0000918 case _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR: {
919 Char* s = (Char*) arg[1];
920 OverlapExtra* extra = (OverlapExtra*)arg[2];
921 MAC_(record_overlap_error)(tid, s, extra);
nethercotee3a53722004-05-05 10:46:22 +0000922 return True;
njn1f8b3e72005-03-22 04:27:14 +0000923 }
nethercotee3a53722004-05-05 10:46:22 +0000924
rjwalshbc0bb832004-06-19 18:12:36 +0000925 case VG_USERREQ__CREATE_MEMPOOL: {
926 Addr pool = (Addr)arg[1];
927 UInt rzB = arg[2];
928 Bool is_zeroed = (Bool)arg[3];
929
930 MAC_(create_mempool) ( pool, rzB, is_zeroed );
931 return True;
932 }
933
934 case VG_USERREQ__DESTROY_MEMPOOL: {
935 Addr pool = (Addr)arg[1];
936
937 MAC_(destroy_mempool) ( pool );
938 return True;
939 }
940
941 case VG_USERREQ__MEMPOOL_ALLOC: {
942 Addr pool = (Addr)arg[1];
943 Addr addr = (Addr)arg[2];
944 UInt size = arg[3];
945
sewardj2a99cf62004-11-24 10:44:19 +0000946 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000947 return True;
948 }
949
950 case VG_USERREQ__MEMPOOL_FREE: {
951 Addr pool = (Addr)arg[1];
952 Addr addr = (Addr)arg[2];
953
954 MAC_(mempool_free) ( pool, addr );
955 return True;
956 }
957
njn47363ab2003-04-21 13:24:40 +0000958 default:
959 return False;
960 }
961}
962
njn5c004e42002-11-18 11:04:50 +0000963/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000964/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000965/*--------------------------------------------------------------------*/