blob: 9594474f1eabbeb36ec6db219851323ae9c77921 [file] [log] [blame]
njn5c004e42002-11-18 11:04:50 +00001
2/*--------------------------------------------------------------------*/
3/*--- Code that is shared between MemCheck and AddrCheck. ---*/
njn00cae242005-05-09 01:13:44 +00004/*--- mac_shared.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
njn51d827b2005-05-09 01:02:08 +0000148Bool MAC_(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
njn16390462005-05-08 15:26:00 +0000167 // Perhaps we should also check the addrinfo.akinds for equality.
168 // That would result in more error reports, but only in cases where
169 // a register contains uninitialised bytes and points to memory
170 // containing uninitialised bytes. Currently, the 2nd of those to be
171 // detected won't be reported. That is (nearly?) always the memory
172 // error, which is good.
njn5c004e42002-11-18 11:04:50 +0000173 case ParamErr:
njn16390462005-05-08 15:26:00 +0000174 if (0 != VG_(strcmp)(VG_(get_error_string)(e1),
175 VG_(get_error_string)(e2))) return False;
176 // fall through
177 case UserErr:
178 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000179 return True;
180
181 case FreeErr:
182 case FreeMismatchErr:
183 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
184 cause excessive duplication of errors. Not even AddrErr
185 below does that. So don't compare either the .addr field
186 or the .addrinfo fields. */
187 /* if (e1->addr != e2->addr) return False; */
188 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
189 return False;
190 */
191 return True;
192
193 case AddrErr:
194 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
195 if (e1_extra->size != e2_extra->size) return False;
196 /*
197 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
198 return False;
199 */
200 return True;
201
202 case ValueErr:
203 if (e1_extra->size != e2_extra->size) return False;
204 return True;
205
njn34419c12003-05-02 17:24:29 +0000206 case OverlapErr:
207 return True;
208
njn43c799e2003-04-08 00:08:52 +0000209 case LeakErr:
njn51d827b2005-05-09 01:02:08 +0000210 VG_(tool_panic)("Shouldn't get LeakErr in MAC_(eq_Error),\n"
njn43c799e2003-04-08 00:08:52 +0000211 "since it's handled with VG_(unique_error)()!");
212
rjwalshbc0bb832004-06-19 18:12:36 +0000213 case IllegalMempoolErr:
214 return True;
215
njn5c004e42002-11-18 11:04:50 +0000216 default:
217 VG_(printf)("Error:\n unknown error code %d\n",
218 VG_(get_error_kind)(e1));
njn51d827b2005-05-09 01:02:08 +0000219 VG_(tool_panic)("unknown error code in MAC_(eq_Error)");
njn5c004e42002-11-18 11:04:50 +0000220 }
221}
222
njn43c799e2003-04-08 00:08:52 +0000223void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000224{
225 switch (ai->akind) {
226 case Stack:
227 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000228 " Address 0x%lx is on thread %d's stack",
229 (ULong)a, ai->stack_tid);
njn5c004e42002-11-18 11:04:50 +0000230 break;
231 case Unknown:
232 if (ai->maybe_gcc) {
233 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000234 " Address 0x%lx is just below %%esp. Possibly a bug in GCC/G++",
235 (ULong)a);
njn5c004e42002-11-18 11:04:50 +0000236 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000237 " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes");
njn5c004e42002-11-18 11:04:50 +0000238 } else {
239 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000240 " Address 0x%lx is not stack'd, malloc'd or (recently) free'd",
241 (ULong)a);
njn5c004e42002-11-18 11:04:50 +0000242 }
243 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000244 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000245 SizeT delta;
sewardjb5f6f512005-03-10 23:59:00 +0000246 const Char* relative;
247 const Char* kind;
rjwalshbc0bb832004-06-19 18:12:36 +0000248 if (ai->akind == Mempool) {
249 kind = "mempool";
250 } else {
251 kind = "block";
252 }
sewardjb5f6f512005-03-10 23:59:00 +0000253 if (ai->desc != NULL)
254 kind = ai->desc;
255
njn5c004e42002-11-18 11:04:50 +0000256 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000257 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000258 relative = "before";
259 } else if (ai->rwoffset >= ai->blksize) {
260 delta = ai->rwoffset - ai->blksize;
261 relative = "after";
262 } else {
263 delta = ai->rwoffset;
264 relative = "inside";
265 }
sewardja81709d2002-12-28 12:55:48 +0000266 VG_(message)(Vg_UserMsg,
tom14ea6852005-05-03 18:16:12 +0000267 " Address 0x%lx is %llu bytes %s a %s of size %d %s",
268 (ULong)a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000269 ai->blksize,
270 ai->akind==Mallocd ? "alloc'd"
271 : ai->akind==Freed ? "free'd"
272 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000273 VG_(pp_ExeContext)(ai->lastchange);
274 break;
275 }
nethercote8b76fe52004-11-08 19:20:09 +0000276 case Register:
277 // print nothing
njnca82cc02004-11-22 17:18:48 +0000278 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000279 break;
njn5c004e42002-11-18 11:04:50 +0000280 default:
njn67993252004-11-22 18:02:32 +0000281 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000282 }
283}
284
285/* This prints out the message for the error types where Memcheck and
286 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000287void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000288{
289 MAC_Error* err_extra = VG_(get_error_extra)(err);
290
291 switch (VG_(get_error_kind)(err)) {
292 case FreeErr:
njn10785452003-05-20 16:38:24 +0000293 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000294 /* fall through */
295 case FreeMismatchErr:
296 if (VG_(get_error_kind)(err) == FreeMismatchErr)
297 VG_(message)(Vg_UserMsg,
298 "Mismatched free() / delete / delete []");
299 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
300 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
301 break;
302
njn89409f82003-09-26 14:55:31 +0000303 case AddrErr:
304 switch (err_extra->axskind) {
305 case ReadAxs:
306 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
307 err_extra->size );
308 break;
309 case WriteAxs:
310 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
311 err_extra->size );
312 break;
313 case ExecAxs:
314 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
315 "stated on the next line");
316 break;
317 default:
njn51d827b2005-05-09 01:02:08 +0000318 VG_(tool_panic)("MAC_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000319 }
320 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
321 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
322 break;
323
njnb6cae9f2003-09-04 20:50:47 +0000324 case OverlapErr: {
325 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
326 if (ov_extra->len == -1)
327 VG_(message)(Vg_UserMsg,
328 "Source and destination overlap in %s(%p, %p)",
329 VG_(get_error_string)(err),
330 ov_extra->dst, ov_extra->src);
331 else
332 VG_(message)(Vg_UserMsg,
333 "Source and destination overlap in %s(%p, %p, %d)",
334 VG_(get_error_string)(err),
335 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000336 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
337 break;
njnb6cae9f2003-09-04 20:50:47 +0000338 }
njn43c799e2003-04-08 00:08:52 +0000339 case LeakErr: {
340 /* Totally abusing the types of these spare fields... oh well. */
njnc6168192004-11-29 13:54:10 +0000341 UInt n_this_record = (UWord)VG_(get_error_address)(err);
342 UInt n_total_records = (UWord)VG_(get_error_string) (err);
njn43c799e2003-04-08 00:08:52 +0000343
344 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
345 break;
346 }
347
rjwalshbc0bb832004-06-19 18:12:36 +0000348 case IllegalMempoolErr:
349 VG_(message)(Vg_UserMsg, "Illegal memory pool address");
350 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
351 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
352 break;
353
njn43c799e2003-04-08 00:08:52 +0000354 default:
355 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
356 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000357 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000358 }
359}
360
361/*------------------------------------------------------------*/
362/*--- Recording errors ---*/
363/*------------------------------------------------------------*/
364
njn43c799e2003-04-08 00:08:52 +0000365/* Additional description function for describe_addr(); used by
366 MemCheck for user blocks, which Addrcheck doesn't support. */
367Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000368
369/* Callback for searching thread stacks */
370static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
371{
372 Addr a = *(Addr *)ap;
373
374 return (stack_min <= a && a <= stack_max);
375}
376
377/* Callback for searching free'd list */
378static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
379{
380 Addr a = *(Addr *)ap;
381
njn717cde52005-05-10 02:47:21 +0000382 return VG_(addr_is_in_block)( a, mc->data, mc->size,
383 MAC_MALLOC_REDZONE_SZB );
thughes4ad52d02004-06-27 17:37:21 +0000384}
385
386/* Callback for searching malloc'd lists */
387static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
388{
389 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
390}
391
njn43c799e2003-04-08 00:08:52 +0000392/* Describe an address as best you can, for error messages,
393 putting the result in ai. */
394static void describe_addr ( Addr a, AddrInfo* ai )
395{
njn3e884182003-04-15 13:03:23 +0000396 MAC_Chunk* sc;
397 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000398
njn43c799e2003-04-08 00:08:52 +0000399 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
400 if (NULL != MAC_(describe_addr_supp)) {
401 if (MAC_(describe_addr_supp)( a, ai ))
402 return;
403 }
404 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000405 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000406 if (tid != VG_INVALID_THREADID) {
407 ai->akind = Stack;
408 ai->stack_tid = tid;
409 return;
410 }
411 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000412 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000413 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000414 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000415 ai->blksize = sc->size;
416 ai->rwoffset = (Int)a - (Int)sc->data;
417 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000418 return;
419 }
420 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000421 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000422 if (NULL != sc) {
423 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000424 ai->blksize = sc->size;
425 ai->rwoffset = (Int)(a) - (Int)sc->data;
426 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000427 return;
428 }
429 /* Clueless ... */
430 ai->akind = Unknown;
431 return;
432}
433
njn5c004e42002-11-18 11:04:50 +0000434/* Is this address within some small distance below %ESP? Used only
435 for the --workaround-gcc296-bugs kludge. */
436static Bool is_just_below_ESP( Addr esp, Addr aa )
437{
nethercote50397c22004-11-04 18:03:06 +0000438 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000439 return True;
440 else
441 return False;
442}
443
sewardjaf48a602003-07-06 00:54:47 +0000444/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000445
njn72718642003-07-24 08:45:32 +0000446void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000447 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000448{
njn43c799e2003-04-08 00:08:52 +0000449 MAC_Error err_extra;
450 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000451
njn67516132005-03-22 04:02:43 +0000452 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
njn5c004e42002-11-18 11:04:50 +0000453
454 /* If this is caused by an access immediately below %ESP, and the
455 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000456 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000457 return;
458
njn43c799e2003-04-08 00:08:52 +0000459 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000460 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
461 err_extra.size = size;
462 err_extra.addrinfo.akind = Undescribed;
463 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000464 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000465}
466
467/* These ones are called from non-generated code */
468
469/* This is for memory errors in pthread functions, as opposed to pthread API
470 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000471void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000472{
njn43c799e2003-04-08 00:08:52 +0000473 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000474
njn43c799e2003-04-08 00:08:52 +0000475 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000476 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000477 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000478}
479
njn16390462005-05-08 15:26:00 +0000480// Three kinds of param errors:
481// - register arg contains undefined bytes
482// - memory arg is unaddressable
483// - memory arg contains undefined bytes
484// 'isReg' and 'isUnaddr' dictate which of these it is.
nethercote8b76fe52004-11-08 19:20:09 +0000485void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
486 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000487{
njn43c799e2003-04-08 00:08:52 +0000488 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000489
njnca82cc02004-11-22 17:18:48 +0000490 tl_assert(VG_INVALID_THREADID != tid);
njn16390462005-05-08 15:26:00 +0000491 if (isUnaddr) tl_assert(!isReg); // unaddressable register is impossible
njn43c799e2003-04-08 00:08:52 +0000492 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000493 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
494 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000495 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000496}
497
njn72718642003-07-24 08:45:32 +0000498void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000499{
njn43c799e2003-04-08 00:08:52 +0000500 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000501
njnca82cc02004-11-22 17:18:48 +0000502 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000503 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000504 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000505 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000506 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000507 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000508}
509
njn72718642003-07-24 08:45:32 +0000510void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000511{
njn43c799e2003-04-08 00:08:52 +0000512 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000513
njnca82cc02004-11-22 17:18:48 +0000514 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000515 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000516 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000517 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000518}
519
rjwalshbc0bb832004-06-19 18:12:36 +0000520void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
521{
522 MAC_Error err_extra;
523
njnca82cc02004-11-22 17:18:48 +0000524 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000525 MAC_(clear_MAC_Error)( &err_extra );
526 err_extra.addrinfo.akind = Undescribed;
527 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
528}
529
njn72718642003-07-24 08:45:32 +0000530void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000531{
njn43c799e2003-04-08 00:08:52 +0000532 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000533
njnca82cc02004-11-22 17:18:48 +0000534 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000535 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000536 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000537 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000538}
539
sewardj2a99cf62004-11-24 10:44:19 +0000540void MAC_(record_overlap_error) ( ThreadId tid,
541 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000542{
sewardj2a99cf62004-11-24 10:44:19 +0000543 VG_(maybe_record_error)(
544 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000545}
546
547
njnb6cae9f2003-09-04 20:50:47 +0000548/* Updates the copy with address info if necessary (but not for all errors). */
njn51d827b2005-05-09 01:02:08 +0000549UInt MAC_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000550{
njnb6cae9f2003-09-04 20:50:47 +0000551 switch (VG_(get_error_kind)(err)) {
552 case ValueErr:
553 case CoreMemErr:
554 case AddrErr:
555 case ParamErr:
556 case UserErr:
557 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000558 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000559 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000560 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000561 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
562 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
563 }
564 return sizeof(MAC_Error);
565 }
njn43c799e2003-04-08 00:08:52 +0000566 /* Don't need to return the correct size -- LeakErrs are always shown with
567 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000568 case LeakErr: return 0;
569 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000570 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000571 }
njn43c799e2003-04-08 00:08:52 +0000572}
573
574
njn5c004e42002-11-18 11:04:50 +0000575/*------------------------------------------------------------*/
576/*--- Suppressions ---*/
577/*------------------------------------------------------------*/
578
njn43c799e2003-04-08 00:08:52 +0000579Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
580{
581 SuppKind skind;
582
583 if (VG_STREQ(name, "Param")) skind = ParamSupp;
584 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
585 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
586 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
587 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
588 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000589 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000590 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
591 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000592 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000593 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000594 else
595 return False;
596
597 VG_(set_supp_kind)(su, skind);
598 return True;
599}
600
njn51d827b2005-05-09 01:02:08 +0000601Bool MAC_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000602{
603 Bool eof;
604
605 if (VG_(get_supp_kind)(su) == ParamSupp) {
606 eof = VG_(get_line) ( fd, buf, nBuf );
607 if (eof) return False;
608 VG_(set_supp_string)(su, VG_(strdup)(buf));
609 }
610 return True;
611}
612
njn51d827b2005-05-09 01:02:08 +0000613Bool MAC_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000614{
sewardj05bcdcb2003-05-18 10:05:38 +0000615 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000616 MAC_Error* err_extra = VG_(get_error_extra)(err);
617 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000618
619 switch (VG_(get_supp_kind)(su)) {
620 case ParamSupp:
621 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000622 && VG_STREQ(VG_(get_error_string)(err),
623 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000624
625 case CoreMemSupp:
626 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000627 && VG_STREQ(VG_(get_error_string)(err),
628 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000629
630 case Value0Supp: su_size = 0; goto value_case;
631 case Value1Supp: su_size = 1; goto value_case;
632 case Value2Supp: su_size = 2; goto value_case;
633 case Value4Supp: su_size = 4; goto value_case;
634 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000635 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000636 value_case:
637 return (ekind == ValueErr && err_extra->size == su_size);
638
639 case Addr1Supp: su_size = 1; goto addr_case;
640 case Addr2Supp: su_size = 2; goto addr_case;
641 case Addr4Supp: su_size = 4; goto addr_case;
642 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000643 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000644 addr_case:
645 return (ekind == AddrErr && err_extra->size == su_size);
646
647 case FreeSupp:
648 return (ekind == FreeErr || ekind == FreeMismatchErr);
649
njn34419c12003-05-02 17:24:29 +0000650 case OverlapSupp:
651 return (ekind = OverlapErr);
652
sewardj4a19e2f2002-12-26 11:50:21 +0000653 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000654 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000655
rjwalshbc0bb832004-06-19 18:12:36 +0000656 case MempoolSupp:
657 return (ekind == IllegalMempoolErr);
658
njn5c004e42002-11-18 11:04:50 +0000659 default:
660 VG_(printf)("Error:\n"
661 " unknown suppression type %d\n",
662 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000663 VG_(tool_panic)("unknown suppression type in "
njn51d827b2005-05-09 01:02:08 +0000664 "MAC_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000665 }
666}
667
njn51d827b2005-05-09 01:02:08 +0000668Char* MAC_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000669{
670 Char* s;
671 switch (VG_(get_error_kind)(err)) {
672 case ParamErr: return "Param";
673 case UserErr: return NULL; /* Can't suppress User errors */
674 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000675 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000676 case FreeErr: return "Free";
677 case AddrErr:
678 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
679 case 1: return "Addr1";
680 case 2: return "Addr2";
681 case 4: return "Addr4";
682 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000683 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000684 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000685 }
686
687 case ValueErr:
688 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
689 case 0: return "Cond";
690 case 1: return "Value1";
691 case 2: return "Value2";
692 case 4: return "Value4";
693 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000694 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000695 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000696 }
697 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000698 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000699 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000700 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000701 }
702 VG_(printf)(s);
703}
704
njn51d827b2005-05-09 01:02:08 +0000705void MAC_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000706{
707 if (ParamErr == VG_(get_error_kind)(err)) {
708 VG_(printf)(" %s\n", VG_(get_error_string)(err));
709 }
710}
njn5c004e42002-11-18 11:04:50 +0000711
712/*------------------------------------------------------------*/
713/*--- Crude profiling machinery. ---*/
714/*------------------------------------------------------------*/
715
716/* Event index. If just the name of the fn is given, this means the
717 number of calls to the fn. Otherwise it is the specified event.
718 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
719 The rest are shared.
720
721 10 alloc_secondary_map
722
723 20 get_abit
724M 21 get_vbyte
725 22 set_abit
726M 23 set_vbyte
727 24 get_abits4_ALIGNED
728M 25 get_vbytes4_ALIGNED
729
730 30 set_address_range_perms
731 31 set_address_range_perms(lower byte loop)
732 32 set_address_range_perms(quadword loop)
733 33 set_address_range_perms(upper byte loop)
734
735 35 make_noaccess
736 36 make_writable
737 37 make_readable
738A 38 make_accessible
739
740 40 copy_address_range_state
741 41 copy_address_range_state(byte loop)
742 42 check_writable
743 43 check_writable(byte loop)
744 44 check_readable
745 45 check_readable(byte loop)
746 46 check_readable_asciiz
747 47 check_readable_asciiz(byte loop)
748A 48 check_accessible
749A 49 check_accessible(byte loop)
750
751 50 make_noaccess_aligned
752 51 make_writable_aligned
753
754M 60 helperc_LOADV4
755M 61 helperc_STOREV4
756M 62 helperc_LOADV2
757M 63 helperc_STOREV2
758M 64 helperc_LOADV1
759M 65 helperc_STOREV1
760
761A 66 helperc_ACCESS4
762A 67 helperc_ACCESS2
763A 68 helperc_ACCESS1
764
765M 70 rim_rd_V4_SLOWLY
766M 71 rim_wr_V4_SLOWLY
767M 72 rim_rd_V2_SLOWLY
768M 73 rim_wr_V2_SLOWLY
769M 74 rim_rd_V1_SLOWLY
770M 75 rim_wr_V1_SLOWLY
771
772A 76 ACCESS4_SLOWLY
773A 77 ACCESS2_SLOWLY
774A 78 ACCESS1_SLOWLY
775
776 80 fpu_read
777 81 fpu_read aligned 4
778 82 fpu_read aligned 8
779 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000780 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000781
782M 85 fpu_write
783M 86 fpu_write aligned 4
784M 87 fpu_write aligned 8
785M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000786M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000787
788 90 fpu_access
789 91 fpu_access aligned 4
790 92 fpu_access aligned 8
791 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000792 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000793
794 100 fpu_access_check_SLOWLY
795 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000796
797 110 new_mem_stack_4
798 111 new_mem_stack_8
799 112 new_mem_stack_12
800 113 new_mem_stack_16
801 114 new_mem_stack_32
802 115 new_mem_stack
803
804 120 die_mem_stack_4
805 121 die_mem_stack_8
806 122 die_mem_stack_12
807 123 die_mem_stack_16
808 124 die_mem_stack_32
809 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000810*/
811
njn43c799e2003-04-08 00:08:52 +0000812#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000813
sewardjc1a2cda2005-04-21 17:34:00 +0000814UInt MAC_(event_ctr)[N_PROF_EVENTS];
815HChar* MAC_(event_ctr_name)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000816
njnb4aee052003-04-15 14:09:58 +0000817static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000818{
819 Int i;
sewardjc1a2cda2005-04-21 17:34:00 +0000820 for (i = 0; i < N_PROF_EVENTS; i++) {
njn43c799e2003-04-08 00:08:52 +0000821 MAC_(event_ctr)[i] = 0;
sewardjc1a2cda2005-04-21 17:34:00 +0000822 MAC_(event_ctr_name)[i] = NULL;
823 }
njn5c004e42002-11-18 11:04:50 +0000824}
825
njnb4aee052003-04-15 14:09:58 +0000826static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000827{
sewardjc1a2cda2005-04-21 17:34:00 +0000828 Int i;
829 Bool spaced = False;
njn5c004e42002-11-18 11:04:50 +0000830 for (i = 0; i < N_PROF_EVENTS; i++) {
sewardjc1a2cda2005-04-21 17:34:00 +0000831 if (!spaced && (i % 10) == 0) {
njn5c004e42002-11-18 11:04:50 +0000832 VG_(printf)("\n");
sewardjc1a2cda2005-04-21 17:34:00 +0000833 spaced = True;
834 }
835 if (MAC_(event_ctr)[i] > 0) {
836 spaced = False;
837 VG_(printf)( "prof mem event %3d: %9d %s\n",
838 i, MAC_(event_ctr)[i],
839 MAC_(event_ctr_name)[i]
840 ? MAC_(event_ctr_name)[i] : "unnamed");
841 }
njn5c004e42002-11-18 11:04:50 +0000842 }
njn5c004e42002-11-18 11:04:50 +0000843}
844
845#else
846
njnb4aee052003-04-15 14:09:58 +0000847static void init_prof_mem ( void ) { }
848static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000849
njn5c004e42002-11-18 11:04:50 +0000850#endif
851
852/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000853/*--- Common initialisation + finalisation ---*/
854/*------------------------------------------------------------*/
855
856void MAC_(common_pre_clo_init)(void)
857{
858 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000859 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000860 init_prof_mem();
861}
862
njnb8dca862005-03-14 02:42:44 +0000863void MAC_(common_fini)(void (*leak_check)(ThreadId tid, LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000864{
njn86f12dc2005-03-14 01:16:05 +0000865 MAC_(print_malloc_stats)();
njn3e884182003-04-15 13:03:23 +0000866
867 if (VG_(clo_verbosity) == 1) {
sewardjb5f6f512005-03-10 23:59:00 +0000868 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000869 VG_(message)(Vg_UserMsg,
870 "For a detailed leak analysis, rerun with: --leak-check=yes");
871
872 VG_(message)(Vg_UserMsg,
873 "For counts of detected errors, rerun with: -v");
874 }
sewardjb5f6f512005-03-10 23:59:00 +0000875 if (MAC_(clo_leak_check) != LC_Off)
njnb8dca862005-03-14 02:42:44 +0000876 leak_check(1/*bogus ThreadId*/, MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000877
878 done_prof_mem();
879}
880
881/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000882/*--- Common client request handling ---*/
883/*------------------------------------------------------------*/
884
nethercoted1b64b22004-11-04 18:22:28 +0000885Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000886{
njnd7994182003-10-02 13:44:04 +0000887 Char* err =
888 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
889 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
890 " program to incorporate the updates in the Valgrind header files.\n"
891 " You shouldn't need to change the text of your program at all.\n"
892 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000893
894 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000895 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000896 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000897 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
898 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000899 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000900 *argp[2] = MAC_(bytes_dubious);
901 *argp[3] = MAC_(bytes_reachable);
902 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000903 // there is no argp[5]
904 //*argp[5] = MAC_(bytes_indirect);
905 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000906 *ret = 0;
907 return True;
njn10785452003-05-20 16:38:24 +0000908 }
njnd7994182003-10-02 13:44:04 +0000909 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
910 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000911 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000912
njn10785452003-05-20 16:38:24 +0000913 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000914 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000915 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000916 UInt rzB = arg[3];
917 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000918
sewardj2a99cf62004-11-24 10:44:19 +0000919 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000920 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000921 return True;
922 }
923 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000924 Addr p = (Addr)arg[1];
925 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000926
sewardj2a99cf62004-11-24 10:44:19 +0000927 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000928 return True;
929 }
njnd7994182003-10-02 13:44:04 +0000930
njn1f8b3e72005-03-22 04:27:14 +0000931 case _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR: {
932 Char* s = (Char*) arg[1];
933 OverlapExtra* extra = (OverlapExtra*)arg[2];
934 MAC_(record_overlap_error)(tid, s, extra);
nethercotee3a53722004-05-05 10:46:22 +0000935 return True;
njn1f8b3e72005-03-22 04:27:14 +0000936 }
nethercotee3a53722004-05-05 10:46:22 +0000937
rjwalshbc0bb832004-06-19 18:12:36 +0000938 case VG_USERREQ__CREATE_MEMPOOL: {
939 Addr pool = (Addr)arg[1];
940 UInt rzB = arg[2];
941 Bool is_zeroed = (Bool)arg[3];
942
943 MAC_(create_mempool) ( pool, rzB, is_zeroed );
944 return True;
945 }
946
947 case VG_USERREQ__DESTROY_MEMPOOL: {
948 Addr pool = (Addr)arg[1];
949
950 MAC_(destroy_mempool) ( pool );
951 return True;
952 }
953
954 case VG_USERREQ__MEMPOOL_ALLOC: {
955 Addr pool = (Addr)arg[1];
956 Addr addr = (Addr)arg[2];
957 UInt size = arg[3];
958
sewardj2a99cf62004-11-24 10:44:19 +0000959 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000960 return True;
961 }
962
963 case VG_USERREQ__MEMPOOL_FREE: {
964 Addr pool = (Addr)arg[1];
965 Addr addr = (Addr)arg[2];
966
967 MAC_(mempool_free) ( pool, addr );
968 return True;
969 }
970
njn47363ab2003-04-21 13:24:40 +0000971 default:
972 return False;
973 }
974}
975
njn5c004e42002-11-18 11:04:50 +0000976/*--------------------------------------------------------------------*/
njn00cae242005-05-09 01:13:44 +0000977/*--- end ---*/
njn5c004e42002-11-18 11:04:50 +0000978/*--------------------------------------------------------------------*/