blob: 7342460c7a9c02c881a1e0ad11ddc41b3a4d28fb [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;
52LeakCheckMode MAC_(clo_leak_check) = LC_Off;
53VgRes MAC_(clo_leak_resolution) = Vg_LowRes;
54Bool MAC_(clo_show_reachable) = False;
55Bool MAC_(clo_workaround_gcc296_bugs) = False;
njn5c004e42002-11-18 11:04:50 +000056
njn43c799e2003-04-08 00:08:52 +000057Bool MAC_(process_common_cmd_line_option)(Char* arg)
njn5c004e42002-11-18 11:04:50 +000058{
sewardjb5f6f512005-03-10 23:59:00 +000059 VG_BOOL_CLO("--partial-loads-ok", MAC_(clo_partial_loads_ok))
nethercote27fec902004-06-16 21:26:32 +000060 else VG_BOOL_CLO("--show-reachable", MAC_(clo_show_reachable))
61 else VG_BOOL_CLO("--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
62
63 else VG_BNUM_CLO("--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
64
sewardjb5f6f512005-03-10 23:59:00 +000065 else if (VG_CLO_STREQ(arg, "--leak-check=no"))
66 MAC_(clo_leak_check) = LC_Off;
67 else if (VG_CLO_STREQ(arg, "--leak-check=summary"))
68 MAC_(clo_leak_check) = LC_Summary;
69 else if (VG_CLO_STREQ(arg, "--leak-check=yes") ||
70 VG_CLO_STREQ(arg, "--leak-check=full"))
71 MAC_(clo_leak_check) = LC_Full;
72
njn43c799e2003-04-08 00:08:52 +000073 else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
74 MAC_(clo_leak_resolution) = Vg_LowRes;
75 else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
76 MAC_(clo_leak_resolution) = Vg_MedRes;
77 else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
78 MAC_(clo_leak_resolution) = Vg_HighRes;
njn5c004e42002-11-18 11:04:50 +000079
80 else
njn3e884182003-04-15 13:03:23 +000081 return VG_(replacement_malloc_process_cmd_line_option)(arg);
njn5c004e42002-11-18 11:04:50 +000082
83 return True;
njn43c799e2003-04-08 00:08:52 +000084}
njn5c004e42002-11-18 11:04:50 +000085
njn3e884182003-04-15 13:03:23 +000086void MAC_(print_common_usage)(void)
njn43c799e2003-04-08 00:08:52 +000087{
njn3e884182003-04-15 13:03:23 +000088 VG_(printf)(
sewardjb5f6f512005-03-10 23:59:00 +000089" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n"
90" --freelist-vol=<number> volume of freed blocks queue [1000000]\n"
91" --leak-check=no|summary|full search for memory leaks at exit? [no]\n"
92" --leak-resolution=low|med|high how much bt merging in leak check [low]\n"
93" --show-reachable=no|yes show reachable blocks in leak check? [no]\n"
njn3e884182003-04-15 13:03:23 +000094" --workaround-gcc296-bugs=no|yes self explanatory [no]\n"
95 );
96 VG_(replacement_malloc_print_usage)();
njn43c799e2003-04-08 00:08:52 +000097}
98
njn3e884182003-04-15 13:03:23 +000099void MAC_(print_common_debug_usage)(void)
njn43c799e2003-04-08 00:08:52 +0000100{
njn3e884182003-04-15 13:03:23 +0000101 VG_(replacement_malloc_print_debug_usage)();
njn5c004e42002-11-18 11:04:50 +0000102}
103
104/*------------------------------------------------------------*/
105/*--- Comparing and printing errors ---*/
106/*------------------------------------------------------------*/
107
108static __inline__
109void clear_AddrInfo ( AddrInfo* ai )
110{
111 ai->akind = Unknown;
112 ai->blksize = 0;
113 ai->rwoffset = 0;
114 ai->lastchange = NULL;
115 ai->stack_tid = VG_INVALID_THREADID;
116 ai->maybe_gcc = False;
sewardjb5f6f512005-03-10 23:59:00 +0000117 ai->desc = NULL;
njn5c004e42002-11-18 11:04:50 +0000118}
119
njn43c799e2003-04-08 00:08:52 +0000120void MAC_(clear_MAC_Error) ( MAC_Error* err_extra )
njn5c004e42002-11-18 11:04:50 +0000121{
122 err_extra->axskind = ReadAxs;
123 err_extra->size = 0;
124 clear_AddrInfo ( &err_extra->addrinfo );
nethercote8b76fe52004-11-08 19:20:09 +0000125 err_extra->isUnaddr = True;
njn5c004e42002-11-18 11:04:50 +0000126}
127
128__attribute__ ((unused))
129static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
130{
131 if (ai1->akind != Undescribed
132 && ai2->akind != Undescribed
133 && ai1->akind != ai2->akind)
134 return False;
135 if (ai1->akind == Freed || ai1->akind == Mallocd) {
136 if (ai1->blksize != ai2->blksize)
137 return False;
138 if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
139 return False;
140 }
141 return True;
142}
143
144/* Compare error contexts, to detect duplicates. Note that if they
145 are otherwise the same, the faulting addrs and associated rwoffsets
146 are allowed to be different. */
147
njn26f02512004-11-22 18:33:15 +0000148Bool TL_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
njn5c004e42002-11-18 11:04:50 +0000149{
njn43c799e2003-04-08 00:08:52 +0000150 MAC_Error* e1_extra = VG_(get_error_extra)(e1);
151 MAC_Error* e2_extra = VG_(get_error_extra)(e2);
njn7cc53a82002-11-19 16:19:32 +0000152
153 /* Guaranteed by calling function */
njnca82cc02004-11-22 17:18:48 +0000154 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
njn5c004e42002-11-18 11:04:50 +0000155
156 switch (VG_(get_error_kind)(e1)) {
157 case CoreMemErr: {
158 Char *e1s, *e2s;
nethercote8b76fe52004-11-08 19:20:09 +0000159 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000160 e1s = VG_(get_error_string)(e1);
161 e2s = VG_(get_error_string)(e2);
162 if (e1s == e2s) return True;
163 if (0 == VG_(strcmp)(e1s, e2s)) return True;
164 return False;
165 }
166
167 case UserErr:
168 case ParamErr:
nethercote8b76fe52004-11-08 19:20:09 +0000169 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000170 if (VG_(get_error_kind)(e1) == ParamErr
171 && 0 != VG_(strcmp)(VG_(get_error_string)(e1),
172 VG_(get_error_string)(e2))) return False;
173 return True;
174
175 case FreeErr:
176 case FreeMismatchErr:
177 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
178 cause excessive duplication of errors. Not even AddrErr
179 below does that. So don't compare either the .addr field
180 or the .addrinfo fields. */
181 /* if (e1->addr != e2->addr) return False; */
182 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
183 return False;
184 */
185 return True;
186
187 case AddrErr:
188 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
189 if (e1_extra->size != e2_extra->size) return False;
190 /*
191 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
192 return False;
193 */
194 return True;
195
196 case ValueErr:
197 if (e1_extra->size != e2_extra->size) return False;
198 return True;
199
njn34419c12003-05-02 17:24:29 +0000200 case OverlapErr:
201 return True;
202
njn43c799e2003-04-08 00:08:52 +0000203 case LeakErr:
njn26f02512004-11-22 18:33:15 +0000204 VG_(tool_panic)("Shouldn't get LeakErr in TL_(eq_Error),\n"
njn43c799e2003-04-08 00:08:52 +0000205 "since it's handled with VG_(unique_error)()!");
206
rjwalshbc0bb832004-06-19 18:12:36 +0000207 case IllegalMempoolErr:
208 return True;
209
njn5c004e42002-11-18 11:04:50 +0000210 default:
211 VG_(printf)("Error:\n unknown error code %d\n",
212 VG_(get_error_kind)(e1));
njn26f02512004-11-22 18:33:15 +0000213 VG_(tool_panic)("unknown error code in TL_(eq_Error)");
njn5c004e42002-11-18 11:04:50 +0000214 }
215}
216
njn43c799e2003-04-08 00:08:52 +0000217void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000218{
219 switch (ai->akind) {
220 case Stack:
221 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000222 " Address 0x%x is on thread %d's stack",
njn5c004e42002-11-18 11:04:50 +0000223 a, ai->stack_tid);
224 break;
225 case Unknown:
226 if (ai->maybe_gcc) {
227 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000228 " Address 0x%x is just below %%esp. Possibly a bug in GCC/G++",
njn5c004e42002-11-18 11:04:50 +0000229 a);
230 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000231 " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes");
njn5c004e42002-11-18 11:04:50 +0000232 } else {
233 VG_(message)(Vg_UserMsg,
nethercotef798eee2004-04-13 08:36:35 +0000234 " Address 0x%x is not stack'd, malloc'd or (recently) free'd",a);
njn5c004e42002-11-18 11:04:50 +0000235 }
236 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000237 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000238 SizeT delta;
sewardjb5f6f512005-03-10 23:59:00 +0000239 const Char* relative;
240 const Char* kind;
rjwalshbc0bb832004-06-19 18:12:36 +0000241 if (ai->akind == Mempool) {
242 kind = "mempool";
243 } else {
244 kind = "block";
245 }
sewardjb5f6f512005-03-10 23:59:00 +0000246 if (ai->desc != NULL)
247 kind = ai->desc;
248
njn5c004e42002-11-18 11:04:50 +0000249 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000250 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000251 relative = "before";
252 } else if (ai->rwoffset >= ai->blksize) {
253 delta = ai->rwoffset - ai->blksize;
254 relative = "after";
255 } else {
256 delta = ai->rwoffset;
257 relative = "inside";
258 }
sewardja81709d2002-12-28 12:55:48 +0000259 VG_(message)(Vg_UserMsg,
nethercote50397c22004-11-04 18:03:06 +0000260 " Address 0x%x is %llu bytes %s a %s of size %d %s",
261 a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000262 ai->blksize,
263 ai->akind==Mallocd ? "alloc'd"
264 : ai->akind==Freed ? "free'd"
265 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000266 VG_(pp_ExeContext)(ai->lastchange);
267 break;
268 }
nethercote8b76fe52004-11-08 19:20:09 +0000269 case Register:
270 // print nothing
njnca82cc02004-11-22 17:18:48 +0000271 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000272 break;
njn5c004e42002-11-18 11:04:50 +0000273 default:
njn67993252004-11-22 18:02:32 +0000274 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000275 }
276}
277
278/* This prints out the message for the error types where Memcheck and
279 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000280void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000281{
282 MAC_Error* err_extra = VG_(get_error_extra)(err);
283
284 switch (VG_(get_error_kind)(err)) {
285 case FreeErr:
njn10785452003-05-20 16:38:24 +0000286 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000287 /* fall through */
288 case FreeMismatchErr:
289 if (VG_(get_error_kind)(err) == FreeMismatchErr)
290 VG_(message)(Vg_UserMsg,
291 "Mismatched free() / delete / delete []");
292 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
293 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
294 break;
295
njn89409f82003-09-26 14:55:31 +0000296 case AddrErr:
297 switch (err_extra->axskind) {
298 case ReadAxs:
299 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
300 err_extra->size );
301 break;
302 case WriteAxs:
303 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
304 err_extra->size );
305 break;
306 case ExecAxs:
307 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
308 "stated on the next line");
309 break;
310 default:
njn26f02512004-11-22 18:33:15 +0000311 VG_(tool_panic)("TL_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000312 }
313 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
314 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
315 break;
316
njnb6cae9f2003-09-04 20:50:47 +0000317 case OverlapErr: {
318 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
319 if (ov_extra->len == -1)
320 VG_(message)(Vg_UserMsg,
321 "Source and destination overlap in %s(%p, %p)",
322 VG_(get_error_string)(err),
323 ov_extra->dst, ov_extra->src);
324 else
325 VG_(message)(Vg_UserMsg,
326 "Source and destination overlap in %s(%p, %p, %d)",
327 VG_(get_error_string)(err),
328 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000329 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
330 break;
njnb6cae9f2003-09-04 20:50:47 +0000331 }
njn43c799e2003-04-08 00:08:52 +0000332 case LeakErr: {
333 /* Totally abusing the types of these spare fields... oh well. */
njnc6168192004-11-29 13:54:10 +0000334 UInt n_this_record = (UWord)VG_(get_error_address)(err);
335 UInt n_total_records = (UWord)VG_(get_error_string) (err);
njn43c799e2003-04-08 00:08:52 +0000336
337 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
338 break;
339 }
340
rjwalshbc0bb832004-06-19 18:12:36 +0000341 case IllegalMempoolErr:
342 VG_(message)(Vg_UserMsg, "Illegal memory pool address");
343 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
344 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
345 break;
346
njn43c799e2003-04-08 00:08:52 +0000347 default:
348 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
349 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000350 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000351 }
352}
353
354/*------------------------------------------------------------*/
355/*--- Recording errors ---*/
356/*------------------------------------------------------------*/
357
njn43c799e2003-04-08 00:08:52 +0000358/* Additional description function for describe_addr(); used by
359 MemCheck for user blocks, which Addrcheck doesn't support. */
360Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000361
362/* Callback for searching thread stacks */
363static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
364{
365 Addr a = *(Addr *)ap;
366
367 return (stack_min <= a && a <= stack_max);
368}
369
370/* Callback for searching free'd list */
371static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
372{
373 Addr a = *(Addr *)ap;
374
375 return VG_(addr_is_in_block)( a, mc->data, mc->size );
376}
377
378/* Callback for searching malloc'd lists */
379static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
380{
381 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
382}
383
njn43c799e2003-04-08 00:08:52 +0000384/* Describe an address as best you can, for error messages,
385 putting the result in ai. */
386static void describe_addr ( Addr a, AddrInfo* ai )
387{
njn3e884182003-04-15 13:03:23 +0000388 MAC_Chunk* sc;
389 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000390
njn43c799e2003-04-08 00:08:52 +0000391 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
392 if (NULL != MAC_(describe_addr_supp)) {
393 if (MAC_(describe_addr_supp)( a, ai ))
394 return;
395 }
396 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000397 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000398 if (tid != VG_INVALID_THREADID) {
399 ai->akind = Stack;
400 ai->stack_tid = tid;
401 return;
402 }
403 /* Search for a recently freed block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000404 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
njn3e884182003-04-15 13:03:23 +0000405 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000406 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000407 ai->blksize = sc->size;
408 ai->rwoffset = (Int)a - (Int)sc->data;
409 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000410 return;
411 }
412 /* Search for a currently malloc'd block which might bracket it. */
thughes4ad52d02004-06-27 17:37:21 +0000413 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
njn43c799e2003-04-08 00:08:52 +0000414 if (NULL != sc) {
415 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000416 ai->blksize = sc->size;
417 ai->rwoffset = (Int)(a) - (Int)sc->data;
418 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000419 return;
420 }
421 /* Clueless ... */
422 ai->akind = Unknown;
423 return;
424}
425
njn5c004e42002-11-18 11:04:50 +0000426/* Is this address within some small distance below %ESP? Used only
427 for the --workaround-gcc296-bugs kludge. */
428static Bool is_just_below_ESP( Addr esp, Addr aa )
429{
nethercote50397c22004-11-04 18:03:06 +0000430 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000431 return True;
432 else
433 return False;
434}
435
sewardjaf48a602003-07-06 00:54:47 +0000436/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000437
njn72718642003-07-24 08:45:32 +0000438void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000439 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000440{
njn43c799e2003-04-08 00:08:52 +0000441 MAC_Error err_extra;
442 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000443
sewardj2a99cf62004-11-24 10:44:19 +0000444 just_below_esp = is_just_below_ESP(
445 VG_(get_stack_pointer)(tid),
446 a
447 );
njn5c004e42002-11-18 11:04:50 +0000448
449 /* If this is caused by an access immediately below %ESP, and the
450 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000451 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000452 return;
453
njn43c799e2003-04-08 00:08:52 +0000454 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000455 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
456 err_extra.size = size;
457 err_extra.addrinfo.akind = Undescribed;
458 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000459 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000460}
461
462/* These ones are called from non-generated code */
463
464/* This is for memory errors in pthread functions, as opposed to pthread API
465 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000466void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000467{
njn43c799e2003-04-08 00:08:52 +0000468 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000469
njn43c799e2003-04-08 00:08:52 +0000470 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000471 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000472 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000473}
474
nethercote8b76fe52004-11-08 19:20:09 +0000475void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
476 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000477{
njn43c799e2003-04-08 00:08:52 +0000478 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000479
njnca82cc02004-11-22 17:18:48 +0000480 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000481 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000482 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
483 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000484 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000485}
486
njn72718642003-07-24 08:45:32 +0000487void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000488{
njn43c799e2003-04-08 00:08:52 +0000489 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000490
njnca82cc02004-11-22 17:18:48 +0000491 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000492 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000493 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000494 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000495 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000496 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000497}
498
njn72718642003-07-24 08:45:32 +0000499void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000500{
njn43c799e2003-04-08 00:08:52 +0000501 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000502
njnca82cc02004-11-22 17:18:48 +0000503 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000504 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000505 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000506 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000507}
508
rjwalshbc0bb832004-06-19 18:12:36 +0000509void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
510{
511 MAC_Error err_extra;
512
njnca82cc02004-11-22 17:18:48 +0000513 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000514 MAC_(clear_MAC_Error)( &err_extra );
515 err_extra.addrinfo.akind = Undescribed;
516 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
517}
518
njn72718642003-07-24 08:45:32 +0000519void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000520{
njn43c799e2003-04-08 00:08:52 +0000521 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000522
njnca82cc02004-11-22 17:18:48 +0000523 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000524 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000525 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000526 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000527}
528
sewardj2a99cf62004-11-24 10:44:19 +0000529void MAC_(record_overlap_error) ( ThreadId tid,
530 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000531{
sewardj2a99cf62004-11-24 10:44:19 +0000532 VG_(maybe_record_error)(
533 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000534}
535
536
njnb6cae9f2003-09-04 20:50:47 +0000537/* Updates the copy with address info if necessary (but not for all errors). */
njn26f02512004-11-22 18:33:15 +0000538UInt TL_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000539{
njnb6cae9f2003-09-04 20:50:47 +0000540 switch (VG_(get_error_kind)(err)) {
541 case ValueErr:
542 case CoreMemErr:
543 case AddrErr:
544 case ParamErr:
545 case UserErr:
546 case FreeErr:
rjwalshbc0bb832004-06-19 18:12:36 +0000547 case IllegalMempoolErr:
njnb6cae9f2003-09-04 20:50:47 +0000548 case FreeMismatchErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000549 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000550 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
551 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
552 }
553 return sizeof(MAC_Error);
554 }
njn43c799e2003-04-08 00:08:52 +0000555 /* Don't need to return the correct size -- LeakErrs are always shown with
556 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000557 case LeakErr: return 0;
558 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000559 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000560 }
njn43c799e2003-04-08 00:08:52 +0000561}
562
563
njn5c004e42002-11-18 11:04:50 +0000564/*------------------------------------------------------------*/
565/*--- Suppressions ---*/
566/*------------------------------------------------------------*/
567
njn43c799e2003-04-08 00:08:52 +0000568Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
569{
570 SuppKind skind;
571
572 if (VG_STREQ(name, "Param")) skind = ParamSupp;
573 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
574 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
575 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
576 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
577 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000578 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000579 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
580 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000581 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000582 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000583 else
584 return False;
585
586 VG_(set_supp_kind)(su, skind);
587 return True;
588}
589
njn26f02512004-11-22 18:33:15 +0000590Bool TL_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000591{
592 Bool eof;
593
594 if (VG_(get_supp_kind)(su) == ParamSupp) {
595 eof = VG_(get_line) ( fd, buf, nBuf );
596 if (eof) return False;
597 VG_(set_supp_string)(su, VG_(strdup)(buf));
598 }
599 return True;
600}
601
njn26f02512004-11-22 18:33:15 +0000602Bool TL_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000603{
sewardj05bcdcb2003-05-18 10:05:38 +0000604 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000605 MAC_Error* err_extra = VG_(get_error_extra)(err);
606 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000607
608 switch (VG_(get_supp_kind)(su)) {
609 case ParamSupp:
610 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000611 && VG_STREQ(VG_(get_error_string)(err),
612 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000613
614 case CoreMemSupp:
615 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000616 && VG_STREQ(VG_(get_error_string)(err),
617 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000618
619 case Value0Supp: su_size = 0; goto value_case;
620 case Value1Supp: su_size = 1; goto value_case;
621 case Value2Supp: su_size = 2; goto value_case;
622 case Value4Supp: su_size = 4; goto value_case;
623 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000624 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000625 value_case:
626 return (ekind == ValueErr && err_extra->size == su_size);
627
628 case Addr1Supp: su_size = 1; goto addr_case;
629 case Addr2Supp: su_size = 2; goto addr_case;
630 case Addr4Supp: su_size = 4; goto addr_case;
631 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000632 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000633 addr_case:
634 return (ekind == AddrErr && err_extra->size == su_size);
635
636 case FreeSupp:
637 return (ekind == FreeErr || ekind == FreeMismatchErr);
638
njn34419c12003-05-02 17:24:29 +0000639 case OverlapSupp:
640 return (ekind = OverlapErr);
641
sewardj4a19e2f2002-12-26 11:50:21 +0000642 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000643 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000644
rjwalshbc0bb832004-06-19 18:12:36 +0000645 case MempoolSupp:
646 return (ekind == IllegalMempoolErr);
647
njn5c004e42002-11-18 11:04:50 +0000648 default:
649 VG_(printf)("Error:\n"
650 " unknown suppression type %d\n",
651 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000652 VG_(tool_panic)("unknown suppression type in "
njn26f02512004-11-22 18:33:15 +0000653 "TL_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000654 }
655}
656
njn26f02512004-11-22 18:33:15 +0000657Char* TL_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000658{
659 Char* s;
660 switch (VG_(get_error_kind)(err)) {
661 case ParamErr: return "Param";
662 case UserErr: return NULL; /* Can't suppress User errors */
663 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000664 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000665 case FreeErr: return "Free";
666 case AddrErr:
667 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
668 case 1: return "Addr1";
669 case 2: return "Addr2";
670 case 4: return "Addr4";
671 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000672 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000673 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000674 }
675
676 case ValueErr:
677 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
678 case 0: return "Cond";
679 case 1: return "Value1";
680 case 2: return "Value2";
681 case 4: return "Value4";
682 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000683 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000684 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000685 }
686 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000687 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000688 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000689 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000690 }
691 VG_(printf)(s);
692}
693
njn26f02512004-11-22 18:33:15 +0000694void TL_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000695{
696 if (ParamErr == VG_(get_error_kind)(err)) {
697 VG_(printf)(" %s\n", VG_(get_error_string)(err));
698 }
699}
njn5c004e42002-11-18 11:04:50 +0000700
701/*------------------------------------------------------------*/
702/*--- Crude profiling machinery. ---*/
703/*------------------------------------------------------------*/
704
705/* Event index. If just the name of the fn is given, this means the
706 number of calls to the fn. Otherwise it is the specified event.
707 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
708 The rest are shared.
709
710 10 alloc_secondary_map
711
712 20 get_abit
713M 21 get_vbyte
714 22 set_abit
715M 23 set_vbyte
716 24 get_abits4_ALIGNED
717M 25 get_vbytes4_ALIGNED
718
719 30 set_address_range_perms
720 31 set_address_range_perms(lower byte loop)
721 32 set_address_range_perms(quadword loop)
722 33 set_address_range_perms(upper byte loop)
723
724 35 make_noaccess
725 36 make_writable
726 37 make_readable
727A 38 make_accessible
728
729 40 copy_address_range_state
730 41 copy_address_range_state(byte loop)
731 42 check_writable
732 43 check_writable(byte loop)
733 44 check_readable
734 45 check_readable(byte loop)
735 46 check_readable_asciiz
736 47 check_readable_asciiz(byte loop)
737A 48 check_accessible
738A 49 check_accessible(byte loop)
739
740 50 make_noaccess_aligned
741 51 make_writable_aligned
742
743M 60 helperc_LOADV4
744M 61 helperc_STOREV4
745M 62 helperc_LOADV2
746M 63 helperc_STOREV2
747M 64 helperc_LOADV1
748M 65 helperc_STOREV1
749
750A 66 helperc_ACCESS4
751A 67 helperc_ACCESS2
752A 68 helperc_ACCESS1
753
754M 70 rim_rd_V4_SLOWLY
755M 71 rim_wr_V4_SLOWLY
756M 72 rim_rd_V2_SLOWLY
757M 73 rim_wr_V2_SLOWLY
758M 74 rim_rd_V1_SLOWLY
759M 75 rim_wr_V1_SLOWLY
760
761A 76 ACCESS4_SLOWLY
762A 77 ACCESS2_SLOWLY
763A 78 ACCESS1_SLOWLY
764
765 80 fpu_read
766 81 fpu_read aligned 4
767 82 fpu_read aligned 8
768 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000769 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000770
771M 85 fpu_write
772M 86 fpu_write aligned 4
773M 87 fpu_write aligned 8
774M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000775M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000776
777 90 fpu_access
778 91 fpu_access aligned 4
779 92 fpu_access aligned 8
780 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000781 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000782
783 100 fpu_access_check_SLOWLY
784 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000785
786 110 new_mem_stack_4
787 111 new_mem_stack_8
788 112 new_mem_stack_12
789 113 new_mem_stack_16
790 114 new_mem_stack_32
791 115 new_mem_stack
792
793 120 die_mem_stack_4
794 121 die_mem_stack_8
795 122 die_mem_stack_12
796 123 die_mem_stack_16
797 124 die_mem_stack_32
798 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000799*/
800
njn43c799e2003-04-08 00:08:52 +0000801#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000802
njn43c799e2003-04-08 00:08:52 +0000803UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000804
njnb4aee052003-04-15 14:09:58 +0000805static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000806{
807 Int i;
808 for (i = 0; i < N_PROF_EVENTS; i++)
njn43c799e2003-04-08 00:08:52 +0000809 MAC_(event_ctr)[i] = 0;
njn5c004e42002-11-18 11:04:50 +0000810}
811
njnb4aee052003-04-15 14:09:58 +0000812static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000813{
814 Int i;
815 for (i = 0; i < N_PROF_EVENTS; i++) {
816 if ((i % 10) == 0)
817 VG_(printf)("\n");
njn43c799e2003-04-08 00:08:52 +0000818 if (MAC_(event_ctr)[i] > 0)
819 VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] );
njn5c004e42002-11-18 11:04:50 +0000820 }
821 VG_(printf)("\n");
822}
823
824#else
825
njnb4aee052003-04-15 14:09:58 +0000826static void init_prof_mem ( void ) { }
827static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000828
njn5c004e42002-11-18 11:04:50 +0000829#endif
830
831/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000832/*--- Common initialisation + finalisation ---*/
833/*------------------------------------------------------------*/
834
835void MAC_(common_pre_clo_init)(void)
836{
837 MAC_(malloc_list) = VG_(HT_construct)();
rjwalshbc0bb832004-06-19 18:12:36 +0000838 MAC_(mempool_list) = VG_(HT_construct)();
njn3e884182003-04-15 13:03:23 +0000839 init_prof_mem();
840}
841
sewardjb5f6f512005-03-10 23:59:00 +0000842void MAC_(common_fini)(void (*leak_check)(LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000843{
844 MAC_(print_malloc_stats)();
845
846 if (VG_(clo_verbosity) == 1) {
sewardjb5f6f512005-03-10 23:59:00 +0000847 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000848 VG_(message)(Vg_UserMsg,
849 "For a detailed leak analysis, rerun with: --leak-check=yes");
850
851 VG_(message)(Vg_UserMsg,
852 "For counts of detected errors, rerun with: -v");
853 }
sewardjb5f6f512005-03-10 23:59:00 +0000854 if (MAC_(clo_leak_check) != LC_Off)
855 (*leak_check)(MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000856
857 done_prof_mem();
858}
859
860/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000861/*--- Common client request handling ---*/
862/*------------------------------------------------------------*/
863
nethercoted1b64b22004-11-04 18:22:28 +0000864Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000865{
njnd7994182003-10-02 13:44:04 +0000866 Char* err =
867 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
868 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
869 " program to incorporate the updates in the Valgrind header files.\n"
870 " You shouldn't need to change the text of your program at all.\n"
871 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000872
873 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000874 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000875 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000876 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
877 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000878 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000879 *argp[2] = MAC_(bytes_dubious);
880 *argp[3] = MAC_(bytes_reachable);
881 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000882 // there is no argp[5]
883 //*argp[5] = MAC_(bytes_indirect);
884 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000885 *ret = 0;
886 return True;
njn10785452003-05-20 16:38:24 +0000887 }
njnd7994182003-10-02 13:44:04 +0000888 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
889 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000890 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000891
njn10785452003-05-20 16:38:24 +0000892 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000893 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000894 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000895 UInt rzB = arg[3];
896 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000897
sewardj2a99cf62004-11-24 10:44:19 +0000898 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000899 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000900 return True;
901 }
902 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000903 Addr p = (Addr)arg[1];
904 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000905
sewardj2a99cf62004-11-24 10:44:19 +0000906 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000907 return True;
908 }
njnd7994182003-10-02 13:44:04 +0000909
nethercotee3a53722004-05-05 10:46:22 +0000910 case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP:
911 *ret = (Addr)MAC_(record_overlap_error);
912 return True;
913
rjwalshbc0bb832004-06-19 18:12:36 +0000914 case VG_USERREQ__CREATE_MEMPOOL: {
915 Addr pool = (Addr)arg[1];
916 UInt rzB = arg[2];
917 Bool is_zeroed = (Bool)arg[3];
918
919 MAC_(create_mempool) ( pool, rzB, is_zeroed );
920 return True;
921 }
922
923 case VG_USERREQ__DESTROY_MEMPOOL: {
924 Addr pool = (Addr)arg[1];
925
926 MAC_(destroy_mempool) ( pool );
927 return True;
928 }
929
930 case VG_USERREQ__MEMPOOL_ALLOC: {
931 Addr pool = (Addr)arg[1];
932 Addr addr = (Addr)arg[2];
933 UInt size = arg[3];
934
sewardj2a99cf62004-11-24 10:44:19 +0000935 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +0000936 return True;
937 }
938
939 case VG_USERREQ__MEMPOOL_FREE: {
940 Addr pool = (Addr)arg[1];
941 Addr addr = (Addr)arg[2];
942
943 MAC_(mempool_free) ( pool, addr );
944 return True;
945 }
946
njn47363ab2003-04-21 13:24:40 +0000947 default:
948 return False;
949 }
950}
951
njn5c004e42002-11-18 11:04:50 +0000952/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000953/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000954/*--------------------------------------------------------------------*/