blob: e5a3364217b40407b915e0747492178ab57114a7 [file] [log] [blame]
sewardj024598e2008-09-18 14:43:05 +00001
2/*--------------------------------------------------------------------*/
3/*--- Ptrcheck: a pointer-use checker. ---*/
4/*--- Provides stuff shared between sg_ and h_ subtools. ---*/
5/*--- pc_common.c ---*/
6/*--------------------------------------------------------------------*/
7
8/*
9 This file is part of Ptrcheck, a Valgrind tool for checking pointer
10 use in programs.
11
Elliott Hughesed398002017-06-21 14:41:24 -070012 Copyright (C) 2008-2017 OpenWorks Ltd
sewardj024598e2008-09-18 14:43:05 +000013 info@open-works.co.uk
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31
32 Neither the names of the U.S. Department of Energy nor the
33 University of California nor the names of its contributors may be
34 used to endorse or promote products derived from this software
35 without prior written permission.
36*/
37
38#include "pub_tool_basics.h"
39#include "pub_tool_libcbase.h"
40#include "pub_tool_libcprint.h"
sewardjc1bc9d12009-07-15 14:50:22 +000041#include "pub_tool_xarray.h"
sewardj024598e2008-09-18 14:43:05 +000042#include "pub_tool_mallocfree.h"
43#include "pub_tool_libcassert.h"
44#include "pub_tool_options.h"
45#include "pub_tool_replacemalloc.h"
46#include "pub_tool_execontext.h"
47#include "pub_tool_tooliface.h" // CorePart
48#include "pub_tool_threadstate.h" // VG_(get_running_tid)
49#include "pub_tool_debuginfo.h"
50
51#include "pc_common.h" // self, & Seg
52
53#include "h_main.h" // NONPTR, BOTTOM, UNKNOWN
54
55
56//////////////////////////////////////////////////////////////
57// //
58// Command line options //
59// //
60//////////////////////////////////////////////////////////////
61
sewardj4815eb52008-10-20 23:33:49 +000062Bool h_clo_partial_loads_ok = True; /* user visible */
63/* Bool h_clo_lossage_check = False; */ /* dev flag only */
64Bool sg_clo_enable_sg_checks = True; /* user visible */
sewardj024598e2008-09-18 14:43:05 +000065
florian19f91bb2012-11-10 22:29:54 +000066Bool pc_process_cmd_line_options(const HChar* arg)
sewardj024598e2008-09-18 14:43:05 +000067{
njn83df0b62009-02-25 01:01:05 +000068 if VG_BOOL_CLO(arg, "--partial-loads-ok", h_clo_partial_loads_ok) {}
69 /* else if VG_BOOL_CLO(arg, "--lossage-check", h_clo_lossage_check) {} */
70 else if VG_BOOL_CLO(arg, "--enable-sg-checks", sg_clo_enable_sg_checks) {}
sewardj024598e2008-09-18 14:43:05 +000071 else
72 return VG_(replacement_malloc_process_cmd_line_option)(arg);
73
74 return True;
75}
76
77void pc_print_usage(void)
78{
79 VG_(printf)(
sewardj4815eb52008-10-20 23:33:49 +000080 " --partial-loads-ok=no|yes same as for Memcheck [yes]\n"
81 " --enable-sg-checks=no|yes enable stack & global array checking? [yes]\n"
sewardj024598e2008-09-18 14:43:05 +000082 );
sewardj024598e2008-09-18 14:43:05 +000083}
84
85void pc_print_debug_usage(void)
86{
87 VG_(printf)(
njn97db7612009-08-04 02:32:55 +000088" (none)\n"
89//" --lossage-check=no|yes gather stats for quality control [no]\n"
sewardj024598e2008-09-18 14:43:05 +000090 );
sewardj024598e2008-09-18 14:43:05 +000091}
92
93
94
95//////////////////////////////////////////////////////////////
96// //
sewardjc1bc9d12009-07-15 14:50:22 +000097// Error management -- storage //
sewardj024598e2008-09-18 14:43:05 +000098// //
99//////////////////////////////////////////////////////////////
100
101/* What kind of error it is. */
102typedef
103 enum {
104 XE_SorG=1202, // sg: stack or global array inconsistency
105 XE_Heap, // h: mismatched ptr/addr segments on load/store
106 XE_Arith, // h: bad arithmetic between two segment pointers
107 XE_SysParam // h: block straddling >1 segment passed to syscall
108 }
109 XErrorTag;
110
111typedef
112 enum {
113 XS_SorG=2021,
114 XS_Heap,
115 XS_Arith,
116 XS_SysParam
117 }
118 XSuppTag;
119
120typedef
121 struct {
122 XErrorTag tag;
123 union {
124 struct {
125 Addr addr;
126 SSizeT sszB; /* -ve is write, +ve is read */
127 HChar expect[128];
128 HChar actual[128];
sewardjf5b019f2011-05-11 12:01:37 +0000129 HChar delta[32]; // text showing relation to expected
sewardj024598e2008-09-18 14:43:05 +0000130 } SorG;
131 struct {
njnc4431bf2009-01-15 21:29:24 +0000132 Addr addr;
133 SSizeT sszB; /* -ve is write, +ve is read */
134 Seg* vseg;
sewardjc1bc9d12009-07-15 14:50:22 +0000135 XArray* descr1; /* XArray* of HChar */
136 XArray* descr2; /* XArray* of HChar */
florian46cc0452014-10-25 19:20:38 +0000137 const HChar* datasym;
njnc4431bf2009-01-15 21:29:24 +0000138 PtrdiffT datasymoff;
sewardj024598e2008-09-18 14:43:05 +0000139 } Heap;
140 struct {
141 Seg* seg1;
142 Seg* seg2;
143 const HChar* opname; // user-understandable text name
144 } Arith;
145 struct {
146 CorePart part;
147 Addr lo;
148 Addr hi;
149 Seg* seglo;
150 Seg* seghi;
151 } SysParam;
152 } XE;
153 }
154 XError;
155
156
157void sg_record_error_SorG ( ThreadId tid,
158 Addr addr, SSizeT sszB,
sewardjf5b019f2011-05-11 12:01:37 +0000159 HChar* expect, HChar* actual, HChar* delta )
sewardj024598e2008-09-18 14:43:05 +0000160{
161 XError xe;
162 VG_(memset)(&xe, 0, sizeof(xe));
163 xe.tag = XE_SorG;
164 xe.XE.SorG.addr = addr;
165 xe.XE.SorG.sszB = sszB;
166 VG_(strncpy)( &xe.XE.SorG.expect[0],
167 expect, sizeof(xe.XE.SorG.expect) );
168 VG_(strncpy)( &xe.XE.SorG.actual[0],
169 actual, sizeof(xe.XE.SorG.actual) );
sewardjf5b019f2011-05-11 12:01:37 +0000170 VG_(strncpy)( &xe.XE.SorG.delta[0],
171 delta, sizeof(xe.XE.SorG.delta) );
sewardj024598e2008-09-18 14:43:05 +0000172 xe.XE.SorG.expect[ sizeof(xe.XE.SorG.expect)-1 ] = 0;
173 xe.XE.SorG.actual[ sizeof(xe.XE.SorG.actual)-1 ] = 0;
sewardjf5b019f2011-05-11 12:01:37 +0000174 xe.XE.SorG.delta[ sizeof(xe.XE.SorG.delta)-1 ] = 0;
sewardj024598e2008-09-18 14:43:05 +0000175 VG_(maybe_record_error)( tid, XE_SorG, 0, NULL, &xe );
176}
177
178void h_record_heap_error( Addr a, SizeT size, Seg* vseg, Bool is_write )
179{
180 XError xe;
181 tl_assert(size > 0);
182 VG_(memset)(&xe, 0, sizeof(xe));
183 xe.tag = XE_Heap;
184 xe.XE.Heap.addr = a;
185 xe.XE.Heap.sszB = is_write ? -size : size;
186 xe.XE.Heap.vseg = vseg;
187 VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Heap,
188 /*a*/0, /*str*/NULL, /*extra*/(void*)&xe);
189}
190
191void h_record_arith_error( Seg* seg1, Seg* seg2, HChar* opname )
192{
193 XError xe;
194 VG_(memset)(&xe, 0, sizeof(xe));
195 xe.tag = XE_Arith;
196 xe.XE.Arith.seg1 = seg1;
197 xe.XE.Arith.seg2 = seg2;
198 xe.XE.Arith.opname = opname;
199 VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Arith,
200 /*a*/0, /*str*/NULL, /*extra*/(void*)&xe);
201}
202
florian19f91bb2012-11-10 22:29:54 +0000203void h_record_sysparam_error( ThreadId tid, CorePart part, const HChar* s,
sewardj024598e2008-09-18 14:43:05 +0000204 Addr lo, Addr hi, Seg* seglo, Seg* seghi )
205{
206 XError xe;
207 VG_(memset)(&xe, 0, sizeof(xe));
208 xe.tag = XE_SysParam;
209 xe.XE.SysParam.part = part;
210 xe.XE.SysParam.lo = lo;
211 xe.XE.SysParam.hi = hi;
212 xe.XE.SysParam.seglo = seglo;
213 xe.XE.SysParam.seghi = seghi;
214 VG_(maybe_record_error)( tid, XE_SysParam, /*a*/(Addr)0, /*str*/s,
215 /*extra*/(void*)&xe);
216}
217
218
florian8e3fbb52014-10-20 19:02:38 +0000219Bool pc_eq_Error ( VgRes res, const Error* e1, const Error* e2 )
sewardj024598e2008-09-18 14:43:05 +0000220{
221 XError *xe1, *xe2;
222 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
223 //tl_assert(VG_(get_error_string)(e1) == NULL);
224 //tl_assert(VG_(get_error_string)(e2) == NULL);
225
226 xe1 = (XError*)VG_(get_error_extra)(e1);
227 xe2 = (XError*)VG_(get_error_extra)(e2);
228 tl_assert(xe1);
229 tl_assert(xe2);
230
231 if (xe1->tag != xe2->tag)
232 return False;
233
234 switch (xe1->tag) {
235 case XE_SorG:
236 return //xe1->XE.SorG.addr == xe2->XE.SorG.addr
237 //&&
238 xe1->XE.SorG.sszB == xe2->XE.SorG.sszB
239 && 0 == VG_(strncmp)( &xe1->XE.SorG.expect[0],
240 &xe2->XE.SorG.expect[0],
241 sizeof(xe1->XE.SorG.expect) )
242 && 0 == VG_(strncmp)( &xe1->XE.SorG.actual[0],
243 &xe2->XE.SorG.actual[0],
244 sizeof(xe1->XE.SorG.actual) );
245 case XE_Heap:
246 case XE_Arith:
247 case XE_SysParam:
248 return True;
249 default:
250 VG_(tool_panic)("eq_Error: unrecognised error kind");
251 }
252}
253
254
sewardjc1bc9d12009-07-15 14:50:22 +0000255//////////////////////////////////////////////////////////////
256// //
257// Error management -- printing //
258// //
259//////////////////////////////////////////////////////////////
260
261/* This is the "this error is due to be printed shortly; so have a
262 look at it any print any preamble you want" function. Which, in
263 Ptrcheck, we don't use. Hence a no-op.
264*/
florian8e3fbb52014-10-20 19:02:38 +0000265void pc_before_pp_Error ( const Error* err ) {
sewardjc1bc9d12009-07-15 14:50:22 +0000266}
267
268/* Do a printf-style operation on either the XML or normal output
269 channel, depending on the setting of VG_(clo_xml).
270*/
floriandbb35842012-10-27 18:39:11 +0000271static void emit_WRK ( const HChar* format, va_list vargs )
sewardjc1bc9d12009-07-15 14:50:22 +0000272{
273 if (VG_(clo_xml)) {
274 VG_(vprintf_xml)(format, vargs);
275 } else {
276 VG_(vmessage)(Vg_UserMsg, format, vargs);
277 }
278}
floriandbb35842012-10-27 18:39:11 +0000279static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2);
280static void emit ( const HChar* format, ... )
sewardjc1bc9d12009-07-15 14:50:22 +0000281{
282 va_list vargs;
283 va_start(vargs, format);
284 emit_WRK(format, vargs);
285 va_end(vargs);
286}
floriandbb35842012-10-27 18:39:11 +0000287static void emiN ( const HChar* format, ... ) /* With NO FORMAT CHECK */
sewardjc1bc9d12009-07-15 14:50:22 +0000288{
289 va_list vargs;
290 va_start(vargs, format);
291 emit_WRK(format, vargs);
292 va_end(vargs);
293}
294
295
floriandbb35842012-10-27 18:39:11 +0000296static const HChar* readwrite(SSizeT sszB)
sewardj024598e2008-09-18 14:43:05 +0000297{
298 return ( sszB < 0 ? "write" : "read" );
299}
300
301static Word Word__abs ( Word w ) {
302 return w < 0 ? -w : w;
303}
304
florian8e3fbb52014-10-20 19:02:38 +0000305void pc_pp_Error ( const Error* err )
sewardj024598e2008-09-18 14:43:05 +0000306{
sewardjc1bc9d12009-07-15 14:50:22 +0000307 const Bool xml = VG_(clo_xml); /* a shorthand, that's all */
308
sewardj024598e2008-09-18 14:43:05 +0000309 XError *xe = (XError*)VG_(get_error_extra)(err);
310 tl_assert(xe);
311
bart2fa18d92011-10-04 16:28:42 +0000312 if (xml)
313 emit( " <kind>%s</kind>\n", pc_get_error_name(err));
314
sewardj024598e2008-09-18 14:43:05 +0000315 switch (VG_(get_error_kind)(err)) {
316
317 //----------------------------------------------------------
318 case XE_SorG:
sewardjc1bc9d12009-07-15 14:50:22 +0000319
320 if (xml) {
321
sewardjc1bc9d12009-07-15 14:50:22 +0000322 emit( " <what>Invalid %s of size %ld</what>\n",
323 xe->XE.SorG.sszB < 0 ? "write" : "read",
324 Word__abs(xe->XE.SorG.sszB) );
325 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
326
327 emit( " <auxwhat>Address %#lx expected vs actual:</auxwhat>\n",
328 xe->XE.SorG.addr );
bartb3af9cf2011-10-06 19:08:37 +0000329 emiN( " <auxwhat>Expected: %pS</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000330 &xe->XE.SorG.expect[0] );
bartb3af9cf2011-10-06 19:08:37 +0000331 emiN( " <auxwhat>Actual: %pS</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000332 &xe->XE.SorG.actual[0] );
333
334 } else {
335
336 emit( "Invalid %s of size %ld\n",
337 xe->XE.SorG.sszB < 0 ? "write" : "read",
338 Word__abs(xe->XE.SorG.sszB) );
339 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
340
341 emit( " Address %#lx expected vs actual:\n", xe->XE.SorG.addr );
342 emit( " Expected: %s\n", &xe->XE.SorG.expect[0] );
343 emit( " Actual: %s\n", &xe->XE.SorG.actual[0] );
sewardjf5b019f2011-05-11 12:01:37 +0000344 if (xe->XE.SorG.delta[0] != 0)
345 emit(" Actual: is %s Expected\n", &xe->XE.SorG.delta[0]);
sewardjc1bc9d12009-07-15 14:50:22 +0000346 }
sewardj024598e2008-09-18 14:43:05 +0000347 break;
348
349 //----------------------------------------------------------
350 case XE_Heap: {
floriandbb35842012-10-27 18:39:11 +0000351 const HChar *place, *legit, *how_invalid;
sewardj024598e2008-09-18 14:43:05 +0000352 Addr a = xe->XE.Heap.addr;
353 Seg* vseg = xe->XE.Heap.vseg;
354
355 tl_assert(is_known_segment(vseg) || NONPTR == vseg);
356
357 if (NONPTR == vseg) {
358 // Access via a non-pointer
sewardjc1bc9d12009-07-15 14:50:22 +0000359
360 if (xml) {
361
sewardjc1bc9d12009-07-15 14:50:22 +0000362 emit( " <what>Invalid %s of size %ld</what>\n",
363 readwrite(xe->XE.Heap.sszB),
364 Word__abs(xe->XE.Heap.sszB) );
365 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
366
367 emit( " <auxwhat>Address %#lx is not derived from "
368 "any known block</auxwhat>\n", a );
369
370 } else {
371
372 emit( "Invalid %s of size %ld\n",
373 readwrite(xe->XE.Heap.sszB),
374 Word__abs(xe->XE.Heap.sszB) );
375 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
376
377 emit( " Address %#lx is not derived from "
378 "any known block\n", a );
379
380 }
sewardj024598e2008-09-18 14:43:05 +0000381
382 } else {
383 // Access via a pointer, but outside its range.
384 Int cmp;
385 UWord miss_size;
386 Seg__cmp(vseg, a, &cmp, &miss_size);
387 if (cmp < 0) place = "before";
388 else if (cmp == 0) place = "inside";
389 else place = "after";
390 how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp )
391 ? "Doubly-invalid" : "Invalid" );
392 legit = ( Seg__is_freed(vseg) ? "once-" : "" );
393
sewardjc1bc9d12009-07-15 14:50:22 +0000394 if (xml) {
sewardj024598e2008-09-18 14:43:05 +0000395
sewardjc1bc9d12009-07-15 14:50:22 +0000396 emit( " <what>%s %s of size %ld</what>\n",
397 how_invalid,
398 readwrite(xe->XE.Heap.sszB),
399 Word__abs(xe->XE.Heap.sszB) );
400 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
401
402 emit( " <auxwhat>Address %#lx is %lu bytes %s "
403 "the accessing pointer's</auxwhat>\n",
404 a, miss_size, place );
405 emit( " <auxwhat>%slegitimate range, "
406 "a block of size %lu %s</auxwhat>\n",
407 legit, Seg__size(vseg),
408 Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
409 VG_(pp_ExeContext)(Seg__where(vseg));
410
411 } else {
412
413 emit( "%s %s of size %ld\n",
414 how_invalid,
415 readwrite(xe->XE.Heap.sszB),
416 Word__abs(xe->XE.Heap.sszB) );
417 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
418
419 emit( " Address %#lx is %lu bytes %s the accessing pointer's\n",
420 a, miss_size, place );
421 emit( " %slegitimate range, a block of size %lu %s\n",
422 legit, Seg__size(vseg),
423 Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
424 VG_(pp_ExeContext)(Seg__where(vseg));
425
426 }
sewardj024598e2008-09-18 14:43:05 +0000427 }
sewardjc1bc9d12009-07-15 14:50:22 +0000428
429 /* If we have a better description of the address, show it.
430 Note that in XML mode, it will already by nicely wrapped up
431 in tags, either <auxwhat> or <xauxwhat>, so we can just emit
432 it verbatim. */
433 if (xml) {
434
435 if (xe->XE.Heap.descr1)
bartb3af9cf2011-10-06 19:08:37 +0000436 emiN( " %pS\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000437 (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
438 if (xe->XE.Heap.descr2)
bartb3af9cf2011-10-06 19:08:37 +0000439 emiN( " %pS\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000440 (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) );
441 if (xe->XE.Heap.datasym[0] != 0)
442 emiN( " <auxwhat>Address 0x%llx is %llu bytes "
bartb3af9cf2011-10-06 19:08:37 +0000443 "inside data symbol \"%pS\"</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000444 (ULong)xe->XE.Heap.addr,
445 (ULong)xe->XE.Heap.datasymoff,
446 xe->XE.Heap.datasym );
447
448 } else {
449
450 if (xe->XE.Heap.descr1)
451 emit( " %s\n",
452 (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
453 if (xe->XE.Heap.descr2)
454 emit( " %s\n",
455 (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) );
456 if (xe->XE.Heap.datasym[0] != 0)
457 emit( " Address 0x%llx is %llu bytes "
458 "inside data symbol \"%s\"\n",
459 (ULong)xe->XE.Heap.addr,
460 (ULong)xe->XE.Heap.datasymoff,
461 xe->XE.Heap.datasym );
462
463 }
sewardj024598e2008-09-18 14:43:05 +0000464 break;
465 }
466
467 //----------------------------------------------------------
468 case XE_Arith: {
469 Seg* seg1 = xe->XE.Arith.seg1;
470 Seg* seg2 = xe->XE.Arith.seg2;
floriandbb35842012-10-27 18:39:11 +0000471 const HChar* which;
sewardj024598e2008-09-18 14:43:05 +0000472
473 tl_assert(BOTTOM != seg1);
474 tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);
475
sewardjc1bc9d12009-07-15 14:50:22 +0000476 if (xml) {
sewardj024598e2008-09-18 14:43:05 +0000477
sewardjc1bc9d12009-07-15 14:50:22 +0000478 emit( " <what>Invalid arguments to %s</what>\n",
479 xe->XE.Arith.opname );
480 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
481
482 if (seg1 != seg2) {
483 if (NONPTR == seg1) {
484 emit( " <auxwhat>First arg not a pointer</auxwhat>\n" );
485 } else if (UNKNOWN == seg1) {
486 emit( " <auxwhat>First arg may be a pointer</auxwhat>\n" );
487 } else {
488 emit( " <auxwhat>First arg derived from address %#lx of "
489 "%lu-byte block alloc'd</auxwhat>\n",
490 Seg__addr(seg1), Seg__size(seg1) );
491 VG_(pp_ExeContext)(Seg__where(seg1));
492 }
493 which = "Second arg";
sewardj024598e2008-09-18 14:43:05 +0000494 } else {
sewardjc1bc9d12009-07-15 14:50:22 +0000495 which = "Both args";
sewardj024598e2008-09-18 14:43:05 +0000496 }
sewardjc1bc9d12009-07-15 14:50:22 +0000497 if (NONPTR == seg2) {
498 emit( " <auxwhat>%s not a pointer</auxwhat>\n", which );
499 } else {
500 emit( " <auxwhat>%s derived from address %#lx of "
501 "%lu-byte block alloc'd</auxwhat>\n",
502 which, Seg__addr(seg2), Seg__size(seg2) );
503 VG_(pp_ExeContext)(Seg__where(seg2));
504 }
505
sewardj024598e2008-09-18 14:43:05 +0000506 } else {
sewardjc1bc9d12009-07-15 14:50:22 +0000507
508 emit( "Invalid arguments to %s\n",
509 xe->XE.Arith.opname );
510 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
511
512 if (seg1 != seg2) {
513 if (NONPTR == seg1) {
514 emit( " First arg not a pointer\n" );
515 } else if (UNKNOWN == seg1) {
516 emit( " First arg may be a pointer\n" );
517 } else {
518 emit( " First arg derived from address %#lx of "
519 "%lu-byte block alloc'd\n",
520 Seg__addr(seg1), Seg__size(seg1) );
521 VG_(pp_ExeContext)(Seg__where(seg1));
522 }
523 which = "Second arg";
524 } else {
525 which = "Both args";
526 }
527 if (NONPTR == seg2) {
528 emit( " %s not a pointer\n", which );
529 } else {
530 emit( " %s derived from address %#lx of "
531 "%lu-byte block alloc'd\n",
532 which, Seg__addr(seg2), Seg__size(seg2) );
533 VG_(pp_ExeContext)(Seg__where(seg2));
534 }
535
sewardj024598e2008-09-18 14:43:05 +0000536 }
sewardjc1bc9d12009-07-15 14:50:22 +0000537
sewardj024598e2008-09-18 14:43:05 +0000538 break;
539 }
540
541 //----------------------------------------------------------
542 case XE_SysParam: {
543 Addr lo = xe->XE.SysParam.lo;
544 Addr hi = xe->XE.SysParam.hi;
545 Seg* seglo = xe->XE.SysParam.seglo;
546 Seg* seghi = xe->XE.SysParam.seghi;
floriane543f302012-10-21 19:43:43 +0000547 const HChar* s = VG_(get_error_string) (err);
floriandbb35842012-10-27 18:39:11 +0000548 const HChar* what;
sewardj024598e2008-09-18 14:43:05 +0000549
550 tl_assert(BOTTOM != seglo && BOTTOM != seghi);
551
552 if (Vg_CoreSysCall == xe->XE.SysParam.part)
553 what = "Syscall param ";
554 else VG_(tool_panic)("bad CorePart");
555
556 if (seglo == seghi) {
557 // freed block
558 tl_assert(is_known_segment(seglo));
559 tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled?
sewardj024598e2008-09-18 14:43:05 +0000560
sewardjc1bc9d12009-07-15 14:50:22 +0000561 if (xml) {
562
sewardjc1bc9d12009-07-15 14:50:22 +0000563 emit( " <what>%s%s contains unaddressable byte(s)</what>\n",
564 what, s );
565 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
566
florian16eef852015-08-03 21:05:20 +0000567 emit( " <auxwhat>Address %#lx is %lu bytes inside a "
568 "%lu-byte block free'd</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000569 lo, lo-Seg__addr(seglo), Seg__size(seglo) );
570 VG_(pp_ExeContext)(Seg__where(seglo));
571
572 } else {
573
574 emit( " %s%s contains unaddressable byte(s)\n",
575 what, s );
576 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
577
florian16eef852015-08-03 21:05:20 +0000578 emit( " Address %#lx is %lu bytes inside a "
579 "%lu-byte block free'd\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000580 lo, lo-Seg__addr(seglo), Seg__size(seglo) );
581 VG_(pp_ExeContext)(Seg__where(seglo));
582
583 }
sewardj024598e2008-09-18 14:43:05 +0000584
585 } else {
586 // mismatch
sewardj024598e2008-09-18 14:43:05 +0000587
sewardjc1bc9d12009-07-15 14:50:22 +0000588 if (xml) {
589
sewardjc1bc9d12009-07-15 14:50:22 +0000590 emit( " <what>%s%s is non-contiguous</what>\n",
591 what, s );
592 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
593
594 if (UNKNOWN == seglo) {
595 emit( " <auxwhat>First byte is "
596 "not inside a known block</auxwhat>\n" );
597 } else {
florian16eef852015-08-03 21:05:20 +0000598 emit( " <auxwhat>First byte (%#lx) is %lu bytes inside a "
599 "%lu-byte block alloc'd</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000600 lo, lo-Seg__addr(seglo), Seg__size(seglo) );
601 VG_(pp_ExeContext)(Seg__where(seglo));
602 }
603
604 if (UNKNOWN == seghi) {
605 emit( " <auxwhat>Last byte is "
606 "not inside a known block</auxwhat>\n" );
607 } else {
florian16eef852015-08-03 21:05:20 +0000608 emit( " <auxwhat>Last byte (%#lx) is %lu bytes inside a "
609 "%lu-byte block alloc'd</auxwhat>\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000610 hi, hi-Seg__addr(seghi), Seg__size(seghi) );
611 VG_(pp_ExeContext)(Seg__where(seghi));
612 }
613
sewardj024598e2008-09-18 14:43:05 +0000614 } else {
sewardjc1bc9d12009-07-15 14:50:22 +0000615
616 emit( "%s%s is non-contiguous\n",
617 what, s );
618 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
619
620 if (UNKNOWN == seglo) {
621 emit( " First byte is not inside a known block\n" );
622 } else {
florian16eef852015-08-03 21:05:20 +0000623 emit( " First byte (%#lx) is %lu bytes inside a "
624 "%lu-byte block alloc'd\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000625 lo, lo-Seg__addr(seglo), Seg__size(seglo) );
626 VG_(pp_ExeContext)(Seg__where(seglo));
627 }
628
629 if (UNKNOWN == seghi) {
630 emit( " Last byte is not inside a known block\n" );
631 } else {
florian16eef852015-08-03 21:05:20 +0000632 emit( " Last byte (%#lx) is %lu bytes inside a "
633 "%lu-byte block alloc'd\n",
sewardjc1bc9d12009-07-15 14:50:22 +0000634 hi, hi-Seg__addr(seghi), Seg__size(seghi) );
635 VG_(pp_ExeContext)(Seg__where(seghi));
636 }
637
sewardj024598e2008-09-18 14:43:05 +0000638 }
639
sewardj024598e2008-09-18 14:43:05 +0000640 }
641 break;
642 }
643
644 default:
645 VG_(tool_panic)("pp_Error: unrecognised error kind");
646 }
647}
648
649
florian8e3fbb52014-10-20 19:02:38 +0000650UInt pc_update_Error_extra ( const Error* err )
sewardj024598e2008-09-18 14:43:05 +0000651{
652 XError *xe = (XError*)VG_(get_error_extra)(err);
653 tl_assert(xe);
654 switch (xe->tag) {
655 case XE_SorG:
sewardjc1bc9d12009-07-15 14:50:22 +0000656 break;
sewardj024598e2008-09-18 14:43:05 +0000657 case XE_Heap: {
sewardjc1bc9d12009-07-15 14:50:22 +0000658 Bool have_descr;
659
sewardjc1bc9d12009-07-15 14:50:22 +0000660 xe->XE.Heap.datasymoff = 0;
florian46cc0452014-10-25 19:20:38 +0000661 xe->XE.Heap.datasym = NULL;
sewardjc1bc9d12009-07-15 14:50:22 +0000662
663 tl_assert(!xe->XE.Heap.descr1);
664 tl_assert(!xe->XE.Heap.descr2);
665
666 xe->XE.Heap.descr1
667 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1",
668 VG_(free), sizeof(HChar) );
669 xe->XE.Heap.descr2
670 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1",
671 VG_(free), sizeof(HChar) );
672
sewardj024598e2008-09-18 14:43:05 +0000673 xe->XE.Heap.datasymoff = 0;
sewardjc1bc9d12009-07-15 14:50:22 +0000674
675 have_descr
676 = VG_(get_data_description)( xe->XE.Heap.descr1,
677 xe->XE.Heap.descr2,
678 xe->XE.Heap.addr );
679
680 /* If there's nothing in descr1/2, free it. Why is it safe to
681 to VG_(indexXA) at zero here? Because
682 VG_(get_data_description) guarantees to zero terminate
683 descr1/2 regardless of the outcome of the call. So there's
684 always at least one element in each XA after the call.
685 */
686 if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr1, 0 ))
687 || !have_descr) {
688 VG_(deleteXA)( xe->XE.Heap.descr1 );
689 xe->XE.Heap.descr1 = NULL;
sewardj024598e2008-09-18 14:43:05 +0000690 }
sewardjc1bc9d12009-07-15 14:50:22 +0000691 if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr2, 0 ))
692 || !have_descr) {
693 VG_(deleteXA)( xe->XE.Heap.descr2 );
694 xe->XE.Heap.descr2 = NULL;
sewardj024598e2008-09-18 14:43:05 +0000695 }
sewardjc1bc9d12009-07-15 14:50:22 +0000696
697 /* If Dwarf3 info produced nothing useful, see at least if
698 we can fish something useful out of the ELF symbol info. */
699 if (!have_descr) {
florian46cc0452014-10-25 19:20:38 +0000700 const HChar *name;
sewardjc1bc9d12009-07-15 14:50:22 +0000701 if (VG_(get_datasym_and_offset)(
florian46cc0452014-10-25 19:20:38 +0000702 xe->XE.Heap.addr, &name,
sewardjc1bc9d12009-07-15 14:50:22 +0000703 &xe->XE.Heap.datasymoff )
704 ) {
florian46cc0452014-10-25 19:20:38 +0000705 xe->XE.Heap.datasym =
706 VG_(strdup)("pc.update_extra.Heap.datasym", name);
sewardjc1bc9d12009-07-15 14:50:22 +0000707 }
708 }
709 break;
sewardj024598e2008-09-18 14:43:05 +0000710 }
711 case XE_Arith:
sewardjc1bc9d12009-07-15 14:50:22 +0000712 break;
sewardj024598e2008-09-18 14:43:05 +0000713 case XE_SysParam:
sewardjc1bc9d12009-07-15 14:50:22 +0000714 break;
sewardj024598e2008-09-18 14:43:05 +0000715 default:
716 VG_(tool_panic)("update_extra");
717 }
sewardjc1bc9d12009-07-15 14:50:22 +0000718 return sizeof(XError);
sewardj024598e2008-09-18 14:43:05 +0000719}
720
florian19f91bb2012-11-10 22:29:54 +0000721Bool pc_is_recognised_suppression ( const HChar* name, Supp *su )
sewardj024598e2008-09-18 14:43:05 +0000722{
723 SuppKind skind;
724
725 if (VG_STREQ(name, "SorG")) skind = XS_SorG;
726 else if (VG_STREQ(name, "Heap")) skind = XS_Heap;
727 else if (VG_STREQ(name, "Arith")) skind = XS_Arith;
728 else if (VG_STREQ(name, "SysParam")) skind = XS_SysParam;
729 else
730 return False;
731
732 VG_(set_supp_kind)(su, skind);
733 return True;
734}
735
florian19f91bb2012-11-10 22:29:54 +0000736Bool pc_read_extra_suppression_info ( Int fd, HChar** bufpp,
florian8e3fbb52014-10-20 19:02:38 +0000737 SizeT* nBufp, Int* lineno,
738 Supp* su )
sewardj024598e2008-09-18 14:43:05 +0000739{
740 Bool eof;
741 if (VG_(get_supp_kind)(su) == XS_SysParam) {
philippe362441d2013-07-22 22:00:13 +0000742 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
sewardj024598e2008-09-18 14:43:05 +0000743 if (eof) return False;
njn35db56c2009-07-24 07:38:29 +0000744 VG_(set_supp_string)(su, VG_(strdup)("pc.common.presi.1", *bufpp));
sewardj024598e2008-09-18 14:43:05 +0000745 }
746 return True;
747}
748
florian8e3fbb52014-10-20 19:02:38 +0000749Bool pc_error_matches_suppression (const Error* err, const Supp* su)
sewardj024598e2008-09-18 14:43:05 +0000750{
751 ErrorKind ekind = VG_(get_error_kind)(err);
752 switch (VG_(get_supp_kind)(su)) {
753 case XS_SorG: return ekind == XE_SorG;
754 case XS_Heap: return ekind == XE_Heap;
755 case XS_Arith: return ekind == XE_Arith;
756 case XS_SysParam: return ekind == XE_SysParam;
757 default:
758 VG_(printf)("Error:\n"
759 " unknown suppression type %d\n",
760 VG_(get_supp_kind)(su));
761 VG_(tool_panic)("unknown suppression type in "
762 "pc_error_matches_suppression");
763 }
764}
765
florian8e3fbb52014-10-20 19:02:38 +0000766const HChar* pc_get_error_name ( const Error* err )
sewardj024598e2008-09-18 14:43:05 +0000767{
768 XError *xe = (XError*)VG_(get_error_extra)(err);
769 tl_assert(xe);
770 switch (xe->tag) {
771 case XE_SorG: return "SorG";
772 case XE_Heap: return "Heap";
773 case XE_Arith: return "Arith";
774 case XE_SysParam: return "SysParam";
775 default: VG_(tool_panic)("get_error_name: unexpected type");
776 }
777}
778
florian8e3fbb52014-10-20 19:02:38 +0000779SizeT pc_get_extra_suppression_info ( const Error* err,
florian3e81b8b2014-10-07 14:28:52 +0000780 /*OUT*/HChar* buf, Int nBuf )
sewardj024598e2008-09-18 14:43:05 +0000781{
Elliott Hughesa0664b92017-04-18 17:46:52 -0700782 ErrorKind ekind = VG_(get_error_kind)(err);
sewardj588adef2009-08-15 22:41:51 +0000783 tl_assert(buf);
florian3e81b8b2014-10-07 14:28:52 +0000784 tl_assert(nBuf >= 1);
785
sewardj588adef2009-08-15 22:41:51 +0000786 if (XE_SysParam == ekind) {
floriane543f302012-10-21 19:43:43 +0000787 const HChar* errstr = VG_(get_error_string)(err);
sewardj588adef2009-08-15 22:41:51 +0000788 tl_assert(errstr);
florian3e81b8b2014-10-07 14:28:52 +0000789 return VG_(snprintf)(buf, nBuf, "%s", errstr);
sewardj588adef2009-08-15 22:41:51 +0000790 } else {
florian3e81b8b2014-10-07 14:28:52 +0000791 buf[0] = '\0';
792 return 0;
sewardj024598e2008-09-18 14:43:05 +0000793 }
794}
795
florian8e3fbb52014-10-20 19:02:38 +0000796SizeT pc_print_extra_suppression_use ( const Supp* su,
florian3e81b8b2014-10-07 14:28:52 +0000797 /*OUT*/HChar* buf, Int nBuf )
philippe4e32d672013-10-17 22:10:41 +0000798{
florian3e81b8b2014-10-07 14:28:52 +0000799 tl_assert(nBuf >= 1);
800 buf[0] = '\0';
801 return 0;
philippe4e32d672013-10-17 22:10:41 +0000802}
803
florian8e3fbb52014-10-20 19:02:38 +0000804void pc_update_extra_suppression_use (const Error* err, const Supp* su)
philippe4e32d672013-10-17 22:10:41 +0000805{
806 return;
807}
sewardj024598e2008-09-18 14:43:05 +0000808
sewardj024598e2008-09-18 14:43:05 +0000809/*--------------------------------------------------------------------*/
810/*--- end pc_common.c ---*/
811/*--------------------------------------------------------------------*/