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-2010 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(Char* 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 } SorG; 130 struct { 131 Addr addr; 132 SSizeT sszB; /* -ve is write, +ve is read */ 133 Seg* vseg; 134 XArray* descr1; /* XArray* of HChar */ 135 XArray* descr2; /* XArray* of HChar */ 136 Char datasym[96]; 137 PtrdiffT datasymoff; 138 } Heap; 139 struct { 140 Seg* seg1; 141 Seg* seg2; 142 const HChar* opname; // user-understandable text name 143 } Arith; 144 struct { 145 CorePart part; 146 Addr lo; 147 Addr hi; 148 Seg* seglo; 149 Seg* seghi; 150 } SysParam; 151 } XE; 152 } 153 XError; 154 155 156 void sg_record_error_SorG ( ThreadId tid, 157 Addr addr, SSizeT sszB, 158 HChar* expect, HChar* actual ) 159 { 160 XError xe; 161 VG_(memset)(&xe, 0, sizeof(xe)); 162 xe.tag = XE_SorG; 163 xe.XE.SorG.addr = addr; 164 xe.XE.SorG.sszB = sszB; 165 VG_(strncpy)( &xe.XE.SorG.expect[0], 166 expect, sizeof(xe.XE.SorG.expect) ); 167 VG_(strncpy)( &xe.XE.SorG.actual[0], 168 actual, sizeof(xe.XE.SorG.actual) ); 169 xe.XE.SorG.expect[ sizeof(xe.XE.SorG.expect)-1 ] = 0; 170 xe.XE.SorG.actual[ sizeof(xe.XE.SorG.actual)-1 ] = 0; 171 VG_(maybe_record_error)( tid, XE_SorG, 0, NULL, &xe ); 172 } 173 174 void h_record_heap_error( Addr a, SizeT size, Seg* vseg, Bool is_write ) 175 { 176 XError xe; 177 tl_assert(size > 0); 178 VG_(memset)(&xe, 0, sizeof(xe)); 179 xe.tag = XE_Heap; 180 xe.XE.Heap.addr = a; 181 xe.XE.Heap.sszB = is_write ? -size : size; 182 xe.XE.Heap.vseg = vseg; 183 VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Heap, 184 /*a*/0, /*str*/NULL, /*extra*/(void*)&xe); 185 } 186 187 void h_record_arith_error( Seg* seg1, Seg* seg2, HChar* opname ) 188 { 189 XError xe; 190 VG_(memset)(&xe, 0, sizeof(xe)); 191 xe.tag = XE_Arith; 192 xe.XE.Arith.seg1 = seg1; 193 xe.XE.Arith.seg2 = seg2; 194 xe.XE.Arith.opname = opname; 195 VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Arith, 196 /*a*/0, /*str*/NULL, /*extra*/(void*)&xe); 197 } 198 199 void h_record_sysparam_error( ThreadId tid, CorePart part, Char* s, 200 Addr lo, Addr hi, Seg* seglo, Seg* seghi ) 201 { 202 XError xe; 203 VG_(memset)(&xe, 0, sizeof(xe)); 204 xe.tag = XE_SysParam; 205 xe.XE.SysParam.part = part; 206 xe.XE.SysParam.lo = lo; 207 xe.XE.SysParam.hi = hi; 208 xe.XE.SysParam.seglo = seglo; 209 xe.XE.SysParam.seghi = seghi; 210 VG_(maybe_record_error)( tid, XE_SysParam, /*a*/(Addr)0, /*str*/s, 211 /*extra*/(void*)&xe); 212 } 213 214 215 Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 ) 216 { 217 XError *xe1, *xe2; 218 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); 219 //tl_assert(VG_(get_error_string)(e1) == NULL); 220 //tl_assert(VG_(get_error_string)(e2) == NULL); 221 222 xe1 = (XError*)VG_(get_error_extra)(e1); 223 xe2 = (XError*)VG_(get_error_extra)(e2); 224 tl_assert(xe1); 225 tl_assert(xe2); 226 227 if (xe1->tag != xe2->tag) 228 return False; 229 230 switch (xe1->tag) { 231 case XE_SorG: 232 return //xe1->XE.SorG.addr == xe2->XE.SorG.addr 233 //&& 234 xe1->XE.SorG.sszB == xe2->XE.SorG.sszB 235 && 0 == VG_(strncmp)( &xe1->XE.SorG.expect[0], 236 &xe2->XE.SorG.expect[0], 237 sizeof(xe1->XE.SorG.expect) ) 238 && 0 == VG_(strncmp)( &xe1->XE.SorG.actual[0], 239 &xe2->XE.SorG.actual[0], 240 sizeof(xe1->XE.SorG.actual) ); 241 case XE_Heap: 242 case XE_Arith: 243 case XE_SysParam: 244 return True; 245 default: 246 VG_(tool_panic)("eq_Error: unrecognised error kind"); 247 } 248 } 249 250 251 ////////////////////////////////////////////////////////////// 252 // // 253 // Error management -- printing // 254 // // 255 ////////////////////////////////////////////////////////////// 256 257 /* This is the "this error is due to be printed shortly; so have a 258 look at it any print any preamble you want" function. Which, in 259 Ptrcheck, we don't use. Hence a no-op. 260 */ 261 void pc_before_pp_Error ( Error* err ) { 262 } 263 264 /* Do a printf-style operation on either the XML or normal output 265 channel, depending on the setting of VG_(clo_xml). 266 */ 267 static void emit_WRK ( HChar* format, va_list vargs ) 268 { 269 if (VG_(clo_xml)) { 270 VG_(vprintf_xml)(format, vargs); 271 } else { 272 VG_(vmessage)(Vg_UserMsg, format, vargs); 273 } 274 } 275 static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2); 276 static void emit ( HChar* format, ... ) 277 { 278 va_list vargs; 279 va_start(vargs, format); 280 emit_WRK(format, vargs); 281 va_end(vargs); 282 } 283 static void emiN ( HChar* format, ... ) /* With NO FORMAT CHECK */ 284 { 285 va_list vargs; 286 va_start(vargs, format); 287 emit_WRK(format, vargs); 288 va_end(vargs); 289 } 290 291 292 static Char* readwrite(SSizeT sszB) 293 { 294 return ( sszB < 0 ? "write" : "read" ); 295 } 296 297 static Word Word__abs ( Word w ) { 298 return w < 0 ? -w : w; 299 } 300 301 void pc_pp_Error ( Error* err ) 302 { 303 const Bool xml = VG_(clo_xml); /* a shorthand, that's all */ 304 305 XError *xe = (XError*)VG_(get_error_extra)(err); 306 tl_assert(xe); 307 308 switch (VG_(get_error_kind)(err)) { 309 310 //---------------------------------------------------------- 311 case XE_SorG: 312 313 if (xml) { 314 315 emit( " <kind>SorG</kind>\n"); 316 emit( " <what>Invalid %s of size %ld</what>\n", 317 xe->XE.SorG.sszB < 0 ? "write" : "read", 318 Word__abs(xe->XE.SorG.sszB) ); 319 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 320 321 emit( " <auxwhat>Address %#lx expected vs actual:</auxwhat>\n", 322 xe->XE.SorG.addr ); 323 emiN( " <auxwhat>Expected: %t</auxwhat>\n", 324 &xe->XE.SorG.expect[0] ); 325 emiN( " <auxwhat>Actual: %t</auxwhat>\n", 326 &xe->XE.SorG.actual[0] ); 327 328 } else { 329 330 emit( "Invalid %s of size %ld\n", 331 xe->XE.SorG.sszB < 0 ? "write" : "read", 332 Word__abs(xe->XE.SorG.sszB) ); 333 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 334 335 emit( " Address %#lx expected vs actual:\n", xe->XE.SorG.addr ); 336 emit( " Expected: %s\n", &xe->XE.SorG.expect[0] ); 337 emit( " Actual: %s\n", &xe->XE.SorG.actual[0] ); 338 339 } 340 break; 341 342 //---------------------------------------------------------- 343 case XE_Heap: { 344 Char *place, *legit, *how_invalid; 345 Addr a = xe->XE.Heap.addr; 346 Seg* vseg = xe->XE.Heap.vseg; 347 348 tl_assert(is_known_segment(vseg) || NONPTR == vseg); 349 350 if (NONPTR == vseg) { 351 // Access via a non-pointer 352 353 if (xml) { 354 355 emit( " <kind>Heap</kind>\n"); 356 emit( " <what>Invalid %s of size %ld</what>\n", 357 readwrite(xe->XE.Heap.sszB), 358 Word__abs(xe->XE.Heap.sszB) ); 359 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 360 361 emit( " <auxwhat>Address %#lx is not derived from " 362 "any known block</auxwhat>\n", a ); 363 364 } else { 365 366 emit( "Invalid %s of size %ld\n", 367 readwrite(xe->XE.Heap.sszB), 368 Word__abs(xe->XE.Heap.sszB) ); 369 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 370 371 emit( " Address %#lx is not derived from " 372 "any known block\n", a ); 373 374 } 375 376 } else { 377 // Access via a pointer, but outside its range. 378 Int cmp; 379 UWord miss_size; 380 Seg__cmp(vseg, a, &cmp, &miss_size); 381 if (cmp < 0) place = "before"; 382 else if (cmp == 0) place = "inside"; 383 else place = "after"; 384 how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp ) 385 ? "Doubly-invalid" : "Invalid" ); 386 legit = ( Seg__is_freed(vseg) ? "once-" : "" ); 387 388 if (xml) { 389 390 emit( " <kind>Heap</kind>\n"); 391 emit( " <what>%s %s of size %ld</what>\n", 392 how_invalid, 393 readwrite(xe->XE.Heap.sszB), 394 Word__abs(xe->XE.Heap.sszB) ); 395 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 396 397 emit( " <auxwhat>Address %#lx is %lu bytes %s " 398 "the accessing pointer's</auxwhat>\n", 399 a, miss_size, place ); 400 emit( " <auxwhat>%slegitimate range, " 401 "a block of size %lu %s</auxwhat>\n", 402 legit, Seg__size(vseg), 403 Seg__is_freed(vseg) ? "free'd" : "alloc'd" ); 404 VG_(pp_ExeContext)(Seg__where(vseg)); 405 406 } else { 407 408 emit( "%s %s of size %ld\n", 409 how_invalid, 410 readwrite(xe->XE.Heap.sszB), 411 Word__abs(xe->XE.Heap.sszB) ); 412 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 413 414 emit( " Address %#lx is %lu bytes %s the accessing pointer's\n", 415 a, miss_size, place ); 416 emit( " %slegitimate range, a block of size %lu %s\n", 417 legit, Seg__size(vseg), 418 Seg__is_freed(vseg) ? "free'd" : "alloc'd" ); 419 VG_(pp_ExeContext)(Seg__where(vseg)); 420 421 } 422 } 423 424 /* If we have a better description of the address, show it. 425 Note that in XML mode, it will already by nicely wrapped up 426 in tags, either <auxwhat> or <xauxwhat>, so we can just emit 427 it verbatim. */ 428 if (xml) { 429 430 if (xe->XE.Heap.descr1) 431 emiN( " %t\n", 432 (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) ); 433 if (xe->XE.Heap.descr2) 434 emiN( " %t\n", 435 (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) ); 436 if (xe->XE.Heap.datasym[0] != 0) 437 emiN( " <auxwhat>Address 0x%llx is %llu bytes " 438 "inside data symbol \"%t\"</auxwhat>\n", 439 (ULong)xe->XE.Heap.addr, 440 (ULong)xe->XE.Heap.datasymoff, 441 xe->XE.Heap.datasym ); 442 443 } else { 444 445 if (xe->XE.Heap.descr1) 446 emit( " %s\n", 447 (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) ); 448 if (xe->XE.Heap.descr2) 449 emit( " %s\n", 450 (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) ); 451 if (xe->XE.Heap.datasym[0] != 0) 452 emit( " Address 0x%llx is %llu bytes " 453 "inside data symbol \"%s\"\n", 454 (ULong)xe->XE.Heap.addr, 455 (ULong)xe->XE.Heap.datasymoff, 456 xe->XE.Heap.datasym ); 457 458 } 459 break; 460 } 461 462 //---------------------------------------------------------- 463 case XE_Arith: { 464 Seg* seg1 = xe->XE.Arith.seg1; 465 Seg* seg2 = xe->XE.Arith.seg2; 466 Char* which; 467 468 tl_assert(BOTTOM != seg1); 469 tl_assert(BOTTOM != seg2 && UNKNOWN != seg2); 470 471 if (xml) { 472 473 emit( " <kind>Arith</kind>\n"); 474 emit( " <what>Invalid arguments to %s</what>\n", 475 xe->XE.Arith.opname ); 476 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 477 478 if (seg1 != seg2) { 479 if (NONPTR == seg1) { 480 emit( " <auxwhat>First arg not a pointer</auxwhat>\n" ); 481 } else if (UNKNOWN == seg1) { 482 emit( " <auxwhat>First arg may be a pointer</auxwhat>\n" ); 483 } else { 484 emit( " <auxwhat>First arg derived from address %#lx of " 485 "%lu-byte block alloc'd</auxwhat>\n", 486 Seg__addr(seg1), Seg__size(seg1) ); 487 VG_(pp_ExeContext)(Seg__where(seg1)); 488 } 489 which = "Second arg"; 490 } else { 491 which = "Both args"; 492 } 493 if (NONPTR == seg2) { 494 emit( " <auxwhat>%s not a pointer</auxwhat>\n", which ); 495 } else { 496 emit( " <auxwhat>%s derived from address %#lx of " 497 "%lu-byte block alloc'd</auxwhat>\n", 498 which, Seg__addr(seg2), Seg__size(seg2) ); 499 VG_(pp_ExeContext)(Seg__where(seg2)); 500 } 501 502 } else { 503 504 emit( "Invalid arguments to %s\n", 505 xe->XE.Arith.opname ); 506 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 507 508 if (seg1 != seg2) { 509 if (NONPTR == seg1) { 510 emit( " First arg not a pointer\n" ); 511 } else if (UNKNOWN == seg1) { 512 emit( " First arg may be a pointer\n" ); 513 } else { 514 emit( " First arg derived from address %#lx of " 515 "%lu-byte block alloc'd\n", 516 Seg__addr(seg1), Seg__size(seg1) ); 517 VG_(pp_ExeContext)(Seg__where(seg1)); 518 } 519 which = "Second arg"; 520 } else { 521 which = "Both args"; 522 } 523 if (NONPTR == seg2) { 524 emit( " %s not a pointer\n", which ); 525 } else { 526 emit( " %s derived from address %#lx of " 527 "%lu-byte block alloc'd\n", 528 which, Seg__addr(seg2), Seg__size(seg2) ); 529 VG_(pp_ExeContext)(Seg__where(seg2)); 530 } 531 532 } 533 534 break; 535 } 536 537 //---------------------------------------------------------- 538 case XE_SysParam: { 539 Addr lo = xe->XE.SysParam.lo; 540 Addr hi = xe->XE.SysParam.hi; 541 Seg* seglo = xe->XE.SysParam.seglo; 542 Seg* seghi = xe->XE.SysParam.seghi; 543 Char* s = VG_(get_error_string) (err); 544 Char* what; 545 546 tl_assert(BOTTOM != seglo && BOTTOM != seghi); 547 548 if (Vg_CoreSysCall == xe->XE.SysParam.part) 549 what = "Syscall param "; 550 else VG_(tool_panic)("bad CorePart"); 551 552 if (seglo == seghi) { 553 // freed block 554 tl_assert(is_known_segment(seglo)); 555 tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled? 556 557 if (xml) { 558 559 emit( " <kind>SysParam</kind>\n"); 560 emit( " <what>%s%s contains unaddressable byte(s)</what>\n", 561 what, s ); 562 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 563 564 emit( " <auxwhat>Address %#lx is %ld bytes inside a " 565 "%ld-byte block free'd</auxwhat>\n", 566 lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 567 VG_(pp_ExeContext)(Seg__where(seglo)); 568 569 } else { 570 571 emit( " %s%s contains unaddressable byte(s)\n", 572 what, s ); 573 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 574 575 emit( " Address %#lx is %ld bytes inside a " 576 "%ld-byte block free'd\n", 577 lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 578 VG_(pp_ExeContext)(Seg__where(seglo)); 579 580 } 581 582 } else { 583 // mismatch 584 585 if (xml) { 586 587 emit( " <kind>SysParam</kind>\n"); 588 emit( " <what>%s%s is non-contiguous</what>\n", 589 what, s ); 590 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 591 592 if (UNKNOWN == seglo) { 593 emit( " <auxwhat>First byte is " 594 "not inside a known block</auxwhat>\n" ); 595 } else { 596 emit( " <auxwhat>First byte (%#lx) is %ld bytes inside a " 597 "%ld-byte block alloc'd</auxwhat>\n", 598 lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 599 VG_(pp_ExeContext)(Seg__where(seglo)); 600 } 601 602 if (UNKNOWN == seghi) { 603 emit( " <auxwhat>Last byte is " 604 "not inside a known block</auxwhat>\n" ); 605 } else { 606 emit( " <auxwhat>Last byte (%#lx) is %ld bytes inside a " 607 "%ld-byte block alloc'd</auxwhat>\n", 608 hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 609 VG_(pp_ExeContext)(Seg__where(seghi)); 610 } 611 612 } else { 613 614 emit( "%s%s is non-contiguous\n", 615 what, s ); 616 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 617 618 if (UNKNOWN == seglo) { 619 emit( " First byte is not inside a known block\n" ); 620 } else { 621 emit( " First byte (%#lx) is %ld bytes inside a " 622 "%ld-byte block alloc'd\n", 623 lo, lo-Seg__addr(seglo), Seg__size(seglo) ); 624 VG_(pp_ExeContext)(Seg__where(seglo)); 625 } 626 627 if (UNKNOWN == seghi) { 628 emit( " Last byte is not inside a known block\n" ); 629 } else { 630 emit( " Last byte (%#lx) is %ld bytes inside a " 631 "%ld-byte block alloc'd\n", 632 hi, hi-Seg__addr(seghi), Seg__size(seghi) ); 633 VG_(pp_ExeContext)(Seg__where(seghi)); 634 } 635 636 } 637 638 } 639 break; 640 } 641 642 default: 643 VG_(tool_panic)("pp_Error: unrecognised error kind"); 644 } 645 } 646 647 648 UInt pc_update_Error_extra ( Error* err ) 649 { 650 XError *xe = (XError*)VG_(get_error_extra)(err); 651 tl_assert(xe); 652 switch (xe->tag) { 653 case XE_SorG: 654 break; 655 case XE_Heap: { 656 Bool have_descr; 657 658 tl_assert(sizeof(xe->XE.Heap.datasym) > 0); 659 xe->XE.Heap.datasymoff = 0; 660 xe->XE.Heap.datasym[0] = 0; 661 662 tl_assert(!xe->XE.Heap.descr1); 663 tl_assert(!xe->XE.Heap.descr2); 664 665 xe->XE.Heap.descr1 666 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 667 VG_(free), sizeof(HChar) ); 668 xe->XE.Heap.descr2 669 = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", 670 VG_(free), sizeof(HChar) ); 671 672 VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym)); 673 xe->XE.Heap.datasymoff = 0; 674 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; 690 } 691 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; 695 } 696 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) { 700 if (VG_(get_datasym_and_offset)( 701 xe->XE.Heap.addr, &xe->XE.Heap.datasym[0], 702 sizeof(xe->XE.Heap.datasym)-1, 703 &xe->XE.Heap.datasymoff ) 704 ) { 705 tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] 706 == 0); 707 } 708 } 709 break; 710 } 711 case XE_Arith: 712 break; 713 case XE_SysParam: 714 break; 715 default: 716 VG_(tool_panic)("update_extra"); 717 } 718 return sizeof(XError); 719 } 720 721 Bool pc_is_recognised_suppression ( Char* name, Supp *su ) 722 { 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 736 Bool pc_read_extra_suppression_info ( Int fd, Char** bufpp, 737 SizeT* nBufp, Supp* su ) 738 { 739 Bool eof; 740 if (VG_(get_supp_kind)(su) == XS_SysParam) { 741 eof = VG_(get_line) ( fd, bufpp, nBufp, NULL ); 742 if (eof) return False; 743 VG_(set_supp_string)(su, VG_(strdup)("pc.common.presi.1", *bufpp)); 744 } 745 return True; 746 } 747 748 Bool pc_error_matches_suppression (Error* err, Supp* su) 749 { 750 ErrorKind ekind = VG_(get_error_kind)(err); 751 switch (VG_(get_supp_kind)(su)) { 752 case XS_SorG: return ekind == XE_SorG; 753 case XS_Heap: return ekind == XE_Heap; 754 case XS_Arith: return ekind == XE_Arith; 755 case XS_SysParam: return ekind == XE_SysParam; 756 default: 757 VG_(printf)("Error:\n" 758 " unknown suppression type %d\n", 759 VG_(get_supp_kind)(su)); 760 VG_(tool_panic)("unknown suppression type in " 761 "pc_error_matches_suppression"); 762 } 763 } 764 765 Char* pc_get_error_name ( Error* err ) 766 { 767 XError *xe = (XError*)VG_(get_error_extra)(err); 768 tl_assert(xe); 769 switch (xe->tag) { 770 case XE_SorG: return "SorG"; 771 case XE_Heap: return "Heap"; 772 case XE_Arith: return "Arith"; 773 case XE_SysParam: return "SysParam"; 774 default: VG_(tool_panic)("get_error_name: unexpected type"); 775 } 776 } 777 778 Bool pc_get_extra_suppression_info ( Error* err, 779 /*OUT*/Char* buf, Int nBuf ) 780 { 781 ErrorKind ekind = VG_(get_error_kind )(err); 782 tl_assert(buf); 783 tl_assert(nBuf >= 16); // stay sane 784 if (XE_SysParam == ekind) { 785 Char* errstr = VG_(get_error_string)(err); 786 tl_assert(errstr); 787 VG_(snprintf)(buf, nBuf-1, "%s", errstr); 788 return True; 789 } else { 790 return False; 791 } 792 } 793 794 795 /*--------------------------------------------------------------------*/ 796 /*--- end pc_common.c ---*/ 797 /*--------------------------------------------------------------------*/ 798