blob: f9e9390fc69d88addca8b1dec467c75fc5b523f2 [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
njnc7561b92005-06-19 01:24:32 +000033#include "pub_tool_basics.h"
34#include "pub_tool_errormgr.h" // For mac_shared.h
35#include "pub_tool_execontext.h" // For mac_shared.h
36#include "pub_tool_hashtable.h" // For mac_shared.h
njn132bfcc2005-06-04 19:16:06 +000037#include "pub_tool_libcassert.h"
njn97405b22005-06-02 03:39:33 +000038#include "pub_tool_libcbase.h"
njn36a20fa2005-06-03 03:08:39 +000039#include "pub_tool_libcprint.h"
njnc7561b92005-06-19 01:24:32 +000040#include "pub_tool_mallocfree.h"
njnf536bbb2005-06-13 04:21:38 +000041#include "pub_tool_machine.h"
njnc7561b92005-06-19 01:24:32 +000042#include "pub_tool_options.h"
43#include "pub_tool_profile.h" // For mac_shared.h
44#include "pub_tool_replacemalloc.h"
45#include "pub_tool_threadstate.h"
46#include "mac_shared.h"
njn47363ab2003-04-21 13:24:40 +000047#include "memcheck.h" /* for VG_USERREQ__* */
48
njn5c004e42002-11-18 11:04:50 +000049/*------------------------------------------------------------*/
50/*--- Defns ---*/
51/*------------------------------------------------------------*/
52
53/* These many bytes below %ESP are considered addressible if we're
54 doing the --workaround-gcc296-bugs hack. */
55#define VG_GCC296_BUG_STACK_SLOP 1024
56
57/*------------------------------------------------------------*/
58/*--- Command line options ---*/
59/*------------------------------------------------------------*/
60
sewardjb5f6f512005-03-10 23:59:00 +000061Bool MAC_(clo_partial_loads_ok) = True;
62Int MAC_(clo_freelist_vol) = 1000000;
njn6a329422005-03-12 20:38:13 +000063LeakCheckMode MAC_(clo_leak_check) = LC_Summary;
sewardjb5f6f512005-03-10 23:59:00 +000064VgRes MAC_(clo_leak_resolution) = Vg_LowRes;
65Bool MAC_(clo_show_reachable) = False;
66Bool MAC_(clo_workaround_gcc296_bugs) = False;
njn5c004e42002-11-18 11:04:50 +000067
njn43c799e2003-04-08 00:08:52 +000068Bool MAC_(process_common_cmd_line_option)(Char* arg)
njn5c004e42002-11-18 11:04:50 +000069{
njn45270a22005-03-27 01:00:11 +000070 VG_BOOL_CLO(arg, "--partial-loads-ok", MAC_(clo_partial_loads_ok))
71 else VG_BOOL_CLO(arg, "--show-reachable", MAC_(clo_show_reachable))
72 else VG_BOOL_CLO(arg, "--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
nethercote27fec902004-06-16 21:26:32 +000073
njn45270a22005-03-27 01:00:11 +000074 else VG_BNUM_CLO(arg, "--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
nethercote27fec902004-06-16 21:26:32 +000075
sewardjb5f6f512005-03-10 23:59:00 +000076 else if (VG_CLO_STREQ(arg, "--leak-check=no"))
77 MAC_(clo_leak_check) = LC_Off;
78 else if (VG_CLO_STREQ(arg, "--leak-check=summary"))
79 MAC_(clo_leak_check) = LC_Summary;
80 else if (VG_CLO_STREQ(arg, "--leak-check=yes") ||
81 VG_CLO_STREQ(arg, "--leak-check=full"))
82 MAC_(clo_leak_check) = LC_Full;
83
njn43c799e2003-04-08 00:08:52 +000084 else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
85 MAC_(clo_leak_resolution) = Vg_LowRes;
86 else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
87 MAC_(clo_leak_resolution) = Vg_MedRes;
88 else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
89 MAC_(clo_leak_resolution) = Vg_HighRes;
njn5c004e42002-11-18 11:04:50 +000090
91 else
njn3e884182003-04-15 13:03:23 +000092 return VG_(replacement_malloc_process_cmd_line_option)(arg);
njn5c004e42002-11-18 11:04:50 +000093
94 return True;
njn43c799e2003-04-08 00:08:52 +000095}
njn5c004e42002-11-18 11:04:50 +000096
njn3e884182003-04-15 13:03:23 +000097void MAC_(print_common_usage)(void)
njn43c799e2003-04-08 00:08:52 +000098{
njn3e884182003-04-15 13:03:23 +000099 VG_(printf)(
njn6a329422005-03-12 20:38:13 +0000100" --leak-check=no|summary|full search for memory leaks at exit? [summary]\n"
sewardjb5f6f512005-03-10 23:59:00 +0000101" --leak-resolution=low|med|high how much bt merging in leak check [low]\n"
102" --show-reachable=no|yes show reachable blocks in leak check? [no]\n"
njn4d056022005-07-25 23:18:04 +0000103" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n"
104" --freelist-vol=<number> volume of freed blocks queue [1000000]\n"
njn3e884182003-04-15 13:03:23 +0000105" --workaround-gcc296-bugs=no|yes self explanatory [no]\n"
106 );
107 VG_(replacement_malloc_print_usage)();
njn43c799e2003-04-08 00:08:52 +0000108}
109
njn3e884182003-04-15 13:03:23 +0000110void MAC_(print_common_debug_usage)(void)
njn43c799e2003-04-08 00:08:52 +0000111{
njn3e884182003-04-15 13:03:23 +0000112 VG_(replacement_malloc_print_debug_usage)();
njn5c004e42002-11-18 11:04:50 +0000113}
114
115/*------------------------------------------------------------*/
116/*--- Comparing and printing errors ---*/
117/*------------------------------------------------------------*/
118
119static __inline__
120void clear_AddrInfo ( AddrInfo* ai )
121{
122 ai->akind = Unknown;
123 ai->blksize = 0;
124 ai->rwoffset = 0;
125 ai->lastchange = NULL;
126 ai->stack_tid = VG_INVALID_THREADID;
127 ai->maybe_gcc = False;
sewardjb5f6f512005-03-10 23:59:00 +0000128 ai->desc = NULL;
njn5c004e42002-11-18 11:04:50 +0000129}
130
njn43c799e2003-04-08 00:08:52 +0000131void MAC_(clear_MAC_Error) ( MAC_Error* err_extra )
njn5c004e42002-11-18 11:04:50 +0000132{
133 err_extra->axskind = ReadAxs;
134 err_extra->size = 0;
135 clear_AddrInfo ( &err_extra->addrinfo );
nethercote8b76fe52004-11-08 19:20:09 +0000136 err_extra->isUnaddr = True;
njn5c004e42002-11-18 11:04:50 +0000137}
138
139__attribute__ ((unused))
140static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
141{
142 if (ai1->akind != Undescribed
143 && ai2->akind != Undescribed
144 && ai1->akind != ai2->akind)
145 return False;
146 if (ai1->akind == Freed || ai1->akind == Mallocd) {
147 if (ai1->blksize != ai2->blksize)
148 return False;
149 if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
150 return False;
151 }
152 return True;
153}
154
155/* Compare error contexts, to detect duplicates. Note that if they
156 are otherwise the same, the faulting addrs and associated rwoffsets
157 are allowed to be different. */
158
njn51d827b2005-05-09 01:02:08 +0000159Bool MAC_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
njn5c004e42002-11-18 11:04:50 +0000160{
njn43c799e2003-04-08 00:08:52 +0000161 MAC_Error* e1_extra = VG_(get_error_extra)(e1);
162 MAC_Error* e2_extra = VG_(get_error_extra)(e2);
njn7cc53a82002-11-19 16:19:32 +0000163
164 /* Guaranteed by calling function */
njnca82cc02004-11-22 17:18:48 +0000165 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
njn5c004e42002-11-18 11:04:50 +0000166
167 switch (VG_(get_error_kind)(e1)) {
168 case CoreMemErr: {
169 Char *e1s, *e2s;
nethercote8b76fe52004-11-08 19:20:09 +0000170 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000171 e1s = VG_(get_error_string)(e1);
172 e2s = VG_(get_error_string)(e2);
173 if (e1s == e2s) return True;
174 if (0 == VG_(strcmp)(e1s, e2s)) return True;
175 return False;
176 }
177
njn16390462005-05-08 15:26:00 +0000178 // Perhaps we should also check the addrinfo.akinds for equality.
179 // That would result in more error reports, but only in cases where
180 // a register contains uninitialised bytes and points to memory
181 // containing uninitialised bytes. Currently, the 2nd of those to be
182 // detected won't be reported. That is (nearly?) always the memory
183 // error, which is good.
njn5c004e42002-11-18 11:04:50 +0000184 case ParamErr:
njn16390462005-05-08 15:26:00 +0000185 if (0 != VG_(strcmp)(VG_(get_error_string)(e1),
186 VG_(get_error_string)(e2))) return False;
187 // fall through
188 case UserErr:
189 if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
njn5c004e42002-11-18 11:04:50 +0000190 return True;
191
192 case FreeErr:
193 case FreeMismatchErr:
194 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
195 cause excessive duplication of errors. Not even AddrErr
196 below does that. So don't compare either the .addr field
197 or the .addrinfo fields. */
198 /* if (e1->addr != e2->addr) return False; */
199 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
200 return False;
201 */
202 return True;
203
204 case AddrErr:
205 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
206 if (e1_extra->size != e2_extra->size) return False;
207 /*
208 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
209 return False;
210 */
211 return True;
212
213 case ValueErr:
214 if (e1_extra->size != e2_extra->size) return False;
215 return True;
216
njn34419c12003-05-02 17:24:29 +0000217 case OverlapErr:
218 return True;
219
njn43c799e2003-04-08 00:08:52 +0000220 case LeakErr:
njn51d827b2005-05-09 01:02:08 +0000221 VG_(tool_panic)("Shouldn't get LeakErr in MAC_(eq_Error),\n"
njn43c799e2003-04-08 00:08:52 +0000222 "since it's handled with VG_(unique_error)()!");
223
rjwalshbc0bb832004-06-19 18:12:36 +0000224 case IllegalMempoolErr:
225 return True;
226
njn5c004e42002-11-18 11:04:50 +0000227 default:
228 VG_(printf)("Error:\n unknown error code %d\n",
229 VG_(get_error_kind)(e1));
njn51d827b2005-05-09 01:02:08 +0000230 VG_(tool_panic)("unknown error code in MAC_(eq_Error)");
njn5c004e42002-11-18 11:04:50 +0000231 }
232}
233
njn43c799e2003-04-08 00:08:52 +0000234void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000235{
sewardj71bc3cb2005-05-19 00:25:45 +0000236 HChar* xpre = VG_(clo_xml) ? " <auxwhat>" : " ";
237 HChar* xpost = VG_(clo_xml) ? "</auxwhat>" : "";
238
njn5c004e42002-11-18 11:04:50 +0000239 switch (ai->akind) {
240 case Stack:
241 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000242 "%sAddress 0x%llx is on thread %d's stack%s",
243 xpre, (ULong)a, ai->stack_tid, xpost);
njn5c004e42002-11-18 11:04:50 +0000244 break;
245 case Unknown:
246 if (ai->maybe_gcc) {
247 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000248 "%sAddress 0x%llx is just below the stack ptr. "
249 "To suppress, use: --workaround-gcc296-bugs=yes%s",
250 xpre, (ULong)a, xpost
251 );
njn5c004e42002-11-18 11:04:50 +0000252 } else {
253 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000254 "%sAddress 0x%llx "
255 "is not stack'd, malloc'd or (recently) free'd%s",
256 xpre, (ULong)a, xpost);
njn5c004e42002-11-18 11:04:50 +0000257 }
258 break;
rjwalshbc0bb832004-06-19 18:12:36 +0000259 case Freed: case Mallocd: case UserG: case Mempool: {
nethercote50397c22004-11-04 18:03:06 +0000260 SizeT delta;
sewardjb5f6f512005-03-10 23:59:00 +0000261 const Char* relative;
262 const Char* kind;
rjwalshbc0bb832004-06-19 18:12:36 +0000263 if (ai->akind == Mempool) {
264 kind = "mempool";
265 } else {
266 kind = "block";
267 }
sewardjb5f6f512005-03-10 23:59:00 +0000268 if (ai->desc != NULL)
269 kind = ai->desc;
270
njn5c004e42002-11-18 11:04:50 +0000271 if (ai->rwoffset < 0) {
nethercote50397c22004-11-04 18:03:06 +0000272 delta = (SizeT)(- ai->rwoffset);
njn5c004e42002-11-18 11:04:50 +0000273 relative = "before";
274 } else if (ai->rwoffset >= ai->blksize) {
275 delta = ai->rwoffset - ai->blksize;
276 relative = "after";
277 } else {
278 delta = ai->rwoffset;
279 relative = "inside";
280 }
sewardja81709d2002-12-28 12:55:48 +0000281 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000282 "%sAddress 0x%llx is %llu bytes %s a %s of size %d %s%s",
283 xpre,
tom14ea6852005-05-03 18:16:12 +0000284 (ULong)a, (ULong)delta, relative, kind,
sewardja81709d2002-12-28 12:55:48 +0000285 ai->blksize,
286 ai->akind==Mallocd ? "alloc'd"
287 : ai->akind==Freed ? "free'd"
sewardj71bc3cb2005-05-19 00:25:45 +0000288 : "client-defined",
289 xpost);
njn5c004e42002-11-18 11:04:50 +0000290 VG_(pp_ExeContext)(ai->lastchange);
291 break;
292 }
nethercote8b76fe52004-11-08 19:20:09 +0000293 case Register:
294 // print nothing
njnca82cc02004-11-22 17:18:48 +0000295 tl_assert(0 == a);
nethercote8b76fe52004-11-08 19:20:09 +0000296 break;
njn5c004e42002-11-18 11:04:50 +0000297 default:
njn67993252004-11-22 18:02:32 +0000298 VG_(tool_panic)("MAC_(pp_AddrInfo)");
njn43c799e2003-04-08 00:08:52 +0000299 }
300}
301
302/* This prints out the message for the error types where Memcheck and
303 Addrcheck have identical messages */
njnb126f732004-11-22 17:57:07 +0000304void MAC_(pp_shared_Error) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000305{
306 MAC_Error* err_extra = VG_(get_error_extra)(err);
307
sewardj71bc3cb2005-05-19 00:25:45 +0000308 HChar* xpre = VG_(clo_xml) ? " <what>" : "";
309 HChar* xpost = VG_(clo_xml) ? "</what>" : "";
310
njn43c799e2003-04-08 00:08:52 +0000311 switch (VG_(get_error_kind)(err)) {
312 case FreeErr:
sewardj71bc3cb2005-05-19 00:25:45 +0000313 if (VG_(clo_xml))
314 VG_(message)(Vg_UserMsg, " <kind>InvalidFree</kind>");
315 VG_(message)(Vg_UserMsg,
316 "%sInvalid free() / delete / delete[]%s",
317 xpre, xpost);
318 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
319 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
320 break;
321
njn43c799e2003-04-08 00:08:52 +0000322 case FreeMismatchErr:
sewardj71bc3cb2005-05-19 00:25:45 +0000323 if (VG_(clo_xml))
324 VG_(message)(Vg_UserMsg, " <kind>MismatchedFree</kind>");
325 VG_(message)(Vg_UserMsg,
326 "%sMismatched free() / delete / delete []%s",
327 xpre, xpost);
njn43c799e2003-04-08 00:08:52 +0000328 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
329 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
330 break;
331
njn89409f82003-09-26 14:55:31 +0000332 case AddrErr:
333 switch (err_extra->axskind) {
334 case ReadAxs:
sewardj71bc3cb2005-05-19 00:25:45 +0000335 if (VG_(clo_xml))
336 VG_(message)(Vg_UserMsg, " <kind>InvalidRead</kind>");
337 VG_(message)(Vg_UserMsg,
338 "%sInvalid read of size %d%s",
339 xpre, err_extra->size, xpost );
njn89409f82003-09-26 14:55:31 +0000340 break;
341 case WriteAxs:
sewardj71bc3cb2005-05-19 00:25:45 +0000342 if (VG_(clo_xml))
343 VG_(message)(Vg_UserMsg, " <kind>InvalidWrite</kind>");
344 VG_(message)(Vg_UserMsg,
345 "%sInvalid write of size %d%s",
346 xpre, err_extra->size, xpost );
njn89409f82003-09-26 14:55:31 +0000347 break;
348 case ExecAxs:
sewardj71bc3cb2005-05-19 00:25:45 +0000349 if (VG_(clo_xml))
350 VG_(message)(Vg_UserMsg, " <kind>InvalidJump</kind>");
351 VG_(message)(Vg_UserMsg,
352 "%sJump to the invalid address "
353 "stated on the next line%s",
354 xpre, xpost);
njn89409f82003-09-26 14:55:31 +0000355 break;
356 default:
njn51d827b2005-05-09 01:02:08 +0000357 VG_(tool_panic)("MAC_(pp_shared_Error)(axskind)");
njn89409f82003-09-26 14:55:31 +0000358 }
359 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
360 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
361 break;
362
njnb6cae9f2003-09-04 20:50:47 +0000363 case OverlapErr: {
364 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
sewardj71bc3cb2005-05-19 00:25:45 +0000365 if (VG_(clo_xml))
366 VG_(message)(Vg_UserMsg, " <kind>Overlap</kind>");
njnb6cae9f2003-09-04 20:50:47 +0000367 if (ov_extra->len == -1)
368 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000369 "%sSource and destination overlap in %s(%p, %p)%s",
370 xpre,
njnb6cae9f2003-09-04 20:50:47 +0000371 VG_(get_error_string)(err),
sewardj71bc3cb2005-05-19 00:25:45 +0000372 ov_extra->dst, ov_extra->src,
373 xpost);
njnb6cae9f2003-09-04 20:50:47 +0000374 else
375 VG_(message)(Vg_UserMsg,
sewardj71bc3cb2005-05-19 00:25:45 +0000376 "%sSource and destination overlap in %s(%p, %p, %d)%s",
377 xpre,
njnb6cae9f2003-09-04 20:50:47 +0000378 VG_(get_error_string)(err),
sewardj71bc3cb2005-05-19 00:25:45 +0000379 ov_extra->dst, ov_extra->src, ov_extra->len,
380 xpost);
njn66fe05a2003-07-22 09:12:33 +0000381 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
382 break;
njnb6cae9f2003-09-04 20:50:47 +0000383 }
njn43c799e2003-04-08 00:08:52 +0000384 case LeakErr: {
njn02977032005-05-17 04:00:11 +0000385 MAC_(pp_LeakError)(err_extra);
njn43c799e2003-04-08 00:08:52 +0000386 break;
387 }
388
rjwalshbc0bb832004-06-19 18:12:36 +0000389 case IllegalMempoolErr:
sewardj71bc3cb2005-05-19 00:25:45 +0000390 if (VG_(clo_xml))
391 VG_(message)(Vg_UserMsg, " <kind>InvalidMemPool</kind>");
392 VG_(message)(Vg_UserMsg, "%sIllegal memory pool address%s",
393 xpre, xpost);
rjwalshbc0bb832004-06-19 18:12:36 +0000394 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
395 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
396 break;
397
njn43c799e2003-04-08 00:08:52 +0000398 default:
399 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
400 VG_(get_error_kind)(err));
njn67993252004-11-22 18:02:32 +0000401 VG_(tool_panic)("unknown error code in MAC_(pp_shared_Error)");
njn5c004e42002-11-18 11:04:50 +0000402 }
403}
404
405/*------------------------------------------------------------*/
406/*--- Recording errors ---*/
407/*------------------------------------------------------------*/
408
njn43c799e2003-04-08 00:08:52 +0000409/* Additional description function for describe_addr(); used by
410 MemCheck for user blocks, which Addrcheck doesn't support. */
411Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
thughes4ad52d02004-06-27 17:37:21 +0000412
413/* Callback for searching thread stacks */
414static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
415{
416 Addr a = *(Addr *)ap;
417
418 return (stack_min <= a && a <= stack_max);
419}
420
421/* Callback for searching free'd list */
422static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
423{
424 Addr a = *(Addr *)ap;
425
njn717cde52005-05-10 02:47:21 +0000426 return VG_(addr_is_in_block)( a, mc->data, mc->size,
427 MAC_MALLOC_REDZONE_SZB );
thughes4ad52d02004-06-27 17:37:21 +0000428}
429
430/* Callback for searching malloc'd lists */
431static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
432{
433 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
434}
435
njn43c799e2003-04-08 00:08:52 +0000436/* Describe an address as best you can, for error messages,
437 putting the result in ai. */
438static void describe_addr ( Addr a, AddrInfo* ai )
439{
njn34582fb2005-08-11 00:06:36 +0000440 MAC_Chunk* mc;
njn3e884182003-04-15 13:03:23 +0000441 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000442
njn43c799e2003-04-08 00:08:52 +0000443 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
444 if (NULL != MAC_(describe_addr_supp)) {
445 if (MAC_(describe_addr_supp)( a, ai ))
446 return;
447 }
448 /* Perhaps it's on a thread's stack? */
thughes4ad52d02004-06-27 17:37:21 +0000449 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
njn43c799e2003-04-08 00:08:52 +0000450 if (tid != VG_INVALID_THREADID) {
451 ai->akind = Stack;
452 ai->stack_tid = tid;
453 return;
454 }
455 /* Search for a recently freed block which might bracket it. */
njn34582fb2005-08-11 00:06:36 +0000456 mc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
457 if (NULL != mc) {
njn43c799e2003-04-08 00:08:52 +0000458 ai->akind = Freed;
njn34582fb2005-08-11 00:06:36 +0000459 ai->blksize = mc->size;
460 ai->rwoffset = (Int)a - (Int)mc->data;
461 ai->lastchange = mc->where;
njn43c799e2003-04-08 00:08:52 +0000462 return;
463 }
464 /* Search for a currently malloc'd block which might bracket it. */
njn34582fb2005-08-11 00:06:36 +0000465 mc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
466 if (NULL != mc) {
njn43c799e2003-04-08 00:08:52 +0000467 ai->akind = Mallocd;
njn34582fb2005-08-11 00:06:36 +0000468 ai->blksize = mc->size;
469 ai->rwoffset = (Int)(a) - (Int)mc->data;
470 ai->lastchange = mc->where;
njn43c799e2003-04-08 00:08:52 +0000471 return;
472 }
473 /* Clueless ... */
474 ai->akind = Unknown;
475 return;
476}
477
njn4bd67b52005-08-11 00:47:10 +0000478/* Describe an address as best you can, for FreeMismatch error messages.
479 By the time this is called 'ai' is already setup with all the relevant
480 info. So the only thing this can do is change that to UserG if 'a' is in
481 a user block, otherwise change it from 'Mallocd' to 'Freed'.
482*/
483static void describe_addr_FreeMismatch ( Addr a, AddrInfo* ai )
484{
485 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
486 if (NULL != MAC_(describe_addr_supp)) {
487 (void)MAC_(describe_addr_supp)( a, ai );
488 }
489}
490
njn5c004e42002-11-18 11:04:50 +0000491/* Is this address within some small distance below %ESP? Used only
492 for the --workaround-gcc296-bugs kludge. */
493static Bool is_just_below_ESP( Addr esp, Addr aa )
494{
nethercote50397c22004-11-04 18:03:06 +0000495 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
njn5c004e42002-11-18 11:04:50 +0000496 return True;
497 else
498 return False;
499}
500
sewardjaf48a602003-07-06 00:54:47 +0000501/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000502
njn72718642003-07-24 08:45:32 +0000503void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000504 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000505{
njn43c799e2003-04-08 00:08:52 +0000506 MAC_Error err_extra;
507 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000508
njn67516132005-03-22 04:02:43 +0000509 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
njn5c004e42002-11-18 11:04:50 +0000510
511 /* If this is caused by an access immediately below %ESP, and the
512 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000513 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000514 return;
515
njn43c799e2003-04-08 00:08:52 +0000516 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000517 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
518 err_extra.size = size;
519 err_extra.addrinfo.akind = Undescribed;
520 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000521 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000522}
523
524/* These ones are called from non-generated code */
525
526/* This is for memory errors in pthread functions, as opposed to pthread API
527 errors which are found by the core. */
nethercote8b76fe52004-11-08 19:20:09 +0000528void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000529{
njn43c799e2003-04-08 00:08:52 +0000530 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000531
njn43c799e2003-04-08 00:08:52 +0000532 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000533 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000534 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000535}
536
njn16390462005-05-08 15:26:00 +0000537// Three kinds of param errors:
538// - register arg contains undefined bytes
539// - memory arg is unaddressable
540// - memory arg contains undefined bytes
541// 'isReg' and 'isUnaddr' dictate which of these it is.
nethercote8b76fe52004-11-08 19:20:09 +0000542void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
543 Bool isUnaddr, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000544{
njn43c799e2003-04-08 00:08:52 +0000545 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000546
njnca82cc02004-11-22 17:18:48 +0000547 tl_assert(VG_INVALID_THREADID != tid);
njn16390462005-05-08 15:26:00 +0000548 if (isUnaddr) tl_assert(!isReg); // unaddressable register is impossible
njn43c799e2003-04-08 00:08:52 +0000549 MAC_(clear_MAC_Error)( &err_extra );
nethercote8b76fe52004-11-08 19:20:09 +0000550 err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
551 err_extra.isUnaddr = isUnaddr;
njn72718642003-07-24 08:45:32 +0000552 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000553}
554
njn72718642003-07-24 08:45:32 +0000555void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000556{
njn43c799e2003-04-08 00:08:52 +0000557 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000558
njnca82cc02004-11-22 17:18:48 +0000559 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000560 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000561 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000562 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000563 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000564 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000565}
566
njn72718642003-07-24 08:45:32 +0000567void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000568{
njn43c799e2003-04-08 00:08:52 +0000569 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000570
njnca82cc02004-11-22 17:18:48 +0000571 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000572 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000573 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000574 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000575}
576
rjwalshbc0bb832004-06-19 18:12:36 +0000577void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
578{
579 MAC_Error err_extra;
580
njnca82cc02004-11-22 17:18:48 +0000581 tl_assert(VG_INVALID_THREADID != tid);
rjwalshbc0bb832004-06-19 18:12:36 +0000582 MAC_(clear_MAC_Error)( &err_extra );
583 err_extra.addrinfo.akind = Undescribed;
584 VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
585}
586
njn4bd67b52005-08-11 00:47:10 +0000587void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a, MAC_Chunk* mc )
njn5c004e42002-11-18 11:04:50 +0000588{
njn43c799e2003-04-08 00:08:52 +0000589 MAC_Error err_extra;
njn4bd67b52005-08-11 00:47:10 +0000590 AddrInfo* ai;
njn5c004e42002-11-18 11:04:50 +0000591
njnca82cc02004-11-22 17:18:48 +0000592 tl_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000593 MAC_(clear_MAC_Error)( &err_extra );
njn4bd67b52005-08-11 00:47:10 +0000594 ai = &err_extra.addrinfo;
595 ai->akind = Mallocd; // Nb: not 'Freed'
596 ai->blksize = mc->size;
597 ai->rwoffset = (Int)a - (Int)mc->data;
598 ai->lastchange = mc->where;
njn72718642003-07-24 08:45:32 +0000599 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000600}
601
sewardj2a99cf62004-11-24 10:44:19 +0000602void MAC_(record_overlap_error) ( ThreadId tid,
603 Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000604{
sewardj2a99cf62004-11-24 10:44:19 +0000605 VG_(maybe_record_error)(
606 tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000607}
608
609
njnb6cae9f2003-09-04 20:50:47 +0000610/* Updates the copy with address info if necessary (but not for all errors). */
njn51d827b2005-05-09 01:02:08 +0000611UInt MAC_(update_extra)( Error* err )
njn43c799e2003-04-08 00:08:52 +0000612{
njnb6cae9f2003-09-04 20:50:47 +0000613 switch (VG_(get_error_kind)(err)) {
614 case ValueErr:
615 case CoreMemErr:
616 case AddrErr:
617 case ParamErr:
618 case UserErr:
619 case FreeErr:
njn4bd67b52005-08-11 00:47:10 +0000620 case IllegalMempoolErr: {
nethercote8b76fe52004-11-08 19:20:09 +0000621 MAC_Error* extra = VG_(get_error_extra)(err);
njnb6cae9f2003-09-04 20:50:47 +0000622 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
623 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
624 }
625 return sizeof(MAC_Error);
626 }
njn4bd67b52005-08-11 00:47:10 +0000627
628 case FreeMismatchErr: {
629 MAC_Error* extra = VG_(get_error_extra)(err);
630 tl_assert(extra && Mallocd == extra->addrinfo.akind);
631 describe_addr_FreeMismatch ( VG_(get_error_address)(err), &(extra->addrinfo) );
632 return sizeof(MAC_Error);
633 }
634
njn43c799e2003-04-08 00:08:52 +0000635 /* Don't need to return the correct size -- LeakErrs are always shown with
636 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000637 case LeakErr: return 0;
638 case OverlapErr: return sizeof(OverlapExtra);
njn67993252004-11-22 18:02:32 +0000639 default: VG_(tool_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000640 }
njn43c799e2003-04-08 00:08:52 +0000641}
642
643
njn5c004e42002-11-18 11:04:50 +0000644/*------------------------------------------------------------*/
645/*--- Suppressions ---*/
646/*------------------------------------------------------------*/
647
njn43c799e2003-04-08 00:08:52 +0000648Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
649{
650 SuppKind skind;
651
652 if (VG_STREQ(name, "Param")) skind = ParamSupp;
653 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
654 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
655 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
656 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
657 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000658 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000659 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
660 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000661 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
rjwalshbc0bb832004-06-19 18:12:36 +0000662 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
njn43c799e2003-04-08 00:08:52 +0000663 else
664 return False;
665
666 VG_(set_supp_kind)(su, skind);
667 return True;
668}
669
njn51d827b2005-05-09 01:02:08 +0000670Bool MAC_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
njn5c004e42002-11-18 11:04:50 +0000671{
672 Bool eof;
673
674 if (VG_(get_supp_kind)(su) == ParamSupp) {
675 eof = VG_(get_line) ( fd, buf, nBuf );
676 if (eof) return False;
677 VG_(set_supp_string)(su, VG_(strdup)(buf));
678 }
679 return True;
680}
681
njn51d827b2005-05-09 01:02:08 +0000682Bool MAC_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000683{
sewardj05bcdcb2003-05-18 10:05:38 +0000684 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000685 MAC_Error* err_extra = VG_(get_error_extra)(err);
686 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000687
688 switch (VG_(get_supp_kind)(su)) {
689 case ParamSupp:
690 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000691 && VG_STREQ(VG_(get_error_string)(err),
692 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000693
694 case CoreMemSupp:
695 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000696 && VG_STREQ(VG_(get_error_string)(err),
697 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000698
699 case Value0Supp: su_size = 0; goto value_case;
700 case Value1Supp: su_size = 1; goto value_case;
701 case Value2Supp: su_size = 2; goto value_case;
702 case Value4Supp: su_size = 4; goto value_case;
703 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000704 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000705 value_case:
706 return (ekind == ValueErr && err_extra->size == su_size);
707
708 case Addr1Supp: su_size = 1; goto addr_case;
709 case Addr2Supp: su_size = 2; goto addr_case;
710 case Addr4Supp: su_size = 4; goto addr_case;
711 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000712 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000713 addr_case:
714 return (ekind == AddrErr && err_extra->size == su_size);
715
716 case FreeSupp:
717 return (ekind == FreeErr || ekind == FreeMismatchErr);
718
njn34419c12003-05-02 17:24:29 +0000719 case OverlapSupp:
720 return (ekind = OverlapErr);
721
sewardj4a19e2f2002-12-26 11:50:21 +0000722 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000723 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000724
rjwalshbc0bb832004-06-19 18:12:36 +0000725 case MempoolSupp:
726 return (ekind == IllegalMempoolErr);
727
njn5c004e42002-11-18 11:04:50 +0000728 default:
729 VG_(printf)("Error:\n"
730 " unknown suppression type %d\n",
731 VG_(get_supp_kind)(su));
njn67993252004-11-22 18:02:32 +0000732 VG_(tool_panic)("unknown suppression type in "
njn51d827b2005-05-09 01:02:08 +0000733 "MAC_(error_matches_suppression)");
njn5c004e42002-11-18 11:04:50 +0000734 }
735}
736
njn51d827b2005-05-09 01:02:08 +0000737Char* MAC_(get_error_name) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000738{
739 Char* s;
740 switch (VG_(get_error_kind)(err)) {
741 case ParamErr: return "Param";
742 case UserErr: return NULL; /* Can't suppress User errors */
743 case FreeMismatchErr: return "Free";
rjwalshbc0bb832004-06-19 18:12:36 +0000744 case IllegalMempoolErr: return "Mempool";
njn43c799e2003-04-08 00:08:52 +0000745 case FreeErr: return "Free";
746 case AddrErr:
747 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
748 case 1: return "Addr1";
749 case 2: return "Addr2";
750 case 4: return "Addr4";
751 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000752 case 16: return "Addr16";
njn67993252004-11-22 18:02:32 +0000753 default: VG_(tool_panic)("unexpected size for Addr");
njn43c799e2003-04-08 00:08:52 +0000754 }
755
756 case ValueErr:
757 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
758 case 0: return "Cond";
759 case 1: return "Value1";
760 case 2: return "Value2";
761 case 4: return "Value4";
762 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000763 case 16: return "Value16";
njn67993252004-11-22 18:02:32 +0000764 default: VG_(tool_panic)("unexpected size for Value");
njn43c799e2003-04-08 00:08:52 +0000765 }
766 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000767 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000768 case LeakErr: return "Leak";
njn67993252004-11-22 18:02:32 +0000769 default: VG_(tool_panic)("get_error_name: unexpected type");
njn43c799e2003-04-08 00:08:52 +0000770 }
771 VG_(printf)(s);
772}
773
njn51d827b2005-05-09 01:02:08 +0000774void MAC_(print_extra_suppression_info) ( Error* err )
njn43c799e2003-04-08 00:08:52 +0000775{
776 if (ParamErr == VG_(get_error_kind)(err)) {
777 VG_(printf)(" %s\n", VG_(get_error_string)(err));
778 }
779}
njn5c004e42002-11-18 11:04:50 +0000780
781/*------------------------------------------------------------*/
782/*--- Crude profiling machinery. ---*/
783/*------------------------------------------------------------*/
784
785/* Event index. If just the name of the fn is given, this means the
786 number of calls to the fn. Otherwise it is the specified event.
787 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
788 The rest are shared.
789
790 10 alloc_secondary_map
791
792 20 get_abit
793M 21 get_vbyte
794 22 set_abit
795M 23 set_vbyte
796 24 get_abits4_ALIGNED
797M 25 get_vbytes4_ALIGNED
798
799 30 set_address_range_perms
800 31 set_address_range_perms(lower byte loop)
801 32 set_address_range_perms(quadword loop)
802 33 set_address_range_perms(upper byte loop)
803
804 35 make_noaccess
805 36 make_writable
806 37 make_readable
807A 38 make_accessible
808
809 40 copy_address_range_state
810 41 copy_address_range_state(byte loop)
811 42 check_writable
812 43 check_writable(byte loop)
813 44 check_readable
814 45 check_readable(byte loop)
815 46 check_readable_asciiz
816 47 check_readable_asciiz(byte loop)
817A 48 check_accessible
818A 49 check_accessible(byte loop)
819
820 50 make_noaccess_aligned
821 51 make_writable_aligned
822
823M 60 helperc_LOADV4
824M 61 helperc_STOREV4
825M 62 helperc_LOADV2
826M 63 helperc_STOREV2
827M 64 helperc_LOADV1
828M 65 helperc_STOREV1
829
830A 66 helperc_ACCESS4
831A 67 helperc_ACCESS2
832A 68 helperc_ACCESS1
833
834M 70 rim_rd_V4_SLOWLY
835M 71 rim_wr_V4_SLOWLY
836M 72 rim_rd_V2_SLOWLY
837M 73 rim_wr_V2_SLOWLY
838M 74 rim_rd_V1_SLOWLY
839M 75 rim_wr_V1_SLOWLY
840
841A 76 ACCESS4_SLOWLY
842A 77 ACCESS2_SLOWLY
843A 78 ACCESS1_SLOWLY
844
845 80 fpu_read
846 81 fpu_read aligned 4
847 82 fpu_read aligned 8
848 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000849 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000850
851M 85 fpu_write
852M 86 fpu_write aligned 4
853M 87 fpu_write aligned 8
854M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000855M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000856
857 90 fpu_access
858 91 fpu_access aligned 4
859 92 fpu_access aligned 8
860 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000861 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000862
863 100 fpu_access_check_SLOWLY
864 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000865
866 110 new_mem_stack_4
867 111 new_mem_stack_8
868 112 new_mem_stack_12
869 113 new_mem_stack_16
870 114 new_mem_stack_32
871 115 new_mem_stack
872
873 120 die_mem_stack_4
874 121 die_mem_stack_8
875 122 die_mem_stack_12
876 123 die_mem_stack_16
877 124 die_mem_stack_32
878 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000879*/
880
njn43c799e2003-04-08 00:08:52 +0000881#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000882
sewardjc1a2cda2005-04-21 17:34:00 +0000883UInt MAC_(event_ctr)[N_PROF_EVENTS];
884HChar* MAC_(event_ctr_name)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000885
njnb4aee052003-04-15 14:09:58 +0000886static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000887{
888 Int i;
sewardjc1a2cda2005-04-21 17:34:00 +0000889 for (i = 0; i < N_PROF_EVENTS; i++) {
njn43c799e2003-04-08 00:08:52 +0000890 MAC_(event_ctr)[i] = 0;
sewardjc1a2cda2005-04-21 17:34:00 +0000891 MAC_(event_ctr_name)[i] = NULL;
892 }
njn5c004e42002-11-18 11:04:50 +0000893}
894
njnb4aee052003-04-15 14:09:58 +0000895static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000896{
sewardjc1a2cda2005-04-21 17:34:00 +0000897 Int i;
898 Bool spaced = False;
njn5c004e42002-11-18 11:04:50 +0000899 for (i = 0; i < N_PROF_EVENTS; i++) {
sewardjc1a2cda2005-04-21 17:34:00 +0000900 if (!spaced && (i % 10) == 0) {
njn5c004e42002-11-18 11:04:50 +0000901 VG_(printf)("\n");
sewardjc1a2cda2005-04-21 17:34:00 +0000902 spaced = True;
903 }
904 if (MAC_(event_ctr)[i] > 0) {
905 spaced = False;
906 VG_(printf)( "prof mem event %3d: %9d %s\n",
907 i, MAC_(event_ctr)[i],
908 MAC_(event_ctr_name)[i]
909 ? MAC_(event_ctr_name)[i] : "unnamed");
910 }
njn5c004e42002-11-18 11:04:50 +0000911 }
njn5c004e42002-11-18 11:04:50 +0000912}
913
914#else
915
njnb4aee052003-04-15 14:09:58 +0000916static void init_prof_mem ( void ) { }
917static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000918
njn5c004e42002-11-18 11:04:50 +0000919#endif
920
921/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000922/*--- Common initialisation + finalisation ---*/
923/*------------------------------------------------------------*/
924
925void MAC_(common_pre_clo_init)(void)
926{
njnf69f9452005-07-03 17:53:11 +0000927 MAC_(malloc_list) = VG_(HT_construct)( 80021 ); // prime, big
928 MAC_(mempool_list) = VG_(HT_construct)( 1009 ); // prime, not so big
njn3e884182003-04-15 13:03:23 +0000929 init_prof_mem();
930}
931
njnb8dca862005-03-14 02:42:44 +0000932void MAC_(common_fini)(void (*leak_check)(ThreadId tid, LeakCheckMode mode))
njn3e884182003-04-15 13:03:23 +0000933{
njn86f12dc2005-03-14 01:16:05 +0000934 MAC_(print_malloc_stats)();
njn3e884182003-04-15 13:03:23 +0000935
sewardj71bc3cb2005-05-19 00:25:45 +0000936 if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) {
sewardjb5f6f512005-03-10 23:59:00 +0000937 if (MAC_(clo_leak_check) == LC_Off)
njn3e884182003-04-15 13:03:23 +0000938 VG_(message)(Vg_UserMsg,
939 "For a detailed leak analysis, rerun with: --leak-check=yes");
940
941 VG_(message)(Vg_UserMsg,
942 "For counts of detected errors, rerun with: -v");
943 }
sewardjb5f6f512005-03-10 23:59:00 +0000944 if (MAC_(clo_leak_check) != LC_Off)
njnb8dca862005-03-14 02:42:44 +0000945 leak_check(1/*bogus ThreadId*/, MAC_(clo_leak_check));
njn3e884182003-04-15 13:03:23 +0000946
947 done_prof_mem();
948}
949
950/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000951/*--- Common client request handling ---*/
952/*------------------------------------------------------------*/
953
nethercoted1b64b22004-11-04 18:22:28 +0000954Bool MAC_(handle_common_client_requests)(ThreadId tid, UWord* arg, UWord* ret )
njn47363ab2003-04-21 13:24:40 +0000955{
njnd7994182003-10-02 13:44:04 +0000956 Char* err =
957 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
958 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
959 " program to incorporate the updates in the Valgrind header files.\n"
960 " You shouldn't need to change the text of your program at all.\n"
961 " Everything should then work as before. Sorry for the bother.\n";
njn47363ab2003-04-21 13:24:40 +0000962
963 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000964 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
nethercoted1b64b22004-11-04 18:22:28 +0000965 UWord** argp = (UWord**)arg;
njne8b5c052003-07-22 22:03:58 +0000966 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
967 // if no prior leak checks performed).
sewardjb5f6f512005-03-10 23:59:00 +0000968 *argp[1] = MAC_(bytes_leaked) + MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000969 *argp[2] = MAC_(bytes_dubious);
970 *argp[3] = MAC_(bytes_reachable);
971 *argp[4] = MAC_(bytes_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +0000972 // there is no argp[5]
973 //*argp[5] = MAC_(bytes_indirect);
974 // XXX need to make *argp[1-4] readable
njn47363ab2003-04-21 13:24:40 +0000975 *ret = 0;
976 return True;
njn10785452003-05-20 16:38:24 +0000977 }
njnd7994182003-10-02 13:44:04 +0000978 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
979 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
njn67993252004-11-22 18:02:32 +0000980 VG_(tool_panic)(err);
njnd7994182003-10-02 13:44:04 +0000981
njn10785452003-05-20 16:38:24 +0000982 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000983 Addr p = (Addr)arg[1];
nethercote928a5f72004-11-03 18:10:37 +0000984 SizeT sizeB = arg[2];
njnd7994182003-10-02 13:44:04 +0000985 UInt rzB = arg[3];
986 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000987
sewardj2a99cf62004-11-24 10:44:19 +0000988 MAC_(new_block) ( tid, p, sizeB, /*ignored*/0, rzB, is_zeroed,
nethercote57e36b32004-07-10 14:56:28 +0000989 MAC_AllocCustom, MAC_(malloc_list) );
njn10785452003-05-20 16:38:24 +0000990 return True;
991 }
992 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000993 Addr p = (Addr)arg[1];
994 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000995
sewardj2a99cf62004-11-24 10:44:19 +0000996 MAC_(handle_free) ( tid, p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000997 return True;
998 }
njnd7994182003-10-02 13:44:04 +0000999
njn1f8b3e72005-03-22 04:27:14 +00001000 case _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR: {
1001 Char* s = (Char*) arg[1];
1002 OverlapExtra* extra = (OverlapExtra*)arg[2];
1003 MAC_(record_overlap_error)(tid, s, extra);
nethercotee3a53722004-05-05 10:46:22 +00001004 return True;
njn1f8b3e72005-03-22 04:27:14 +00001005 }
nethercotee3a53722004-05-05 10:46:22 +00001006
rjwalshbc0bb832004-06-19 18:12:36 +00001007 case VG_USERREQ__CREATE_MEMPOOL: {
1008 Addr pool = (Addr)arg[1];
1009 UInt rzB = arg[2];
1010 Bool is_zeroed = (Bool)arg[3];
1011
1012 MAC_(create_mempool) ( pool, rzB, is_zeroed );
1013 return True;
1014 }
1015
1016 case VG_USERREQ__DESTROY_MEMPOOL: {
1017 Addr pool = (Addr)arg[1];
1018
1019 MAC_(destroy_mempool) ( pool );
1020 return True;
1021 }
1022
1023 case VG_USERREQ__MEMPOOL_ALLOC: {
1024 Addr pool = (Addr)arg[1];
1025 Addr addr = (Addr)arg[2];
1026 UInt size = arg[3];
1027
sewardj2a99cf62004-11-24 10:44:19 +00001028 MAC_(mempool_alloc) ( tid, pool, addr, size );
rjwalshbc0bb832004-06-19 18:12:36 +00001029 return True;
1030 }
1031
1032 case VG_USERREQ__MEMPOOL_FREE: {
1033 Addr pool = (Addr)arg[1];
1034 Addr addr = (Addr)arg[2];
1035
1036 MAC_(mempool_free) ( pool, addr );
1037 return True;
1038 }
1039
njn47363ab2003-04-21 13:24:40 +00001040 default:
1041 return False;
1042 }
1043}
1044
njn5c004e42002-11-18 11:04:50 +00001045/*--------------------------------------------------------------------*/
njn00cae242005-05-09 01:13:44 +00001046/*--- end ---*/
njn5c004e42002-11-18 11:04:50 +00001047/*--------------------------------------------------------------------*/