|
From: <sv...@va...> - 2008-09-09 08:35:07
|
Author: sewardj
Date: 2008-09-09 09:35:09 +0100 (Tue, 09 Sep 2008)
New Revision: 8589
Log:
Fix up enough plumbing so this at least compiles.
Added:
branches/PTRCHECK/exp-ptrcheck/h_main.h
branches/PTRCHECK/exp-ptrcheck/pc_common.c
branches/PTRCHECK/exp-ptrcheck/pc_common.h
branches/PTRCHECK/exp-ptrcheck/pc_main.c
branches/PTRCHECK/exp-ptrcheck/sg_main.h
Modified:
branches/PTRCHECK/exp-ptrcheck/Makefile.am
branches/PTRCHECK/exp-ptrcheck/h_list.c
branches/PTRCHECK/exp-ptrcheck/h_main.c
branches/PTRCHECK/exp-ptrcheck/sg_main.c
Modified: branches/PTRCHECK/exp-ptrcheck/Makefile.am
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/Makefile.am 2008-09-08 18:43:53 UTC (rev 8588)
+++ branches/PTRCHECK/exp-ptrcheck/Makefile.am 2008-09-09 08:35:09 UTC (rev 8589)
@@ -21,7 +21,7 @@
endif
-VGPRELOAD_EXP_PTRCHECK_SOURCES_COMMON = pc_intercepts.c
+VGPRELOAD_EXP_PTRCHECK_SOURCES_COMMON = h_intercepts.c
vgpreload_exp_ptrcheck_x86_linux_so_SOURCES = $(VGPRELOAD_EXP_PTRCHECK_SOURCES_COMMON)
vgpreload_exp_ptrcheck_x86_linux_so_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
@@ -79,7 +79,8 @@
-EXP_PTRCHECK_SOURCES_COMMON = pc_list.c pc_main.c
+EXP_PTRCHECK_SOURCES_COMMON = \
+ pc_common.c h_list.c h_main.c sg_main.c pc_main.c
exp_ptrcheck_x86_linux_SOURCES = $(EXP_PTRCHECK_SOURCES_COMMON)
exp_ptrcheck_x86_linux_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX)
@@ -123,5 +124,5 @@
exp_ptrcheck_ppc64_aix5_LDADD = $(TOOL_LDADD_PPC64_AIX5)
exp_ptrcheck_ppc64_aix5_LDFLAGS = $(TOOL_LDFLAGS_PPC64_AIX5)
-noinst_HEADERS = pc_list.h
+noinst_HEADERS = h_list.h h_main.h sg_main.h pc_common.h
Modified: branches/PTRCHECK/exp-ptrcheck/h_list.c
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/h_list.c 2008-09-08 18:43:53 UTC (rev 8588)
+++ branches/PTRCHECK/exp-ptrcheck/h_list.c 2008-09-09 08:35:09 UTC (rev 8589)
@@ -46,7 +46,7 @@
#include "pub_tool_execontext.h"
#include "pub_tool_hashtable.h"
-#include "pc_list.h"
+#include "h_list.h"
#ifdef OUTSIDE_PTRCHECK
#include <assert.h>
Modified: branches/PTRCHECK/exp-ptrcheck/h_main.c
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/h_main.c 2008-09-08 18:43:53 UTC (rev 8588)
+++ branches/PTRCHECK/exp-ptrcheck/h_main.c 2008-09-09 08:35:09 UTC (rev 8589)
@@ -9,8 +9,13 @@
This file is part of Ptrcheck, a Valgrind tool for checking pointer
use in programs.
+ Initial version (Annelid):
+
Copyright (C) 2003-2008 Nicholas Nethercote
nj...@va...
+
+ Valgrind-3.X port:
+
Copyright (C) 2008-2008 OpenWorks Ltd
in...@op...
@@ -224,10 +229,14 @@
#include "pub_tool_threadstate.h" // VG_(get_running_tid)
#include "pub_tool_oset.h"
#include "pub_tool_vkiscnums.h"
+#include "pub_tool_machine.h"
-#include "pc_list.h"
+#include "h_list.h"
+#include "h_main.h"
+#include "pc_common.h"
+
/*------------------------------------------------------------*/
/*--- Debug/trace options ---*/
/*------------------------------------------------------------*/
@@ -239,47 +248,11 @@
/*------------------------------------------------------------*/
-/*--- Command line options ---*/
-/*------------------------------------------------------------*/
-
-static Bool clo_partial_loads_ok = True; /* user visible */
-static Bool clo_lossage_check = False; /* dev flag only */
-
-static Bool pc_process_cmd_line_options(Char* arg)
-{
- VG_BOOL_CLO(arg, "--partial-loads-ok", clo_partial_loads_ok)
- else VG_BOOL_CLO(arg, "--lossage-check", clo_lossage_check)
- else
- return VG_(replacement_malloc_process_cmd_line_option)(arg);
-
- return True;
-}
-
-static void pc_print_usage(void)
-{
- VG_(printf)(
- " --partial-loads-ok=no|yes same as for Memcheck [yes]\n"
- );
- VG_(replacement_malloc_print_usage)();
-}
-
-static void pc_print_debug_usage(void)
-{
- VG_(printf)(
- " --lossage-check=no|yes gather stats for quality control [no]\n"
- );
- VG_(replacement_malloc_print_debug_usage)();
-}
-
-
-/*------------------------------------------------------------*/
/*--- Segments ---*/
/*------------------------------------------------------------*/
-// Choose values that couldn't possibly be pointers
-#define NONPTR ((Seg)0xA1)
-#define UNKNOWN ((Seg)0xB2)
-#define BOTTOM ((Seg)0xC3)
+// NONPTR, UNKNOWN, BOTTOM defined in h_main.h since
+// pc_common.c needs to see them, for error processing
static ISList* seglist = NULL;
@@ -635,420 +608,41 @@
}
-/*--------------------------------------------------------------------*/
-/*--- Error handling ---*/
-/*--------------------------------------------------------------------*/
-
-typedef
- enum {
- /* Possible data race */
- LoadStoreSupp,
- ArithSupp,
- SysParamSupp,
- }
- PtrcheckSuppKind;
-
-/* What kind of error it is. */
-typedef
- enum {
- LoadStoreErr, // mismatched ptr/addr segments on load/store
- ArithErr, // bad arithmetic between two segment pointers
- SysParamErr, // block straddling >1 segment passed to syscall
- }
- PtrcheckErrorKind;
-
-
-// These ones called from generated code.
-
-typedef
- struct {
- Addr a;
- UInt size;
- Seg vseg;
- Bool is_write;
- Char descr1[96];
- Char descr2[96];
- Char datasym[96];
- OffT datasymoff;
- }
- LoadStoreExtra;
-
-typedef
- struct {
- Seg seg1;
- Seg seg2;
- const HChar* opname; // user-understandable text name
- }
- ArithExtra;
-
-typedef
- struct {
- CorePart part;
- Addr lo;
- Addr hi;
- Seg seglo;
- Seg seghi;
- }
- SysParamExtra;
-
-
-static
-void record_loadstore_error( Addr a, UInt size, Seg vseg, Bool is_write )
-{
- LoadStoreExtra extra = {
- .a = a, .size = size, .vseg = vseg, .is_write = is_write
- };
- extra.descr1[0] = extra.descr2[0] = extra.datasym[0] = 0;
- extra.datasymoff = 0;
- VG_(maybe_record_error)( VG_(get_running_tid)(), LoadStoreErr,
- /*a*/0, /*str*/NULL, /*extra*/(void*)&extra);
-}
-
-static void
-record_arith_error( Seg seg1, Seg seg2, HChar* opname )
-{
- ArithExtra extra = {
- .seg1 = seg1, .seg2 = seg2, .opname = opname
- };
- VG_(maybe_record_error)( VG_(get_running_tid)(), ArithErr,
- /*a*/0, /*str*/NULL, /*extra*/(void*)&extra);
-}
-
-static void record_sysparam_error( ThreadId tid, CorePart part, Char* s,
- Addr lo, Addr hi, Seg seglo, Seg seghi )
-{
- SysParamExtra extra = {
- .part = part, .lo = lo, .hi = hi, .seglo = seglo, .seghi = seghi
- };
- VG_(maybe_record_error)( tid, SysParamErr, /*a*/(Addr)0, /*str*/s,
- /*extra*/(void*)&extra);
-}
-
-static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
-{
- tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
-
- // Nb: ok to compare string pointers, rather than string contents,
- // because the same static strings are shared.
-
- switch (VG_(get_error_kind)(e1)) {
-
- case LoadStoreErr:
- tl_assert( VG_(get_error_string)(e1) == NULL );
- tl_assert( VG_(get_error_string)(e2) == NULL );
- return True;
-
- case SysParamErr:
- case ArithErr:
- return True;
-
- default:
- VG_(tool_panic)("eq_Error: unrecognised error kind");
- }
-}
-
-static Char* readwrite(Bool is_write)
-{
- return ( is_write ? "write" : "read" );
-}
-
-static inline
-Bool is_known_segment(Seg seg)
-{
- return (UNKNOWN != seg && BOTTOM != seg && NONPTR != seg);
-}
-
-static void pp_Error ( Error* err )
-{
- switch (VG_(get_error_kind)(err)) {
- //----------------------------------------------------------
- case LoadStoreErr: {
- LoadStoreExtra* extra = (LoadStoreExtra*)VG_(get_error_extra)(err);
- Char *place, *legit, *how_invalid;
- Addr a = extra->a;
- Seg vseg = extra->vseg;
-
- tl_assert(is_known_segment(vseg) || NONPTR == vseg);
-
- if (NONPTR == vseg) {
- // Access via a non-pointer
- VG_(message)(Vg_UserMsg, "Invalid %s of size %u",
- readwrite(extra->is_write), extra->size);
- VG_(pp_ExeContext)( VG_(get_error_where)(err) );
- VG_(message)(Vg_UserMsg,
- " Address %#lx is not derived from any known block", a);
-
- } else {
- // Access via a pointer, but outside its range.
- Int cmp;
- UWord miss_size;
- Seg__cmp(vseg, a, &cmp, &miss_size);
- if (cmp < 0) place = "before";
- else if (cmp == 0) place = "inside";
- else place = "after";
- how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp )
- ? "Doubly-invalid" : "Invalid" );
- legit = ( Seg__is_freed(vseg) ? "once-" : "" );
-
- VG_(message)(Vg_UserMsg, "%s %s of size %u", how_invalid,
- readwrite(extra->is_write), extra->size);
- VG_(pp_ExeContext)( VG_(get_error_where)(err) );
-
- VG_(message)(Vg_UserMsg,
- " Address %#lx is %lu bytes %s the accessing pointer's",
- a, miss_size, place);
- VG_(message)(Vg_UserMsg,
- " %slegitimate range, a block of size %lu %s",
- legit, Seg__size(vseg), Seg__status_str(vseg) );
- VG_(pp_ExeContext)(Seg__where(vseg));
- }
- if (extra->descr1[0] != 0)
- VG_(message)(Vg_UserMsg, " %s", extra->descr1);
- if (extra->descr2[0] != 0)
- VG_(message)(Vg_UserMsg, " %s", extra->descr2);
- if (extra->datasym[0] != 0)
- VG_(message)(Vg_UserMsg, " Address 0x%llx is %llu bytes "
- "inside data symbol \"%s\"",
- (ULong)extra->a, (ULong)extra->datasymoff,
- extra->datasym);
- break;
- }
-
- //----------------------------------------------------------
- case ArithErr: {
- ArithExtra* extra = VG_(get_error_extra)(err);
- Seg seg1 = extra->seg1;
- Seg seg2 = extra->seg2;
- Char* which;
-
- tl_assert(BOTTOM != seg1);
- tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);
-
- VG_(message)(Vg_UserMsg, "Invalid arguments to %s", extra->opname);
- VG_(pp_ExeContext)( VG_(get_error_where)(err) );
-
- if (seg1 != seg2) {
- if (NONPTR == seg1) {
- VG_(message)(Vg_UserMsg, " First arg not a pointer");
- } else if (UNKNOWN == seg1) {
- VG_(message)(Vg_UserMsg, " First arg may be a pointer");
- } else {
- VG_(message)(Vg_UserMsg, " First arg derived from address %#lx of "
- "%lu-byte block %s",
- Seg__a(seg1), Seg__size(seg1),
- Seg__status_str(seg1) );
- VG_(pp_ExeContext)(Seg__where(seg1));
- }
- which = "Second arg";
- } else {
- which = "Both args";
- }
- if (NONPTR == seg2) {
- VG_(message)(Vg_UserMsg, " %s not a pointer", which);
- } else {
- VG_(message)(Vg_UserMsg, " %s derived from address %#lx of "
- "%lu-byte block %s",
- which, Seg__a(seg2), Seg__size(seg2),
- Seg__status_str(seg2));
- VG_(pp_ExeContext)(Seg__where(seg2));
- }
- break;
- }
-
- //----------------------------------------------------------
- case SysParamErr: {
- SysParamExtra* extra = (SysParamExtra*)VG_(get_error_extra)(err);
- Addr lo = extra->lo;
- Addr hi = extra->hi;
- Seg seglo = extra->seglo;
- Seg seghi = extra->seghi;
- Char* s = VG_(get_error_string) (err);
- Char* what;
-
- tl_assert(BOTTOM != seglo && BOTTOM != seghi);
-
- if (Vg_CoreSysCall == extra->part) what = "Syscall param ";
- else VG_(tool_panic)("bad CorePart");
-
- if (seglo == seghi) {
- // freed block
- tl_assert(is_known_segment(seglo));
- tl_assert(Seg__is_freed(seglo));
- VG_(message)(Vg_UserMsg, "%s%s contains unaddressable byte(s)",
- what, s);
- VG_(pp_ExeContext)( VG_(get_error_where)(err) );
-
- VG_(message)(Vg_UserMsg, " Address %#lx is %ld bytes inside a "
- "%ld-byte block %s",
- lo, lo-Seg__a(seglo), Seg__size(seglo),
- Seg__status_str(seglo) );
- VG_(pp_ExeContext)(Seg__where(seglo));
-
- } else {
- // mismatch
- VG_(message)(Vg_UserMsg, "%s%s is non-contiguous", what, s);
- VG_(pp_ExeContext)( VG_(get_error_where)(err) );
-
- if (UNKNOWN == seglo) {
- VG_(message)(Vg_UserMsg, " First byte is not inside a known block");
- } else {
- VG_(message)(Vg_UserMsg, " First byte (%#lx) is %ld bytes inside a "
- "%ld-byte block %s",
- lo, lo-Seg__a(seglo), Seg__size(seglo),
- Seg__status_str(seglo) );
- VG_(pp_ExeContext)(Seg__where(seglo));
- }
-
- if (UNKNOWN == seghi) {
- VG_(message)(Vg_UserMsg, " Last byte is not inside a known block");
- } else {
- VG_(message)(Vg_UserMsg, " Last byte (%#lx) is %ld bytes inside a "
- "%ld-byte block %s",
- hi, hi-Seg__a(seghi), Seg__size(seghi),
- Seg__status_str(seghi));
- VG_(pp_ExeContext)(Seg__where(seghi));
- }
- }
- break;
- }
-
- default:
- VG_(tool_panic)("pp_Error: unrecognised error kind");
- }
-}
-
-static UInt update_Error_extra ( Error* err )
-{
- switch (VG_(get_error_kind)(err)) {
- case LoadStoreErr: {
- LoadStoreExtra* ex = (LoadStoreExtra*)VG_(get_error_extra)(err);
- tl_assert(ex);
- tl_assert(sizeof(ex->descr1) == sizeof(ex->descr2));
- tl_assert(sizeof(ex->descr1) > 0);
- tl_assert(sizeof(ex->datasym) > 0);
- VG_(memset)(&ex->descr1, 0, sizeof(ex->descr1));
- VG_(memset)(&ex->descr2, 0, sizeof(ex->descr2));
- VG_(memset)(&ex->datasym, 0, sizeof(ex->datasym));
- ex->datasymoff = 0;
- if (VG_(get_data_description)( &ex->descr1[0], &ex->descr2[0],
- sizeof(ex->descr1)-1, ex->a )) {
- tl_assert(ex->descr1[sizeof(ex->descr1)-1] == 0);
- tl_assert(ex->descr1[sizeof(ex->descr2)-1] == 0);
- }
- else
- if (VG_(get_datasym_and_offset)( ex->a, &ex->datasym[0],
- sizeof(ex->datasym)-1,
- &ex->datasymoff )) {
- tl_assert(ex->datasym[sizeof(ex->datasym)-1] == 0);
- }
- return sizeof(LoadStoreExtra);
- }
- case ArithErr:
- return sizeof(ArithExtra);
- case SysParamErr:
- return sizeof(SysParamExtra);
- default:
- VG_(tool_panic)("update_extra");
- }
-}
-
-static Bool is_recognised_suppression ( Char* name, Supp *su )
-{
- SuppKind skind;
-
- if (VG_STREQ(name, "LoadStore")) skind = LoadStoreSupp;
- else if (VG_STREQ(name, "Arith")) skind = ArithSupp;
- else if (VG_STREQ(name, "SysParam")) skind = SysParamSupp;
- else
- return False;
-
- VG_(set_supp_kind)(su, skind);
- return True;
-}
-
-static Bool read_extra_suppression_info ( Int fd, Char* buf,
- Int nBuf, Supp* su )
-{
- Bool eof;
-
- if (VG_(get_supp_kind)(su) == SysParamSupp) {
- eof = VG_(get_line) ( fd, buf, nBuf );
- if (eof) return False;
- VG_(set_supp_string)(su, VG_(strdup)(buf));
- }
- return True;
-}
-
-static Bool error_matches_suppression (Error* err, Supp* su)
-{
- ErrorKind ekind = VG_(get_error_kind )(err);
-
- switch (VG_(get_supp_kind)(su)) {
- case LoadStoreSupp: return (ekind == LoadStoreErr);
- case ArithSupp: return (ekind == ArithErr);
- case SysParamSupp: return (ekind == SysParamErr);
- default:
- VG_(printf)("Error:\n"
- " unknown suppression type %d\n",
- VG_(get_supp_kind)(su));
- VG_(tool_panic)("unknown suppression type in "
- "SK_(error_matches_suppression)");
- }
-}
-
-static Char* get_error_name ( Error* err )
-{
- switch (VG_(get_error_kind)(err)) {
- case LoadStoreErr: return "LoadStore";
- case ArithErr: return "Arith";
- case SysParamErr: return "SysParam";
- default: VG_(tool_panic)("get_error_name: unexpected type");
- }
-}
-
-static void print_extra_suppression_info ( Error* err )
-{
- if (SysParamErr == VG_(get_error_kind)(err)) {
- VG_(printf)(" %s\n", VG_(get_error_string)(err));
- }
-}
-
-
/*------------------------------------------------------------*/
/*--- malloc() et al replacements ---*/
/*------------------------------------------------------------*/
-static void* pc_replace_malloc ( ThreadId tid, SizeT n )
+void* h_replace_malloc ( ThreadId tid, SizeT n )
{
return alloc_and_new_mem_heap ( tid, n, VG_(clo_alignment),
/*is_zeroed*/False );
}
-static void* pc_replace___builtin_new ( ThreadId tid, SizeT n )
+void* h_replace___builtin_new ( ThreadId tid, SizeT n )
{
return alloc_and_new_mem_heap ( tid, n, VG_(clo_alignment),
/*is_zeroed*/False );
}
-static void* pc_replace___builtin_vec_new ( ThreadId tid, SizeT n )
+void* h_replace___builtin_vec_new ( ThreadId tid, SizeT n )
{
return alloc_and_new_mem_heap ( tid, n, VG_(clo_alignment),
/*is_zeroed*/False );
}
-static void* pc_replace_memalign ( ThreadId tid, SizeT align, SizeT n )
+void* h_replace_memalign ( ThreadId tid, SizeT align, SizeT n )
{
return alloc_and_new_mem_heap ( tid, n, align,
/*is_zeroed*/False );
}
-static void* pc_replace_calloc ( ThreadId tid, SizeT nmemb, SizeT size1 )
+void* h_replace_calloc ( ThreadId tid, SizeT nmemb, SizeT size1 )
{
return alloc_and_new_mem_heap ( tid, nmemb*size1, VG_(clo_alignment),
/*is_zeroed*/True );
}
-static void pc_replace_free ( ThreadId tid, void* p )
+void h_replace_free ( ThreadId tid, void* p )
{
// Should arguably check here if p.vseg matches the segID of the
// pointed-to block... unfortunately, by this stage, we don't know what
@@ -1066,17 +660,17 @@
handle_free_heap(tid, p);
}
-static void pc_replace___builtin_delete ( ThreadId tid, void* p )
+void h_replace___builtin_delete ( ThreadId tid, void* p )
{
handle_free_heap(tid, p);
}
-static void pc_replace___builtin_vec_delete ( ThreadId tid, void* p )
+void h_replace___builtin_vec_delete ( ThreadId tid, void* p )
{
handle_free_heap(tid, p);
}
-static void* pc_replace_realloc ( ThreadId tid, void* p_old, SizeT new_size )
+void* h_replace_realloc ( ThreadId tid, void* p_old, SizeT new_size )
{
Seg seg;
@@ -1157,7 +751,8 @@
//zz set_mem( a, len, NONPTR );
//zz }
-static void new_mem_startup( Addr a, SizeT len, Bool rr, Bool ww, Bool xx )
+void h_new_mem_startup( Addr a, SizeT len,
+ Bool rr, Bool ww, Bool xx, ULong di_handle )
{
if (0) VG_(printf)("new_mem_startup(%#lx,%lu)\n", a, len);
set_mem_unknown( a, len );
@@ -1188,7 +783,8 @@
// Not quite right: if you mmap a segment into a specified place, it could
// be legitimate to do certain arithmetic with the pointer that it wouldn't
// otherwise. Hopefully this is rare, though.
-static void new_mem_mmap( Addr a, SizeT len, Bool rr, Bool ww, Bool xx )
+void h_new_mem_mmap( Addr a, SizeT len,
+ Bool rr, Bool ww, Bool xx, ULong di_handle )
{
if (0) VG_(printf)("new_mem_mmap(%#lx,%lu)\n", a, len);
//zz #if 0
@@ -1263,7 +859,7 @@
//zz // VG_(skin_panic)("can't handle die_mem_brk()");
//zz }
-static void die_mem_munmap( Addr a, SizeT len )
+void h_die_mem_munmap( Addr a, SizeT len )
{
// handle_free_munmap( (void*)a, len );
}
@@ -1315,29 +911,29 @@
/* First identify the case where start and end are in different
segments but s and e don't both fall in either. */
if ( ! ((s_in_seglo && e_in_seglo) || (s_in_seghi && e_in_seghi)) ) {
- record_sysparam_error(tid, part, str, s, e, seglo, seghi);
+ h_record_sysparam_error(tid, part, str, s, e, seglo, seghi);
}
/* Now we know that s and e are both in the same known segment.
Identify the case where that segment is freed. */
else if (s_in_seglo && Seg__is_freed(seglo)) {
tl_assert(e_in_seglo);
- record_sysparam_error(tid, part, str, s, e, seglo, UNKNOWN);
+ h_record_sysparam_error(tid, part, str, s, e, seglo, UNKNOWN);
}
else if (s_in_seghi && Seg__is_freed(seghi)) {
tl_assert(e_in_seghi);
- record_sysparam_error(tid, part, str, s, e, seghi, UNKNOWN);
+ h_record_sysparam_error(tid, part, str, s, e, seghi, UNKNOWN);
}
}
}
-static void pre_mem_access ( CorePart part, ThreadId tid, Char* s,
- Addr base, SizeT size )
+void h_pre_mem_access ( CorePart part, ThreadId tid, Char* s,
+ Addr base, SizeT size )
{
pre_mem_access2( part, tid, s, base, base + size - 1 );
}
-static
-void pre_mem_read_asciiz ( CorePart part, ThreadId tid, Char* s, Addr lo )
+void h_pre_mem_read_asciiz ( CorePart part, ThreadId tid,
+ Char* s, Addr lo )
{
Addr hi = lo;
@@ -2101,9 +1697,8 @@
}
}
-static
-void post_reg_write_demux ( CorePart part, ThreadId tid,
- OffT guest_state_offset, SizeT size)
+void h_post_reg_write_demux ( CorePart part, ThreadId tid,
+ OffT guest_state_offset, SizeT size)
{
if (0)
VG_(printf)("post_reg_write_demux: tid %d part %d off %ld size %ld\n",
@@ -2133,19 +1728,18 @@
}
}
-static
-void post_reg_write_clientcall(ThreadId tid, OffT guest_state_offset,
- SizeT size, Addr f )
+void h_post_reg_write_clientcall(ThreadId tid, OffT guest_state_offset,
+ SizeT size, Addr f )
{
UWord p;
// Having to do this is a bit nasty...
- if (f == (Addr)pc_replace_malloc
- || f == (Addr)pc_replace___builtin_new
- || f == (Addr)pc_replace___builtin_vec_new
- || f == (Addr)pc_replace_calloc
- || f == (Addr)pc_replace_memalign
- || f == (Addr)pc_replace_realloc)
+ if (f == (Addr)h_replace_malloc
+ || f == (Addr)h_replace___builtin_new
+ || f == (Addr)h_replace___builtin_vec_new
+ || f == (Addr)h_replace_calloc
+ || f == (Addr)h_replace_memalign
+ || f == (Addr)h_replace_realloc)
{
// We remembered the last added segment; make sure it's the right one.
/* What's going on: at this point, the scheduler has just called
@@ -2174,9 +1768,9 @@
guest_state_offset, size, (UWord)last_seg_added );
}
}
- else if (f == (Addr)pc_replace_free
- || f == (Addr)pc_replace___builtin_delete
- || f == (Addr)pc_replace___builtin_vec_delete
+ else if (f == (Addr)h_replace_free
+ || f == (Addr)h_replace___builtin_delete
+ || f == (Addr)h_replace___builtin_vec_delete
// || f == (Addr)VG_(cli_block_size)
|| f == (Addr)VG_(message))
{
@@ -2237,7 +1831,7 @@
/*--- System calls ---*/
/*--------------------------------------------------------------------*/
-static void pre_syscall ( ThreadId tid, UInt syscallno )
+void h_pre_syscall ( ThreadId tid, UInt syscallno )
{
//zz #if 0
//zz UInt mmap_flags;
@@ -2265,7 +1859,7 @@
//zz return NULL;
}
-static void post_syscall ( ThreadId tid, UInt syscallno, SysRes res )
+void h_post_syscall ( ThreadId tid, UInt syscallno, SysRes res )
{
switch (syscallno) {
@@ -2621,7 +2215,7 @@
static __inline__
void check_load_or_store(Bool is_write, Addr m, UInt sz, Seg mptr_vseg)
{
- if (clo_lossage_check) {
+ if (h_clo_lossage_check) {
Seg seg;
stats__tot_mem_refs++;
if (ISList__findI0( seglist, (Addr)m, &seg )) {
@@ -2637,7 +2231,7 @@
if (UNKNOWN == mptr_vseg
|| BOTTOM == mptr_vseg || NONPTR == mptr_vseg) {
ExeContext* ec;
- Char buf[100];
+ Char buf[100];
static UWord xx = 0;
stats__refs_lost_seg++;
ec = VG_(record_ExeContext)( VG_(get_running_tid)(), 0 );
@@ -2672,7 +2266,7 @@
// do nothing
} else if (NONPTR == mptr_vseg) {
- record_loadstore_error( m, sz, mptr_vseg, is_write );
+ h_record_heap_error( m, sz, mptr_vseg, is_write );
} else {
// check all segment ranges in the circle
@@ -2687,7 +2281,7 @@
// gcc's/glibc's habits of doing word-sized accesses that read past
// the ends of arrays/strings.
if (!is_write && sz == sizeof(UWord)
- && clo_partial_loads_ok && SHMEM_IS_WORD_ALIGNED(m)) {
+ && h_clo_partial_loads_ok && SHMEM_IS_WORD_ALIGNED(m)) {
mhi = m;
} else {
mhi = m+sz-1;
@@ -2711,7 +2305,7 @@
// warnings, since the first one mentions that the block has been
// freed.
if ( ! is_ok || Seg__is_freed(curr) )
- record_loadstore_error( m, sz, mptr_vseg, is_write );
+ h_record_heap_error( m, sz, mptr_vseg, is_write );
}
}
@@ -3056,7 +2650,7 @@
}
#define BINERROR(opname) \
- record_arith_error(seg1, seg2, opname); \
+ h_record_arith_error(seg1, seg2, opname); \
out = NONPTR
@@ -3218,7 +2812,7 @@
checkSeg(seg2);
# endif
if (is_known_segment(seg1) && is_known_segment(seg2))
- record_arith_error(seg1, seg2, "Mul32/Mul64");
+ h_record_arith_error(seg1, seg2, "Mul32/Mul64");
return NONPTR;
}
@@ -4547,11 +4141,11 @@
static
-IRSB* pc_instrument ( VgCallbackClosure* closure,
- IRSB* sbIn,
- VexGuestLayout* layout,
- VexGuestExtents* vge,
- IRType gWordTy, IRType hWordTy )
+IRSB* h_instrument ( VgCallbackClosure* closure,
+ IRSB* sbIn,
+ VexGuestLayout* layout,
+ VexGuestExtents* vge,
+ IRType gWordTy, IRType hWordTy )
{
Bool verboze = 0||False;
Int i /*, j*/;
@@ -4663,88 +4257,8 @@
/*--- Initialisation ---*/
/*--------------------------------------------------------------------*/
-static void pc_post_clo_init ( void ); /* just below */
-static void pc_fini ( Int exitcode ); /* just below */
-
-static void pc_pre_clo_init ( void )
+void h_pre_clo_init ( void )
{
- VG_(details_name) ("exp-ptrcheck");
- VG_(details_version) (NULL);
- VG_(details_description) ("a pointer-use checker");
- VG_(details_copyright_author)(
- "Copyright (C) 2003-2008, and GNU GPL'd, by Nicholas Nethercote.");
- VG_(details_bug_reports_to) ("nj...@va...");
-
- VG_(basic_tool_funcs)( pc_post_clo_init,
- pc_instrument,
- pc_fini );
-
- VG_(needs_malloc_replacement)( pc_replace_malloc,
- pc_replace___builtin_new,
- pc_replace___builtin_vec_new,
- pc_replace_memalign,
- pc_replace_calloc,
- pc_replace_free,
- pc_replace___builtin_delete,
- pc_replace___builtin_vec_delete,
- pc_replace_realloc,
- 0 /* no need for client heap redzones */ );
-
- VG_(needs_core_errors) ();
- VG_(needs_tool_errors) (eq_Error,
- pp_Error,
- True,/*show TIDs for errors*/
- update_Error_extra,
- is_recognised_suppression,
- read_extra_suppression_info,
- error_matches_suppression,
- get_error_name,
- print_extra_suppression_info);
-
- VG_(needs_syscall_wrapper)( pre_syscall,
- post_syscall );
-
- VG_(needs_command_line_options)(pc_process_cmd_line_options,
- pc_print_usage,
- pc_print_debug_usage);
-
- VG_(needs_var_info)();
-
-//zz // No needs
-//zz VG_(needs_core_errors) ();
-//zz VG_(needs_skin_errors) ();
-//zz VG_(needs_shadow_regs) ();
-//zz VG_(needs_command_line_options)();
-//zz VG_(needs_syscall_wrapper) ();
-//zz VG_(needs_sanity_checks) ();
-//zz
-//zz // Memory events to track
- VG_(track_new_mem_startup) ( new_mem_startup );
-//zz VG_(track_new_mem_stack_signal) ( NULL );
-//zz VG_(track_new_mem_brk) ( new_mem_brk );
- VG_(track_new_mem_mmap) ( new_mem_mmap );
-//zz
-//zz VG_(track_copy_mem_remap) ( copy_mem_remap );
-//zz VG_(track_change_mem_mprotect) ( NULL );
-//zz
-//zz VG_(track_die_mem_stack_signal) ( NULL );
-//zz VG_(track_die_mem_brk) ( die_mem_brk );
- VG_(track_die_mem_munmap) ( die_mem_munmap );
-
- VG_(track_pre_mem_read) ( pre_mem_access );
- VG_(track_pre_mem_read_asciiz) ( pre_mem_read_asciiz );
- VG_(track_pre_mem_write) ( pre_mem_access );
-//zz VG_(track_post_mem_write) ( post_mem_write );
-
- // Register events to track
-//zz VG_(track_post_regs_write_init) ( post_regs_write_init );
-//zz VG_(track_post_reg_write_syscall_return) ( post_reg_write_nonptr );
-//zz VG_(track_post_reg_write_deliver_signal) ( post_reg_write_nonptr_or_unknown );
-//zz VG_(track_post_reg_write_pthread_return) ( post_reg_write_nonptr_or_unknown );
-//zz VG_(track_post_reg_write_clientreq_return) ( post_reg_write_nonptr );
- VG_(track_post_reg_write_clientcall_return) ( post_reg_write_clientcall );
- VG_(track_post_reg_write)( post_reg_write_demux );
-
// Other initialisation
init_shadow_memory();
seglist = ISList__construct();
@@ -4758,7 +4272,7 @@
// above.
}
-static void pc_post_clo_init ( void )
+void h_post_clo_init ( void )
{
}
@@ -4766,9 +4280,9 @@
/*--- Finalisation ---*/
/*--------------------------------------------------------------------*/
-static void pc_fini ( Int exitcode )
+void h_fini ( Int exitcode )
{
- if (clo_lossage_check) {
+ if (h_clo_lossage_check) {
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg, "%12lld total memory references",
stats__tot_mem_refs);
@@ -4784,7 +4298,6 @@
}
}
-VG_DETERMINE_INTERFACE_VERSION(pc_pre_clo_init)
/*--------------------------------------------------------------------*/
/*--- end h_main.c ---*/
Added: branches/PTRCHECK/exp-ptrcheck/h_main.h
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/h_main.h (rev 0)
+++ branches/PTRCHECK/exp-ptrcheck/h_main.h 2008-09-09 08:35:09 UTC (rev 8589)
@@ -0,0 +1,84 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Ptrcheck: a pointer-use checker. ---*/
+/*--- Exports for heap access checking. ---*/
+/*--- h_main.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Ptrcheck, a Valgrind tool for checking pointer
+ use in programs.
+
+ Copyright (C) 2003-2008 Nicholas Nethercote
+ nj...@va...
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ in...@op...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __H_MAIN_H
+
+#define __H_MAIN_H
+
+// Choose values that couldn't possibly be pointers
+#define NONPTR ((Seg)0xA1)
+#define UNKNOWN ((Seg)0xB2)
+#define BOTTOM ((Seg)0xC3)
+
+static inline Bool is_known_segment(Seg seg) {
+ return (UNKNOWN != seg && BOTTOM != seg && NONPTR != seg);
+}
+
+void h_pre_clo_init ( void );
+void h_post_clo_init ( void );
+void h_fini ( Int exitcode );
+
+void* h_replace_malloc ( ThreadId tid, SizeT n );
+void* h_replace___builtin_new ( ThreadId tid, SizeT n );
+void* h_replace___builtin_vec_new ( ThreadId tid, SizeT n );
+void* h_replace_memalign ( ThreadId tid, SizeT align, SizeT n );
+void* h_replace_calloc ( ThreadId tid, SizeT nmemb, SizeT size1 );
+void h_replace_free ( ThreadId tid, void* p );
+void h_replace___builtin_delete ( ThreadId tid, void* p );
+void h_replace___builtin_vec_delete ( ThreadId tid, void* p );
+void* h_replace_realloc ( ThreadId tid, void* p_old, SizeT new_size );
+
+void h_new_mem_startup( Addr a, SizeT len,
+ Bool rr, Bool ww, Bool xx, ULong di_handle );
+void h_new_mem_mmap( Addr a, SizeT len,
+ Bool rr, Bool ww, Bool xx, ULong di_handle );
+void h_die_mem_munmap( Addr a, SizeT len );
+void h_pre_mem_access ( CorePart part, ThreadId tid, Char* s,
+ Addr base, SizeT size );
+void h_pre_mem_read_asciiz ( CorePart part, ThreadId tid,
+ Char* s, Addr lo );
+
+void h_post_reg_write_demux ( CorePart part, ThreadId tid,
+ OffT guest_state_offset, SizeT size);
+void h_post_reg_write_clientcall(ThreadId tid, OffT guest_state_offset,
+ SizeT size, Addr f );
+
+void h_pre_syscall ( ThreadId tid, UInt syscallno );
+void h_post_syscall ( ThreadId tid, UInt syscallno, SysRes res );
+
+#endif
+
+/*--------------------------------------------------------------------*/
+/*--- end h_main.h ---*/
+/*--------------------------------------------------------------------*/
Added: branches/PTRCHECK/exp-ptrcheck/pc_common.c
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/pc_common.c (rev 0)
+++ branches/PTRCHECK/exp-ptrcheck/pc_common.c 2008-09-09 08:35:09 UTC (rev 8589)
@@ -0,0 +1,544 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Ptrcheck: a pointer-use checker. ---*/
+/*--- Provides stuff shared between sg_ and h_ subtools. ---*/
+/*--- pc_common.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Ptrcheck, a Valgrind tool for checking pointer
+ use in programs.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ in...@op...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+
+ Neither the names of the U.S. Department of Energy nor the
+ University of California nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without prior written permission.
+*/
+
+#include "pub_tool_basics.h"
+#include "pub_tool_libcbase.h"
+#include "pub_tool_libcprint.h"
+#include "pub_tool_mallocfree.h"
+#include "pub_tool_libcassert.h"
+#include "pub_tool_options.h"
+#include "pub_tool_replacemalloc.h"
+#include "pub_tool_execontext.h"
+#include "pub_tool_tooliface.h" // CorePart
+#include "pub_tool_threadstate.h" // VG_(get_running_tid)
+#include "pub_tool_debuginfo.h"
+
+#include "h_list.h" // Seg
+#include "h_main.h" // NONPTR, BOTTOM, UNKNOWN
+
+#include "pc_common.h" // self
+
+
+//////////////////////////////////////////////////////////////
+// //
+// Command line options //
+// //
+//////////////////////////////////////////////////////////////
+
+Bool h_clo_partial_loads_ok = True; /* user visible */
+Bool h_clo_lossage_check = False; /* dev flag only */
+
+Bool pc_process_cmd_line_options(Char* arg)
+{
+ VG_BOOL_CLO(arg, "--partial-loads-ok", h_clo_partial_loads_ok)
+ else VG_BOOL_CLO(arg, "--lossage-check", h_clo_lossage_check)
+ else
+ return VG_(replacement_malloc_process_cmd_line_option)(arg);
+
+ return True;
+}
+
+void pc_print_usage(void)
+{
+ VG_(printf)(
+ " --partial-loads-ok=no|yes same as for Memcheck [yes]\n"
+ );
+ VG_(replacement_malloc_print_usage)();
+}
+
+void pc_print_debug_usage(void)
+{
+ VG_(printf)(
+ " --lossage-check=no|yes gather stats for quality control [no]\n"
+ );
+ VG_(replacement_malloc_print_debug_usage)();
+}
+
+
+
+//////////////////////////////////////////////////////////////
+// //
+// Error management //
+// //
+//////////////////////////////////////////////////////////////
+
+/* What kind of error it is. */
+typedef
+ enum {
+ XE_SorG=1202, // sg: stack or global array inconsistency
+ XE_Heap, // h: mismatched ptr/addr segments on load/store
+ XE_Arith, // h: bad arithmetic between two segment pointers
+ XE_SysParam // h: block straddling >1 segment passed to syscall
+ }
+ XErrorTag;
+
+typedef
+ enum {
+ XS_SorG=2021,
+ XS_Heap,
+ XS_Arith,
+ XS_SysParam
+ }
+ XSuppTag;
+
+typedef
+ struct {
+ XErrorTag tag;
+ union {
+ struct {
+ Addr addr;
+ SSizeT sszB; /* -ve is write, +ve is read */
+ HChar expect[128];
+ HChar actual[128];
+ } SorG;
+ struct {
+ Addr addr;
+ SSizeT sszB; /* -ve is write, +ve is read */
+ Seg vseg;
+ Char descr1[96];
+ Char descr2[96];
+ Char datasym[96];
+ OffT datasymoff;
+ } Heap;
+ struct {
+ Seg seg1;
+ Seg seg2;
+ const HChar* opname; // user-understandable text name
+ } Arith;
+ struct {
+ CorePart part;
+ Addr lo;
+ Addr hi;
+ Seg seglo;
+ Seg seghi;
+ } SysParam;
+ } XE;
+ }
+ XError;
+
+
+void sg_record_error_SorG ( ThreadId tid,
+ Addr addr, SSizeT sszB,
+ HChar* expect, HChar* actual )
+{
+ XError xe;
+ VG_(memset)(&xe, 0, sizeof(xe));
+ xe.XE.SorG.addr = addr;
+ xe.XE.SorG.sszB = sszB;
+ VG_(strncpy)( &xe.XE.SorG.expect[0],
+ expect, sizeof(xe.XE.SorG.expect) );
+ VG_(strncpy)( &xe.XE.SorG.actual[0],
+ actual, sizeof(xe.XE.SorG.actual) );
+ xe.XE.SorG.expect[ sizeof(xe.XE.SorG.expect)-1 ] = 0;
+ xe.XE.SorG.actual[ sizeof(xe.XE.SorG.actual)-1 ] = 0;
+ VG_(maybe_record_error)( tid, XE_SorG, 0, NULL, &xe );
+}
+
+void h_record_heap_error( Addr a, SizeT size, Seg vseg, Bool is_write )
+{
+ XError xe;
+ tl_assert(size > 0);
+ VG_(memset)(&xe, 0, sizeof(xe));
+ xe.tag = XE_Heap;
+ xe.XE.Heap.addr = a;
+ xe.XE.Heap.sszB = is_write ? -size : size;
+ xe.XE.Heap.vseg = vseg;
+ VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Heap,
+ /*a*/0, /*str*/NULL, /*extra*/(void*)&xe);
+}
+
+void h_record_arith_error( Seg seg1, Seg seg2, HChar* opname )
+{
+ XError xe;
+ VG_(memset)(&xe, 0, sizeof(xe));
+ xe.tag = XE_Arith;
+ xe.XE.Arith.seg1 = seg1;
+ xe.XE.Arith.seg2 = seg2;
+ xe.XE.Arith.opname = opname;
+ VG_(maybe_record_error)( VG_(get_running_tid)(), XE_Arith,
+ /*a*/0, /*str*/NULL, /*extra*/(void*)&xe);
+}
+
+void h_record_sysparam_error( ThreadId tid, CorePart part, Char* s,
+ Addr lo, Addr hi, Seg seglo, Seg seghi )
+{
+ XError xe;
+ VG_(memset)(&xe, 0, sizeof(xe));
+ xe.tag = XE_SysParam;
+ xe.XE.SysParam.part = part;
+ xe.XE.SysParam.lo = lo;
+ xe.XE.SysParam.hi = hi;
+ xe.XE.SysParam.seglo = seglo;
+ xe.XE.SysParam.seghi = seghi;
+ VG_(maybe_record_error)( tid, XE_SysParam, /*a*/(Addr)0, /*str*/s,
+ /*extra*/(void*)&xe);
+}
+
+
+Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 )
+{
+ XError *xe1, *xe2;
+ tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
+ tl_assert(VG_(get_error_string)(e1) == NULL);
+ tl_assert(VG_(get_error_string)(e2) == NULL);
+
+ xe1 = (XError*)VG_(get_error_extra)(e1);
+ xe2 = (XError*)VG_(get_error_extra)(e2);
+ tl_assert(xe1);
+ tl_assert(xe2);
+
+ if (xe1->tag != xe2->tag)
+ return False;
+
+ switch (xe1->tag) {
+ case XE_SorG:
+ return //xe1->XE.SorG.addr == xe2->XE.SorG.addr
+ //&&
+ xe1->XE.SorG.sszB == xe2->XE.SorG.sszB
+ && 0 == VG_(strncmp)( &xe1->XE.SorG.expect[0],
+ &xe2->XE.SorG.expect[0],
+ sizeof(xe1->XE.SorG.expect) )
+ && 0 == VG_(strncmp)( &xe1->XE.SorG.actual[0],
+ &xe2->XE.SorG.actual[0],
+ sizeof(xe1->XE.SorG.actual) );
+ case XE_Heap:
+ case XE_Arith:
+ case XE_SysParam:
+ return True;
+ default:
+ VG_(tool_panic)("eq_Error: unrecognised error kind");
+ }
+}
+
+
+static Char* readwrite(SSizeT sszB)
+{
+ return ( sszB < 0 ? "write" : "read" );
+}
+
+static Word Word__abs ( Word w ) {
+ return w < 0 ? -w : w;
+}
+
+void pc_pp_Error ( Error* err )
+{
+ XError *xe = (XError*)VG_(get_error_extra)(err);
+ tl_assert(xe);
+
+ switch (VG_(get_error_kind)(err)) {
+
+ //----------------------------------------------------------
+ case XE_SorG:
+ tl_assert(xe);
+ VG_(message)(Vg_UserMsg, "Invalid %s of size %ld",
+ xe->XE.SorG.sszB < 0 ? "write" : "read",
+ Word__abs(xe->XE.SorG.sszB) );
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+ VG_(message)(Vg_UserMsg, " Address %#lx expected vs actual:",
+ xe->XE.SorG.addr);
+ VG_(message)(Vg_UserMsg, " Expected: %s", &xe->XE.SorG.expect[0] );
+ VG_(message)(Vg_UserMsg, " Actual: %s", &xe->XE.SorG.actual[0] );
+ break;
+
+ //----------------------------------------------------------
+ case XE_Heap: {
+ Char *place, *legit, *how_invalid;
+ Addr a = xe->XE.Heap.addr;
+ Seg vseg = xe->XE.Heap.vseg;
+
+ tl_assert(is_known_segment(vseg) || NONPTR == vseg);
+
+ if (NONPTR == vseg) {
+ // Access via a non-pointer
+ VG_(message)(Vg_UserMsg, "Invalid %s of size %ld",
+ readwrite(xe->XE.Heap.sszB),
+ xe->XE.Heap.sszB);
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+ VG_(message)(Vg_UserMsg,
+ " Address %#lx is not derived from any known block", a);
+
+ } else {
+ // Access via a pointer, but outside its range.
+ Int cmp;
+ UWord miss_size;
+ Seg__cmp(vseg, a, &cmp, &miss_size);
+ if (cmp < 0) place = "before";
+ else if (cmp == 0) place = "inside";
+ else place = "after";
+ how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp )
+ ? "Doubly-invalid" : "Invalid" );
+ legit = ( Seg__is_freed(vseg) ? "once-" : "" );
+
+ VG_(message)(Vg_UserMsg, "%s %s of size %ld", how_invalid,
+ readwrite(xe->XE.Heap.sszB),
+ xe->XE.Heap.sszB);
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+
+ VG_(message)(Vg_UserMsg,
+ " Address %#lx is %lu bytes %s the accessing pointer's",
+ a, miss_size, place);
+ VG_(message)(Vg_UserMsg,
+ " %slegitimate range, a block of size %lu %s",
+ legit, Seg__size(vseg), Seg__status_str(vseg) );
+ VG_(pp_ExeContext)(Seg__where(vseg));
+ }
+ if (xe->XE.Heap.descr1[0] != 0)
+ VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr1);
+ if (xe->XE.Heap.descr2[0] != 0)
+ VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr2);
+ if (xe->XE.Heap.datasym[0] != 0)
+ VG_(message)(Vg_UserMsg, " Address 0x%llx is %llu bytes "
+ "inside data symbol \"%s\"",
+ (ULong)xe->XE.Heap.addr,
+ (ULong)xe->XE.Heap.datasymoff,
+ xe->XE.Heap.datasym);
+ break;
+ }
+
+ //----------------------------------------------------------
+ case XE_Arith: {
+ Seg seg1 = xe->XE.Arith.seg1;
+ Seg seg2 = xe->XE.Arith.seg2;
+ Char* which;
+
+ tl_assert(BOTTOM != seg1);
+ tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);
+
+ VG_(message)(Vg_UserMsg, "Invalid arguments to %s", xe->XE.Arith.opname);
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+
+ if (seg1 != seg2) {
+ if (NONPTR == seg1) {
+ VG_(message)(Vg_UserMsg, " First arg not a pointer");
+ } else if (UNKNOWN == seg1) {
+ VG_(message)(Vg_UserMsg, " First arg may be a pointer");
+ } else {
+ VG_(message)(Vg_UserMsg, " First arg derived from address %#lx of "
+ "%lu-byte block %s",
+ Seg__a(seg1), Seg__size(seg1),
+ Seg__status_str(seg1) );
+ VG_(pp_ExeContext)(Seg__where(seg1));
+ }
+ which = "Second arg";
+ } else {
+ which = "Both args";
+ }
+ if (NONPTR == seg2) {
+ VG_(message)(Vg_UserMsg, " %s not a pointer", which);
+ } else {
+ VG_(message)(Vg_UserMsg, " %s derived from address %#lx of "
+ "%lu-byte block %s",
+ which, Seg__a(seg2), Seg__size(seg2),
+ Seg__status_str(seg2));
+ VG_(pp_ExeContext)(Seg__where(seg2));
+ }
+ break;
+ }
+
+ //----------------------------------------------------------
+ case XE_SysParam: {
+ Addr lo = xe->XE.SysParam.lo;
+ Addr hi = xe->XE.SysParam.hi;
+ Seg seglo = xe->XE.SysParam.seglo;
+ Seg seghi = xe->XE.SysParam.seghi;
+ Char* s = VG_(get_error_string) (err);
+ Char* what;
+
+ tl_assert(BOTTOM != seglo && BOTTOM != seghi);
+
+ if (Vg_CoreSysCall == xe->XE.SysParam.part)
+ what = "Syscall param ";
+ else VG_(tool_panic)("bad CorePart");
+
+ if (seglo == seghi) {
+ // freed block
+ tl_assert(is_known_segment(seglo));
+ tl_assert(Seg__is_freed(seglo));
+ VG_(message)(Vg_UserMsg, "%s%s contains unaddressable byte(s)",
+ what, s);
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+
+ VG_(message)(Vg_UserMsg, " Address %#lx is %ld bytes inside a "
+ "%ld-byte block %s",
+ lo, lo-Seg__a(seglo), Seg__size(seglo),
+ Seg__status_str(seglo) );
+ VG_(pp_ExeContext)(Seg__where(seglo));
+
+ } else {
+ // mismatch
+ VG_(message)(Vg_UserMsg, "%s%s is non-contiguous", what, s);
+ VG_(pp_ExeContext)( VG_(get_error_where)(err) );
+
+ if (UNKNOWN == seglo) {
+ VG_(message)(Vg_UserMsg, " First byte is not inside a known block");
+ } else {
+ VG_(message)(Vg_UserMsg, " First byte (%#lx) is %ld bytes inside a "
+ "%ld-byte block %s",
+ lo, lo-Seg__a(seglo), Seg__size(seglo),
+ Seg__status_str(seglo) );
+ VG_(pp_ExeContext)(Seg__where(seglo));
+ }
+
+ if (UNKNOWN == seghi) {
+ VG_(message)(Vg_UserMsg, " Last byte is not inside a known block");
+ } else {
+ VG_(message)(Vg_UserMsg, " Last byte (%#lx) is %ld bytes inside a "
+ "%ld-byte block %s",
+ hi, hi-Seg__a(seghi), Seg__size(seghi),
+ Seg__status_str(seghi));
+ VG_(pp_ExeContext)(Seg__where(seghi));
+ }
+ }
+ break;
+ }
+
+ default:
+ VG_(tool_panic)("pp_Error: unrecognised error kind");
+ }
+}
+
+
+UInt pc_update_Error_extra ( Error* err )
+{
+ XError *xe = (XError*)VG_(get_error_extra)(err);
+ tl_assert(xe);
+ switch (xe->tag) {
+ case XE_SorG:
+ return sizeof(XError);
+ case XE_Heap: {
+ tl_assert(sizeof(xe->XE.Heap.descr1) == sizeof(xe->XE.Heap.descr2));
+ tl_assert(sizeof(xe->XE.Heap.descr1) > 0);
+ tl_assert(sizeof(xe->XE.Heap.datasym) > 0);
+ VG_(memset)(&xe->XE.Heap.descr1, 0, sizeof(xe->XE.Heap.descr1));
+ VG_(memset)(&xe->XE.Heap.descr2, 0, sizeof(xe->XE.Heap.descr2));
+ VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym));
+ xe->XE.Heap.datasymoff = 0;
+ if (VG_(get_data_description)( &xe->XE.Heap.descr1[0],
+ &xe->XE.Heap.descr2[0],
+ sizeof(xe->XE.Heap.descr1)-1,
+ xe->XE.Heap.addr )) {
+ tl_assert(xe->XE.Heap.descr1[sizeof(xe->XE.Heap.descr1)-1] == 0);
+ tl_assert(xe->XE.Heap.descr1[sizeof(xe->XE.Heap.descr2)-1] == 0);
+ }
+ else
+ if (VG_(get_datasym_and_offset)( xe->XE.Heap.addr,
+ &xe->XE.Heap.datasym[0],
+ sizeof(xe->XE.Heap.datasym)-1,
+ &xe->XE.Heap.datasymoff )) {
+ tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] == 0);
+ }
+ return sizeof(XError);
+ }
+ case XE_Arith:
+ return sizeof(XError);
+ case XE_SysParam:
+ return sizeof(XError);
+ default:
+ VG_(tool_panic)("update_extra");
+ }
+}
+
+Bool pc_is_recognised_suppression ( Char* name, Supp *su )
+{
+ SuppKind skind;
+
+ if (VG_STREQ(name, "SorG")) skind = XS_SorG;
+ else if (VG_STREQ(name, "Heap")) skind = XS_Heap;
+ else if (VG_STREQ(name, "Arith")) skind = XS_Arith;
+ else if (VG_STREQ(name, "SysParam")) skind = XS_SysParam;
+ else
+ return False;
+
+ VG_(set_supp_kind)(su, skind);
+ return True;
+}
+
+Bool pc_read_extra_suppression_info ( Int fd, Char* buf,
+ Int nBuf, Supp* su )
+{
+ Bool eof;
+ if (VG_(get_supp_kind)(su) == XS_SysParam) {
+ eof = VG_(get_line) ( fd, buf, nBuf );
+ if (eof) return False;
+ VG_(set_supp_string)(su, VG_(strdup)(buf));
+ }
+ return True;
+}
+
+Bool pc_error_matches_suppression (Error* err, Supp* su)
+{
+ ErrorKind ekind = VG_(get_error_kind)(err);
+ switch (VG_(get_supp_kind)(su)) {
+ case XS_SorG: return ekind == XE_SorG;
+ case XS_Heap: return ekind == XE_Heap;
+ case XS_Arith: return ekind == XE_Arith;
+ case XS_SysParam: return ekind == XE_SysParam;
+ default:
+ VG_(printf)("Error:\n"
+ " unknown suppression type %d\n",
+ VG_(get_supp_kind)(su));
+ VG_(tool_panic)("unknown suppression type in "
+ "pc_error_matches_suppression");
+ }
+}
+
+Char* pc_get_error_name ( Error* err )
+{
+ XError *xe = (XError*)VG_(get_error_extra)(err);
+ tl_assert(xe);
+ switch (xe->tag) {
+ case XE_SorG: return "SorG";
+ case XE_Heap: return "Heap";
+ case XE_Arith: return "Arith";
+ case XE_SysParam: return "SysParam";
+ default: VG_(tool_panic)("get_error_name: unexpected type");
+ }
+}
+
+void pc_print_extra_suppression_info ( Error* err )
+{
+ if (XE_SysParam == VG_(get_error_kind)(err)) {
+ VG_(printf)(" %s\n", VG_(get_error_string)(err));
+ }
+}
+
+
+
+
+/*--------------------------------------------------------------------*/
+/*--- end pc_common.c ---*/
+/*--------------------------------------------------------------------*/
Added: branches/PTRCHECK/exp-ptrcheck/pc_common.h
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/pc_common.h (rev 0)
+++ branches/PTRCHECK/exp-ptrcheck/pc_common.h 2008-09-09 08:35:09 UTC (rev 8589)
@@ -0,0 +1,70 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Ptrcheck: a pointer-use checker. ---*/
+/*--- Exports for stuff shared between sg_ and h_ subtools. ---*/
+/*--- pc_common.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Ptrcheck, a Valgrind tool for checking pointer
+ use in programs.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ in...@op...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PC_COMMON_H
+
+#define __PC_COMMON_H
+
+void sg_record_error_SorG ( ThreadId tid,
+ Addr addr, SSizeT sszB,
+ HChar* expect, HChar* actual );
+
+void h_record_heap_error( Addr a, SizeT size, Seg vseg, Bool is_write );
+
+void h_record_arith_error( Seg seg1, Seg seg2, HChar* opname );
+
+void h_record_sysparam_error( ThreadId tid, CorePart part, Char* s,
+ Addr lo, Addr hi, Seg seglo, Seg seghi );
+
+Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 );
+void pc_pp_Error ( Error* err );
+UInt pc_update_Error_extra ( Error* err );
+Bool pc_is_recognised_suppression ( Char* name, Supp *su );
+Bool pc_read_extra_suppression_info ( Int fd, Char* buf,
+ Int nBuf, Supp* su );
+Bool pc_error_matches_suppression (Error* err, Supp* su);
+Char* pc_get_error_name ( Error* err );
+void pc_print_extra_suppression_info ( Error* err );
+
+extern Bool h_clo_partial_loads_ok;
+extern Bool h_clo_lossage_check;
+
+Bool pc_process_cmd_line_options(Char* arg);
+void pc_print_usage(void);
+void pc_print_debug_usage(void);
+
+
+#endif
+
+/*--------------------------------------------------------------------*/
+/*--- end pc_common.h ---*/
+/*--------------------------------------------------------------------*/
Added: branches/PTRCHECK/exp-ptrcheck/pc_main.c
===================================================================
--- branches/PTRCHECK/exp-ptrcheck/pc_main.c (rev 0)
+++ branches/PTRCHECK/exp-ptrcheck/pc_main.c 2008-09-09 08:35:09 UTC (rev 8589)
@@ -0,0 +1,207 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Ptrcheck: a pointer-use checker. ---*/
+/*--- This file coordinates the h_ and sg_ subtools. ---*/
+/*--- pc_main.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Ptrcheck, a Valgrind tool for checking pointer
+ use in programs.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ in...@op...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+
+ Neither the names of the U.S. Department of Energy nor the
+ University of California nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without prior written permission.
+*/
+
+#include "pub_tool_basics.h"
+#include "pub_tool_libcassert.h"
+#include "pub_tool_execontext.h"
+#include "pub_tool_toolifa...
[truncated message content] |