17ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
27ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
37ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Management, printing, etc, of errors and suppressions.       ---*/
47ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*---                                                  mc_errors.c ---*/
57ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
67ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
77ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*
87ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   This file is part of MemCheck, a heavyweight Valgrind tool for
97ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   detecting memory errors.
107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11b3a1e4bffbdbbf38304f216af405009868f43628sewardj   Copyright (C) 2000-2015 Julian Seward
127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      jseward@acm.org
137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   This program is free software; you can redistribute it and/or
157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   modify it under the terms of the GNU General Public License as
167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   published by the Free Software Foundation; either version 2 of the
177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   License, or (at your option) any later version.
187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   This program is distributed in the hope that it will be useful, but
207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   General Public License for more details.
237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   You should have received a copy of the GNU General Public License
257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   along with this program; if not, write to the Free Software
267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   02111-1307, USA.
287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   The GNU General Public License is contained in the file COPYING.
307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj*/
317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_basics.h"
333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include "pub_tool_gdbserver.h"
346643e96a72e8530a7c8830c02ffb2fb4aee74c88philippe#include "pub_tool_poolalloc.h"     // For mc_include.h
357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_hashtable.h"     // For mc_include.h
367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcbase.h"
377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcassert.h"
387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcprint.h"
397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_machine.h"
407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_mallocfree.h"
417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_options.h"
427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_replacemalloc.h"
437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_tooliface.h"
447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_threadstate.h"
457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
466b523cd2df025375e86b161de9995187edf2fcb6sewardj#include "pub_tool_xarray.h"
47f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include "pub_tool_aspacemgr.h"
4807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_tool_addrinfo.h"
497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "mc_include.h"
517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Error types                                          ---*/
557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* See comment in mc_include.h */
587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(any_value_errors) = False;
597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* ------------------ Errors ----------------------- */
627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* What kind of error it is. */
647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Value,
677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Cond,
687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_CoreMem,
697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Addr,
707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Jump,
717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_RegParam,
727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_MemParam,
737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_User,
747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Free,
757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_FreeMismatch,
767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Overlap,
777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Leak,
787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_IllegalMempool,
797b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      Err_FishyValue,
807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_ErrorTag;
827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef struct _MC_Error MC_Error;
857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstruct _MC_Error {
877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //MC_ErrorTag tag;
897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   union {
917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value:
927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a pointer in a load or store
937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a jump target
947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT szB;   // size of value in bytes
967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Value;
1007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value in a conditional branch or move.
1027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Cond;
1077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Addressability error in core (signal-handling) operation.
1097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // It would be good to get rid of this error kind, merge it with
1107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // another one somehow.
1117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } CoreMem;
1137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an unaddressable memory location in a load or store.
1157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isWrite;    // read or write?
1177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT    szB;        // not used for exec (jump) errors
1187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     maybe_gcc;  // True if just below %esp -- could be a gcc bug
1197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Addr;
1217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Jump to an unaddressable memory location.
1237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Jump;
1267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call register input contains undefined bytes.
1287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } RegParam;
1337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call memory input contains undefined/unaddressable bytes
1357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
1377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } MemParam;
1427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
1447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
1467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } User;
1517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program tried to free() something that's not a heap block (this
1537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // covers double-frees). */
1547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Free;
1577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program allocates heap block with one function
1597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // (malloc/new/new[]/custom) and deallocates with not the matching one.
1607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } FreeMismatch;
1637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Call to strcpy, memcpy, etc, with overlapping blocks.
1657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
166dfa54a53736ab016611db71c37b3e34a96d9f604philippe         Addr  src;   // Source block
167dfa54a53736ab016611db71c37b3e34a96d9f604philippe         Addr  dst;   // Destination block
168dfa54a53736ab016611db71c37b3e34a96d9f604philippe         SizeT szB;   // Size in bytes;  0 if unused.
1697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Overlap;
1707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory leak.
1727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record;
1747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records;
175b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr;
1767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Leak;
1777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory pool error.
1797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } IllegalMempool;
1827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1837b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      // A fishy function argument value
1847b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      // An argument value is considered fishy if the corresponding
1857b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      // parameter has SizeT type and the value when interpreted as a
1867b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      // signed number is negative.
1877b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian     struct {
1887b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         const HChar *function_name;
1897b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         const HChar *argument_name;
1907b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         SizeT value;
1917b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      } FishyValue;
1927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   } Err;
1937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj};
1947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
1977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Printing errors                                      ---*/
1987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
1997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2006b523cd2df025375e86b161de9995187edf2fcb6sewardj/* This is the "this error is due to be printed shortly; so have a
2016b523cd2df025375e86b161de9995187edf2fcb6sewardj   look at it any print any preamble you want" function.  Which, in
2026b523cd2df025375e86b161de9995187edf2fcb6sewardj   Memcheck, we don't use.  Hence a no-op.
2036b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
2048e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid MC_(before_pp_Error) ( const Error* err ) {
2056b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2066b523cd2df025375e86b161de9995187edf2fcb6sewardj
2076b523cd2df025375e86b161de9995187edf2fcb6sewardj/* Do a printf-style operation on either the XML or normal output
2086b523cd2df025375e86b161de9995187edf2fcb6sewardj   channel, depending on the setting of VG_(clo_xml).
2096b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
210dbb3584f591710a15a437918c0fc27e300993566florianstatic void emit_WRK ( const HChar* format, va_list vargs )
2116b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2126b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (VG_(clo_xml)) {
2136b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vprintf_xml)(format, vargs);
2146b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
2156b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vmessage)(Vg_UserMsg, format, vargs);
2166b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
2176b523cd2df025375e86b161de9995187edf2fcb6sewardj}
218dbb3584f591710a15a437918c0fc27e300993566florianstatic void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2);
219dbb3584f591710a15a437918c0fc27e300993566florianstatic void emit ( const HChar* format, ... )
2206b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2216b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_list vargs;
2226b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_start(vargs, format);
2236b523cd2df025375e86b161de9995187edf2fcb6sewardj   emit_WRK(format, vargs);
2246b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_end(vargs);
2256b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2266b523cd2df025375e86b161de9995187edf2fcb6sewardj
2276b523cd2df025375e86b161de9995187edf2fcb6sewardj
2287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* str_leak_lossmode ( Reachedness lossmode )
2297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
2307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
2317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
2327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "definitely lost"; break;
2337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "indirectly lost"; break;
2348225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "possibly lost"; break;
2358225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "still reachable"; break;
2367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
2377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
2387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
2397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* xml_leak_kind ( Reachedness lossmode )
2417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
2427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
2437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
2447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "Leak_DefinitelyLost"; break;
2457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
2468225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "Leak_PossiblyLost"; break;
2478225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "Leak_StillReachable"; break;
2487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
2497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
2507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
2517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
252ec905f7ed1659f2251045114c785659fbb11ea88philippeconst HChar* MC_(parse_leak_kinds_tokens) =
253ec905f7ed1659f2251045114c785659fbb11ea88philippe   "reachable,possible,indirect,definite";
254ec905f7ed1659f2251045114c785659fbb11ea88philippe
255ec905f7ed1659f2251045114c785659fbb11ea88philippeUInt MC_(all_Reachedness)(void)
2562193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe{
257ec905f7ed1659f2251045114c785659fbb11ea88philippe   static UInt all;
258ec905f7ed1659f2251045114c785659fbb11ea88philippe
259ec905f7ed1659f2251045114c785659fbb11ea88philippe   if (all == 0) {
260ec905f7ed1659f2251045114c785659fbb11ea88philippe      // Compute a set with all values by doing a parsing of the "all" keyword.
261ec905f7ed1659f2251045114c785659fbb11ea88philippe      Bool parseok = VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
262ec905f7ed1659f2251045114c785659fbb11ea88philippe                                         True,/*allow_all*/
263ec905f7ed1659f2251045114c785659fbb11ea88philippe                                         "all",
264ec905f7ed1659f2251045114c785659fbb11ea88philippe                                         &all);
265ec905f7ed1659f2251045114c785659fbb11ea88philippe      tl_assert (parseok && all);
266ec905f7ed1659f2251045114c785659fbb11ea88philippe   }
267ec905f7ed1659f2251045114c785659fbb11ea88philippe
268ec905f7ed1659f2251045114c785659fbb11ea88philippe   return all;
2692193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe}
2702193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
2712193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippestatic const HChar* pp_Reachedness_for_leak_kinds(Reachedness r)
2722193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe{
2732193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   switch(r) {
2742193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   case Reachable:    return "reachable";
2752193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   case Possible:     return "possible";
2762193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   case IndirectLeak: return "indirect";
2772193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   case Unreached:    return "definite";
2782193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   default:           tl_assert(0);
2792193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   }
2802193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe}
2812193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
2827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void mc_pp_origin ( ExeContext* ec, UInt okind )
2837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
284a5f894c271248c13e0bb387e5ca33fa122b4819cflorian   const HChar* src = NULL;
2857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(ec);
2867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (okind) {
2887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_STACK:   src = " by a stack allocation"; break;
2897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_HEAP:    src = " by a heap allocation"; break;
2907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_USER:    src = " by a client request"; break;
2917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_UNKNOWN: src = ""; break;
2927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
2937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(src); /* guards against invalid 'okind' */
2947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(clo_xml)) {
2966b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( "  <auxwhat>Uninitialised value was created%s</auxwhat>\n",
2976b523cd2df025375e86b161de9995187edf2fcb6sewardj            src);
2986b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
2996b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
3006b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( " Uninitialised value was created%s\n", src);
3016b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
3027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
3037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
3047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
305dbb3584f591710a15a437918c0fc27e300993566florianHChar * MC_(snprintf_delta) (HChar * buf, Int size,
306dbb3584f591710a15a437918c0fc27e300993566florian                             SizeT current_val, SizeT old_val,
307dbb3584f591710a15a437918c0fc27e300993566florian                             LeakCheckDeltaMode delta_mode)
308c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj{
309cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   // Make sure the buffer size is large enough. With old_val == 0 and
310cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   // current_val == ULLONG_MAX the delta including inserted commas is:
311cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   // 18,446,744,073,709,551,615
312cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   // whose length is 26. Therefore:
313cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   tl_assert(size >= 26 + 4 + 1);
314cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian
315c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   if (delta_mode == LCD_Any)
316c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      buf[0] = '\0';
317c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   else if (current_val >= old_val)
318c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val);
319c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   else
320c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val);
321c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
322c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   return buf;
323c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj}
324c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
325a22f59db02284784a1e5e51587e2ce09db3a2a18philippestatic void pp_LossRecord(UInt n_this_record, UInt n_total_records,
326a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                          LossRecord* lr, Bool xml)
327a22f59db02284784a1e5e51587e2ce09db3a2a18philippe{
328a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   // char arrays to produce the indication of increase/decrease in case
329a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   // of delta_mode != LCD_Any
330cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   HChar d_bytes[31];
331cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   HChar d_direct_bytes[31];
332cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   HChar d_indirect_bytes[31];
333cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   HChar d_num_blocks[31];
334a22f59db02284784a1e5e51587e2ce09db3a2a18philippe
335cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   MC_(snprintf_delta) (d_bytes, sizeof(d_bytes),
336a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->szB + lr->indirect_szB,
337a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->old_szB + lr->old_indirect_szB,
338a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        MC_(detect_memory_leaks_last_delta_mode));
339cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes),
340a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->szB,
341a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->old_szB,
342a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        MC_(detect_memory_leaks_last_delta_mode));
343cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   MC_(snprintf_delta) (d_indirect_bytes, sizeof(d_indirect_bytes),
344a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->indirect_szB,
345a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        lr->old_indirect_szB,
346a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        MC_(detect_memory_leaks_last_delta_mode));
347cf6e734a9f88b521a5116b7ca119b3a26aede1a8florian   MC_(snprintf_delta) (d_num_blocks, sizeof(d_num_blocks),
348a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        (SizeT) lr->num_blocks,
349a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        (SizeT) lr->old_num_blocks,
350a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        MC_(detect_memory_leaks_last_delta_mode));
351a22f59db02284784a1e5e51587e2ce09db3a2a18philippe
352a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   if (xml) {
353a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      emit("  <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
354a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      if (lr->indirect_szB > 0) {
355a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "  <xwhat>\n" );
356a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "    <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
357a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               "in %'u%s blocks"
358a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               " are %s in loss record %'u of %'u</text>\n",
359a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->szB + lr->indirect_szB, d_bytes,
360a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->szB, d_direct_bytes,
361a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->indirect_szB, d_indirect_bytes,
362a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->num_blocks, d_num_blocks,
363a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               str_leak_lossmode(lr->key.state),
364a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               n_this_record, n_total_records );
365a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         // Nb: don't put commas in these XML numbers
366a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "    <leakedbytes>%lu</leakedbytes>\n",
367a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->szB + lr->indirect_szB );
368a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
369a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "  </xwhat>\n" );
370a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      } else {
371a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "  <xwhat>\n" );
372a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "    <text>%'lu%s bytes in %'u%s blocks"
373a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               " are %s in loss record %'u of %'u</text>\n",
374a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->szB, d_direct_bytes,
375a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               lr->num_blocks, d_num_blocks,
376a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               str_leak_lossmode(lr->key.state),
377a22f59db02284784a1e5e51587e2ce09db3a2a18philippe               n_this_record, n_total_records );
378de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian         emit( "    <leakedbytes>%lu</leakedbytes>\n", lr->szB);
379de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian         emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks);
380a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit( "  </xwhat>\n" );
381a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      }
382a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      VG_(pp_ExeContext)(lr->key.allocated_at);
383a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   } else { /* ! if (xml) */
384a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      if (lr->indirect_szB > 0) {
385a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit(
386a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
387a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            " are %s in loss record %'u of %'u\n",
388a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->szB + lr->indirect_szB, d_bytes,
389a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->szB, d_direct_bytes,
390a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->indirect_szB, d_indirect_bytes,
391a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->num_blocks, d_num_blocks,
392a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            str_leak_lossmode(lr->key.state),
393a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            n_this_record, n_total_records
394a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         );
395a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      } else {
396a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         emit(
397a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
398a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->szB, d_direct_bytes,
399a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            lr->num_blocks, d_num_blocks,
400a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            str_leak_lossmode(lr->key.state),
401a22f59db02284784a1e5e51587e2ce09db3a2a18philippe            n_this_record, n_total_records
402a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         );
403a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      }
404a22f59db02284784a1e5e51587e2ce09db3a2a18philippe      VG_(pp_ExeContext)(lr->key.allocated_at);
405a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   } /* if (xml) */
406a22f59db02284784a1e5e51587e2ce09db3a2a18philippe}
407a22f59db02284784a1e5e51587e2ce09db3a2a18philippe
408a22f59db02284784a1e5e51587e2ce09db3a2a18philippevoid MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records,
409a22f59db02284784a1e5e51587e2ce09db3a2a18philippe                        LossRecord* l)
410a22f59db02284784a1e5e51587e2ce09db3a2a18philippe{
411a22f59db02284784a1e5e51587e2ce09db3a2a18philippe   pp_LossRecord (n_this_record, n_total_records, l, /* xml */ False);
412a22f59db02284784a1e5e51587e2ce09db3a2a18philippe}
413a22f59db02284784a1e5e51587e2ce09db3a2a18philippe
4148e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid MC_(pp_Error) ( const Error* err )
4157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4166b523cd2df025375e86b161de9995187edf2fcb6sewardj   const Bool xml  = VG_(clo_xml); /* a shorthand */
4177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
4187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
4206b523cd2df025375e86b161de9995187edf2fcb6sewardj      case Err_CoreMem:
4217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
4227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
4237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            signal handler frame.  --njn */
4246b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
4256b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
4266b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4276b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>CoreMemError</kind>\n" );
4286d0e77bd100add36475334b3451586582d179021philippe            emit( "  <what>%pS contains unaddressable byte(s)</what>\n",
4296b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4306b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4316b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
4326b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s contains unaddressable byte(s)\n",
4336b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4346b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4356b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
4367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
4397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4406b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4416b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitValue</kind>\n" );
442de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian            emit( "  <what>Use of uninitialised value of size %lu</what>\n",
4436b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4446b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4456b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4466b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4476b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
4496b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
4506b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
451de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian            emit( "Use of uninitialised value of size %lu\n",
4526b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4536b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4546b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4556b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4566b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
4587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
4617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4626b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4636b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitCondition</kind>\n" );
4646b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Conditional jump or move depends"
4656b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)</what>\n" );
4666b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4676b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
4686b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
4696b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
4707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
4716b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
4726b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
4736b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Conditional jump or move depends"
4746b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)\n" );
4756b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4766b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
4776b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
4786b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
4797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
4807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
4837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4846b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4856b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
4866d0e77bd100add36475334b3451586582d179021philippe            emit( "  <what>Syscall param %pS contains "
4876b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "uninitialised byte(s)</what>\n",
4886b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
4896b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4906b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
4916b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
4926b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
4936b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
4946b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s contains uninitialised byte(s)\n",
4956b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
4966b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4976b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
4986b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
4996b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
5006b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
5047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.MemParam.isAddrErr)
5057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5066b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5076b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
5086d0e77bd100add36475334b3451586582d179021philippe            emit( "  <what>Syscall param %pS points to %s byte(s)</what>\n",
5096b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5106b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5116b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5126b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
51307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
51407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                &extra->Err.MemParam.ai, False);
5156b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5166b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5176b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5186b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5196b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5206b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s points to %s byte(s)\n",
5216b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5226b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5236b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5246b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
52507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
52607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                &extra->Err.MemParam.ai, False);
5276b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5286b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5296b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5306b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5316b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
5357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.User.isAddrErr)
5367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5376b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5386b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>ClientCheck</kind>\n" );
5396b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>%s byte(s) found "
5406b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "during client check request</what>\n",
5416b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5426b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5436b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
54407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
54507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                False);
5466b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5476b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5486b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5496b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5506b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s byte(s) found during client check request\n",
5516b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5526b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5536b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
55407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
55507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                False);
5566b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5576b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5586b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5596b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
5636b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5646b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidFree</kind>\n" );
565913473803432ee37d6edaf232e21978d4f426125bart            emit( "  <what>Invalid free() / delete / delete[]"
566913473803432ee37d6edaf232e21978d4f426125bart                  " / realloc()</what>\n" );
5676b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
56807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
56907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.Free.ai, False );
5706b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
571913473803432ee37d6edaf232e21978d4f426125bart            emit( "Invalid free() / delete / delete[] / realloc()\n" );
5726b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
57307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
57407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.Free.ai, False );
5756b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
5796b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5806b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>MismatchedFree</kind>\n" );
5816b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Mismatched free() / delete / delete []</what>\n" );
5826b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
58307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
58407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                &extra->Err.FreeMismatch.ai, False);
5856b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5866b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Mismatched free() / delete / delete []\n" );
5876b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
58807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
58907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                &extra->Err.FreeMismatch.ai, False);
5906b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
5946b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5956b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Invalid%s</kind>\n",
5966b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "Write" : "Read"  );
597de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian            emit( "  <what>Invalid %s of size %lu</what>\n",
5986b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
5996b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6006b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
60107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
60207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.Addr.ai,
60307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 extra->Err.Addr.maybe_gcc );
6047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
605de3df034fc4d7b42a86eb3d4c64fd15d840d092bflorian            emit( "Invalid %s of size %lu\n",
6066b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
6076b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6086b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6096b523cd2df025375e86b161de9995187edf2fcb6sewardj
61007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
61107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.Addr.ai,
61207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 extra->Err.Addr.maybe_gcc );
6137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
6147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
6176b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6186b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidJump</kind>\n" );
6196b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Jump to the invalid address stated "
6206b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "on the next line</what>\n" );
6216b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
62207c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
62307c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 False );
6246b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6256b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Jump to the invalid address stated on the next line\n" );
6266b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
62707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
62807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 False );
6296b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
6336b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6346b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Overlap</kind>\n" );
6356b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
6366d0e77bd100add36475334b3451586582d179021philippe               emit( "  <what>Source and destination overlap "
637b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart                     "in %pS(%#lx, %#lx)\n</what>\n",
6386b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6396b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6406b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
6416b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <what>Source and destination overlap "
6426a90cfb1b6f4f8ab35295e316b3cba5b18418f1bflorian                     "in %pS(%#lx, %#lx, %lu)</what>\n",
6436b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6446b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6456b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6466b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6476b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6486b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6496b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
6506a90cfb1b6f4f8ab35295e316b3cba5b18418f1bflorian               emit( "Source and destination overlap in %s(%#lx, %#lx)\n",
6516b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6526b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6536b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
654dfa54a53736ab016611db71c37b3e34a96d9f604philippe               emit( "Source and destination overlap in %s(%#lx, %#lx, %lu)\n",
6556b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6566b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6576b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6586b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6596b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6606b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
6646b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
6656b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
6666b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6676b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidMemPool</kind>\n" );
6686b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Illegal memory pool address</what>\n" );
6696b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
67007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
67107c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.IllegalMempool.ai, False );
6726b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6736b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Illegal memory pool address\n" );
6746b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
67507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
67607c08527f05caeb0062b42ca9a58ee774ec5fba1philippe                                 &extra->Err.IllegalMempool.ai, False );
6776b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak: {
6817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record   = extra->Err.Leak.n_this_record;
6827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records = extra->Err.Leak.n_total_records;
683b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr              = extra->Err.Leak.lr;
684a22f59db02284784a1e5e51587e2ce09db3a2a18philippe         pp_LossRecord (n_this_record, n_total_records, lr, xml);
6857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
6877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6887b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      case Err_FishyValue:
6897b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         if (xml) {
6907b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            emit( "  <kind>FishyValue</kind>\n" );
6917b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            emit( "  <what>");
6927b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            emit( "Argument '%s' of function %s has a fishy "
6937b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  "(possibly negative) value: %ld\n",
6947b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  extra->Err.FishyValue.argument_name,
6957b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  extra->Err.FishyValue.function_name,
6967b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  (SSizeT)extra->Err.FishyValue.value);
6977b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            emit( "</what>");
6987b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6997b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         } else {
7007b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            emit( "Argument '%s' of function %s has a fishy "
7017b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  "(possibly negative) value: %ld\n",
7027b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  extra->Err.FishyValue.argument_name,
7037b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  extra->Err.FishyValue.function_name,
7047b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                  (SSizeT)extra->Err.FishyValue.value);
7057b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
7067b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         }
7077b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         break;
7087b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
7097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
7107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown Memcheck error code %d\n",
7117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(err));
7127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_pp_Error)");
7137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
7147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
7177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Recording errors                                     ---*/
7187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
7197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* These many bytes below %ESP are considered addressible if we're
7217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   doing the --workaround-gcc296-bugs hack. */
7227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#define VG_GCC296_BUG_STACK_SLOP 1024
7237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Is this address within some small distance below %ESP?  Used only
7257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for the --workaround-gcc296-bugs kludge. */
7267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool is_just_below_ESP( Addr esp, Addr aa )
7277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7287d751b2b72d806d1ef747f8ee661aeb52e7563aasewardj   esp -= VG_STACK_REDZONE_SZB;
7297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
7307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return True;
7317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
7327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
7337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from generated and non-generated code --- */
7367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
7387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Bool isWrite )
7397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
7417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool     just_below_esp;
7427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(in_ignored_range)(a))
7447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
7457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB))
7473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return;
7483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
7507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* If this is caused by an access immediately below %ESP, and the
7527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      user asks nicely, we just ignore it. */
7537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
7547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
7557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.isWrite   = isWrite;
7577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.szB       = szB;
7587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.maybe_gcc = just_below_esp;
7597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.ai.tag    = Addr_Undescribed;
7607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
7617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
7647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
7667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
7677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
7687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
7697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.szB       = szB;
7707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.otag      = otag;
7717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.origin_ec = NULL;  /* Filled in later */
7727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
7737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_cond_error) ( ThreadId tid, UInt otag )
7767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
7787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
7797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
7807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
7817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.otag      = otag;
7827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
7837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
7847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from non-generated code --- */
7877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7881dcee097db02f9ef3ba355162c4373d90d0e895cnjn/* This is for memory errors in signal-related memory. */
789e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianvoid MC_(record_core_mem_error) ( ThreadId tid, const HChar* msg )
7907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
7927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
794e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianvoid MC_(record_regparam_error) ( ThreadId tid, const HChar* msg, UInt otag )
7957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
7977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
7987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
7997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.otag      = otag;
8017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
8027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
8037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_memparam_error) ( ThreadId tid, Addr a,
806e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian                                  Bool isAddrErr, const HChar* msg, UInt otag )
8077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr)
8117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
8127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
8137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( !isAddrErr );
8157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
8167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.isAddrErr = isAddrErr;
8177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.ai.tag    = Addr_Undescribed;
8187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.otag      = otag;
8197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
8207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
8217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_jump_error) ( ThreadId tid, Addr a )
8247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Jump.ai.tag = Addr_Undescribed;
8287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
8297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_free_error) ( ThreadId tid, Addr a )
8327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Free.ai.tag = Addr_Undescribed;
8367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
8377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
8407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrInfo* ai = &extra.Err.FreeMismatch.ai;
8437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->tag = Addr_Block;
8457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
8467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_desc = "block";
8477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_szB  = mc->szB;
8487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.rwoffset   = 0;
8498617b5b8f16570c9003379464d60e8572a801a8cphilippe   ai->Addr.Block.allocated_at = MC_(allocated_at) (mc);
8500c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe   VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
8518617b5b8f16570c9003379464d60e8572a801a8cphilippe   ai->Addr.Block.freed_at = MC_(freed_at) (mc);
8527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
8537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            &extra );
8547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
8577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
8617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
8627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
864e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianvoid MC_(record_overlap_error) ( ThreadId tid, const HChar* function,
8657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Addr src, Addr dst, SizeT szB )
8667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.src = src;
8707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.dst = dst;
8717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.szB = szB;
8727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)(
8737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
8747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
877b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn                              UInt n_total_records, LossRecord* lr,
87818afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                              Bool print_record, Bool count_error )
8797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_this_record   = n_this_record;
8827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_total_records = n_total_records;
883b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn   extra.Err.Leak.lr              = lr;
8847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return
8857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
88629a5c01528ca7cffe17880a038b4563de920f08dnjn                       lr->key.allocated_at, print_record,
88718afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                       /*allow_GDB_attach*/False, count_error );
8887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8907b6899dd211aafa1e0d3e3a0dc0cf798ea882768florianBool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name,
8917b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                                     const HChar *argument_name, SizeT value)
8927b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian{
8937b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   MC_Error extra;
8947b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
8957b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   tl_assert(VG_INVALID_THREADID != tid);
8967b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
8977b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   if ((SSizeT)value >= 0) return False;  // not a fishy value
8987b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
8997b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   extra.Err.FishyValue.function_name = function_name;
9007b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   extra.Err.FishyValue.argument_name = argument_name;
9017b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   extra.Err.FishyValue.value = value;
9027b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
9037b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   VG_(maybe_record_error)(
9047b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      tid, Err_FishyValue, /*addr*/0, /*s*/NULL, &extra );
9057b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
9067b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   return True;
9077b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian}
9087b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
9097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_user_error) ( ThreadId tid, Addr a,
9107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                              Bool isAddrErr, UInt otag )
9117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
9147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(!isAddrErr);
9157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
9167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr) {
9187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
9197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.isAddrErr = isAddrErr;
9227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.ai.tag    = Addr_Undescribed;
9237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.otag      = otag;
9247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.origin_ec = NULL;  /* Filled in later */
9257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
9267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
9297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Other error operations                               ---*/
9307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
9317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Compare error contexts, to detect duplicates.  Note that if they
9337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are otherwise the same, the faulting addrs and associated rwoffsets
9347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are allowed to be different.  */
9358e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianBool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 )
9367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra1 = VG_(get_error_extra)(e1);
9387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra2 = VG_(get_error_extra)(e2);
9397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Guaranteed by calling function */
9417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
9427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(e1)) {
9447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_CoreMem: {
945e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian         const HChar *e1s, *e2s;
9467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e1s = VG_(get_error_string)(e1);
9477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e2s = VG_(get_error_string)(e2);
9487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (e1s == e2s)                   return True;
9497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (VG_STREQ(e1s, e2s))           return True;
9507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return False;
9517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
9527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
9547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
9557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Perhaps we should also check the addrinfo.akinds for equality.
9577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // That would result in more error reports, but only in cases where
9587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // a register contains uninitialised bytes and points to memory
9597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // containing uninitialised bytes.  Currently, the 2nd of those to be
9607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // detected won't be reported.  That is (nearly?) always the memory
9617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // error, which is good.
9627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
9637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!VG_STREQ(VG_(get_error_string)(e1),
9647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                       VG_(get_error_string)(e2))) return False;
9657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // fall through
9667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
9677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
9687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
9697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
9717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
9727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
9737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
9747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
9757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
9767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
9777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9787b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      case Err_FishyValue:
9797b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         return VG_STREQ(extra1->Err.FishyValue.function_name,
9807b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                         extra2->Err.FishyValue.function_name) &&
9817b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                VG_STREQ(extra1->Err.FishyValue.argument_name,
9827b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                         extra2->Err.FishyValue.argument_name);
9837b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
9847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
9857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
9867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
9877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
9897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Value.szB == extra2->Err.Value.szB
9907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
9917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak:
9937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
9947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "since it's handled with VG_(unique_error)()!");
9957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
9977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown error code %d\n",
9987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(e1));
9997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_eq_Error");
10007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
10017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
10027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
100362b9104a05dede4b9cabfaa483da76480131127esewardj/* Functions used when searching MC_Chunk lists */
100462b9104a05dede4b9cabfaa483da76480131127esewardjstatic
100562b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
10067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1008d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe                                 MC_(Malloc_Redzone_SzB) );
10097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
101062b9104a05dede4b9cabfaa483da76480131127esewardjstatic
101162b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
101262b9104a05dede4b9cabfaa483da76480131127esewardj{
101362b9104a05dede4b9cabfaa483da76480131127esewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
101462b9104a05dede4b9cabfaa483da76480131127esewardj                                 rzB );
101562b9104a05dede4b9cabfaa483da76480131127esewardj}
10167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
101762b9104a05dede4b9cabfaa483da76480131127esewardj// Forward declarations
10187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
101962b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
10207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Describe an address as best you can, for error messages,
10237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   putting the result in ai. */
10247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
10257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Chunk*  mc;
10277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(Addr_Undescribed == ai->tag);
10297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
103062b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's a user-named block? -- */
10317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (client_block_maybe_describe( a, ai )) {
10327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
10337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
103462b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's in mempool block? -- */
103562b9104a05dede4b9cabfaa483da76480131127esewardj   if (mempool_block_maybe_describe( a, ai )) {
103662b9104a05dede4b9cabfaa483da76480131127esewardj      return;
103762b9104a05dede4b9cabfaa483da76480131127esewardj   }
103811cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe   /* Blocks allocated by memcheck malloc functions are either
103911cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      on the recently freed list or on the malloc-ed list.
104011cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      Custom blocks can be on both : a recently freed block might
104111cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      have been just re-allocated.
104211cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      So, first search the malloc-ed block, as the most recent
104311cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      block is the probable cause of error.
104411cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      We however detect and report that this is a recently re-allocated
104511cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      block. */
10466b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Search for a currently malloc'd block which might bracket it. -- */
10477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(HT_ResetIter)(MC_(malloc_list));
10487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
104962b9104a05dede4b9cabfaa483da76480131127esewardj      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
10507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
10517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_Mallocd;
105211cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe         if (MC_(get_freed_block_bracketting)( a ))
105311cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe            ai->Addr.Block.block_desc = "recently re-allocated block";
105411cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe         else
105511cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe            ai->Addr.Block.block_desc = "block";
10567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = mc->szB;
105756adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
10588617b5b8f16570c9003379464d60e8572a801a8cphilippe         ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
10590c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe         VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
10608617b5b8f16570c9003379464d60e8572a801a8cphilippe         ai->Addr.Block.freed_at = MC_(freed_at)(mc);
10617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
10627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
10637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
106411cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe   /* -- Search for a recently freed block which might bracket it. -- */
106511cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe   mc = MC_(get_freed_block_bracketting)( a );
106611cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe   if (mc) {
106711cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      ai->tag = Addr_Block;
106811cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      ai->Addr.Block.block_kind = Block_Freed;
106911cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      ai->Addr.Block.block_desc = "block";
107011cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      ai->Addr.Block.block_szB  = mc->szB;
107111cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
10728617b5b8f16570c9003379464d60e8572a801a8cphilippe      ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
10730c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe      VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
10748617b5b8f16570c9003379464d60e8572a801a8cphilippe      ai->Addr.Block.freed_at = MC_(freed_at)(mc);
107511cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe      return;
107611cc9cecfee993abfdf1e6e4c9731f46fd4276d1philippe   }
107707c08527f05caeb0062b42ca9a58ee774ec5fba1philippe
107807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe   /* No block found. Search a non-heap block description. */
107907c08527f05caeb0062b42ca9a58ee774ec5fba1philippe   VG_(describe_addr) (a, ai);
10807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
10817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid MC_(pp_describe_addr) ( Addr a )
10833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
10843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   AddrInfo ai;
10853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ai.tag = Addr_Undescribed;
10873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   describe_addr (a, &ai);
108807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe   VG_(pp_addrinfo_mc) (a, &ai, /* maybe_gcc */ False);
1089f7ec77f53fd09a5682dbe6db049efe0746df7948philippe   VG_(clear_addrinfo) (&ai);
10903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
10913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Fill in *origin_ec as specified by otag, or NULL it out if otag
10937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   does not refer to a known origin. */
10947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void update_origin ( /*OUT*/ExeContext** origin_ec,
10957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            UInt otag )
10967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UInt ecu = otag & ~3;
10987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   *origin_ec = NULL;
10997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(is_plausible_ECU)(ecu)) {
11007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
11017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
11037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Updates the copy with address info if necessary (but not for all errors). */
11058e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianUInt MC_(update_Error_extra)( const Error* err )
11067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
11077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
11087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
11107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones don't have addresses associated with them, and so don't
11117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // need any updating.
11127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:
11137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Value:
11147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Cond:
11157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:
11167b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   case Err_FishyValue:
11177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For Err_Leaks the returned size does not matter -- they are always
11187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // shown with VG_(unique_error)() so they 'extra' not copied.  But
11197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we make it consistent with the others.
11207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:
11217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For value errors, get the ExeContext corresponding to the
11247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // origin tag.  Note that it is a kludge to assume that
11257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // a length-1 trace indicates a stack origin.  FIXME.
11267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value:
11277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Value.origin_ec,
11287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Value.otag );
11297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:
11317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Cond.origin_ec,
11327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Cond.otag );
11337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:
11357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.RegParam.origin_ec,
11367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.RegParam.otag );
11377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones always involve a memory address.
11407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr:
11417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Addr.ai );
11437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:
11457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.MemParam.ai );
11477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.MemParam.origin_ec,
11487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.MemParam.otag );
11497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:
11517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Jump.ai );
11537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:
11557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.User.ai );
11577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.User.origin_ec,
11587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.User.otag );
11597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:
11617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Free.ai );
11637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool:
11657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
11667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.IllegalMempool.ai );
11677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Err_FreeMismatches have already had their address described;  this is
11707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // possible because we have the MC_Chunk on hand when the error is
11717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // detected.  However, the address may be part of a user block, and if so
11727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we override the pre-determined description with a user block one.
11737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch: {
11747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(extra && Block_Mallocd ==
11757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
11767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      (void)client_block_maybe_describe( VG_(get_error_address)(err),
11777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                        &extra->Err.FreeMismatch.ai );
11787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
11797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default: VG_(tool_panic)("mc_update_extra: bad errkind");
11827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
11847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
118562b9104a05dede4b9cabfaa483da76480131127esewardj
11867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a,
11877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                         /*OUT*/AddrInfo* ai )
11887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
118956adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj   UWord      i;
11907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   CGenBlock* cgbs = NULL;
11917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UWord      cgb_used = 0;
119256adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj
11937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
11947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (cgbs == NULL)
11957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(cgb_used == 0);
11967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Perhaps it's a general block ? */
11987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for (i = 0; i < cgb_used; i++) {
11997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (cgbs[i].start == 0 && cgbs[i].size == 0)
12007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         continue;
12017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use zero as the redzone for client blocks.
12027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
12037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
12047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_UserG;
12057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = cgbs[i].desc;
12067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = cgbs[i].size;
120756adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
12088617b5b8f16570c9003379464d60e8572a801a8cphilippe         ai->Addr.Block.allocated_at = cgbs[i].where;
12090c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe         VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
12108617b5b8f16570c9003379464d60e8572a801a8cphilippe         ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
12117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
12127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
12137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return False;
12157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
12167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
121862b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a,
121962b9104a05dede4b9cabfaa483da76480131127esewardj                                          /*OUT*/AddrInfo* ai )
122062b9104a05dede4b9cabfaa483da76480131127esewardj{
122162b9104a05dede4b9cabfaa483da76480131127esewardj   MC_Mempool* mp;
122262b9104a05dede4b9cabfaa483da76480131127esewardj   tl_assert( MC_(mempool_list) );
122362b9104a05dede4b9cabfaa483da76480131127esewardj
122462b9104a05dede4b9cabfaa483da76480131127esewardj   VG_(HT_ResetIter)( MC_(mempool_list) );
122562b9104a05dede4b9cabfaa483da76480131127esewardj   while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
122662b9104a05dede4b9cabfaa483da76480131127esewardj      if (mp->chunks != NULL) {
122762b9104a05dede4b9cabfaa483da76480131127esewardj         MC_Chunk* mc;
122862b9104a05dede4b9cabfaa483da76480131127esewardj         VG_(HT_ResetIter)(mp->chunks);
122962b9104a05dede4b9cabfaa483da76480131127esewardj         while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
123062b9104a05dede4b9cabfaa483da76480131127esewardj            if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
123162b9104a05dede4b9cabfaa483da76480131127esewardj               ai->tag = Addr_Block;
123262b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_kind = Block_MempoolChunk;
123362b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_desc = "block";
123462b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_szB  = mc->szB;
123562b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
12368617b5b8f16570c9003379464d60e8572a801a8cphilippe               ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
12370c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe               VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
12388617b5b8f16570c9003379464d60e8572a801a8cphilippe               ai->Addr.Block.freed_at = MC_(freed_at)(mc);
123962b9104a05dede4b9cabfaa483da76480131127esewardj               return True;
124062b9104a05dede4b9cabfaa483da76480131127esewardj            }
124162b9104a05dede4b9cabfaa483da76480131127esewardj         }
124262b9104a05dede4b9cabfaa483da76480131127esewardj      }
124362b9104a05dede4b9cabfaa483da76480131127esewardj   }
124462b9104a05dede4b9cabfaa483da76480131127esewardj   return False;
124562b9104a05dede4b9cabfaa483da76480131127esewardj}
124662b9104a05dede4b9cabfaa483da76480131127esewardj
124762b9104a05dede4b9cabfaa483da76480131127esewardj
12487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
12497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Suppressions                                         ---*/
12507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
12517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
12537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
12547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ParamSupp,     // Bad syscall params
12557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      UserSupp,      // Errors arising from client-request checks
12567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
12577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value errors of given size
12599d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, Value32Supp,
12607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value error in conditional.
12627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CondSupp,
12637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Unaddressable read/write attempt at given size
12659d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp,
12667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      JumpSupp,      // Jump to unaddressable target
12687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      FreeSupp,      // Invalid or mismatching free
12697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
12707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      LeakSupp,      // Something to be suppressed in a leak check.
12717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MempoolSupp,   // Memory pool suppression.
12727b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      FishyValueSupp,// Fishy value suppression.
12737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_SuppKind;
12757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
127619f91bbaedb4caef8a60ce94b0f507193cc0bc10florianBool MC_(is_recognised_suppression) ( const HChar* name, Supp* su )
12777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
12787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   SuppKind skind;
12797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
12817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "User"))    skind = UserSupp;
12827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
12837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
12847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
12857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
12867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
12877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
12889d83e99f26cc6501c491912512d21f2e3200a03arhyskidd   else if (VG_STREQ(name, "Addr32"))  skind = Addr32Supp;
12897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
12907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
12917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
12927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
12937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
12947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
12957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
12967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
12977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
12987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
12997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
13007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
13019d83e99f26cc6501c491912512d21f2e3200a03arhyskidd   else if (VG_STREQ(name, "Value32")) skind = Value32Supp;
13027b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp;
13037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
13047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
13057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(set_supp_kind)(su, skind);
13077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
13087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13102193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippetypedef struct _MC_LeakSuppExtra MC_LeakSuppExtra;
13112193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
13122193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippestruct _MC_LeakSuppExtra {
13132193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   UInt match_leak_kinds;
13144e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe
13154e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   /* Maintains nr of blocks and bytes suppressed with this suppression
13164e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      during the leak search identified by leak_search_gen.
13174e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      blocks_suppressed and bytes_suppressed are reset to 0 when
13184e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      used the first time during a leak search. */
13194e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   SizeT blocks_suppressed;
13204e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   SizeT bytes_suppressed;
13214e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   UInt  leak_search_gen;
13222193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe};
13232193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
13247b6899dd211aafa1e0d3e3a0dc0cf798ea882768floriantypedef struct {
13257b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   const HChar *function_name;
13267b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   const HChar *argument_name;
13277b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian} MC_FishyValueExtra;
13287b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
132919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianBool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
1330362441db825242200142a91bb07c4a0300b36a3ephilippe                                        SizeT* nBufp, Int* lineno, Supp *su )
13317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
13327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool eof;
13332193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   Int i;
13347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(get_supp_kind)(su) == ParamSupp) {
1336362441db825242200142a91bb07c4a0300b36a3ephilippe      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
13377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (eof) return False;
133835db56c19847654f22b62da059083d41ff4258c5njn      VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
13392193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   } else if (VG_(get_supp_kind)(su) == LeakSupp) {
13402193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      // We might have the optional match-leak-kinds line
13412193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      MC_LeakSuppExtra* lse;
13422193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
1343ec905f7ed1659f2251045114c785659fbb11ea88philippe      lse->match_leak_kinds = MC_(all_Reachedness)();
13444e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      lse->blocks_suppressed = 0;
13454e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      lse->bytes_suppressed = 0;
13464e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      lse->leak_search_gen = 0;
13472193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
1348362441db825242200142a91bb07c4a0300b36a3ephilippe      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
13492193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
13502193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) {
13512193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         i = 17;
13522193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         while ((*bufpp)[i] && VG_(isspace((*bufpp)[i])))
13532193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            i++;
1354ec905f7ed1659f2251045114c785659fbb11ea88philippe         if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
1355ec905f7ed1659f2251045114c785659fbb11ea88philippe                                  True/*allow_all*/,
1356ec905f7ed1659f2251045114c785659fbb11ea88philippe                                  (*bufpp)+i, &lse->match_leak_kinds)) {
13572193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            return False;
13582193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         }
13592193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      } else {
13602193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         return False; // unknown extra line.
13612193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      }
13627b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   } else if (VG_(get_supp_kind)(su) == FishyValueSupp) {
13637b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      MC_FishyValueExtra *extra;
1364659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      HChar *p, *function_name, *argument_name = NULL;
13657b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
13667b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
13677b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      if (eof) return True;
13687b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
13697b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      // The suppression string is: function_name(argument_name)
1370659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      function_name = VG_(strdup)("mv.resi.4", *bufpp);
1371659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      p = VG_(strchr)(function_name, '(');
1372659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      if (p != NULL) {
1373659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         *p++ = '\0';
1374659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         argument_name = p;
1375659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         p = VG_(strchr)(p, ')');
1376659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         if (p != NULL)
1377659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian            *p = '\0';
1378659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      }
1379659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      if (p == NULL) {    // malformed suppression string
1380659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         VG_(free)(function_name);
1381659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian         return False;
1382659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      }
1383659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian
1384659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      extra = VG_(malloc)("mc.resi.3", sizeof *extra);
1385659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      extra->function_name = function_name;
1386659efdee5b18c6c0ca3e6a1ff395be813ebb4a72florian      extra->argument_name = argument_name;
13877b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
13887b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      VG_(set_supp_extra)(su, extra);
13897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
13917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13938e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianBool MC_(error_matches_suppression) ( const Error* err, const Supp* su )
13947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
13957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Int       su_szB;
13967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
13977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
13987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_supp_kind)(su)) {
14007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case ParamSupp:
14017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ((ekind == Err_RegParam || ekind == Err_MemParam)
14027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case UserSupp:
14067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_User);
14077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CoreMemSupp:
14097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_CoreMem
14107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value1Supp: su_szB = 1; goto value_case;
14147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value2Supp: su_szB = 2; goto value_case;
14157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value4Supp: su_szB = 4; goto value_case;
14167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value8Supp: su_szB = 8; goto value_case;
14177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value16Supp:su_szB =16; goto value_case;
14189d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      case Value32Supp:su_szB =32; goto value_case;
14197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      value_case:
14207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
14217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CondSupp:
14237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Cond);
14247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr1Supp: su_szB = 1; goto addr_case;
14267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr2Supp: su_szB = 2; goto addr_case;
14277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr4Supp: su_szB = 4; goto addr_case;
14287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr8Supp: su_szB = 8; goto addr_case;
14297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr16Supp:su_szB =16; goto addr_case;
14309d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      case Addr32Supp:su_szB =32; goto addr_case;
14317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      addr_case:
14327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
14337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case JumpSupp:
14357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Jump);
14367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case FreeSupp:
14387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Free || ekind == Err_FreeMismatch);
14397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case OverlapSupp:
14417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Overlap);
14427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case LeakSupp:
14442193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         if (ekind == Err_Leak) {
14452193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
14464e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe            if (lse->leak_search_gen != MC_(leak_search_gen)) {
14474e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe               // First time we see this suppression during this leak search.
14484e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe               // => reset the counters to 0.
14494e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe               lse->blocks_suppressed = 0;
14504e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe               lse->bytes_suppressed = 0;
14514e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe               lse->leak_search_gen = MC_(leak_search_gen);
14524e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe            }
14532193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
14542193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         } else
14552193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            return False;
14567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MempoolSupp:
14587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_IllegalMempool);
14597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14607b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      case FishyValueSupp: {
14617b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su);
14627b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
14637b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian         return (ekind == Err_FishyValue) &&
14647b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                VG_STREQ(extra->Err.FishyValue.function_name,
14657b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                         supp_extra->function_name) &&
14667b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                VG_STREQ(extra->Err.FishyValue.argument_name,
14677b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian                         supp_extra->argument_name);
14687b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      }
14697b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian
14707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
14717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n"
14727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     "  unknown suppression type %d\n",
14737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_supp_kind)(su));
14747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown suppression type in "
14757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "MC_(error_matches_suppression)");
14767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14798e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianconst HChar* MC_(get_error_name) ( const Error* err )
14807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
14817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
14827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:       return "Param";
14837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:       return "Param";
14847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:           return "User";
14857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch:   return "Free";
14867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool: return "Mempool";
14877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:           return "Free";
14887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:           return "Jump";
14897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:        return "CoreMem";
14907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:        return "Overlap";
14917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:           return "Leak";
14927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:           return "Cond";
14937b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   case Err_FishyValue:     return "FishyValue";
14947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr: {
14957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
14967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Addr.szB ) {
14977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Addr1";
14987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Addr2";
14997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Addr4";
15007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Addr8";
15017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Addr16";
15029d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      case 32:              return "Addr32";
15037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Addr");
15047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
15057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value: {
15077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
15087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Value.szB ) {
15097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Value1";
15107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Value2";
15117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Value4";
15127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Value8";
15137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Value16";
15149d83e99f26cc6501c491912512d21f2e3200a03arhyskidd      case 32:              return "Value32";
15157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Value");
15167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
15177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default:                 VG_(tool_panic)("get_error_name: unexpected type");
15197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15228e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianSizeT MC_(get_extra_suppression_info) ( const Error* err,
15233e81b8bed1f7ab6848a83f5507487131a6f9d778florian                                        /*OUT*/HChar* buf, Int nBuf )
15247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
15257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
1526588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   tl_assert(buf);
15273e81b8bed1f7ab6848a83f5507487131a6f9d778florian   tl_assert(nBuf >= 1);
15283e81b8bed1f7ab6848a83f5507487131a6f9d778florian
15297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (Err_RegParam == ekind || Err_MemParam == ekind) {
1530e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian      const HChar* errstr = VG_(get_error_string)(err);
1531588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      tl_assert(errstr);
15323e81b8bed1f7ab6848a83f5507487131a6f9d778florian      return VG_(snprintf)(buf, nBuf, "%s", errstr);
15332193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   } else if (Err_Leak == ekind) {
15342193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      MC_Error* extra = VG_(get_error_extra)(err);
15353e81b8bed1f7ab6848a83f5507487131a6f9d778florian      return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s",
15362193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe          pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state));
15377b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian   } else if (Err_FishyValue == ekind) {
15387b6899dd211aafa1e0d3e3a0dc0cf798ea882768florian      MC_Error* extra = VG_(get_error_extra)(err);
15393e81b8bed1f7ab6848a83f5507487131a6f9d778florian      return VG_(snprintf) (buf, nBuf, "%s(%s)",
15403e81b8bed1f7ab6848a83f5507487131a6f9d778florian                            extra->Err.FishyValue.function_name,
15413e81b8bed1f7ab6848a83f5507487131a6f9d778florian                            extra->Err.FishyValue.argument_name);
1542588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   } else {
15433e81b8bed1f7ab6848a83f5507487131a6f9d778florian      buf[0] = '\0';
15443e81b8bed1f7ab6848a83f5507487131a6f9d778florian      return 0;
15457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15488e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianSizeT MC_(print_extra_suppression_use) ( const Supp *su,
15493e81b8bed1f7ab6848a83f5507487131a6f9d778florian                                         /*OUT*/HChar *buf, Int nBuf )
15504e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe{
15513e81b8bed1f7ab6848a83f5507487131a6f9d778florian   tl_assert(nBuf >= 1);
15523e81b8bed1f7ab6848a83f5507487131a6f9d778florian
15534e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   if (VG_(get_supp_kind)(su) == LeakSupp) {
15544e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
15554e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe
15564e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      if (lse->leak_search_gen == MC_(leak_search_gen)
15574e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe          && lse->blocks_suppressed > 0) {
15583e81b8bed1f7ab6848a83f5507487131a6f9d778florian         return VG_(snprintf) (buf, nBuf,
15593e81b8bed1f7ab6848a83f5507487131a6f9d778florian                               "suppressed: %'lu bytes in %'lu blocks",
15603e81b8bed1f7ab6848a83f5507487131a6f9d778florian                               lse->bytes_suppressed,
15613e81b8bed1f7ab6848a83f5507487131a6f9d778florian                               lse->blocks_suppressed);
15623e81b8bed1f7ab6848a83f5507487131a6f9d778florian      }
15633e81b8bed1f7ab6848a83f5507487131a6f9d778florian   }
15643e81b8bed1f7ab6848a83f5507487131a6f9d778florian
15653e81b8bed1f7ab6848a83f5507487131a6f9d778florian   buf[0] = '\0';
15663e81b8bed1f7ab6848a83f5507487131a6f9d778florian   return 0;
15674e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe}
15684e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe
15698e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid MC_(update_extra_suppression_use) ( const Error* err, const Supp* su)
15704e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe{
15714e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   if (VG_(get_supp_kind)(su) == LeakSupp) {
15724e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
15734e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      MC_Error* extra = VG_(get_error_extra)(err);
15744e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe
1575e4200b5083e7bb1b81cb98de1744a0c0f3663e56philippe      tl_assert (lse->leak_search_gen == MC_(leak_search_gen));
15764e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
15774e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      lse->bytes_suppressed
15784e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
15794e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe   }
15804e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe}
15817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
15837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- end                                              mc_errors.c ---*/
15847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
1585