In the core, include malloc_usable_size() as one of the functions that must
be replaced if malloc() et al are replaced by a tool.  This is because
different tools implement the function in different ways.

Add an appropriate malloc_usable_size() replacement to each of Memcheck,
Helgrind, DRD, Ptrcheck, Massif.

Update memcheck/tests/malloc_usable and add massif/tests/malloc_usable.

Merged from the DARWIN branch.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9193 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index f9108a8..ddc441b 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -121,6 +121,7 @@
 void  MC_(__builtin_delete)     ( ThreadId tid, void* p );
 void  MC_(__builtin_vec_delete) ( ThreadId tid, void* p );
 void* MC_(realloc)              ( ThreadId tid, void* p, SizeT new_size );
+SizeT MC_(malloc_usable_size)   ( ThreadId tid, void* p );
 
 
 /*------------------------------------------------------------*/
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index fe3941a..6363e92 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -5711,6 +5711,7 @@
                                    MC_(__builtin_delete),
                                    MC_(__builtin_vec_delete),
                                    MC_(realloc),
+                                   MC_(malloc_usable_size), 
                                    MC_MALLOC_REDZONE_SZB );
    VG_(needs_xml_output)          ();
 
diff --git a/memcheck/mc_malloc_wrappers.c b/memcheck/mc_malloc_wrappers.c
index e2a9eae..a37288a 100644
--- a/memcheck/mc_malloc_wrappers.c
+++ b/memcheck/mc_malloc_wrappers.c
@@ -483,6 +483,15 @@
    return p_new;
 }
 
+SizeT MC_(malloc_usable_size) ( ThreadId tid, void* p )
+{
+   MC_Chunk* mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)p );
+
+   // There may be slop, but pretend there isn't because only the asked-for
+   // area will be marked as addressable.
+   return ( mc ? mc->szB : 0 );
+}
+
 /* Memory pool stuff. */
 
 void MC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed)
diff --git a/memcheck/tests/malloc_usable.c b/memcheck/tests/malloc_usable.c
index a42a5a5..8055c95 100644
--- a/memcheck/tests/malloc_usable.c
+++ b/memcheck/tests/malloc_usable.c
@@ -5,10 +5,16 @@
 
 int main(void)
 {
-   // Since our allocations are in multiples of 8, 99 will round up to 104.
+   // Because Memcheck marks any slop as inaccessible, it doesn't round up
+   // sizes for malloc_usable_size().
    int* x = malloc(99);
+
+   // DDD: would be better to have a HAVE_MALLOC_USABLE_SIZE variable here
 #  if !defined(_AIX)
-   assert(104 == malloc_usable_size(x));
+   assert(99 == malloc_usable_size(x));
+   assert( 0 == malloc_usable_size(NULL));
+   assert( 0 == malloc_usable_size((void*)0xdeadbeef));
 #  endif
+
    return 0;
 }