mc_errors.c revision 913473803432ee37d6edaf232e21978d4f426125
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"
337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_hashtable.h"     // For mc_include.h
347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcbase.h"
357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcassert.h"
367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_libcprint.h"
377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_machine.h"
387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_mallocfree.h"
397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_options.h"
407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_replacemalloc.h"
417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_tooliface.h"
427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_threadstate.h"
437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
446b523cd2df025375e86b161de9995187edf2fcb6sewardj#include "pub_tool_xarray.h"
457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#include "mc_include.h"
477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Error types                                          ---*/
517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* See comment in mc_include.h */
547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(any_value_errors) = False;
557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj// Different kinds of blocks.
587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef enum {
597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Mallocd = 111,
607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Freed,
617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_Mempool,
627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_MempoolChunk,
637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Block_UserG
647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj} BlockKind;
657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* ------------------ Addresses -------------------- */
677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* The classification of a faulting address. */
697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Undescribed, // as-yet unclassified
727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Unknown,     // classification yielded nothing useful
737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Block,       // in malloc'd/free'd block
747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Stack,       // on a thread's stack
757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_DataSym,     // in a global data sym
767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_Variable,    // variable described by the debug info
777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr_SectKind     // last-ditch classification attempt
787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrTag;
807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   struct _AddrInfo
837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrInfo;
847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstruct _AddrInfo {
867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrTag tag;
877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   union {
887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // As-yet unclassified.
897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct { } Undescribed;
907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // On a stack.
927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ThreadId tid;        // Which thread's stack?
947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Stack;
957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // This covers heap blocks (normal and from mempools) and user-defined
977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // blocks.
987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         BlockKind   block_kind;
1007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char*       block_desc;    // "block", "mempool" or user-defined
1017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT       block_szB;
102c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT    rwoffset;
1037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* lastchange;
1047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Block;
1057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
106c4431bfe04c7490ea2d74939d222d87f13f30960njn      // In a global .data symbol.  This holds the first 127 chars of
107c4431bfe04c7490ea2d74939d222d87f13f30960njn      // the variable's name (zero terminated), plus a (memory) offset.
1087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
109c4431bfe04c7490ea2d74939d222d87f13f30960njn         Char     name[128];
110c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT offset;
1117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } DataSym;
1127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1136b523cd2df025375e86b161de9995187edf2fcb6sewardj      // Is described by Dwarf debug info.  XArray*s of HChar.
1147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1156b523cd2df025375e86b161de9995187edf2fcb6sewardj         XArray* /* of HChar */ descr1;
1166b523cd2df025375e86b161de9995187edf2fcb6sewardj         XArray* /* of HChar */ descr2;
1177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Variable;
1187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Could only narrow it down to be the PLT/GOT/etc of a given
1207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // object.  Better than nothing, perhaps.
1217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char       objname[128];
1237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VgSectKind kind;
1247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } SectKind;
1257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Classification yielded nothing useful.
1277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct { } Unknown;
1287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   } Addr;
1307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj};
1317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* ------------------ Errors ----------------------- */
1337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* What kind of error it is. */
1357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
1367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
1377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Value,
1387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Cond,
1397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_CoreMem,
1407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Addr,
1417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Jump,
1427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_RegParam,
1437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_MemParam,
1447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_User,
1457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Free,
1467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_FreeMismatch,
1477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Overlap,
1487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_Leak,
1497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Err_IllegalMempool,
1507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
1517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_ErrorTag;
1527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef struct _MC_Error MC_Error;
1557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstruct _MC_Error {
1577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
1587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //MC_ErrorTag tag;
1597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   union {
1617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value:
1627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a pointer in a load or store
1637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // - as a jump target
1647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT szB;   // size of value in bytes
1667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Value;
1707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an undefined value in a conditional branch or move.
1727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
1747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
1757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
1767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Cond;
1777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Addressability error in core (signal-handling) operation.
1797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // It would be good to get rid of this error kind, merge it with
1807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // another one somehow.
1817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } CoreMem;
1837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use of an unaddressable memory location in a load or store.
1857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isWrite;    // read or write?
1877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         SizeT    szB;        // not used for exec (jump) errors
1887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     maybe_gcc;  // True if just below %esp -- could be a gcc bug
1897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Addr;
1917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Jump to an unaddressable memory location.
1937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
1957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Jump;
1967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call register input contains undefined bytes.
1987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
1997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } RegParam;
2037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // System call memory input contains undefined/unaddressable bytes
2057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
2077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } MemParam;
2127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
2147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Bool     isAddrErr;  // Addressability or definedness error?
2167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // Origin info
2187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        otag;      // origin tag
2197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ExeContext* origin_ec; // filled in later
2207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } User;
2217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program tried to free() something that's not a heap block (this
2237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // covers double-frees). */
2247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Free;
2277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Program allocates heap block with one function
2297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // (malloc/new/new[]/custom) and deallocates with not the matching one.
2307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } FreeMismatch;
2337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Call to strcpy, memcpy, etc, with overlapping blocks.
2357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Addr src;   // Source block
2377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Addr dst;   // Destination block
2387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Int  szB;   // Size in bytes;  0 if unused.
2397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Overlap;
2407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory leak.
2427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record;
2447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records;
245b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr;
2467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } Leak;
2477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // A memory pool error.
2497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      struct {
2507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         AddrInfo ai;
2517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } IllegalMempool;
2527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   } Err;
2547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj};
2557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
2587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Printing errors                                      ---*/
2597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
2607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
2616b523cd2df025375e86b161de9995187edf2fcb6sewardj/* This is the "this error is due to be printed shortly; so have a
2626b523cd2df025375e86b161de9995187edf2fcb6sewardj   look at it any print any preamble you want" function.  Which, in
2636b523cd2df025375e86b161de9995187edf2fcb6sewardj   Memcheck, we don't use.  Hence a no-op.
2646b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
2656b523cd2df025375e86b161de9995187edf2fcb6sewardjvoid MC_(before_pp_Error) ( Error* err ) {
2666b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2676b523cd2df025375e86b161de9995187edf2fcb6sewardj
2686b523cd2df025375e86b161de9995187edf2fcb6sewardj/* Do a printf-style operation on either the XML or normal output
2696b523cd2df025375e86b161de9995187edf2fcb6sewardj   channel, depending on the setting of VG_(clo_xml).
2706b523cd2df025375e86b161de9995187edf2fcb6sewardj*/
2716b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit_WRK ( HChar* format, va_list vargs )
2726b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2736b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (VG_(clo_xml)) {
2746b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vprintf_xml)(format, vargs);
2756b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
2766b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(vmessage)(Vg_UserMsg, format, vargs);
2776b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
2786b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2796b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
2806b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emit ( HChar* format, ... )
2816b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2826b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_list vargs;
2836b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_start(vargs, format);
2846b523cd2df025375e86b161de9995187edf2fcb6sewardj   emit_WRK(format, vargs);
2856b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_end(vargs);
2866b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2876b523cd2df025375e86b161de9995187edf2fcb6sewardjstatic void emiN ( HChar* format, ... ) /* NO FORMAT CHECK */
2886b523cd2df025375e86b161de9995187edf2fcb6sewardj{
2896b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_list vargs;
2906b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_start(vargs, format);
2916b523cd2df025375e86b161de9995187edf2fcb6sewardj   emit_WRK(format, vargs);
2926b523cd2df025375e86b161de9995187edf2fcb6sewardj   va_end(vargs);
2936b523cd2df025375e86b161de9995187edf2fcb6sewardj}
2946b523cd2df025375e86b161de9995187edf2fcb6sewardj
2956b523cd2df025375e86b161de9995187edf2fcb6sewardj
2967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
2977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
2987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
2997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
3007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (ai->tag) {
3027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Unknown:
3037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (maybe_gcc) {
3046b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%sAddress 0x%llx is just below the stack ptr.  "
3056b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "To suppress, use: --workaround-gcc296-bugs=yes%s\n",
3066b523cd2df025375e86b161de9995187edf2fcb6sewardj                  xpre, (ULong)a, xpost );
3077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj	 } else {
3086b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%sAddress 0x%llx "
3096b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "is not stack'd, malloc'd or (recently) free'd%s\n",
3106b523cd2df025375e86b161de9995187edf2fcb6sewardj                  xpre, (ULong)a, xpost );
3117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
3127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Stack:
3156b523cd2df025375e86b161de9995187edf2fcb6sewardj         emit( "%sAddress 0x%llx is on thread %d's stack%s\n",
3166b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre, (ULong)a, ai->Addr.Stack.tid, xpost );
3177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Block: {
320c4431bfe04c7490ea2d74939d222d87f13f30960njn         SizeT    block_szB = ai->Addr.Block.block_szB;
321c4431bfe04c7490ea2d74939d222d87f13f30960njn         PtrdiffT rwoffset  = ai->Addr.Block.rwoffset;
322c4431bfe04c7490ea2d74939d222d87f13f30960njn         SizeT    delta;
323c4431bfe04c7490ea2d74939d222d87f13f30960njn         const    Char* relative;
3247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (rwoffset < 0) {
3267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = (SizeT)(-rwoffset);
3277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "before";
3287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else if (rwoffset >= block_szB) {
3297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = rwoffset - block_szB;
3307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "after";
3317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
3327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            delta    = rwoffset;
3337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            relative = "inside";
3347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
3356b523cd2df025375e86b161de9995187edf2fcb6sewardj         emit(
3366b523cd2df025375e86b161de9995187edf2fcb6sewardj            "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n",
3377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            xpre,
3387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            a, delta, relative, ai->Addr.Block.block_desc,
3397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            block_szB,
3407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
3417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            : ai->Addr.Block.block_kind==Block_Freed ? "free'd"
3427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                                     : "client-defined",
3436b523cd2df025375e86b161de9995187edf2fcb6sewardj            xpost
3446b523cd2df025375e86b161de9995187edf2fcb6sewardj         );
3457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(pp_ExeContext)(ai->Addr.Block.lastchange);
3467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
3487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_DataSym:
3506b523cd2df025375e86b161de9995187edf2fcb6sewardj         emiN( "%sAddress 0x%llx is %llu bytes "
3516b523cd2df025375e86b161de9995187edf2fcb6sewardj               "inside data symbol \"%t\"%s\n",
3526b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre,
3536b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)a,
3546b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)ai->Addr.DataSym.offset,
3556b523cd2df025375e86b161de9995187edf2fcb6sewardj               ai->Addr.DataSym.name,
3566b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpost );
3577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_Variable:
3606b523cd2df025375e86b161de9995187edf2fcb6sewardj         /* Note, no need for XML tags here, because descr1/2 will
3616b523cd2df025375e86b161de9995187edf2fcb6sewardj            already have <auxwhat> or <xauxwhat>s on them, in XML
3626b523cd2df025375e86b161de9995187edf2fcb6sewardj            mode. */
3636b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (ai->Addr.Variable.descr1)
3646b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s%s\n",
3656b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(clo_xml) ? "  " : " ",
3666b523cd2df025375e86b161de9995187edf2fcb6sewardj                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) );
3676b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (ai->Addr.Variable.descr2)
3686b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s%s\n",
3696b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(clo_xml) ? "  " : " ",
3706b523cd2df025375e86b161de9995187edf2fcb6sewardj                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) );
3717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr_SectKind:
3746b523cd2df025375e86b161de9995187edf2fcb6sewardj         emiN( "%sAddress 0x%llx is in the %t segment of %t%s\n",
3756b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpre,
3766b523cd2df025375e86b161de9995187edf2fcb6sewardj               (ULong)a,
3776b523cd2df025375e86b161de9995187edf2fcb6sewardj               VG_(pp_SectKind)(ai->Addr.SectKind.kind),
3786b523cd2df025375e86b161de9995187edf2fcb6sewardj               ai->Addr.SectKind.objname,
3796b523cd2df025375e86b161de9995187edf2fcb6sewardj               xpost );
3807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
3817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
3837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("mc_pp_AddrInfo");
3847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
3857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
3867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* str_leak_lossmode ( Reachedness lossmode )
3887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
3897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
3907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
3917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "definitely lost"; break;
3927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "indirectly lost"; break;
3938225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "possibly lost"; break;
3948225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "still reachable"; break;
3957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
3967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
3977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
3987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
3997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic const HChar* xml_leak_kind ( Reachedness lossmode )
4007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   const HChar *loss = "?";
4027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (lossmode) {
4037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Unreached:    loss = "Leak_DefinitelyLost"; break;
4047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
4058225cc0de2ccf390127b5910dceb7c6185091a38njn      case Possible:     loss = "Leak_PossiblyLost"; break;
4068225cc0de2ccf390127b5910dceb7c6185091a38njn      case Reachable:    loss = "Leak_StillReachable"; break;
4077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return loss;
4097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
4107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void mc_pp_origin ( ExeContext* ec, UInt okind )
4127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4136b523cd2df025375e86b161de9995187edf2fcb6sewardj   HChar* src = NULL;
4147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(ec);
4157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (okind) {
4177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_STACK:   src = " by a stack allocation"; break;
4187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_HEAP:    src = " by a heap allocation"; break;
4197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_USER:    src = " by a client request"; break;
4207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MC_OKIND_UNKNOWN: src = ""; break;
4217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(src); /* guards against invalid 'okind' */
4237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(clo_xml)) {
4256b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( "  <auxwhat>Uninitialised value was created%s</auxwhat>\n",
4266b523cd2df025375e86b161de9995187edf2fcb6sewardj            src);
4276b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
4286b523cd2df025375e86b161de9995187edf2fcb6sewardj   } else {
4296b523cd2df025375e86b161de9995187edf2fcb6sewardj      emit( " Uninitialised value was created%s\n", src);
4306b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(pp_ExeContext)( ec );
4317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
4327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
4337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(pp_Error) ( Error* err )
4357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
4366b523cd2df025375e86b161de9995187edf2fcb6sewardj   const Bool xml  = VG_(clo_xml); /* a shorthand */
4377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
4387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
4406b523cd2df025375e86b161de9995187edf2fcb6sewardj      case Err_CoreMem:
4417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
4427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
4437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            signal handler frame.  --njn */
4446b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
4456b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
4466b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4476b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>CoreMemError</kind>\n" );
4486b523cd2df025375e86b161de9995187edf2fcb6sewardj            emiN( "  <what>%t contains unaddressable byte(s)</what>\n",
4496b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4506b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4516b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
4526b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s contains unaddressable byte(s)\n",
4536b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err));
4546b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4556b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
4567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
4597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4606b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4616b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitValue</kind>\n" );
4626b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Use of uninitialised value of size %ld</what>\n",
4636b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4646b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4656b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4666b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4676b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
4696b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
4706b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
4716b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Use of uninitialised value of size %ld\n",
4726b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Value.szB );
4736b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4746b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Value.origin_ec)
4756b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Value.origin_ec,
4766b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Value.otag & 3 );
4777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
4787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
4797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
4807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
4817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
4826b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
4836b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>UninitCondition</kind>\n" );
4846b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Conditional jump or move depends"
4856b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)</what>\n" );
4866b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4876b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
4886b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
4896b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
4907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
4916b523cd2df025375e86b161de9995187edf2fcb6sewardj            /* Could also show extra->Err.Cond.otag if debugging origin
4926b523cd2df025375e86b161de9995187edf2fcb6sewardj               tracking */
4936b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Conditional jump or move depends"
4946b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " on uninitialised value(s)\n" );
4956b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
4966b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Cond.origin_ec)
4976b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.Cond.origin_ec,
4986b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.Cond.otag & 3 );
4997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
5007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
5037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         MC_(any_value_errors) = True;
5046b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5056b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
5066b523cd2df025375e86b161de9995187edf2fcb6sewardj            emiN( "  <what>Syscall param %t contains "
5076b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "uninitialised byte(s)</what>\n",
5086b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
5096b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5106b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
5116b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
5126b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
5136b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5146b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s contains uninitialised byte(s)\n",
5156b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err) );
5166b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5176b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.RegParam.origin_ec)
5186b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.RegParam.origin_ec,
5196b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.RegParam.otag & 3 );
5206b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
5247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.MemParam.isAddrErr)
5257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5266b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5276b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>SyscallParam</kind>\n" );
5286b523cd2df025375e86b161de9995187edf2fcb6sewardj            emiN( "  <what>Syscall param %t points to %s byte(s)</what>\n",
5296b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5306b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5316b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5326b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5336b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
5346b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.MemParam.ai, False);
5356b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5366b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5376b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5386b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5396b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5406b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Syscall param %s points to %s byte(s)\n",
5416b523cd2df025375e86b161de9995187edf2fcb6sewardj                  VG_(get_error_string)(err),
5426b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.MemParam.isAddrErr
5436b523cd2df025375e86b161de9995187edf2fcb6sewardj                     ? "unaddressable" : "uninitialised" );
5446b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5456b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
5466b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.MemParam.ai, False);
5476b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.MemParam.origin_ec
5486b523cd2df025375e86b161de9995187edf2fcb6sewardj                && !extra->Err.MemParam.isAddrErr)
5496b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.MemParam.origin_ec,
5506b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.MemParam.otag & 3 );
5516b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
5557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!extra->Err.User.isAddrErr)
5567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            MC_(any_value_errors) = True;
5576b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5586b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>ClientCheck</kind>\n" );
5596b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>%s byte(s) found "
5606b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "during client check request</what>\n",
5616b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5626b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5636b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5646b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
5656b523cd2df025375e86b161de9995187edf2fcb6sewardj                           False);
5666b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5676b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5686b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5696b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
5706b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "%s byte(s) found during client check request\n",
5716b523cd2df025375e86b161de9995187edf2fcb6sewardj                   extra->Err.User.isAddrErr
5726b523cd2df025375e86b161de9995187edf2fcb6sewardj                      ? "Unaddressable" : "Uninitialised" );
5736b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5746b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
5756b523cd2df025375e86b161de9995187edf2fcb6sewardj                           False);
5766b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
5776b523cd2df025375e86b161de9995187edf2fcb6sewardj               mc_pp_origin( extra->Err.User.origin_ec,
5786b523cd2df025375e86b161de9995187edf2fcb6sewardj                             extra->Err.User.otag & 3 );
5796b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
5836b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
5846b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidFree</kind>\n" );
585913473803432ee37d6edaf232e21978d4f426125bart            emit( "  <what>Invalid free() / delete / delete[]"
586913473803432ee37d6edaf232e21978d4f426125bart                  " / realloc()</what>\n" );
5876b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5886b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
5896b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Free.ai, False );
5906b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
591913473803432ee37d6edaf232e21978d4f426125bart            emit( "Invalid free() / delete / delete[] / realloc()\n" );
5926b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
5936b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
5946b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Free.ai, False );
5956b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
5967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
5977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
5987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
5996b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6006b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>MismatchedFree</kind>\n" );
6016b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Mismatched free() / delete / delete []</what>\n" );
6026b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6036b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
6046b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.FreeMismatch.ai, False);
6056b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6066b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Mismatched free() / delete / delete []\n" );
6076b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6086b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo(VG_(get_error_address)(err),
6096b523cd2df025375e86b161de9995187edf2fcb6sewardj                           &extra->Err.FreeMismatch.ai, False);
6106b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
6146b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6156b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Invalid%s</kind>\n",
6166b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "Write" : "Read"  );
6176b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Invalid %s of size %ld</what>\n",
6186b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
6196b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6206b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6216b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6226b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Addr.ai,
6236b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Addr.maybe_gcc );
6247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         } else {
6256b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Invalid %s of size %ld\n",
6266b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.isWrite ? "write" : "read",
6276b523cd2df025375e86b161de9995187edf2fcb6sewardj                  extra->Err.Addr.szB );
6286b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6296b523cd2df025375e86b161de9995187edf2fcb6sewardj
6306b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6316b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.Addr.ai,
6326b523cd2df025375e86b161de9995187edf2fcb6sewardj                            extra->Err.Addr.maybe_gcc );
6337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         }
6347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
6376b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6386b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidJump</kind>\n" );
6396b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Jump to the invalid address stated "
6406b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "on the next line</what>\n" );
6416b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6426b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
6436b523cd2df025375e86b161de9995187edf2fcb6sewardj                            False );
6446b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6456b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Jump to the invalid address stated on the next line\n" );
6466b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6476b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
6486b523cd2df025375e86b161de9995187edf2fcb6sewardj                            False );
6496b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
6536b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6546b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>Overlap</kind>\n" );
6556b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
6566b523cd2df025375e86b161de9995187edf2fcb6sewardj               emiN( "  <what>Source and destination overlap "
6576b523cd2df025375e86b161de9995187edf2fcb6sewardj                     "in %t(%#lx, %#lx)\n</what>\n",
6586b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6596b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6606b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
6616b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <what>Source and destination overlap "
6626b523cd2df025375e86b161de9995187edf2fcb6sewardj                     "in %s(%#lx, %#lx, %d)</what>\n",
6636b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6646b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6656b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6666b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6676b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6686b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6696b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (extra->Err.Overlap.szB == 0) {
6706b523cd2df025375e86b161de9995187edf2fcb6sewardj               emiN( "Source and destination overlap in %t(%#lx, %#lx)\n",
6716b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6726b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
6736b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
6746b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "Source and destination overlap in %s(%#lx, %#lx, %d)\n",
6756b523cd2df025375e86b161de9995187edf2fcb6sewardj                     VG_(get_error_string)(err),
6766b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
6776b523cd2df025375e86b161de9995187edf2fcb6sewardj                     extra->Err.Overlap.szB );
6786b523cd2df025375e86b161de9995187edf2fcb6sewardj            }
6796b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6806b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
6837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
6846b523cd2df025375e86b161de9995187edf2fcb6sewardj         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
6856b523cd2df025375e86b161de9995187edf2fcb6sewardj         // the following code is untested.  Bad.
6866b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
6876b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <kind>InvalidMemPool</kind>\n" );
6886b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "  <what>Illegal memory pool address</what>\n" );
6896b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6906b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6916b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.IllegalMempool.ai, False );
6926b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else {
6936b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit( "Illegal memory pool address\n" );
6946b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
6956b523cd2df025375e86b161de9995187edf2fcb6sewardj            mc_pp_AddrInfo( VG_(get_error_address)(err),
6966b523cd2df025375e86b161de9995187edf2fcb6sewardj                            &extra->Err.IllegalMempool.ai, False );
6976b523cd2df025375e86b161de9995187edf2fcb6sewardj         }
6987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
6997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak: {
7017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_this_record   = extra->Err.Leak.n_this_record;
7027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         UInt        n_total_records = extra->Err.Leak.n_total_records;
703b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn         LossRecord* lr              = extra->Err.Leak.lr;
7046b523cd2df025375e86b161de9995187edf2fcb6sewardj         if (xml) {
7056b523cd2df025375e86b161de9995187edf2fcb6sewardj            emit("  <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
7066b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (lr->indirect_szB > 0) {
7076b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <xwhat>\n" );
7086b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <text>%'lu (%'lu direct, %'lu indirect) bytes "
7096b523cd2df025375e86b161de9995187edf2fcb6sewardj                     "in %'u blocks"
7106b523cd2df025375e86b161de9995187edf2fcb6sewardj                     " are %s in loss record %'u of %'u</text>\n",
7116b523cd2df025375e86b161de9995187edf2fcb6sewardj                     lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB,
7126b523cd2df025375e86b161de9995187edf2fcb6sewardj                     lr->num_blocks,
7136b523cd2df025375e86b161de9995187edf2fcb6sewardj                     str_leak_lossmode(lr->key.state),
7146b523cd2df025375e86b161de9995187edf2fcb6sewardj                     n_this_record, n_total_records );
7157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj               // Nb: don't put commas in these XML numbers
7166b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedbytes>%lu</leakedbytes>\n",
7176b523cd2df025375e86b161de9995187edf2fcb6sewardj                     lr->szB + lr->indirect_szB );
7186b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
7196b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  </xwhat>\n" );
7206b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
7216b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  <xwhat>\n" );
7226b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <text>%'lu bytes in %'u blocks"
7236b523cd2df025375e86b161de9995187edf2fcb6sewardj                     " are %s in loss record %'u of %'u</text>\n",
7246b523cd2df025375e86b161de9995187edf2fcb6sewardj                     lr->szB, lr->num_blocks,
7256b523cd2df025375e86b161de9995187edf2fcb6sewardj                     str_leak_lossmode(lr->key.state),
7266b523cd2df025375e86b161de9995187edf2fcb6sewardj                     n_this_record, n_total_records );
7276b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedbytes>%ld</leakedbytes>\n", lr->szB);
7286b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "    <leakedblocks>%d</leakedblocks>\n", lr->num_blocks);
7296b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit( "  </xwhat>\n" );
7307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            }
7316b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)(lr->key.allocated_at);
7326b523cd2df025375e86b161de9995187edf2fcb6sewardj         } else { /* ! if (xml) */
7336b523cd2df025375e86b161de9995187edf2fcb6sewardj            if (lr->indirect_szB > 0) {
7346b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit(
7356b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "%'lu (%'lu direct, %'lu indirect) bytes in %'u blocks"
7366b523cd2df025375e86b161de9995187edf2fcb6sewardj                  " are %s in loss record %'u of %'u\n",
7376b523cd2df025375e86b161de9995187edf2fcb6sewardj                  lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB,
7386b523cd2df025375e86b161de9995187edf2fcb6sewardj                  lr->num_blocks, str_leak_lossmode(lr->key.state),
7396b523cd2df025375e86b161de9995187edf2fcb6sewardj                  n_this_record, n_total_records
7406b523cd2df025375e86b161de9995187edf2fcb6sewardj               );
7416b523cd2df025375e86b161de9995187edf2fcb6sewardj            } else {
7426b523cd2df025375e86b161de9995187edf2fcb6sewardj               emit(
7436b523cd2df025375e86b161de9995187edf2fcb6sewardj                  "%'lu bytes in %'u blocks are %s in loss record %'u of %'u\n",
7446b523cd2df025375e86b161de9995187edf2fcb6sewardj                  lr->szB, lr->num_blocks, str_leak_lossmode(lr->key.state),
7456b523cd2df025375e86b161de9995187edf2fcb6sewardj                  n_this_record, n_total_records
7466b523cd2df025375e86b161de9995187edf2fcb6sewardj               );
7477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj            }
7486b523cd2df025375e86b161de9995187edf2fcb6sewardj            VG_(pp_ExeContext)(lr->key.allocated_at);
7496b523cd2df025375e86b161de9995187edf2fcb6sewardj         } /* if (xml) */
7507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         break;
7517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
7527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
7547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown Memcheck error code %d\n",
7557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(err));
7567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_pp_Error)");
7577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
7587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
7617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Recording errors                                     ---*/
7627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
7637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* These many bytes below %ESP are considered addressible if we're
7657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   doing the --workaround-gcc296-bugs hack. */
7667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#define VG_GCC296_BUG_STACK_SLOP 1024
7677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Is this address within some small distance below %ESP?  Used only
7697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for the --workaround-gcc296-bugs kludge. */
7707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool is_just_below_ESP( Addr esp, Addr aa )
7717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7727d751b2b72d806d1ef747f8ee661aeb52e7563aasewardj   esp -= VG_STACK_REDZONE_SZB;
7737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
7747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return True;
7757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
7767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
7777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
7787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from generated and non-generated code --- */
7807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
7827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Bool isWrite )
7837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
7847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
7857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool     just_below_esp;
7867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(in_ignored_range)(a))
7887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
7897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
7907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
7917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* AIX zero-page handling.  On AIX, reads from page zero are,
7927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      bizarrely enough, legitimate.  Writes to page zero aren't,
7937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      though.  Since memcheck can't distinguish reads from writes, the
7947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      best we can do is to 'act normal' and mark the A bits in the
7957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      normal way as noaccess, but then hide any reads from that page
7967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      that get reported here. */
7977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if ((!isWrite) && a >= 0 && a < 4096 && a+szB <= 4096)
7987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
7997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Appalling AIX hack.  It suppresses reads done by glink
8017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      fragments.  Getting rid of this would require figuring out
8027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      somehow where the referenced data areas are (and their
8037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      sizes). */
8047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if ((!isWrite) && szB == sizeof(Word)) {
8057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      UInt i1, i2;
8067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      UInt* pc = (UInt*)VG_(get_IP)(tid);
8077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (sizeof(Word) == 4) {
8087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         i1 = 0x800c0000; /* lwz r0,0(r12) */
8097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         i2 = 0x804c0004; /* lwz r2,4(r12) */
8107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      } else {
8117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         i1 = 0xe80c0000; /* ld  r0,0(r12) */
8127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         i2 = 0xe84c0008; /* ld  r2,8(r12) */
8137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
8147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (pc[0] == i1 && pc[1] == i2) return;
8157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (pc[0] == i2 && pc[-1] == i1) return;
8167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
8177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj#  endif
8187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
8207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* If this is caused by an access immediately below %ESP, and the
8227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      user asks nicely, we just ignore it. */
8237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
8247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
8257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.isWrite   = isWrite;
8277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.szB       = szB;
8287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.maybe_gcc = just_below_esp;
8297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Addr.ai.tag    = Addr_Undescribed;
8307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
8317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
8347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
8377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.szB       = szB;
8407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.otag      = otag;
8417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Value.origin_ec = NULL;  /* Filled in later */
8427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
8437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_cond_error) ( ThreadId tid, UInt otag )
8467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( MC_(clo_mc_level) >= 2 );
8497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.otag      = otag;
8527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
8537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
8547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* --- Called from non-generated code --- */
8577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8581dcee097db02f9ef3ba355162c4373d90d0e895cnjn/* This is for memory errors in signal-related memory. */
8591dcee097db02f9ef3ba355162c4373d90d0e895cnjnvoid MC_(record_core_mem_error) ( ThreadId tid, Char* msg )
8607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
8627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag )
8657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag > 0)
8697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.otag      = otag;
8717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
8727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
8737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_memparam_error) ( ThreadId tid, Addr a,
8767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                  Bool isAddrErr, Char* msg, UInt otag )
8777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr)
8817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
8827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
8837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
8847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( !isAddrErr );
8857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
8867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.isAddrErr = isAddrErr;
8877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.ai.tag    = Addr_Undescribed;
8887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.otag      = otag;
8897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
8907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
8917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
8927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
8937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_jump_error) ( ThreadId tid, Addr a )
8947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
8957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
8967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
8977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Jump.ai.tag = Addr_Undescribed;
8987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
8997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_free_error) ( ThreadId tid, Addr a )
9027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Free.ai.tag = Addr_Undescribed;
9067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
9077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
9107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   AddrInfo* ai = &extra.Err.FreeMismatch.ai;
9137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->tag = Addr_Block;
9157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
9167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_desc = "block";
9177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.block_szB  = mc->szB;
9187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.rwoffset   = 0;
9197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->Addr.Block.lastchange = mc->where;
9207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
9217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            &extra );
9227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
9257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
9297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
9307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_overlap_error) ( ThreadId tid, Char* function,
9337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 Addr src, Addr dst, SizeT szB )
9347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.src = src;
9387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.dst = dst;
9397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Overlap.szB = szB;
9407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)(
9417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
9427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
945b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn                              UInt n_total_records, LossRecord* lr,
94618afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                              Bool print_record, Bool count_error )
9477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_this_record   = n_this_record;
9507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.Leak.n_total_records = n_total_records;
951b7a4e2ea4e1adfda6bf2d7e3c448f663c5d173a9njn   extra.Err.Leak.lr              = lr;
9527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return
9537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
95429a5c01528ca7cffe17880a038b4563de920f08dnjn                       lr->key.allocated_at, print_record,
95518afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                       /*allow_GDB_attach*/False, count_error );
9567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjvoid MC_(record_user_error) ( ThreadId tid, Addr a,
9597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                              Bool isAddrErr, UInt otag )
9607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error extra;
9627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (otag != 0) {
9637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(!isAddrErr);
9647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) == 3 );
9657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (!isAddrErr) {
9677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( MC_(clo_mc_level) >= 2 );
9687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
9697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_INVALID_THREADID != tid);
9707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.isAddrErr = isAddrErr;
9717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.ai.tag    = Addr_Undescribed;
9727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.otag      = otag;
9737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   extra.Err.User.origin_ec = NULL;  /* Filled in later */
9747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
9757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
9767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
9787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Other error operations                               ---*/
9797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
9807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Compare error contexts, to detect duplicates.  Note that if they
9827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are otherwise the same, the faulting addrs and associated rwoffsets
9837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   are allowed to be different.  */
9847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
9857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
9867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra1 = VG_(get_error_extra)(e1);
9877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra2 = VG_(get_error_extra)(e2);
9887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Guaranteed by calling function */
9907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
9917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
9927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(e1)) {
9937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_CoreMem: {
9947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         Char *e1s, *e2s;
9957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e1s = VG_(get_error_string)(e1);
9967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         e2s = VG_(get_error_string)(e2);
9977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (e1s == e2s)                   return True;
9987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (VG_STREQ(e1s, e2s))           return True;
9997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return False;
10007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
10017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_RegParam:
10037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
10047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Perhaps we should also check the addrinfo.akinds for equality.
10067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // That would result in more error reports, but only in cases where
10077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // a register contains uninitialised bytes and points to memory
10087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // containing uninitialised bytes.  Currently, the 2nd of those to be
10097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // detected won't be reported.  That is (nearly?) always the memory
10107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // error, which is good.
10117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_MemParam:
10127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         if (!VG_STREQ(VG_(get_error_string)(e1),
10137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                       VG_(get_error_string)(e2))) return False;
10147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         // fall through
10157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_User:
10167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
10177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Free:
10207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_FreeMismatch:
10217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Jump:
10227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_IllegalMempool:
10237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Overlap:
10247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Cond:
10257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
10267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Addr:
10287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
10297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Value:
10327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ( extra1->Err.Value.szB == extra2->Err.Value.szB
10337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                ? True : False );
10347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Err_Leak:
10367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
10377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "since it's handled with VG_(unique_error)()!");
10387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
10407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n  unknown error code %d\n",
10417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_error_kind)(e1));
10427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown error code in mc_eq_Error");
10437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
10447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
10457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
104662b9104a05dede4b9cabfaa483da76480131127esewardj/* Functions used when searching MC_Chunk lists */
104762b9104a05dede4b9cabfaa483da76480131127esewardjstatic
104862b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
10497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
10517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                 MC_MALLOC_REDZONE_SZB );
10527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
105362b9104a05dede4b9cabfaa483da76480131127esewardjstatic
105462b9104a05dede4b9cabfaa483da76480131127esewardjBool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
105562b9104a05dede4b9cabfaa483da76480131127esewardj{
105662b9104a05dede4b9cabfaa483da76480131127esewardj   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
105762b9104a05dede4b9cabfaa483da76480131127esewardj                                 rzB );
105862b9104a05dede4b9cabfaa483da76480131127esewardj}
10597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
106062b9104a05dede4b9cabfaa483da76480131127esewardj// Forward declarations
10617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
106262b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
10637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Describe an address as best you can, for error messages,
10667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   putting the result in ai. */
10677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
10687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
10697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Chunk*  mc;
10707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ThreadId   tid;
10717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Addr       stack_min, stack_max;
10727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VgSectKind sect;
10737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
10747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert(Addr_Undescribed == ai->tag);
10757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
107662b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's a user-named block? -- */
10777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (client_block_maybe_describe( a, ai )) {
10787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
10797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
108062b9104a05dede4b9cabfaa483da76480131127esewardj   /* -- Perhaps it's in mempool block? -- */
108162b9104a05dede4b9cabfaa483da76480131127esewardj   if (mempool_block_maybe_describe( a, ai )) {
108262b9104a05dede4b9cabfaa483da76480131127esewardj      return;
108362b9104a05dede4b9cabfaa483da76480131127esewardj   }
10846b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Search for a recently freed block which might bracket it. -- */
10857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   mc = MC_(get_freed_list_head)();
10867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while (mc) {
108762b9104a05dede4b9cabfaa483da76480131127esewardj      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
10887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
10897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_Freed;
10907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = "block";
10917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = mc->szB;
109256adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
10937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = mc->where;
10947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
10957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
10967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      mc = mc->next;
10977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
10986b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Search for a currently malloc'd block which might bracket it. -- */
10997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(HT_ResetIter)(MC_(malloc_list));
11007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
110162b9104a05dede4b9cabfaa483da76480131127esewardj      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
11027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
11037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_Mallocd;
11047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = "block";
11057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = mc->szB;
110656adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
11077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = mc->where;
11087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
11097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
11107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11116b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Perhaps the variable type/location data describes it? -- */
11126b523cd2df025375e86b161de9995187edf2fcb6sewardj   ai->Addr.Variable.descr1
11136b523cd2df025375e86b161de9995187edf2fcb6sewardj      = VG_(newXA)( VG_(malloc), "mc.da.descr1",
11146b523cd2df025375e86b161de9995187edf2fcb6sewardj                    VG_(free), sizeof(HChar) );
11156b523cd2df025375e86b161de9995187edf2fcb6sewardj   ai->Addr.Variable.descr2
11166b523cd2df025375e86b161de9995187edf2fcb6sewardj      = VG_(newXA)( VG_(malloc), "mc.da.descr2",
11176b523cd2df025375e86b161de9995187edf2fcb6sewardj                    VG_(free), sizeof(HChar) );
11186b523cd2df025375e86b161de9995187edf2fcb6sewardj
11196b523cd2df025375e86b161de9995187edf2fcb6sewardj   (void) VG_(get_data_description)( ai->Addr.Variable.descr1,
11206b523cd2df025375e86b161de9995187edf2fcb6sewardj                                     ai->Addr.Variable.descr2, a );
11216b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* If there's nothing in descr1/2, free them.  Why is it safe to to
11226b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(indexXA) at zero here?  Because VG_(get_data_description)
11236b523cd2df025375e86b161de9995187edf2fcb6sewardj      guarantees to zero terminate descr1/2 regardless of the outcome
11246b523cd2df025375e86b161de9995187edf2fcb6sewardj      of the call.  So there's always at least one element in each XA
11256b523cd2df025375e86b161de9995187edf2fcb6sewardj      after the call.
11266b523cd2df025375e86b161de9995187edf2fcb6sewardj   */
11276b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) {
11286b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(deleteXA)( ai->Addr.Variable.descr1 );
11296b523cd2df025375e86b161de9995187edf2fcb6sewardj      ai->Addr.Variable.descr1 = NULL;
11306b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
11316b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) {
11326b523cd2df025375e86b161de9995187edf2fcb6sewardj      VG_(deleteXA)( ai->Addr.Variable.descr2 );
11336b523cd2df025375e86b161de9995187edf2fcb6sewardj      ai->Addr.Variable.descr2 = NULL;
11346b523cd2df025375e86b161de9995187edf2fcb6sewardj   }
11356b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* Assume (assert) that VG_(get_data_description) fills in descr1
11366b523cd2df025375e86b161de9995187edf2fcb6sewardj      before it fills in descr2 */
11376b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (ai->Addr.Variable.descr1 == NULL)
11386b523cd2df025375e86b161de9995187edf2fcb6sewardj      tl_assert(ai->Addr.Variable.descr2 == NULL);
11396b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* So did we get lucky? */
11406b523cd2df025375e86b161de9995187edf2fcb6sewardj   if (ai->Addr.Variable.descr1 != NULL) {
11417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_Variable;
11427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11446b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Have a look at the low level data symbols - perhaps it's in
11456b523cd2df025375e86b161de9995187edf2fcb6sewardj      there. -- */
11467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(memset)( &ai->Addr.DataSym.name,
11477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                0, sizeof(ai->Addr.DataSym.name));
11487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(get_datasym_and_offset)(
11497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             a, &ai->Addr.DataSym.name[0],
11507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             sizeof(ai->Addr.DataSym.name)-1,
11517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj             &ai->Addr.DataSym.offset )) {
11527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_DataSym;
11537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( ai->Addr.DataSym.name
11547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                    [ sizeof(ai->Addr.DataSym.name)-1 ] == 0);
11557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11576b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Perhaps it's on a thread's stack? -- */
11587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(thread_stack_reset_iter)(&tid);
11597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
11607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) {
11617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag            = Addr_Stack;
11627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Stack.tid = tid;
11637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return;
11647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
11657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11666b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- last ditch attempt at classification -- */
11677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
11687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(memset)( &ai->Addr.SectKind.objname,
11697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                0, sizeof(ai->Addr.SectKind.objname));
11707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
1171e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj   sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0],
1172e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj                                    sizeof(ai->Addr.SectKind.objname)-1, a);
11737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (sect != Vg_SectUnknown) {
11747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->tag = Addr_SectKind;
11757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ai->Addr.SectKind.kind = sect;
11767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert( ai->Addr.SectKind.objname
11777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                    [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
11787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return;
11797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11806b523cd2df025375e86b161de9995187edf2fcb6sewardj   /* -- Clueless ... -- */
11817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ai->tag = Addr_Unknown;
11827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return;
11837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
11847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Fill in *origin_ec as specified by otag, or NULL it out if otag
11867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   does not refer to a known origin. */
11877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic void update_origin ( /*OUT*/ExeContext** origin_ec,
11887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                            UInt otag )
11897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
11907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UInt ecu = otag & ~3;
11917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   *origin_ec = NULL;
11927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(is_plausible_ECU)(ecu)) {
11937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
11947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
11957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
11967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
11977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/* Updates the copy with address info if necessary (but not for all errors). */
11987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjUInt MC_(update_Error_extra)( Error* err )
11997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
12007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
12017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
12037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones don't have addresses associated with them, and so don't
12047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // need any updating.
12057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:
12067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Value:
12077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   //case Err_Cond:
12087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:
12097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For Err_Leaks the returned size does not matter -- they are always
12107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // shown with VG_(unique_error)() so they 'extra' not copied.  But
12117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we make it consistent with the others.
12127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:
12137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // For value errors, get the ExeContext corresponding to the
12167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // origin tag.  Note that it is a kludge to assume that
12177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // a length-1 trace indicates a stack origin.  FIXME.
12187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value:
12197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Value.origin_ec,
12207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Value.otag );
12217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:
12237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.Cond.origin_ec,
12247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.Cond.otag );
12257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:
12277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.RegParam.origin_ec,
12287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.RegParam.otag );
12297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // These ones always involve a memory address.
12327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr:
12337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Addr.ai );
12357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:
12377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.MemParam.ai );
12397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.MemParam.origin_ec,
12407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.MemParam.otag );
12417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:
12437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Jump.ai );
12457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:
12477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.User.ai );
12497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      update_origin( &extra->Err.User.origin_ec,
12507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     extra->Err.User.otag );
12517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:
12537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.Free.ai );
12557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool:
12577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      describe_addr ( VG_(get_error_address)(err),
12587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                      &extra->Err.IllegalMempool.ai );
12597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // Err_FreeMismatches have already had their address described;  this is
12627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // possible because we have the MC_Chunk on hand when the error is
12637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // detected.  However, the address may be part of a user block, and if so
12647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   // we override the pre-determined description with a user block one.
12657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch: {
12667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(extra && Block_Mallocd ==
12677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
12687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      (void)client_block_maybe_describe( VG_(get_error_address)(err),
12697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                        &extra->Err.FreeMismatch.ai );
12707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return sizeof(MC_Error);
12717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default: VG_(tool_panic)("mc_update_extra: bad errkind");
12747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
12757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
12767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
127762b9104a05dede4b9cabfaa483da76480131127esewardj
12787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjstatic Bool client_block_maybe_describe( Addr a,
12797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                                         /*OUT*/AddrInfo* ai )
12807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
128156adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj   UWord      i;
12827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   CGenBlock* cgbs = NULL;
12837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   UWord      cgb_used = 0;
128456adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj
12857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
12867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (cgbs == NULL)
12877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      tl_assert(cgb_used == 0);
12887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
12897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   /* Perhaps it's a general block ? */
12907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   for (i = 0; i < cgb_used; i++) {
12917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (cgbs[i].start == 0 && cgbs[i].size == 0)
12927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         continue;
12937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Use zero as the redzone for client blocks.
12947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
12957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->tag = Addr_Block;
12967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_kind = Block_UserG;
12977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_desc = cgbs[i].desc;
12987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.block_szB  = cgbs[i].size;
129956adc358fd23a1b1d9e331ca63f773aca1ec0953sewardj         ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
13007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         ai->Addr.Block.lastchange = cgbs[i].where;
13017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return True;
13027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
13037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return False;
13057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
130862b9104a05dede4b9cabfaa483da76480131127esewardjstatic Bool mempool_block_maybe_describe( Addr a,
130962b9104a05dede4b9cabfaa483da76480131127esewardj                                          /*OUT*/AddrInfo* ai )
131062b9104a05dede4b9cabfaa483da76480131127esewardj{
131162b9104a05dede4b9cabfaa483da76480131127esewardj   MC_Mempool* mp;
131262b9104a05dede4b9cabfaa483da76480131127esewardj   tl_assert( MC_(mempool_list) );
131362b9104a05dede4b9cabfaa483da76480131127esewardj
131462b9104a05dede4b9cabfaa483da76480131127esewardj   VG_(HT_ResetIter)( MC_(mempool_list) );
131562b9104a05dede4b9cabfaa483da76480131127esewardj   while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
131662b9104a05dede4b9cabfaa483da76480131127esewardj      if (mp->chunks != NULL) {
131762b9104a05dede4b9cabfaa483da76480131127esewardj         MC_Chunk* mc;
131862b9104a05dede4b9cabfaa483da76480131127esewardj         VG_(HT_ResetIter)(mp->chunks);
131962b9104a05dede4b9cabfaa483da76480131127esewardj         while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
132062b9104a05dede4b9cabfaa483da76480131127esewardj            if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
132162b9104a05dede4b9cabfaa483da76480131127esewardj               ai->tag = Addr_Block;
132262b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_kind = Block_MempoolChunk;
132362b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_desc = "block";
132462b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.block_szB  = mc->szB;
132562b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
132662b9104a05dede4b9cabfaa483da76480131127esewardj               ai->Addr.Block.lastchange = mc->where;
132762b9104a05dede4b9cabfaa483da76480131127esewardj               return True;
132862b9104a05dede4b9cabfaa483da76480131127esewardj            }
132962b9104a05dede4b9cabfaa483da76480131127esewardj         }
133062b9104a05dede4b9cabfaa483da76480131127esewardj      }
133162b9104a05dede4b9cabfaa483da76480131127esewardj   }
133262b9104a05dede4b9cabfaa483da76480131127esewardj   return False;
133362b9104a05dede4b9cabfaa483da76480131127esewardj}
133462b9104a05dede4b9cabfaa483da76480131127esewardj
133562b9104a05dede4b9cabfaa483da76480131127esewardj
13367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
13377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- Suppressions                                         ---*/
13387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*------------------------------------------------------------*/
13397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjtypedef
13417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   enum {
13427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      ParamSupp,     // Bad syscall params
13437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      UserSupp,      // Errors arising from client-request checks
13447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
13457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value errors of given size
13477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
13487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Undefined value error in conditional.
13507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      CondSupp,
13517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      // Unaddressable read/write attempt at given size
13537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
13547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      JumpSupp,      // Jump to unaddressable target
13567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      FreeSupp,      // Invalid or mismatching free
13577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
13587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      LeakSupp,      // Something to be suppressed in a leak check.
13597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MempoolSupp,   // Memory pool suppression.
13607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
13617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_SuppKind;
13627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(is_recognised_suppression) ( Char* name, Supp* su )
13647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
13657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   SuppKind skind;
13667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
13687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "User"))    skind = UserSupp;
13697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
13707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
13717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
13727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
13737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
13747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
13757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
13767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
13777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
13787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
13797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
13807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
13817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
13827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
13837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
13847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
13857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
13867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
13877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   else
13887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      return False;
13897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   VG_(set_supp_kind)(su, skind);
13917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
13927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
13937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
139435db56c19847654f22b62da059083d41ff4258c5njnBool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp,
139535db56c19847654f22b62da059083d41ff4258c5njn                                        SizeT* nBufp, Supp *su )
13967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
13977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Bool eof;
13987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
13997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (VG_(get_supp_kind)(su) == ParamSupp) {
1400050eec553cdcb2ebeaefbb267aeb0828be7121e5bart      eof = VG_(get_line) ( fd, bufpp, nBufp, NULL );
14017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      if (eof) return False;
140235db56c19847654f22b62da059083d41ff4258c5njn      VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
14037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   return True;
14057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjBool MC_(error_matches_suppression) ( Error* err, Supp* su )
14087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
14097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   Int       su_szB;
14107ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   MC_Error* extra = VG_(get_error_extra)(err);
14117ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
14127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_supp_kind)(su)) {
14147ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case ParamSupp:
14157ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return ((ekind == Err_RegParam || ekind == Err_MemParam)
14167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14177ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14187ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14197ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case UserSupp:
14207ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_User);
14217ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14227ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CoreMemSupp:
14237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_CoreMem
14247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj              && VG_STREQ(VG_(get_error_string)(err),
14257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                          VG_(get_supp_string)(su)));
14267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value1Supp: su_szB = 1; goto value_case;
14287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value2Supp: su_szB = 2; goto value_case;
14297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value4Supp: su_szB = 4; goto value_case;
14307ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value8Supp: su_szB = 8; goto value_case;
14317ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Value16Supp:su_szB =16; goto value_case;
14327ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      value_case:
14337ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
14347ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14357ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case CondSupp:
14367ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Cond);
14377ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14387ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr1Supp: su_szB = 1; goto addr_case;
14397ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr2Supp: su_szB = 2; goto addr_case;
14407ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr4Supp: su_szB = 4; goto addr_case;
14417ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr8Supp: su_szB = 8; goto addr_case;
14427ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case Addr16Supp:su_szB =16; goto addr_case;
14437ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      addr_case:
14447ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
14457ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14467ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case JumpSupp:
14477ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Jump);
14487ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14497ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case FreeSupp:
14507ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Free || ekind == Err_FreeMismatch);
14517ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14527ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case OverlapSupp:
14537ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Overlap);
14547ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14557ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case LeakSupp:
14567ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_Leak);
14577ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14587ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case MempoolSupp:
14597ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         return (ekind == Err_IllegalMempool);
14607ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14617ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:
14627ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(printf)("Error:\n"
14637ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     "  unknown suppression type %d\n",
14647ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                     VG_(get_supp_kind)(su));
14657ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj         VG_(tool_panic)("unknown suppression type in "
14667ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj                         "MC_(error_matches_suppression)");
14677ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14687ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
14697ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
14707ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardjChar* MC_(get_error_name) ( Error* err )
14717ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
14727ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   switch (VG_(get_error_kind)(err)) {
14737ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_RegParam:       return "Param";
14747ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_MemParam:       return "Param";
14757ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_User:           return "User";
14767ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_FreeMismatch:   return "Free";
14777ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_IllegalMempool: return "Mempool";
14787ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Free:           return "Free";
14797ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Jump:           return "Jump";
14807ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_CoreMem:        return "CoreMem";
14817ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Overlap:        return "Overlap";
14827ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Leak:           return "Leak";
14837ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Cond:           return "Cond";
14847ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Addr: {
14857ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
14867ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Addr.szB ) {
14877ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Addr1";
14887ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Addr2";
14897ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Addr4";
14907ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Addr8";
14917ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Addr16";
14927ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Addr");
14937ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
14947ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
14957ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   case Err_Value: {
14967ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      MC_Error* extra = VG_(get_error_extra)(err);
14977ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      switch ( extra->Err.Value.szB ) {
14987ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 1:               return "Value1";
14997ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 2:               return "Value2";
15007ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 4:               return "Value4";
15017ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 8:               return "Value8";
15027ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      case 16:              return "Value16";
15037ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      default:              VG_(tool_panic)("unexpected size for Value");
15047ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj      }
15057ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15067ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   default:                 VG_(tool_panic)("get_error_name: unexpected type");
15077ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15087ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15097ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
1510588adeffafa8102adcfa7a1c035ae272b35cf86dsewardjBool MC_(get_extra_suppression_info) ( Error* err,
1511588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                                       /*OUT*/Char* buf, Int nBuf )
15127ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj{
15137ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   ErrorKind ekind = VG_(get_error_kind )(err);
1514588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   tl_assert(buf);
1515588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   tl_assert(nBuf >= 16); // stay sane
15167ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   if (Err_RegParam == ekind || Err_MemParam == ekind) {
1517588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      Char* errstr = VG_(get_error_string)(err);
1518588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      tl_assert(errstr);
1519588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(snprintf)(buf, nBuf-1, "%s", errstr);
1520588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      return True;
1521588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   } else {
1522588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      return False;
15237ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj   }
15247ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj}
15257ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15267ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj
15277ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
15287ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--- end                                              mc_errors.c ---*/
15297ce7166aeae2d8401f2b3b1f9e6f60be9ae9dd72sewardj/*--------------------------------------------------------------------*/
1530