1 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 12 Copyright (C) 2008-2013 OpenWorks Ltd 13 info (at) 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" 41 #include "pub_tool_xarray.h" 42 #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 62 Bool h_clo_partial_loads_ok = True; /* user visible */ 63 /* Bool h_clo_lossage_check = False; */ /* dev flag only */ 64 Bool sg_clo_enable_sg_checks = True; /* user visible */ 65 66 Bool pc_process_cmd_line_options(const HChar* arg) 67 { 68 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) {} 71 else 72 return VG_(replacement_malloc_process_cmd_line_option)(arg); 73 74 return True; 75 } 76 77 void pc_print_usage(void) 78 { 79 VG_(printf)( 80 " --partial-loads-ok=no|yes same as for Memcheck [yes]\n" 81 " --enable-sg-checks=no|yes enable stack & global array checking? [yes]\n" 82 ); 83 } 84 85 void pc_print_debug_usage(void) 86 { 87 VG_(printf)( 88 " (none)\n" 89 //" --lossage-check=no|yes gather stats for quality control [no]\n" 90 ); 91 } 92 93 94 95 ////////////////////////////////////////////////////////////// 96 // // 97 // Error management -- storage // 98 // // 99 ////////////////////////////////////////////////////////////// 100 101 /* What kind of error it is. */ 102 typedef 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 111 typedef 112 enum { 113 XS_SorG=2021, 114 XS_Heap, 115 XS_Arith, 116 XS_SysParam 117 } 118 XSuppTag; 119 120 typedef 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]; 129 HChar delta[32]; // text showing relation to expected 130 } SorG; 131 struct { 132 Addr addr; 133 SSizeT sszB; /* -ve is write, +ve is read */ 134 Seg* vseg; 135 XArray* descr1; /* XArray* of HChar */ 136 XArray* descr2; /* XArray* of HChar */ 137 HChar datasym[96]; 138 PtrdiffT datasymoff; 139 } 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 157 void sg_record_error_SorG ( ThreadId tid, 158 Addr addr, SSizeT sszB, 159 HChar* expect, HChar* actual, HChar* delta ) 160 { 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) ); 170 VG_(strncpy)( &xe.XE.SorG.delta[0], 171 delta, sizeof(xe.XE.SorG.delta) ); 172 xe.XE.SorG.expect[ sizeof(xe.XE.SorG.expect)-1 ] = 0; 173 xe.XE.SorG.actual[ sizeof(xe.XE.SorG.actual)-1 ] = 0; 174 xe.XE.SorG.delta[ sizeof(xe.XE.SorG.delta)-1 ] = 0; 175 VG_(maybe_record_error)( tid, XE_SorG, 0, NULL, &xe ); 176 } 177 178 void 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 191 void 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 203 void h_record_sysparam_error( ThreadId tid, CorePart part, const HChar* s, 204 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 219 Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 ) 220 { 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 255 ////////////////////////////////////////////////////////////// 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 */ 265 void pc_before_pp_Error ( Error* err ) { 266 } 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 */ 271 static void emit_WRK ( const HChar* format, va_list vargs ) 272 { 273 if (VG_(clo_xml)) { 274 VG_(vprintf_xml)(format, vargs); 275 } else { 276 VG_(vmessage)(Vg_UserMsg, format, vargs); 277 } 278 } 279 static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2); 280 static void emit ( const HChar* format, ... ) 281 { 282 va_list vargs; 283 va_start(vargs, format); 284 emit_WRK(format, vargs); 285 va_end(vargs); 286 } 287 static void emiN ( const HChar* format, ... ) /* With NO FORMAT CHECK */ 288 { 289 va_list vargs; 290 va_start(vargs, format); 291 emit_WRK(format, vargs); 292 va_end(vargs); 293 } 294 295 296 static const HChar* readwrite(SSizeT sszB) 297 { 298 return ( sszB < 0 ? "write" : "read" ); 299 } 300 301 static Word Word__abs ( Word w ) { 302 return w < 0 ? -w : w; 303 } 304 305 void pc_pp_Error ( Error* err ) 306 { 307 const Bool xml = VG_(clo_xml); /* a shorthand, that's all */ 308 309 XError *xe = (XError*)VG_(get_error_extra)(err); 310 tl_assert(xe); 311 312 if (xml) 313 emit( " <kind>%s</kind>\n", pc_get_error_name(err)); 314 315 switch (VG_(get_error_kind)(err)) { 316 317 //---------------------------------------------------------- 318 case XE_SorG: 319 320 if (xml) { 321 322 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 ); 329 emiN( " <auxwhat>Expected: %pS</auxwhat>\n", 330 &xe->XE.SorG.expect[0] ); 331 emiN( " <auxwhat>Actual: %pS</auxwhat>\n", 332 &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] ); 344 if (xe->XE.SorG.delta[0] != 0) 345 emit(" Actual: is %s Expected\n", &xe->XE.SorG.delta[0]); 346 } 347 break; 348 349 //---------------------------------------------------------- 350 case XE_Heap: { 351 const HChar *place, *legit, *how_invalid; 352 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 359 360 if (xml) { 361 362 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 } 381 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 394 if (xml) { 395 396 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 } 427 } 428 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) 436 emiN( " %pS\n", 437 (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) ); 438 if (xe->XE.Heap.descr2) 439 emiN( " %pS\n", 440 (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 " 443 "inside data symbol \"%pS\"</auxwhat>\n", 444 (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 } 464 break; 465 } 466 467 //---------------------------------------------------------- 468 case XE_Arith: { 469 Seg* seg1 = xe->XE.Arith.seg1; 470 Seg* seg2 = xe->XE.Arith.seg2; 471 const HChar* which; 472 473 tl_assert(BOTTOM != seg1); 474 tl_assert(BOTTOM != seg2 && UNKNOWN != seg2); 475 476 if (xml) { 477 478 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"; 494 } else { 495 which = "Both args"; 496 } 497 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 506 } else { 507 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 536 } 537 538 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; 547 const HChar* s = VG_(get_error_string) (err); 548 const HChar* what; 549 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? 560 561 if (xml) { 562 563 emit( " <what>%s%s contains unaddressable byte(s)</what>\n", 564 what, s ); 565 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 566 567 emit( " <auxwhat>Address %#lx is %ld bytes inside a " 568 "%ld-byte block free'd</auxwhat>\n", 569 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 578 emit( " Address %#lx is %ld bytes inside a " 579 "%ld-byte block free'd\n", 580 lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 581 VG_(pp_ExeContext)(Seg__where(seglo)); 582 583 } 584 585 } else { 586 // mismatch 587 588 if (xml) { 589 590 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 { 598 emit( " <auxwhat>First byte (%#lx) is %ld bytes inside a " 599 "%ld-byte block alloc'd</auxwhat>\n", 600 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 { 608 emit( " <auxwhat>Last byte (%#lx) is %ld bytes inside a " 609 "%ld-byte block alloc'd</auxwhat>\n", 610 hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 611 VG_(pp_ExeContext)(Seg__where(seghi)); 612 } 613 614 } else { 615 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 { 623 emit( " First byte (%#lx) is %ld bytes inside a " 624 "%ld-byte block alloc'd\n", 625 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 { 632 emit( " Last byte (%#lx) is %ld bytes inside a " 633 "%ld-byte block alloc'd\n", 634 hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 635 VG_(pp_ExeContext)(Seg__where(seghi)); 636 } 637 638 } 639 640 } 641 break; 642 } 643 644 default: 645 VG_(tool_panic)("pp_Error: unrecognised error kind"); 646 } 647 } 648 649 650 UInt pc_update_Error_extra ( Error* err ) 651 { 652 XError *xe = (XError*)VG_(get_error_extra)(err); 653 tl_assert(xe); 654 switch (xe->tag) { 655 case XE_SorG: 656 break; 657 case XE_Heap: { 658 Bool have_descr; 659 660 tl_assert(sizeof(xe->XE.Heap.datasym) > 0); 661 xe->XE.Heap.datasymoff = 0; 662 xe->XE.Heap.datasym[0] = 0; 663 664 tl_assert(!xe->XE.Heap.descr1); 665 tl_assert(!xe->XE.Heap.descr2); 666 667 xe->XE.Heap.descr1 668 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 669 VG_(free), sizeof(HChar) ); 670 xe->XE.Heap.descr2 671 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 672 VG_(free), sizeof(HChar) ); 673 674 VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym)); 675 xe->XE.Heap.datasymoff = 0; 676 677 have_descr 678 = VG_(get_data_description)( xe->XE.Heap.descr1, 679 xe->XE.Heap.descr2, 680 xe->XE.Heap.addr ); 681 682 /* If there's nothing in descr1/2, free it. Why is it safe to 683 to VG_(indexXA) at zero here? Because 684 VG_(get_data_description) guarantees to zero terminate 685 descr1/2 regardless of the outcome of the call. So there's 686 always at least one element in each XA after the call. 687 */ 688 if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr1, 0 )) 689 || !have_descr) { 690 VG_(deleteXA)( xe->XE.Heap.descr1 ); 691 xe->XE.Heap.descr1 = NULL; 692 } 693 if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr2, 0 )) 694 || !have_descr) { 695 VG_(deleteXA)( xe->XE.Heap.descr2 ); 696 xe->XE.Heap.descr2 = NULL; 697 } 698 699 /* If Dwarf3 info produced nothing useful, see at least if 700 we can fish something useful out of the ELF symbol info. */ 701 if (!have_descr) { 702 if (VG_(get_datasym_and_offset)( 703 xe->XE.Heap.addr, &xe->XE.Heap.datasym[0], 704 sizeof(xe->XE.Heap.datasym)-1, 705 &xe->XE.Heap.datasymoff ) 706 ) { 707 tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] 708 == 0); 709 } 710 } 711 break; 712 } 713 case XE_Arith: 714 break; 715 case XE_SysParam: 716 break; 717 default: 718 VG_(tool_panic)("update_extra"); 719 } 720 return sizeof(XError); 721 } 722 723 Bool pc_is_recognised_suppression ( const HChar* name, Supp *su ) 724 { 725 SuppKind skind; 726 727 if (VG_STREQ(name, "SorG")) skind = XS_SorG; 728 else if (VG_STREQ(name, "Heap")) skind = XS_Heap; 729 else if (VG_STREQ(name, "Arith")) skind = XS_Arith; 730 else if (VG_STREQ(name, "SysParam")) skind = XS_SysParam; 731 else 732 return False; 733 734 VG_(set_supp_kind)(su, skind); 735 return True; 736 } 737 738 Bool pc_read_extra_suppression_info ( Int fd, HChar** bufpp, 739 SizeT* nBufp, Int* lineno, Supp* su ) 740 { 741 Bool eof; 742 if (VG_(get_supp_kind)(su) == XS_SysParam) { 743 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno ); 744 if (eof) return False; 745 VG_(set_supp_string)(su, VG_(strdup)("pc.common.presi.1", *bufpp)); 746 } 747 return True; 748 } 749 750 Bool pc_error_matches_suppression (Error* err, Supp* su) 751 { 752 ErrorKind ekind = VG_(get_error_kind)(err); 753 switch (VG_(get_supp_kind)(su)) { 754 case XS_SorG: return ekind == XE_SorG; 755 case XS_Heap: return ekind == XE_Heap; 756 case XS_Arith: return ekind == XE_Arith; 757 case XS_SysParam: return ekind == XE_SysParam; 758 default: 759 VG_(printf)("Error:\n" 760 " unknown suppression type %d\n", 761 VG_(get_supp_kind)(su)); 762 VG_(tool_panic)("unknown suppression type in " 763 "pc_error_matches_suppression"); 764 } 765 } 766 767 const HChar* pc_get_error_name ( Error* err ) 768 { 769 XError *xe = (XError*)VG_(get_error_extra)(err); 770 tl_assert(xe); 771 switch (xe->tag) { 772 case XE_SorG: return "SorG"; 773 case XE_Heap: return "Heap"; 774 case XE_Arith: return "Arith"; 775 case XE_SysParam: return "SysParam"; 776 default: VG_(tool_panic)("get_error_name: unexpected type"); 777 } 778 } 779 780 Bool pc_get_extra_suppression_info ( Error* err, 781 /*OUT*/HChar* buf, Int nBuf ) 782 { 783 ErrorKind ekind = VG_(get_error_kind )(err); 784 tl_assert(buf); 785 tl_assert(nBuf >= 16); // stay sane 786 if (XE_SysParam == ekind) { 787 const HChar* errstr = VG_(get_error_string)(err); 788 tl_assert(errstr); 789 VG_(snprintf)(buf, nBuf-1, "%s", errstr); 790 return True; 791 } else { 792 return False; 793 } 794 } 795 796 Bool pc_print_extra_suppression_use ( Supp* su, 797 /*OUT*/HChar* buf, Int nBuf ) 798 { 799 return False; 800 } 801 802 void pc_update_extra_suppression_use (Error* err, Supp* su) 803 { 804 return; 805 } 806 807 /*--------------------------------------------------------------------*/ 808 /*--- end pc_common.c ---*/ 809 /*--------------------------------------------------------------------*/ 810