blob: 032ca4dfb240f713320aff1c58a9bb66f87cf999 [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
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:
njn26f02512004-11-22 18:33:15 +0000210 VG_(tool_panic)("Shouldn't get LeakErr in TL_(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));
njn26f02512004-11-22 18:33:15 +0000219 VG_(tool_panic)("unknown error code in TL_(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:
njn26f02512004-11-22 18:33:15 +0000318 VG_(tool_panic)("TL_(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
382 return VG_(addr_is_in_block)( a, mc->data, mc->size );
383}
384
385/* Callback for searching malloc'd lists */
386static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
387{
388 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
389}
390
njn43c799e2003-04-08 00:08:52 +0000391/* Describe an address as best you can, for error messages,
392 putting the result in ai. */
393static void describe_addr ( Addr a, AddrInfo* ai )
394{
njn3e884182003-04-15 13:03:23 +0000395 MAC_Chunk* sc;
396 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000397
njn43c799e2003-04-08 00:08:52 +0000398 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
399 if (NULL != MAC_(describe_addr_supp)) {
400 if (MAC_(describe_addr_supp)( a, ai ))
401 return;
402 }
403 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000404 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000405 if (tid != VG_INVALID_THREADID) {
406 ai->akind = Stack;
407 ai->stack_tid = tid;
408 return;
409 }
410 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000411 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000412 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000413 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000414 ai->blksize = sc->size;
415 ai->rwoffset = (Int)a - (Int)sc->data;
416 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000417 return;
418 }
419 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000420 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000421 if (NULL != sc) {
422 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000423 ai->blksize = sc->size;
424 ai->rwoffset = (Int)(a) - (Int)sc->data;
425 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000426 return;
427 }
428 /* Clueless ... */
429 ai->akind = Unknown;
430 return;
431}
432
njn5c004e42002-11-18 11:04:50 +0000433/* Is this address within some small distance below %ESP? Used only
434 for the --workaround-gcc296-bugs kludge. */
435static Bool is_just_below_ESP( Addr esp, Addr aa )
436{
nethercote50397c22004-11-04 18:03:06 +0000437 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000438 return True;
439 else
440 return False;
441}
442
sewardjaf48a602003-07-06 00:54:47 +0000443/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000444
njn72718642003-07-24 08:45:32 +0000445void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000446 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000447{
njn43c799e2003-04-08 00:08:52 +0000448 MAC_Error err_extra;
449 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000450
njn67516132005-03-22 04:02:43 +0000451 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
njn5c004e42002-11-18 11:04:50 +0000452
453 /* If this is caused by an access immediately below %ESP, and the
454 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000455 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000456 return;
457
njn43c799e2003-04-08 00:08:52 +0000458 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000459 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
460 err_extra.size = size;
461 err_extra.addrinfo.akind = Undescribed;
462 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000463 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000464}
465
466/* These ones are called from non-generated code */
467
468/* This is for memory errors in pthread functions, as opposed to pthread API
469 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000470void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000471{
njn43c799e2003-04-08 00:08:52 +0000472 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000473
njn43c799e2003-04-08 00:08:52 +0000474 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000475 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000476 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000477}
478
njn16390462005-05-08 15:26:00 +0000479// Three kinds of param errors:
480// - register arg contains undefined bytes
481// - memory arg is unaddressable
482// - memory arg contains undefined bytes
483// 'isReg' and 'isUnaddr' dictate which of these it is.
nethercote8b76fe52004-11-08 19:20:09 +0000484void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
485 Bool isUnaddr, Char* msg )
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);
njn16390462005-05-08 15:26:00 +0000490 if (isUnaddr) tl_assert(!isReg); // unaddressable register is impossible
njn43c799e2003-04-08 00:08:52 +0000491 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000492 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
493 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000494 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000495}
496
njn72718642003-07-24 08:45:32 +0000497void MAC_(record_jump_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.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000504 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000505 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000506 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000507}
508
njn72718642003-07-24 08:45:32 +0000509void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000510{
njn43c799e2003-04-08 00:08:52 +0000511 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000512
njnca82cc02004-11-22 17:18:48 +0000513 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000514 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000515 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000516 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000517}
518
rjwalshbc0bb832004-06-19 18:12:36 +0000519void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
520{
521 MAC_Error err_extra;
522
njnca82cc02004-11-22 17:18:48 +0000523 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000524 MAC_(clear_MAC_Error)( &err_extra );
525 err_extra.addrinfo.akind = Undescribed;
526 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
527}
528
njn72718642003-07-24 08:45:32 +0000529void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000530{
njn43c799e2003-04-08 00:08:52 +0000531 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000532
njnca82cc02004-11-22 17:18:48 +0000533 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000534 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000535 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000536 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000537}
538
sewardj2a99cf62004-11-24 10:44:19 +0000539void MAC_(record_overlap_error) ( ThreadId tid,
540 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000541{
sewardj2a99cf62004-11-24 10:44:19 +0000542 VG_(maybe_record_error)(
543 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000544}
545
546
njnb6cae9f2003-09-04 20:50:47 +0000547/* Updates the copy with address info if necessary (but not for all errors). */
njn26f02512004-11-22 18:33:15 +0000548UInt TL_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000549{
njnb6cae9f2003-09-04 20:50:47 +0000550 switch (VG_(get_error_kind)(err)) {
551 case ValueErr:
552 case CoreMemErr:
553 case AddrErr:
554 case ParamErr:
555 case UserErr:
556 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000557 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000558 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000559 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000560 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
561 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
562 }
563 return sizeof(MAC_Error);
564 }
njn43c799e2003-04-08 00:08:52 +0000565 /* Don't need to return the correct size -- LeakErrs are always shown with
566 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000567 case LeakErr: return 0;
568 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000569 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000570 }
njn43c799e2003-04-08 00:08:52 +0000571}
572
573
njn5c004e42002-11-18 11:04:50 +0000574/*------------------------------------------------------------*/
575/*--- Suppressions ---*/
576/*------------------------------------------------------------*/
577
njn43c799e2003-04-08 00:08:52 +0000578Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
579{
580 SuppKind skind;
581
582 if (VG_STREQ(name, "Param")) skind = ParamSupp;
583 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
584 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
585 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
586 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
587 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000588 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000589 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
590 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000591 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000592 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000593 else
594 return False;
595
596 VG_(set_supp_kind)(su, skind);
597 return True;
598}
599
njn26f02512004-11-22 18:33:15 +0000600Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000601{
602 Bool eof;
603
604 if (VG_(get_supp_kind)(su) == ParamSupp) {
605 eof = VG_(get_line) ( fd, buf, nBuf );
606 if (eof) return False;
607 VG_(set_supp_string)(su, VG_(strdup)(buf));
608 }
609 return True;
610}
611
njn26f02512004-11-22 18:33:15 +0000612Bool TL_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000613{
sewardj05bcdcb2003-05-18 10:05:38 +0000614 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000615 MAC_Error* err_extra = VG_(get_error_extra)(err);
616 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000617
618 switch (VG_(get_supp_kind)(su)) {
619 case ParamSupp:
620 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000621 && VG_STREQ(VG_(get_error_string)(err),
622 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000623
624 case CoreMemSupp:
625 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000626 && VG_STREQ(VG_(get_error_string)(err),
627 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000628
629 case Value0Supp: su_size = 0; goto value_case;
630 case Value1Supp: su_size = 1; goto value_case;
631 case Value2Supp: su_size = 2; goto value_case;
632 case Value4Supp: su_size = 4; goto value_case;
633 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000634 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000635 value_case:
636 return (ekind == ValueErr && err_extra->size == su_size);
637
638 case Addr1Supp: su_size = 1; goto addr_case;
639 case Addr2Supp: su_size = 2; goto addr_case;
640 case Addr4Supp: su_size = 4; goto addr_case;
641 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000642 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000643 addr_case:
644 return (ekind == AddrErr && err_extra->size == su_size);
645
646 case FreeSupp:
647 return (ekind == FreeErr || ekind == FreeMismatchErr);
648
njn34419c12003-05-02 17:24:29 +0000649 case OverlapSupp:
650 return (ekind = OverlapErr);
651
sewardj4a19e2f2002-12-26 11:50:21 +0000652 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000653 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000654
rjwalshbc0bb832004-06-19 18:12:36 +0000655 case MempoolSupp:
656 return (ekind == IllegalMempoolErr);
657
njn5c004e42002-11-18 11:04:50 +0000658 default:
659 VG_(printf)("Error:\n"
660 " unknown suppression type %d\n",
661 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000662 VG_(tool_panic)("unknown suppression type in "
njn26f02512004-11-22 18:33:15 +0000663 "TL_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000664 }
665}
666
njn26f02512004-11-22 18:33:15 +0000667Char* TL_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000668{
669 Char* s;
670 switch (VG_(get_error_kind)(err)) {
671 case ParamErr: return "Param";
672 case UserErr: return NULL; /* Can't suppress User errors */
673 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000674 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000675 case FreeErr: return "Free";
676 case AddrErr:
677 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
678 case 1: return "Addr1";
679 case 2: return "Addr2";
680 case 4: return "Addr4";
681 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000682 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000683 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000684 }
685
686 case ValueErr:
687 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
688 case 0: return "Cond";
689 case 1: return "Value1";
690 case 2: return "Value2";
691 case 4: return "Value4";
692 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000693 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000694 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000695 }
696 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000697 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000698 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000699 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000700 }
701 VG_(printf)(s);
702}
703
njn26f02512004-11-22 18:33:15 +0000704void TL_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000705{
706 if (ParamErr == VG_(get_error_kind)(err)) {
707 VG_(printf)(" %s\n", VG_(get_error_string)(err));
708 }
709}
njn5c004e42002-11-18 11:04:50 +0000710
711/*------------------------------------------------------------*/
712/*--- Crude profiling machinery. ---*/
713/*------------------------------------------------------------*/
714
715/* Event index. If just the name of the fn is given, this means the
716 number of calls to the fn. Otherwise it is the specified event.
717 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
718 The rest are shared.
719
720 10 alloc_secondary_map
721
722 20 get_abit
723M 21 get_vbyte
724 22 set_abit
725M 23 set_vbyte
726 24 get_abits4_ALIGNED
727M 25 get_vbytes4_ALIGNED
728
729 30 set_address_range_perms
730 31 set_address_range_perms(lower byte loop)
731 32 set_address_range_perms(quadword loop)
732 33 set_address_range_perms(upper byte loop)
733
734 35 make_noaccess
735 36 make_writable
736 37 make_readable
737A 38 make_accessible
738
739 40 copy_address_range_state
740 41 copy_address_range_state(byte loop)
741 42 check_writable
742 43 check_writable(byte loop)
743 44 check_readable
744 45 check_readable(byte loop)
745 46 check_readable_asciiz
746 47 check_readable_asciiz(byte loop)
747A 48 check_accessible
748A 49 check_accessible(byte loop)
749
750 50 make_noaccess_aligned
751 51 make_writable_aligned
752
753M 60 helperc_LOADV4
754M 61 helperc_STOREV4
755M 62 helperc_LOADV2
756M 63 helperc_STOREV2
757M 64 helperc_LOADV1
758M 65 helperc_STOREV1
759
760A 66 helperc_ACCESS4
761A 67 helperc_ACCESS2
762A 68 helperc_ACCESS1
763
764M 70 rim_rd_V4_SLOWLY
765M 71 rim_wr_V4_SLOWLY
766M 72 rim_rd_V2_SLOWLY
767M 73 rim_wr_V2_SLOWLY
768M 74 rim_rd_V1_SLOWLY
769M 75 rim_wr_V1_SLOWLY
770
771A 76 ACCESS4_SLOWLY
772A 77 ACCESS2_SLOWLY
773A 78 ACCESS1_SLOWLY
774
775 80 fpu_read
776 81 fpu_read aligned 4
777 82 fpu_read aligned 8
778 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000779 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000780
781M 85 fpu_write
782M 86 fpu_write aligned 4
783M 87 fpu_write aligned 8
784M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000785M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000786
787 90 fpu_access
788 91 fpu_access aligned 4
789 92 fpu_access aligned 8
790 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000791 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000792
793 100 fpu_access_check_SLOWLY
794 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000795
796 110 new_mem_stack_4
797 111 new_mem_stack_8
798 112 new_mem_stack_12
799 113 new_mem_stack_16
800 114 new_mem_stack_32
801 115 new_mem_stack
802
803 120 die_mem_stack_4
804 121 die_mem_stack_8
805 122 die_mem_stack_12
806 123 die_mem_stack_16
807 124 die_mem_stack_32
808 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000809*/
810
njn43c799e2003-04-08 00:08:52 +0000811#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000812
sewardjc1a2cda2005-04-21 17:34:00 +0000813UInt MAC_(event_ctr)[N_PROF_EVENTS];
814HChar* MAC_(event_ctr_name)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000815
njnb4aee052003-04-15 14:09:58 +0000816static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000817{
818 Int i;
sewardjc1a2cda2005-04-21 17:34:00 +0000819 for (i = 0; i < N_PROF_EVENTS; i++) {
njn43c799e2003-04-08 00:08:52 +0000820 MAC_(event_ctr)[i] = 0;
sewardjc1a2cda2005-04-21 17:34:00 +0000821 MAC_(event_ctr_name)[i] = NULL;
822 }
njn5c004e42002-11-18 11:04:50 +0000823}
824
njnb4aee052003-04-15 14:09:58 +0000825static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000826{
sewardjc1a2cda2005-04-21 17:34:00 +0000827 Int i;
828 Bool spaced = False;
njn5c004e42002-11-18 11:04:50 +0000829 for (i = 0; i < N_PROF_EVENTS; i++) {
sewardjc1a2cda2005-04-21 17:34:00 +0000830 if (!spaced && (i % 10) == 0) {
njn5c004e42002-11-18 11:04:50 +0000831 VG_(printf)("\n");
sewardjc1a2cda2005-04-21 17:34:00 +0000832 spaced = True;
833 }
834 if (MAC_(event_ctr)[i] > 0) {
835 spaced = False;
836 VG_(printf)( "prof mem event %3d: %9d %s\n",
837 i, MAC_(event_ctr)[i],
838 MAC_(event_ctr_name)[i]
839 ? MAC_(event_ctr_name)[i] : "unnamed");
840 }
njn5c004e42002-11-18 11:04:50 +0000841 }
njn5c004e42002-11-18 11:04:50 +0000842}
843
844#else
845
njnb4aee052003-04-15 14:09:58 +0000846static void init_prof_mem ( void ) { }
847static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000848
njn5c004e42002-11-18 11:04:50 +0000849#endif
850
851/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000852/*--- Common initialisation + finalisation ---*/
853/*------------------------------------------------------------*/
854
855void MAC_(common_pre_clo_init)(void)
856{
857 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000858 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000859 init_prof_mem();
860}
861
njnb8dca862005-03-14 02:42:44 +0000862void MAC_(common_fini)(void (*leak_check)(ThreadId tid, LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000863{
njn86f12dc2005-03-14 01:16:05 +0000864 MAC_(print_malloc_stats)();
njn3e884182003-04-15 13:03:23 +0000865
866 if (VG_(clo_verbosity) == 1) {
sewardjb5f6f512005-03-10 23:59:00 +0000867 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000868 VG_(message)(Vg_UserMsg,
869 "For a detailed leak analysis, rerun with: --leak-check=yes");
870
871 VG_(message)(Vg_UserMsg,
872 "For counts of detected errors, rerun with: -v");
873 }
sewardjb5f6f512005-03-10 23:59:00 +0000874 if (MAC_(clo_leak_check) != LC_Off)
njnb8dca862005-03-14 02:42:44 +0000875 leak_check(1/*bogus ThreadId*/, MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000876
877 done_prof_mem();
878}
879
880/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000881/*--- Common client request handling ---*/
882/*------------------------------------------------------------*/
883
nethercoted1b64b22004-11-04 18:22:28 +0000884Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000885{
njnd7994182003-10-02 13:44:04 +0000886 Char* err =
887 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
888 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
889 " program to incorporate the updates in the Valgrind header files.\n"
890 " You shouldn't need to change the text of your program at all.\n"
891 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000892
893 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000894 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000895 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000896 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
897 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000898 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000899 *argp[2] = MAC_(bytes_dubious);
900 *argp[3] = MAC_(bytes_reachable);
901 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000902 // there is no argp[5]
903 //*argp[5] = MAC_(bytes_indirect);
904 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000905 *ret = 0;
906 return True;
njn10785452003-05-20 16:38:24 +0000907 }
njnd7994182003-10-02 13:44:04 +0000908 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
909 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000910 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000911
njn10785452003-05-20 16:38:24 +0000912 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000913 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000914 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000915 UInt rzB = arg[3];
916 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000917
sewardj2a99cf62004-11-24 10:44:19 +0000918 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000919 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000920 return True;
921 }
922 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000923 Addr p = (Addr)arg[1];
924 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000925
sewardj2a99cf62004-11-24 10:44:19 +0000926 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000927 return True;
928 }
njnd7994182003-10-02 13:44:04 +0000929
njn1f8b3e72005-03-22 04:27:14 +0000930 case _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR: {
931 Char* s = (Char*) arg[1];
932 OverlapExtra* extra = (OverlapExtra*)arg[2];
933 MAC_(record_overlap_error)(tid, s, extra);
nethercotee3a53722004-05-05 10:46:22 +0000934 return True;
njn1f8b3e72005-03-22 04:27:14 +0000935 }
nethercotee3a53722004-05-05 10:46:22 +0000936
rjwalshbc0bb832004-06-19 18:12:36 +0000937 case VG_USERREQ__CREATE_MEMPOOL: {
938 Addr pool = (Addr)arg[1];
939 UInt rzB = arg[2];
940 Bool is_zeroed = (Bool)arg[3];
941
942 MAC_(create_mempool) ( pool, rzB, is_zeroed );
943 return True;
944 }
945
946 case VG_USERREQ__DESTROY_MEMPOOL: {
947 Addr pool = (Addr)arg[1];
948
949 MAC_(destroy_mempool) ( pool );
950 return True;
951 }
952
953 case VG_USERREQ__MEMPOOL_ALLOC: {
954 Addr pool = (Addr)arg[1];
955 Addr addr = (Addr)arg[2];
956 UInt size = arg[3];
957
sewardj2a99cf62004-11-24 10:44:19 +0000958 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000959 return True;
960 }
961
962 case VG_USERREQ__MEMPOOL_FREE: {
963 Addr pool = (Addr)arg[1];
964 Addr addr = (Addr)arg[2];
965
966 MAC_(mempool_free) ( pool, addr );
967 return True;
968 }
969
njn47363ab2003-04-21 13:24:40 +0000970 default:
971 return False;
972 }
973}
974
njn5c004e42002-11-18 11:04:50 +0000975/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000976/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000977/*--------------------------------------------------------------------*/