mc_errors.c revision b3af9cf0b234d0d188347d92944e04ac9c8fbcd0
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
119eecbbb9a9cbbd30b903c09a9e04d8efc20bda33sewardj   Copyright (C) 2000-2010 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"
347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_hashtable.h"     // For mc_include.h
357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcbase.h"
367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcassert.h"
377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcprint.h"
387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_machine.h"
397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_mallocfree.h"
407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_options.h"
417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_replacemalloc.h"
427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_tooliface.h"
437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_threadstate.h"
447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
456b523cd2df025375e86b161de9995187edf2fcb6sewardj#include "pub_tool_xarray.h"
467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "mc_include.h"
487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Error types                                          ---*/
527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* See comment in mc_include.h */
557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(any_value_errors) = False;
567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj// Different kinds of blocks.
597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef enum {
607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Mallocd = 111,
617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Freed,
627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Mempool,
637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_MempoolChunk,
647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_UserG
657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj} BlockKind;
667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* ------------------ Addresses -------------------- */
687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* The classification of a faulting address. */
707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Undescribed, // as-yet unclassified
737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Unknown,     // classification yielded nothing useful
747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Block,       // in malloc'd/free'd block
757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Stack,       // on a thread's stack
767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_DataSym,     // in a global data sym
777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Variable,    // variable described by the debug info
787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_SectKind     // last-ditch classification attempt
797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrTag;
817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   struct _AddrInfo
847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrInfo;
857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstruct _AddrInfo {
877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrTag tag;
887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   union {
897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // As-yet unclassified.
907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct { } Undescribed;
917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // On a stack.
937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ThreadId tid;        // Which thread's stack?
957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Stack;
967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // This covers heap blocks (normal and from mempools) and user-defined
987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // blocks.
997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         BlockKind   block_kind;
1017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char*       block_desc;    // "block", "mempool" or user-defined
1027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT       block_szB;
103c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT    rwoffset;
1047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* lastchange;
1057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Block;
1067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
107c4431bfe04c7490ea2d74939d222d87f13f30960njn      // In a global .data symbol.  This holds the first 127 chars of
108c4431bfe04c7490ea2d74939d222d87f13f30960njn      // the variable's name (zero terminated), plus a (memory) offset.
1097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
110c4431bfe04c7490ea2d74939d222d87f13f30960njn         Char     name[128];
111c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT offset;
1127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } DataSym;
1137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1146b523cd2df025375e86b161de9995187edf2fcb6sewardj      // Is described by Dwarf debug info.  XArray*s of HChar.
1157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1166b523cd2df025375e86b161de9995187edf2fcb6sewardj         XArray* /* of HChar */ descr1;
1176b523cd2df025375e86b161de9995187edf2fcb6sewardj         XArray* /* of HChar */ descr2;
1187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Variable;
1197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Could only narrow it down to be the PLT/GOT/etc of a given
1217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // object.  Better than nothing, perhaps.
1227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char       objname[128];
1247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VgSectKind kind;
1257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } SectKind;
1267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Classification yielded nothing useful.
1287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct { } Unknown;
1297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   } Addr;
1317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj};
1327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* ------------------ Errors ----------------------- */
1347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* What kind of error it is. */
1367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
1377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
1387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Value,
1397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Cond,
1407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_CoreMem,
1417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Addr,
1427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Jump,
1437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_RegParam,
1447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_MemParam,
1457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_User,
1467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Free,
1477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_FreeMismatch,
1487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Overlap,
1497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Leak,
1507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_IllegalMempool,
1517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
1527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_ErrorTag;
1537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef struct _MC_Error MC_Error;
1567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstruct _MC_Error {
1587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
1597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //MC_ErrorTag tag;
1607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   union {
1627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value:
1637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a pointer in a load or store
1647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a jump target
1657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT szB;   // size of value in bytes
1677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Value;
1717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value in a conditional branch or move.
1737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Cond;
1787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Addressability error in core (signal-handling) operation.
1807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // It would be good to get rid of this error kind, merge it with
1817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // another one somehow.
1827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } CoreMem;
1847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an unaddressable memory location in a load or store.
1867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isWrite;    // read or write?
1887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT    szB;        // not used for exec (jump) errors
1897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     maybe_gcc;  // True if just below %esp -- could be a gcc bug
1907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Addr;
1927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Jump to an unaddressable memory location.
1947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Jump;
1977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call register input contains undefined bytes.
1997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } RegParam;
2047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call memory input contains undefined/unaddressable bytes
2067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
2087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } MemParam;
2137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
2157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
2177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } User;
2227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program tried to free() something that's not a heap block (this
2247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // covers double-frees). */
2257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Free;
2287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program allocates heap block with one function
2307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // (malloc/new/new[]/custom) and deallocates with not the matching one.
2317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } FreeMismatch;
2347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Call to strcpy, memcpy, etc, with overlapping blocks.
2367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Addr src;   // Source block
2387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Addr dst;   // Destination block
2397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Int  szB;   // Size in bytes;  0 if unused.
2407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Overlap;
2417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory leak.
2437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record;
2457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records;
246b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr;
2477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Leak;
2487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory pool error.
2507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } IllegalMempool;
2537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   } Err;
2557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj};
2567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
2597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Printing errors                                      ---*/
2607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
2617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2626b523cd2df025375e86b161de9995187edf2fcb6sewardj/* This is the "this error is due to be printed shortly; so have a
2636b523cd2df025375e86b161de9995187edf2fcb6sewardj   look at it any print any preamble you want" function.  Which, in
2646b523cd2df025375e86b161de9995187edf2fcb6sewardj   Memcheck, we don't use.  Hence a no-op.
2656b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
2666b523cd2df025375e86b161de9995187edf2fcb6sewardjvoid MC_(before_pp_Error) ( Error* err ) {
2676b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2686b523cd2df025375e86b161de9995187edf2fcb6sewardj
2696b523cd2df025375e86b161de9995187edf2fcb6sewardj/* Do a printf-style operation on either the XML or normal output
2706b523cd2df025375e86b161de9995187edf2fcb6sewardj   channel, depending on the setting of VG_(clo_xml).
2716b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
2726b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit_WRK ( HChar* format, va_list vargs )
2736b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2746b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (VG_(clo_xml)) {
2756b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vprintf_xml)(format, vargs);
2766b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
2776b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vmessage)(Vg_UserMsg, format, vargs);
2786b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
2796b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2806b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
2816b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit ( HChar* format, ... )
2826b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2836b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_list vargs;
2846b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_start(vargs, format);
2856b523cd2df025375e86b161de9995187edf2fcb6sewardj   emit_WRK(format, vargs);
2866b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_end(vargs);
2876b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2886b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emiN ( HChar* format, ... ) /* NO FORMAT CHECK */
2896b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2906b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_list vargs;
2916b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_start(vargs, format);
2926b523cd2df025375e86b161de9995187edf2fcb6sewardj   emit_WRK(format, vargs);
2936b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_end(vargs);
2946b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2956b523cd2df025375e86b161de9995187edf2fcb6sewardj
2966b523cd2df025375e86b161de9995187edf2fcb6sewardj
2977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
2987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
2997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
3007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
3017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (ai->tag) {
3037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Unknown:
3047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (maybe_gcc) {
3056b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%sAddress 0x%llx is just below the stack ptr.  "
3066b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "To suppress, use: --workaround-gcc296-bugs=yes%s\n",
3076b523cd2df025375e86b161de9995187edf2fcb6sewardj                  xpre, (ULong)a, xpost );
3087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj	 } else {
3096b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%sAddress 0x%llx "
3106b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "is not stack'd, malloc'd or (recently) free'd%s\n",
3116b523cd2df025375e86b161de9995187edf2fcb6sewardj                  xpre, (ULong)a, xpost );
3127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
3137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Stack:
3166b523cd2df025375e86b161de9995187edf2fcb6sewardj         emit( "%sAddress 0x%llx is on thread %d's stack%s\n",
3176b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre, (ULong)a, ai->Addr.Stack.tid, xpost );
3187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Block: {
321c4431bfe04c7490ea2d74939d222d87f13f30960njn         SizeT    block_szB = ai->Addr.Block.block_szB;
322c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT rwoffset  = ai->Addr.Block.rwoffset;
323c4431bfe04c7490ea2d74939d222d87f13f30960njn         SizeT    delta;
324c4431bfe04c7490ea2d74939d222d87f13f30960njn         const    Char* relative;
3257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (rwoffset < 0) {
3277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = (SizeT)(-rwoffset);
3287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "before";
3297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else if (rwoffset >= block_szB) {
3307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = rwoffset - block_szB;
3317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "after";
3327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
3337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = rwoffset;
3347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "inside";
3357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
3366b523cd2df025375e86b161de9995187edf2fcb6sewardj         emit(
3376b523cd2df025375e86b161de9995187edf2fcb6sewardj            "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n",
3387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            xpre,
3397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            a, delta, relative, ai->Addr.Block.block_desc,
3407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            block_szB,
3417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
3427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            : ai->Addr.Block.block_kind==Block_Freed ? "free'd"
3437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                                     : "client-defined",
3446b523cd2df025375e86b161de9995187edf2fcb6sewardj            xpost
3456b523cd2df025375e86b161de9995187edf2fcb6sewardj         );
3467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(pp_ExeContext)(ai->Addr.Block.lastchange);
3477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
3497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_DataSym:
3516b523cd2df025375e86b161de9995187edf2fcb6sewardj         emiN( "%sAddress 0x%llx is %llu bytes "
352b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart               "inside data symbol \"%pS\"%s\n",
3536b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre,
3546b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)a,
3556b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)ai->Addr.DataSym.offset,
3566b523cd2df025375e86b161de9995187edf2fcb6sewardj               ai->Addr.DataSym.name,
3576b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpost );
3587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Variable:
3616b523cd2df025375e86b161de9995187edf2fcb6sewardj         /* Note, no need for XML tags here, because descr1/2 will
3626b523cd2df025375e86b161de9995187edf2fcb6sewardj            already have <auxwhat> or <xauxwhat>s on them, in XML
3636b523cd2df025375e86b161de9995187edf2fcb6sewardj            mode. */
3646b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (ai->Addr.Variable.descr1)
3656b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s%s\n",
3666b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(clo_xml) ? "  " : " ",
3676b523cd2df025375e86b161de9995187edf2fcb6sewardj                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) );
3686b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (ai->Addr.Variable.descr2)
3696b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s%s\n",
3706b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(clo_xml) ? "  " : " ",
3716b523cd2df025375e86b161de9995187edf2fcb6sewardj                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) );
3727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_SectKind:
375b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart         emiN( "%sAddress 0x%llx is in the %pS segment of %pS%s\n",
3766b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre,
3776b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)a,
3786b523cd2df025375e86b161de9995187edf2fcb6sewardj               VG_(pp_SectKind)(ai->Addr.SectKind.kind),
3796b523cd2df025375e86b161de9995187edf2fcb6sewardj               ai->Addr.SectKind.objname,
3806b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpost );
3817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
3847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("mc_pp_AddrInfo");
3857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
3867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
3877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* str_leak_lossmode ( Reachedness lossmode )
3897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
3907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
3917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
3927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "definitely lost"; break;
3937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "indirectly lost"; break;
3948225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "possibly lost"; break;
3958225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "still reachable"; break;
3967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
3977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
3987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
3997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* xml_leak_kind ( Reachedness lossmode )
4017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
4037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
4047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "Leak_DefinitelyLost"; break;
4057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
4068225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "Leak_PossiblyLost"; break;
4078225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "Leak_StillReachable"; break;
4087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
4107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
4117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void mc_pp_origin ( ExeContext* ec, UInt okind )
4137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4146b523cd2df025375e86b161de9995187edf2fcb6sewardj   HChar* src = NULL;
4157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(ec);
4167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (okind) {
4187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_STACK:   src = " by a stack allocation"; break;
4197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_HEAP:    src = " by a heap allocation"; break;
4207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_USER:    src = " by a client request"; break;
4217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_UNKNOWN: src = ""; break;
4227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(src); /* guards against invalid 'okind' */
4247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(clo_xml)) {
4266b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( "  <auxwhat>Uninitialised value was created%s</auxwhat>\n",
4276b523cd2df025375e86b161de9995187edf2fcb6sewardj            src);
4286b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
4296b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
4306b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( " Uninitialised value was created%s\n", src);
4316b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
4327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
4347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
435c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardjchar * MC_(snprintf_delta) (char * buf, Int size,
436c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                            SizeT current_val, SizeT old_val,
437c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                            LeakCheckDeltaMode delta_mode)
438c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj{
439c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   if (delta_mode == LCD_Any)
440c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      buf[0] = '\0';
441c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   else if (current_val >= old_val)
442c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val);
443c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   else
444c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj      VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val);
445c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
446c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj   return buf;
447c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj}
448c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
4497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(pp_Error) ( Error* err )
4507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4516b523cd2df025375e86b161de9995187edf2fcb6sewardj   const Bool xml  = VG_(clo_xml); /* a shorthand */
4527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
4537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
4556b523cd2df025375e86b161de9995187edf2fcb6sewardj      case Err_CoreMem:
4567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
4577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
4587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            signal handler frame.  --njn */
4596b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
4606b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
4616b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4626b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>CoreMemError</kind>\n" );
463b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart            emiN( "  <what>%pS contains unaddressable byte(s)</what>\n",
4646b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4656b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4666b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
4676b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s contains unaddressable byte(s)\n",
4686b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4696b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4706b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
4717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
4747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4756b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4766b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitValue</kind>\n" );
4776b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Use of uninitialised value of size %ld</what>\n",
4786b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4796b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4806b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4816b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4826b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
4846b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
4856b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
4866b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Use of uninitialised value of size %ld\n",
4876b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4886b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4896b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4906b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4916b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
4937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
4967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4976b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4986b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitCondition</kind>\n" );
4996b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Conditional jump or move depends"
5006b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)</what>\n" );
5016b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5026b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
5036b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
5046b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
5057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
5066b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
5076b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
5086b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Conditional jump or move depends"
5096b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)\n" );
5106b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5116b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
5126b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
5136b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
5147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
5157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
5187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
5196b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5206b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
521b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart            emiN( "  <what>Syscall param %pS contains "
5226b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "uninitialised byte(s)</what>\n",
5236b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
5246b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5256b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
5266b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
5276b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
5286b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5296b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s contains uninitialised byte(s)\n",
5306b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
5316b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5326b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
5336b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
5346b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
5356b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
5397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.MemParam.isAddrErr)
5407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5416b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5426b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
543b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart            emiN( "  <what>Syscall param %pS points to %s byte(s)</what>\n",
5446b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5456b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5466b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5476b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5486b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
5496b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.MemParam.ai, False);
5506b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5516b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5526b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5536b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5546b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5556b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s points to %s byte(s)\n",
5566b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5576b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5586b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5596b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5606b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
5616b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.MemParam.ai, False);
5626b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5636b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5646b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5656b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5666b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
5707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.User.isAddrErr)
5717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5726b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5736b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>ClientCheck</kind>\n" );
5746b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>%s byte(s) found "
5756b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "during client check request</what>\n",
5766b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5776b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5786b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5796b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
5806b523cd2df025375e86b161de9995187edf2fcb6sewardj                           False);
5816b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5826b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5836b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5846b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5856b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s byte(s) found during client check request\n",
5866b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5876b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5886b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5896b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
5906b523cd2df025375e86b161de9995187edf2fcb6sewardj                           False);
5916b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5926b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5936b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5946b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
5986b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5996b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidFree</kind>\n" );
600913473803432ee37d6edaf232e21978d4f426125bart            emit( "  <what>Invalid free() / delete / delete[]"
601913473803432ee37d6edaf232e21978d4f426125bart                  " / realloc()</what>\n" );
6026b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6036b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6046b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Free.ai, False );
6056b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
606913473803432ee37d6edaf232e21978d4f426125bart            emit( "Invalid free() / delete / delete[] / realloc()\n" );
6076b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6086b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6096b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Free.ai, False );
6106b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
6146b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6156b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>MismatchedFree</kind>\n" );
6166b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Mismatched free() / delete / delete []</what>\n" );
6176b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6186b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
6196b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.FreeMismatch.ai, False);
6206b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6216b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Mismatched free() / delete / delete []\n" );
6226b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6236b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
6246b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.FreeMismatch.ai, False);
6256b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
6296b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6306b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Invalid%s</kind>\n",
6316b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "Write" : "Read"  );
6326b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Invalid %s of size %ld</what>\n",
6336b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
6346b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6356b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6366b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6376b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Addr.ai,
6386b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Addr.maybe_gcc );
6397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
6406b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Invalid %s of size %ld\n",
6416b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
6426b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6436b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6446b523cd2df025375e86b161de9995187edf2fcb6sewardj
6456b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6466b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Addr.ai,
6476b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Addr.maybe_gcc );
6487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
6497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
6526b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6536b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidJump</kind>\n" );
6546b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Jump to the invalid address stated "
6556b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "on the next line</what>\n" );
6566b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6576b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
6586b523cd2df025375e86b161de9995187edf2fcb6sewardj                            False );
6596b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6606b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Jump to the invalid address stated on the next line\n" );
6616b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6626b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
6636b523cd2df025375e86b161de9995187edf2fcb6sewardj                            False );
6646b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
6686b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6696b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Overlap</kind>\n" );
6706b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
6716b523cd2df025375e86b161de9995187edf2fcb6sewardj               emiN( "  <what>Source and destination overlap "
672b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart                     "in %pS(%#lx, %#lx)\n</what>\n",
6736b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6746b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6756b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
6766b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <what>Source and destination overlap "
6776b523cd2df025375e86b161de9995187edf2fcb6sewardj                     "in %s(%#lx, %#lx, %d)</what>\n",
6786b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6796b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6806b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6816b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6826b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6836b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6846b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
685b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart               emiN( "Source and destination overlap in %pS(%#lx, %#lx)\n",
6866b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6876b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6886b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
6896b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "Source and destination overlap in %s(%#lx, %#lx, %d)\n",
6906b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6916b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6926b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6936b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6946b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6956b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
6996b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
7006b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
7016b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
7026b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidMemPool</kind>\n" );
7036b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Illegal memory pool address</what>\n" );
7046b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
7056b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
7066b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.IllegalMempool.ai, False );
7076b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
7086b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Illegal memory pool address\n" );
7096b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
7106b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
7116b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.IllegalMempool.ai, False );
7126b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
7137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
7147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak: {
7167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record   = extra->Err.Leak.n_this_record;
7177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records = extra->Err.Leak.n_total_records;
718b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr              = extra->Err.Leak.lr;
719c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         // char arrays to produce the indication of increase/decrease in case
72030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // of delta_mode != LCD_Any
721c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         char        d_bytes[20];
722c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         char        d_direct_bytes[20];
723c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         char        d_indirect_bytes[20];
724c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         char        d_num_blocks[20];
725c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
726c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         MC_(snprintf_delta) (d_bytes, 20,
727c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->szB + lr->indirect_szB,
728c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->old_szB + lr->old_indirect_szB,
729c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              MC_(detect_memory_leaks_last_delta_mode));
730c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         MC_(snprintf_delta) (d_direct_bytes, 20,
731c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->szB,
732c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->old_szB,
733c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              MC_(detect_memory_leaks_last_delta_mode));
734c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         MC_(snprintf_delta) (d_indirect_bytes, 20,
735c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->indirect_szB,
736c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              lr->old_indirect_szB,
737c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              MC_(detect_memory_leaks_last_delta_mode));
738c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj         MC_(snprintf_delta) (d_num_blocks, 20,
739c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              (SizeT) lr->num_blocks,
740c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              (SizeT) lr->old_num_blocks,
741c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                              MC_(detect_memory_leaks_last_delta_mode));
742c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj
7436b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
7446b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit("  <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
7456b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (lr->indirect_szB > 0) {
7466b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <xwhat>\n" );
747c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj               emit( "    <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
748c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     "in %'u%s blocks"
7496b523cd2df025375e86b161de9995187edf2fcb6sewardj                     " are %s in loss record %'u of %'u</text>\n",
750c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->szB + lr->indirect_szB, d_bytes,
751c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->szB, d_direct_bytes,
752c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->indirect_szB, d_indirect_bytes,
753c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->num_blocks, d_num_blocks,
7546b523cd2df025375e86b161de9995187edf2fcb6sewardj                     str_leak_lossmode(lr->key.state),
7556b523cd2df025375e86b161de9995187edf2fcb6sewardj                     n_this_record, n_total_records );
7567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj               // Nb: don't put commas in these XML numbers
7576b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedbytes>%lu</leakedbytes>\n",
7586b523cd2df025375e86b161de9995187edf2fcb6sewardj                     lr->szB + lr->indirect_szB );
7596b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
7606b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  </xwhat>\n" );
7616b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
7626b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <xwhat>\n" );
763c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj               emit( "    <text>%'lu%s bytes in %'u%s blocks"
7646b523cd2df025375e86b161de9995187edf2fcb6sewardj                     " are %s in loss record %'u of %'u</text>\n",
765c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->szB, d_direct_bytes,
766c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                     lr->num_blocks, d_num_blocks,
7676b523cd2df025375e86b161de9995187edf2fcb6sewardj                     str_leak_lossmode(lr->key.state),
7686b523cd2df025375e86b161de9995187edf2fcb6sewardj                     n_this_record, n_total_records );
7696b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedbytes>%ld</leakedbytes>\n", lr->szB);
7706b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedblocks>%d</leakedblocks>\n", lr->num_blocks);
7716b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  </xwhat>\n" );
7727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            }
7736b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)(lr->key.allocated_at);
7746b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else { /* ! if (xml) */
7756b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (lr->indirect_szB > 0) {
7766b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit(
777c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
7786b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " are %s in loss record %'u of %'u\n",
779c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->szB + lr->indirect_szB, d_bytes,
780c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->szB, d_direct_bytes,
781c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->indirect_szB, d_indirect_bytes,
782c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->num_blocks, d_num_blocks,
783c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  str_leak_lossmode(lr->key.state),
7846b523cd2df025375e86b161de9995187edf2fcb6sewardj                  n_this_record, n_total_records
7856b523cd2df025375e86b161de9995187edf2fcb6sewardj               );
7866b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
7876b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit(
788c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
789c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->szB, d_direct_bytes,
790c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  lr->num_blocks, d_num_blocks,
791c8bd1df6c23e2409512e1e50616e7dc3bae501a2sewardj                  str_leak_lossmode(lr->key.state),
7926b523cd2df025375e86b161de9995187edf2fcb6sewardj                  n_this_record, n_total_records
7936b523cd2df025375e86b161de9995187edf2fcb6sewardj               );
7947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            }
7956b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)(lr->key.allocated_at);
7966b523cd2df025375e86b161de9995187edf2fcb6sewardj         } /* if (xml) */
7977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
7987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
7997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
8017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown Memcheck error code %d\n",
8027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(err));
8037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_pp_Error)");
8047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
8057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
8087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Recording errors                                     ---*/
8097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
8107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* These many bytes below %ESP are considered addressible if we're
8127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   doing the --workaround-gcc296-bugs hack. */
8137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#define VG_GCC296_BUG_STACK_SLOP 1024
8147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Is this address within some small distance below %ESP?  Used only
8167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for the --workaround-gcc296-bugs kludge. */
8177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool is_just_below_ESP( Addr esp, Addr aa )
8187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8197d751b2b72d806d1ef747f8ee661aeb52e7563aasewardj   esp -= VG_STACK_REDZONE_SZB;
8207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
8217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return True;
8227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
8237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
8247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from generated and non-generated code --- */
8277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
8297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Bool isWrite )
8307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool     just_below_esp;
8337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(in_ignored_range)(a))
8357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
8367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB))
8383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return;
8393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
8417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* If this is caused by an access immediately below %ESP, and the
8437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      user asks nicely, we just ignore it. */
8447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
8457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
8467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.isWrite   = isWrite;
8487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.szB       = szB;
8497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.maybe_gcc = just_below_esp;
8507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.ai.tag    = Addr_Undescribed;
8517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
8527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
8557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
8587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.szB       = szB;
8617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.otag      = otag;
8627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.origin_ec = NULL;  /* Filled in later */
8637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
8647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_cond_error) ( ThreadId tid, UInt otag )
8677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
8707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.otag      = otag;
8737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
8747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
8757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from non-generated code --- */
8787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8791dcee097db02f9ef3ba355162c4373d90d0e895cnjn/* This is for memory errors in signal-related memory. */
8801dcee097db02f9ef3ba355162c4373d90d0e895cnjnvoid MC_(record_core_mem_error) ( ThreadId tid, Char* msg )
8817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
8837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag )
8867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.otag      = otag;
8927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
8937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
8947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_memparam_error) ( ThreadId tid, Addr a,
8977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                  Bool isAddrErr, Char* msg, UInt otag )
8987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr)
9027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
9037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
9047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
9057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( !isAddrErr );
9067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.isAddrErr = isAddrErr;
9087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.ai.tag    = Addr_Undescribed;
9097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.otag      = otag;
9107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
9117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
9127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_jump_error) ( ThreadId tid, Addr a )
9157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Jump.ai.tag = Addr_Undescribed;
9197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
9207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_free_error) ( ThreadId tid, Addr a )
9237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Free.ai.tag = Addr_Undescribed;
9277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
9287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
9317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrInfo* ai = &extra.Err.FreeMismatch.ai;
9347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->tag = Addr_Block;
9367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
9377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_desc = "block";
9387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_szB  = mc->szB;
9397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.rwoffset   = 0;
9407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.lastchange = mc->where;
9417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
9427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            &extra );
9437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
9467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
9507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
9517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_overlap_error) ( ThreadId tid, Char* function,
9547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Addr src, Addr dst, SizeT szB )
9557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.src = src;
9597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.dst = dst;
9607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.szB = szB;
9617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)(
9627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
9637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
966b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn                              UInt n_total_records, LossRecord* lr,
96718afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                              Bool print_record, Bool count_error )
9687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_this_record   = n_this_record;
9717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_total_records = n_total_records;
972b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn   extra.Err.Leak.lr              = lr;
9737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return
9747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
97529a5c01528ca7cffe17880a038b4563de920f08dnjn                       lr->key.allocated_at, print_record,
97618afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                       /*allow_GDB_attach*/False, count_error );
9777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_user_error) ( ThreadId tid, Addr a,
9807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                              Bool isAddrErr, UInt otag )
9817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
9847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(!isAddrErr);
9857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
9867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr) {
9887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
9897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.isAddrErr = isAddrErr;
9927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.ai.tag    = Addr_Undescribed;
9937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.otag      = otag;
9947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.origin_ec = NULL;  /* Filled in later */
9957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
9967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
9997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Other error operations                               ---*/
10007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
10017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Compare error contexts, to detect duplicates.  Note that if they
10037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are otherwise the same, the faulting addrs and associated rwoffsets
10047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are allowed to be different.  */
10057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
10067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra1 = VG_(get_error_extra)(e1);
10087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra2 = VG_(get_error_extra)(e2);
10097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Guaranteed by calling function */
10117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
10127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(e1)) {
10147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_CoreMem: {
10157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char *e1s, *e2s;
10167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e1s = VG_(get_error_string)(e1);
10177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e2s = VG_(get_error_string)(e2);
10187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (e1s == e2s)                   return True;
10197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (VG_STREQ(e1s, e2s))           return True;
10207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return False;
10217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
10227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
10247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
10257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Perhaps we should also check the addrinfo.akinds for equality.
10277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // That would result in more error reports, but only in cases where
10287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // a register contains uninitialised bytes and points to memory
10297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // containing uninitialised bytes.  Currently, the 2nd of those to be
10307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // detected won't be reported.  That is (nearly?) always the memory
10317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // error, which is good.
10327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
10337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!VG_STREQ(VG_(get_error_string)(e1),
10347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                       VG_(get_error_string)(e2))) return False;
10357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // fall through
10367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
10377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
10387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
10417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
10427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
10437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
10447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
10457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
10467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
10477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
10497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
10507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
10537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Value.szB == extra2->Err.Value.szB
10547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak:
10577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
10587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "since it's handled with VG_(unique_error)()!");
10597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
10617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown error code %d\n",
10627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(e1));
10637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_eq_Error");
10647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
10657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
10667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
106762b9104a05dede4b9cabfaa483da76480131127esewardj/* Functions used when searching MC_Chunk lists */
106862b9104a05dede4b9cabfaa483da76480131127esewardjstatic
106962b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
10707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
10727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 MC_MALLOC_REDZONE_SZB );
10737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
107462b9104a05dede4b9cabfaa483da76480131127esewardjstatic
107562b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
107662b9104a05dede4b9cabfaa483da76480131127esewardj{
107762b9104a05dede4b9cabfaa483da76480131127esewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
107862b9104a05dede4b9cabfaa483da76480131127esewardj                                 rzB );
107962b9104a05dede4b9cabfaa483da76480131127esewardj}
10807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
108162b9104a05dede4b9cabfaa483da76480131127esewardj// Forward declarations
10827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
108362b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
10847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Describe an address as best you can, for error messages,
10877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   putting the result in ai. */
10887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
10897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Chunk*  mc;
10917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ThreadId   tid;
10927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Addr       stack_min, stack_max;
10937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VgSectKind sect;
10947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(Addr_Undescribed == ai->tag);
10967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
109762b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's a user-named block? -- */
10987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (client_block_maybe_describe( a, ai )) {
10997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
110162b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's in mempool block? -- */
110262b9104a05dede4b9cabfaa483da76480131127esewardj   if (mempool_block_maybe_describe( a, ai )) {
110362b9104a05dede4b9cabfaa483da76480131127esewardj      return;
110462b9104a05dede4b9cabfaa483da76480131127esewardj   }
11056b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Search for a recently freed block which might bracket it. -- */
11067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   mc = MC_(get_freed_list_head)();
11077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while (mc) {
110862b9104a05dede4b9cabfaa483da76480131127esewardj      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
11097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
11107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_Freed;
11117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = "block";
11127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = mc->szB;
111356adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
11147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = mc->where;
11157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
11167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
11177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      mc = mc->next;
11187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11196b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Search for a currently malloc'd block which might bracket it. -- */
11207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(HT_ResetIter)(MC_(malloc_list));
11217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
112262b9104a05dede4b9cabfaa483da76480131127esewardj      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
11237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
11247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_Mallocd;
11257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = "block";
11267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = mc->szB;
112756adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
11287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = mc->where;
11297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
11307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
11317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11326b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Perhaps the variable type/location data describes it? -- */
11336b523cd2df025375e86b161de9995187edf2fcb6sewardj   ai->Addr.Variable.descr1
11346b523cd2df025375e86b161de9995187edf2fcb6sewardj      = VG_(newXA)( VG_(malloc), "mc.da.descr1",
11356b523cd2df025375e86b161de9995187edf2fcb6sewardj                    VG_(free), sizeof(HChar) );
11366b523cd2df025375e86b161de9995187edf2fcb6sewardj   ai->Addr.Variable.descr2
11376b523cd2df025375e86b161de9995187edf2fcb6sewardj      = VG_(newXA)( VG_(malloc), "mc.da.descr2",
11386b523cd2df025375e86b161de9995187edf2fcb6sewardj                    VG_(free), sizeof(HChar) );
11396b523cd2df025375e86b161de9995187edf2fcb6sewardj
11406b523cd2df025375e86b161de9995187edf2fcb6sewardj   (void) VG_(get_data_description)( ai->Addr.Variable.descr1,
11416b523cd2df025375e86b161de9995187edf2fcb6sewardj                                     ai->Addr.Variable.descr2, a );
11426b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* If there's nothing in descr1/2, free them.  Why is it safe to to
11436b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(indexXA) at zero here?  Because VG_(get_data_description)
11446b523cd2df025375e86b161de9995187edf2fcb6sewardj      guarantees to zero terminate descr1/2 regardless of the outcome
11456b523cd2df025375e86b161de9995187edf2fcb6sewardj      of the call.  So there's always at least one element in each XA
11466b523cd2df025375e86b161de9995187edf2fcb6sewardj      after the call.
11476b523cd2df025375e86b161de9995187edf2fcb6sewardj   */
11486b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) {
11496b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(deleteXA)( ai->Addr.Variable.descr1 );
11506b523cd2df025375e86b161de9995187edf2fcb6sewardj      ai->Addr.Variable.descr1 = NULL;
11516b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
11526b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) {
11536b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(deleteXA)( ai->Addr.Variable.descr2 );
11546b523cd2df025375e86b161de9995187edf2fcb6sewardj      ai->Addr.Variable.descr2 = NULL;
11556b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
11566b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* Assume (assert) that VG_(get_data_description) fills in descr1
11576b523cd2df025375e86b161de9995187edf2fcb6sewardj      before it fills in descr2 */
11586b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (ai->Addr.Variable.descr1 == NULL)
11596b523cd2df025375e86b161de9995187edf2fcb6sewardj      tl_assert(ai->Addr.Variable.descr2 == NULL);
11606b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* So did we get lucky? */
11616b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (ai->Addr.Variable.descr1 != NULL) {
11627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_Variable;
11637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11656b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Have a look at the low level data symbols - perhaps it's in
11666b523cd2df025375e86b161de9995187edf2fcb6sewardj      there. -- */
11677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(memset)( &ai->Addr.DataSym.name,
11687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                0, sizeof(ai->Addr.DataSym.name));
11697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(get_datasym_and_offset)(
11707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             a, &ai->Addr.DataSym.name[0],
11717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             sizeof(ai->Addr.DataSym.name)-1,
11727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             &ai->Addr.DataSym.offset )) {
11737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_DataSym;
11747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( ai->Addr.DataSym.name
11757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                    [ sizeof(ai->Addr.DataSym.name)-1 ] == 0);
11767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11786b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Perhaps it's on a thread's stack? -- */
11797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(thread_stack_reset_iter)(&tid);
11807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
11817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) {
11827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag            = Addr_Stack;
11837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Stack.tid = tid;
11847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
11857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
11867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11876b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- last ditch attempt at classification -- */
11887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
11897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(memset)( &ai->Addr.SectKind.objname,
11907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                0, sizeof(ai->Addr.SectKind.objname));
11917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
1192e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj   sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0],
1193e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj                                    sizeof(ai->Addr.SectKind.objname)-1, a);
11947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (sect != Vg_SectUnknown) {
11957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_SectKind;
11967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->Addr.SectKind.kind = sect;
11977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( ai->Addr.SectKind.objname
11987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                    [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
11997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
12007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12016b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Clueless ... -- */
12027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->tag = Addr_Unknown;
12037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return;
12047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
12057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12063b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid MC_(pp_describe_addr) ( Addr a )
12073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
12083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   AddrInfo ai;
12093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   ai.tag = Addr_Undescribed;
12113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   describe_addr (a, &ai);
12123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   mc_pp_AddrInfo (a, &ai, /* maybe_gcc */ False);
12133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Fill in *origin_ec as specified by otag, or NULL it out if otag
12167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   does not refer to a known origin. */
12177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void update_origin ( /*OUT*/ExeContext** origin_ec,
12187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            UInt otag )
12197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
12207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UInt ecu = otag & ~3;
12217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   *origin_ec = NULL;
12227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(is_plausible_ECU)(ecu)) {
12237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
12247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
12267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Updates the copy with address info if necessary (but not for all errors). */
12287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjUInt MC_(update_Error_extra)( Error* err )
12297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
12307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
12317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
12337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones don't have addresses associated with them, and so don't
12347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // need any updating.
12357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:
12367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Value:
12377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Cond:
12387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:
12397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For Err_Leaks the returned size does not matter -- they are always
12407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // shown with VG_(unique_error)() so they 'extra' not copied.  But
12417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we make it consistent with the others.
12427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:
12437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For value errors, get the ExeContext corresponding to the
12467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // origin tag.  Note that it is a kludge to assume that
12477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // a length-1 trace indicates a stack origin.  FIXME.
12487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value:
12497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Value.origin_ec,
12507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Value.otag );
12517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:
12537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Cond.origin_ec,
12547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Cond.otag );
12557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:
12577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.RegParam.origin_ec,
12587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.RegParam.otag );
12597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones always involve a memory address.
12627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr:
12637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Addr.ai );
12657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:
12677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.MemParam.ai );
12697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.MemParam.origin_ec,
12707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.MemParam.otag );
12717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:
12737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Jump.ai );
12757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:
12777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.User.ai );
12797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.User.origin_ec,
12807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.User.otag );
12817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:
12837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Free.ai );
12857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool:
12877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.IllegalMempool.ai );
12897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Err_FreeMismatches have already had their address described;  this is
12927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // possible because we have the MC_Chunk on hand when the error is
12937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // detected.  However, the address may be part of a user block, and if so
12947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we override the pre-determined description with a user block one.
12957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch: {
12967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(extra && Block_Mallocd ==
12977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
12987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      (void)client_block_maybe_describe( VG_(get_error_address)(err),
12997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                        &extra->Err.FreeMismatch.ai );
13007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
13017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default: VG_(tool_panic)("mc_update_extra: bad errkind");
13047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
130762b9104a05dede4b9cabfaa483da76480131127esewardj
13087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a,
13097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                         /*OUT*/AddrInfo* ai )
13107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
131156adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj   UWord      i;
13127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   CGenBlock* cgbs = NULL;
13137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UWord      cgb_used = 0;
131456adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj
13157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
13167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (cgbs == NULL)
13177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(cgb_used == 0);
13187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Perhaps it's a general block ? */
13207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for (i = 0; i < cgb_used; i++) {
13217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (cgbs[i].start == 0 && cgbs[i].size == 0)
13227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         continue;
13237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use zero as the redzone for client blocks.
13247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
13257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
13267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_UserG;
13277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = cgbs[i].desc;
13287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = cgbs[i].size;
132956adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
13307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = cgbs[i].where;
13317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
13327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
13337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return False;
13357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
133862b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a,
133962b9104a05dede4b9cabfaa483da76480131127esewardj                                          /*OUT*/AddrInfo* ai )
134062b9104a05dede4b9cabfaa483da76480131127esewardj{
134162b9104a05dede4b9cabfaa483da76480131127esewardj   MC_Mempool* mp;
134262b9104a05dede4b9cabfaa483da76480131127esewardj   tl_assert( MC_(mempool_list) );
134362b9104a05dede4b9cabfaa483da76480131127esewardj
134462b9104a05dede4b9cabfaa483da76480131127esewardj   VG_(HT_ResetIter)( MC_(mempool_list) );
134562b9104a05dede4b9cabfaa483da76480131127esewardj   while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
134662b9104a05dede4b9cabfaa483da76480131127esewardj      if (mp->chunks != NULL) {
134762b9104a05dede4b9cabfaa483da76480131127esewardj         MC_Chunk* mc;
134862b9104a05dede4b9cabfaa483da76480131127esewardj         VG_(HT_ResetIter)(mp->chunks);
134962b9104a05dede4b9cabfaa483da76480131127esewardj         while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
135062b9104a05dede4b9cabfaa483da76480131127esewardj            if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
135162b9104a05dede4b9cabfaa483da76480131127esewardj               ai->tag = Addr_Block;
135262b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_kind = Block_MempoolChunk;
135362b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_desc = "block";
135462b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_szB  = mc->szB;
135562b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
135662b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.lastchange = mc->where;
135762b9104a05dede4b9cabfaa483da76480131127esewardj               return True;
135862b9104a05dede4b9cabfaa483da76480131127esewardj            }
135962b9104a05dede4b9cabfaa483da76480131127esewardj         }
136062b9104a05dede4b9cabfaa483da76480131127esewardj      }
136162b9104a05dede4b9cabfaa483da76480131127esewardj   }
136262b9104a05dede4b9cabfaa483da76480131127esewardj   return False;
136362b9104a05dede4b9cabfaa483da76480131127esewardj}
136462b9104a05dede4b9cabfaa483da76480131127esewardj
136562b9104a05dede4b9cabfaa483da76480131127esewardj
13667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
13677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Suppressions                                         ---*/
13687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
13697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
13717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
13727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ParamSupp,     // Bad syscall params
13737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      UserSupp,      // Errors arising from client-request checks
13747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
13757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value errors of given size
13777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
13787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value error in conditional.
13807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CondSupp,
13817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Unaddressable read/write attempt at given size
13837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
13847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      JumpSupp,      // Jump to unaddressable target
13867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      FreeSupp,      // Invalid or mismatching free
13877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
13887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      LeakSupp,      // Something to be suppressed in a leak check.
13897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MempoolSupp,   // Memory pool suppression.
13907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_SuppKind;
13927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(is_recognised_suppression) ( Char* name, Supp* su )
13947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
13957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   SuppKind skind;
13967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
13987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "User"))    skind = UserSupp;
13997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
14007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
14017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
14027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
14037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
14047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
14057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
14067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
14077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
14087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
14097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
14107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
14117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
14127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
14137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
14147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
14157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
14167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
14177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
14187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
14197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(set_supp_kind)(su, skind);
14217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
14227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
142435db56c19847654f22b62da059083d41ff4258c5njnBool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp,
142535db56c19847654f22b62da059083d41ff4258c5njn                                        SizeT* nBufp, Supp *su )
14267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
14277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool eof;
14287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(get_supp_kind)(su) == ParamSupp) {
1430050eec553cdcb2ebeaefbb267aeb0828be7121e5bart      eof = VG_(get_line) ( fd, bufpp, nBufp, NULL );
14317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (eof) return False;
143235db56c19847654f22b62da059083d41ff4258c5njn      VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
14337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
14357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(error_matches_suppression) ( Error* err, Supp* su )
14387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
14397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Int       su_szB;
14407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
14417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
14427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_supp_kind)(su)) {
14447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case ParamSupp:
14457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ((ekind == Err_RegParam || ekind == Err_MemParam)
14467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case UserSupp:
14507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_User);
14517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CoreMemSupp:
14537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_CoreMem
14547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value1Supp: su_szB = 1; goto value_case;
14587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value2Supp: su_szB = 2; goto value_case;
14597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value4Supp: su_szB = 4; goto value_case;
14607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value8Supp: su_szB = 8; goto value_case;
14617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value16Supp:su_szB =16; goto value_case;
14627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      value_case:
14637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
14647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CondSupp:
14667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Cond);
14677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr1Supp: su_szB = 1; goto addr_case;
14697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr2Supp: su_szB = 2; goto addr_case;
14707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr4Supp: su_szB = 4; goto addr_case;
14717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr8Supp: su_szB = 8; goto addr_case;
14727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr16Supp:su_szB =16; goto addr_case;
14737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      addr_case:
14747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
14757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case JumpSupp:
14777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Jump);
14787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case FreeSupp:
14807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Free || ekind == Err_FreeMismatch);
14817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case OverlapSupp:
14837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Overlap);
14847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case LeakSupp:
14867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Leak);
14877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MempoolSupp:
14897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_IllegalMempool);
14907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
14927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n"
14937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     "  unknown suppression type %d\n",
14947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_supp_kind)(su));
14957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown suppression type in "
14967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "MC_(error_matches_suppression)");
14977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjChar* MC_(get_error_name) ( Error* err )
15017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
15027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
15037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:       return "Param";
15047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:       return "Param";
15057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:           return "User";
15067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch:   return "Free";
15077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool: return "Mempool";
15087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:           return "Free";
15097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:           return "Jump";
15107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:        return "CoreMem";
15117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:        return "Overlap";
15127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:           return "Leak";
15137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:           return "Cond";
15147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr: {
15157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
15167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Addr.szB ) {
15177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Addr1";
15187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Addr2";
15197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Addr4";
15207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Addr8";
15217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Addr16";
15227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Addr");
15237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
15247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value: {
15267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
15277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Value.szB ) {
15287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Value1";
15297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Value2";
15307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Value4";
15317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Value8";
15327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Value16";
15337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Value");
15347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
15357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default:                 VG_(tool_panic)("get_error_name: unexpected type");
15377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1540588adeffafa8102adcfa7a1c035ae272b35cf86dsewardjBool MC_(get_extra_suppression_info) ( Error* err,
1541588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                                       /*OUT*/Char* buf, Int nBuf )
15427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
15437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
1544588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   tl_assert(buf);
1545588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   tl_assert(nBuf >= 16); // stay sane
15467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (Err_RegParam == ekind || Err_MemParam == ekind) {
1547588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      Char* errstr = VG_(get_error_string)(err);
1548588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      tl_assert(errstr);
1549588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(snprintf)(buf, nBuf-1, "%s", errstr);
1550588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      return True;
1551588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   } else {
1552588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      return False;
15537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
15587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- end                                              mc_errors.c ---*/
15597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
1560