1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Ptrcheck: a pointer-use checker. ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Provides stuff shared between sg_ and h_ subtools. ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- pc_common.c ---*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Ptrcheck, a Valgrind tool for checking pointer 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use in programs. 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2008-2011 OpenWorks Ltd 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.co.uk 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_basics.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcbase.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcprint.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_xarray.h" 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_mallocfree.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcassert.h" 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_options.h" 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_replacemalloc.h" 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_execontext.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_tooliface.h" // CorePart 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_threadstate.h" // VG_(get_running_tid) 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_debuginfo.h" 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pc_common.h" // self, & Seg 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "h_main.h" // NONPTR, BOTTOM, UNKNOWN 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Command line options // 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool h_clo_partial_loads_ok = True; /* user visible */ 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Bool h_clo_lossage_check = False; */ /* dev flag only */ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool sg_clo_enable_sg_checks = True; /* user visible */ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_process_cmd_line_options(Char* arg) 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if VG_BOOL_CLO(arg, "--partial-loads-ok", h_clo_partial_loads_ok) {} 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else if VG_BOOL_CLO(arg, "--lossage-check", h_clo_lossage_check) {} */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--enable-sg-checks", sg_clo_enable_sg_checks) {} 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(replacement_malloc_process_cmd_line_option)(arg); 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid pc_print_usage(void) 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " --partial-loads-ok=no|yes same as for Memcheck [yes]\n" 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " --enable-sg-checks=no|yes enable stack & global array checking? [yes]\n" 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid pc_print_debug_usage(void) 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" (none)\n" 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//" --lossage-check=no|yes gather stats for quality control [no]\n" 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Error management -- storage // 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* What kind of error it is. */ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XE_SorG=1202, // sg: stack or global array inconsistency 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XE_Heap, // h: mismatched ptr/addr segments on load/store 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XE_Arith, // h: bad arithmetic between two segment pointers 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XE_SysParam // h: block straddling >1 segment passed to syscall 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XErrorTag; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XS_SorG=2021, 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XS_Heap, 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XS_Arith, 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XS_SysParam 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XSuppTag; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XErrorTag tag; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr addr; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SSizeT sszB; /* -ve is write, +ve is read */ 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar expect[128]; 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar actual[128]; 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar delta[32]; // text showing relation to expected 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } SorG; 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr addr; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SSizeT sszB; /* -ve is write, +ve is read */ 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* vseg; 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* descr1; /* XArray* of HChar */ 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* descr2; /* XArray* of HChar */ 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char datasym[96]; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT datasymoff; 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Heap; 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seg1; 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seg2; 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const HChar* opname; // user-understandable text name 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Arith; 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CorePart part; 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr lo; 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr hi; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seglo; 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seghi; 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } SysParam; 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } XE; 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid sg_record_error_SorG ( ThreadId tid, 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr addr, SSizeT sszB, 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* expect, HChar* actual, HChar* delta ) 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError xe; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&xe, 0, sizeof(xe)); 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.tag = XE_SorG; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SorG.addr = addr; 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SorG.sszB = sszB; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strncpy)( &xe.XE.SorG.expect[0], 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expect, sizeof(xe.XE.SorG.expect) ); 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strncpy)( &xe.XE.SorG.actual[0], 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown actual, sizeof(xe.XE.SorG.actual) ); 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(strncpy)( &xe.XE.SorG.delta[0], 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov delta, sizeof(xe.XE.SorG.delta) ); 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SorG.expect[ sizeof(xe.XE.SorG.expect)-1 ] = 0; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SorG.actual[ sizeof(xe.XE.SorG.actual)-1 ] = 0; 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov xe.XE.SorG.delta[ sizeof(xe.XE.SorG.delta)-1 ] = 0; 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, XE_SorG, 0, NULL, &xe ); 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid h_record_heap_error( Addr a, SizeT size, Seg* vseg, Bool is_write ) 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError xe; 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(size > 0); 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&xe, 0, sizeof(xe)); 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.tag = XE_Heap; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Heap.addr = a; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Heap.sszB = is_write ? -size : size; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Heap.vseg = vseg; 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Heap, 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*a*/0, /*str*/NULL, /*extra*/(void*)&xe); 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid h_record_arith_error( Seg* seg1, Seg* seg2, HChar* opname ) 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError xe; 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&xe, 0, sizeof(xe)); 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.tag = XE_Arith; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Arith.seg1 = seg1; 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Arith.seg2 = seg2; 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.Arith.opname = opname; 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Arith, 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*a*/0, /*str*/NULL, /*extra*/(void*)&xe); 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid h_record_sysparam_error( ThreadId tid, CorePart part, Char* s, 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr lo, Addr hi, Seg* seglo, Seg* seghi ) 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError xe; 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&xe, 0, sizeof(xe)); 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.tag = XE_SysParam; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SysParam.part = part; 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SysParam.lo = lo; 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SysParam.hi = hi; 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SysParam.seglo = seglo; 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe.XE.SysParam.seghi = seghi; 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, XE_SysParam, /*a*/(Addr)0, /*str*/s, 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*extra*/(void*)&xe); 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_eq_Error ( VgRes res, Error* e1, Error* e2 ) 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError *xe1, *xe2; 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //tl_assert(VG_(get_error_string)(e1) == NULL); 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //tl_assert(VG_(get_error_string)(e2) == NULL); 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe1 = (XError*)VG_(get_error_extra)(e1); 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe2 = (XError*)VG_(get_error_extra)(e2); 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe1); 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe2); 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe1->tag != xe2->tag) 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (xe1->tag) { 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SorG: 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return //xe1->XE.SorG.addr == xe2->XE.SorG.addr 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //&& 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe1->XE.SorG.sszB == xe2->XE.SorG.sszB 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && 0 == VG_(strncmp)( &xe1->XE.SorG.expect[0], 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &xe2->XE.SorG.expect[0], 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(xe1->XE.SorG.expect) ) 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && 0 == VG_(strncmp)( &xe1->XE.SorG.actual[0], 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &xe2->XE.SorG.actual[0], 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(xe1->XE.SorG.actual) ); 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Heap: 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Arith: 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SysParam: 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("eq_Error: unrecognised error kind"); 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Error management -- printing // 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// // 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown////////////////////////////////////////////////////////////// 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is the "this error is due to be printed shortly; so have a 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown look at it any print any preamble you want" function. Which, in 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ptrcheck, we don't use. Hence a no-op. 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid pc_before_pp_Error ( Error* err ) { 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do a printf-style operation on either the XML or normal output 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown channel, depending on the setting of VG_(clo_xml). 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit_WRK ( HChar* format, va_list vargs ) 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_xml)) { 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(vprintf_xml)(format, vargs); 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(vmessage)(Vg_UserMsg, format, vargs); 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2); 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit ( HChar* format, ... ) 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit_WRK(format, vargs); 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emiN ( HChar* format, ... ) /* With NO FORMAT CHECK */ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit_WRK(format, vargs); 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* readwrite(SSizeT sszB) 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ( sszB < 0 ? "write" : "read" ); 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Word Word__abs ( Word w ) { 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return w < 0 ? -w : w; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid pc_pp_Error ( Error* err ) 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool xml = VG_(clo_xml); /* a shorthand, that's all */ 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError *xe = (XError*)VG_(get_error_extra)(err); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe); 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (xml) 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emit( " <kind>%s</kind>\n", pc_get_error_name(err)); 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_error_kind)(err)) { 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //---------------------------------------------------------- 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SorG: 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Invalid %s of size %ld</what>\n", 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.SorG.sszB < 0 ? "write" : "read", 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.SorG.sszB) ); 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Address %#lx expected vs actual:</auxwhat>\n", 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.SorG.addr ); 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emiN( " <auxwhat>Expected: %pS</auxwhat>\n", 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &xe->XE.SorG.expect[0] ); 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emiN( " <auxwhat>Actual: %pS</auxwhat>\n", 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &xe->XE.SorG.actual[0] ); 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Invalid %s of size %ld\n", 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.SorG.sszB < 0 ? "write" : "read", 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.SorG.sszB) ); 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Address %#lx expected vs actual:\n", xe->XE.SorG.addr ); 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Expected: %s\n", &xe->XE.SorG.expect[0] ); 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Actual: %s\n", &xe->XE.SorG.actual[0] ); 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (xe->XE.SorG.delta[0] != 0) 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emit(" Actual: is %s Expected\n", &xe->XE.SorG.delta[0]); 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //---------------------------------------------------------- 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Heap: { 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char *place, *legit, *how_invalid; 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr a = xe->XE.Heap.addr; 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* vseg = xe->XE.Heap.vseg; 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(is_known_segment(vseg) || NONPTR == vseg); 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (NONPTR == vseg) { 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Access via a non-pointer 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Invalid %s of size %ld</what>\n", 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown readwrite(xe->XE.Heap.sszB), 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.Heap.sszB) ); 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Address %#lx is not derived from " 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "any known block</auxwhat>\n", a ); 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Invalid %s of size %ld\n", 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown readwrite(xe->XE.Heap.sszB), 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.Heap.sszB) ); 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Address %#lx is not derived from " 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "any known block\n", a ); 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Access via a pointer, but outside its range. 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int cmp; 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord miss_size; 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg__cmp(vseg, a, &cmp, &miss_size); 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cmp < 0) place = "before"; 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (cmp == 0) place = "inside"; 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else place = "after"; 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp ) 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? "Doubly-invalid" : "Invalid" ); 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown legit = ( Seg__is_freed(vseg) ? "once-" : "" ); 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>%s %s of size %ld</what>\n", 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown how_invalid, 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown readwrite(xe->XE.Heap.sszB), 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.Heap.sszB) ); 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Address %#lx is %lu bytes %s " 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "the accessing pointer's</auxwhat>\n", 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a, miss_size, place ); 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>%slegitimate range, " 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "a block of size %lu %s</auxwhat>\n", 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown legit, Seg__size(vseg), 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg__is_freed(vseg) ? "free'd" : "alloc'd" ); 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(vseg)); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s %s of size %ld\n", 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown how_invalid, 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown readwrite(xe->XE.Heap.sszB), 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word__abs(xe->XE.Heap.sszB) ); 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Address %#lx is %lu bytes %s the accessing pointer's\n", 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a, miss_size, place ); 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %slegitimate range, a block of size %lu %s\n", 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown legit, Seg__size(vseg), 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg__is_freed(vseg) ? "free'd" : "alloc'd" ); 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(vseg)); 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If we have a better description of the address, show it. 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that in XML mode, it will already by nicely wrapped up 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in tags, either <auxwhat> or <xauxwhat>, so we can just emit 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it verbatim. */ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.descr1) 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emiN( " %pS\n", 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) ); 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.descr2) 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov emiN( " %pS\n", 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) ); 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.datasym[0] != 0) 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( " <auxwhat>Address 0x%llx is %llu bytes " 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "inside data symbol \"%pS\"</auxwhat>\n", 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)xe->XE.Heap.addr, 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)xe->XE.Heap.datasymoff, 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.datasym ); 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.descr1) 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %s\n", 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) ); 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.descr2) 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %s\n", 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) ); 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xe->XE.Heap.datasym[0] != 0) 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Address 0x%llx is %llu bytes " 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "inside data symbol \"%s\"\n", 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)xe->XE.Heap.addr, 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)xe->XE.Heap.datasymoff, 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.datasym ); 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //---------------------------------------------------------- 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Arith: { 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seg1 = xe->XE.Arith.seg1; 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seg2 = xe->XE.Arith.seg2; 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* which; 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(BOTTOM != seg1); 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(BOTTOM != seg2 && UNKNOWN != seg2); 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Invalid arguments to %s</what>\n", 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Arith.opname ); 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg1 != seg2) { 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (NONPTR == seg1) { 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>First arg not a pointer</auxwhat>\n" ); 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else if (UNKNOWN == seg1) { 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>First arg may be a pointer</auxwhat>\n" ); 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>First arg derived from address %#lx of " 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%lu-byte block alloc'd</auxwhat>\n", 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg__addr(seg1), Seg__size(seg1) ); 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seg1)); 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which = "Second arg"; 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which = "Both args"; 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (NONPTR == seg2) { 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>%s not a pointer</auxwhat>\n", which ); 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>%s derived from address %#lx of " 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%lu-byte block alloc'd</auxwhat>\n", 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which, Seg__addr(seg2), Seg__size(seg2) ); 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seg2)); 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Invalid arguments to %s\n", 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Arith.opname ); 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg1 != seg2) { 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (NONPTR == seg1) { 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " First arg not a pointer\n" ); 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else if (UNKNOWN == seg1) { 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " First arg may be a pointer\n" ); 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " First arg derived from address %#lx of " 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%lu-byte block alloc'd\n", 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg__addr(seg1), Seg__size(seg1) ); 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seg1)); 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which = "Second arg"; 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which = "Both args"; 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (NONPTR == seg2) { 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %s not a pointer\n", which ); 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %s derived from address %#lx of " 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%lu-byte block alloc'd\n", 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which, Seg__addr(seg2), Seg__size(seg2) ); 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seg2)); 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //---------------------------------------------------------- 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SysParam: { 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr lo = xe->XE.SysParam.lo; 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr hi = xe->XE.SysParam.hi; 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seglo = xe->XE.SysParam.seglo; 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Seg* seghi = xe->XE.SysParam.seghi; 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* s = VG_(get_error_string) (err); 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* what; 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(BOTTOM != seglo && BOTTOM != seghi); 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (Vg_CoreSysCall == xe->XE.SysParam.part) 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what = "Syscall param "; 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else VG_(tool_panic)("bad CorePart"); 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seglo == seghi) { 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // freed block 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(is_known_segment(seglo)); 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled? 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>%s%s contains unaddressable byte(s)</what>\n", 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what, s ); 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Address %#lx is %ld bytes inside a " 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block free'd</auxwhat>\n", 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seglo)); 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " %s%s contains unaddressable byte(s)\n", 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what, s ); 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Address %#lx is %ld bytes inside a " 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block free'd\n", 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seglo)); 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // mismatch 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>%s%s is non-contiguous</what>\n", 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what, s ); 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNKNOWN == seglo) { 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>First byte is " 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "not inside a known block</auxwhat>\n" ); 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>First byte (%#lx) is %ld bytes inside a " 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block alloc'd</auxwhat>\n", 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seglo)); 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNKNOWN == seghi) { 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Last byte is " 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "not inside a known block</auxwhat>\n" ); 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Last byte (%#lx) is %ld bytes inside a " 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block alloc'd</auxwhat>\n", 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seghi)); 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s%s is non-contiguous\n", 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown what, s ); 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNKNOWN == seglo) { 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " First byte is not inside a known block\n" ); 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " First byte (%#lx) is %ld bytes inside a " 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block alloc'd\n", 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seglo)); 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNKNOWN == seghi) { 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Last byte is not inside a known block\n" ); 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Last byte (%#lx) is %ld bytes inside a " 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%ld-byte block alloc'd\n", 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(Seg__where(seghi)); 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("pp_Error: unrecognised error kind"); 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt pc_update_Error_extra ( Error* err ) 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError *xe = (XError*)VG_(get_error_extra)(err); 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe); 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (xe->tag) { 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SorG: 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Heap: { 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_descr; 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(sizeof(xe->XE.Heap.datasym) > 0); 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.datasymoff = 0; 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.datasym[0] = 0; 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(!xe->XE.Heap.descr1); 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(!xe->XE.Heap.descr2); 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.descr1 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free), sizeof(HChar) ); 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.descr2 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free), sizeof(HChar) ); 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym)); 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.datasymoff = 0; 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_descr 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(get_data_description)( xe->XE.Heap.descr1, 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.descr2, 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.addr ); 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If there's nothing in descr1/2, free it. Why is it safe to 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to VG_(indexXA) at zero here? Because 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_data_description) guarantees to zero terminate 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown descr1/2 regardless of the outcome of the call. So there's 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown always at least one element in each XA after the call. 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr1, 0 )) 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || !have_descr) { 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( xe->XE.Heap.descr1 ); 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.descr1 = NULL; 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr2, 0 )) 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || !have_descr) { 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( xe->XE.Heap.descr2 ); 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.descr2 = NULL; 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If Dwarf3 info produced nothing useful, see at least if 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we can fish something useful out of the ELF symbol info. */ 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!have_descr) { 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(get_datasym_and_offset)( 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xe->XE.Heap.addr, &xe->XE.Heap.datasym[0], 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(xe->XE.Heap.datasym)-1, 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &xe->XE.Heap.datasymoff ) 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) { 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == 0); 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Arith: 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SysParam: 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("update_extra"); 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(XError); 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_is_recognised_suppression ( Char* name, Supp *su ) 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SuppKind skind; 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_STREQ(name, "SorG")) skind = XS_SorG; 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Heap")) skind = XS_Heap; 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Arith")) skind = XS_Arith; 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "SysParam")) skind = XS_SysParam; 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_supp_kind)(su, skind); 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_read_extra_suppression_info ( Int fd, Char** bufpp, 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT* nBufp, Supp* su ) 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool eof; 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(get_supp_kind)(su) == XS_SysParam) { 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eof = VG_(get_line) ( fd, bufpp, nBufp, NULL ); 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (eof) return False; 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_supp_string)(su, VG_(strdup)("pc.common.presi.1", *bufpp)); 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_error_matches_suppression (Error* err, Supp* su) 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ErrorKind ekind = VG_(get_error_kind)(err); 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_supp_kind)(su)) { 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XS_SorG: return ekind == XE_SorG; 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XS_Heap: return ekind == XE_Heap; 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XS_Arith: return ekind == XE_Arith; 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XS_SysParam: return ekind == XE_SysParam; 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("Error:\n" 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " unknown suppression type %d\n", 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_supp_kind)(su)); 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("unknown suppression type in " 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "pc_error_matches_suppression"); 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownChar* pc_get_error_name ( Error* err ) 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XError *xe = (XError*)VG_(get_error_extra)(err); 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(xe); 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (xe->tag) { 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SorG: return "SorG"; 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Heap: return "Heap"; 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_Arith: return "Arith"; 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case XE_SysParam: return "SysParam"; 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: VG_(tool_panic)("get_error_name: unexpected type"); 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool pc_get_extra_suppression_info ( Error* err, 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/Char* buf, Int nBuf ) 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ErrorKind ekind = VG_(get_error_kind )(err); 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(buf); 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(nBuf >= 16); // stay sane 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (XE_SysParam == ekind) { 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* errstr = VG_(get_error_string)(err); 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(errstr); 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(snprintf)(buf, nBuf-1, "%s", errstr); 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end pc_common.c ---*/ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 800