summaryrefslogtreecommitdiff
path: root/coregrind/m_replacemalloc/.svn
diff options
context:
space:
mode:
Diffstat (limited to 'coregrind/m_replacemalloc/.svn')
-rw-r--r--coregrind/m_replacemalloc/.svn/dir-prop-base9
-rw-r--r--coregrind/m_replacemalloc/.svn/entries52
-rw-r--r--coregrind/m_replacemalloc/.svn/format1
-rw-r--r--coregrind/m_replacemalloc/.svn/text-base/replacemalloc_core.c.svn-base118
-rw-r--r--coregrind/m_replacemalloc/.svn/text-base/vg_replace_malloc.c.svn-base643
5 files changed, 823 insertions, 0 deletions
diff --git a/coregrind/m_replacemalloc/.svn/dir-prop-base b/coregrind/m_replacemalloc/.svn/dir-prop-base
new file mode 100644
index 0000000..67452d4
--- /dev/null
+++ b/coregrind/m_replacemalloc/.svn/dir-prop-base
@@ -0,0 +1,9 @@
+K 10
+svn:ignore
+V 31
+*.a
+.deps
+Makefile
+Makefile.in
+
+END
diff --git a/coregrind/m_replacemalloc/.svn/entries b/coregrind/m_replacemalloc/.svn/entries
new file mode 100644
index 0000000..e9dd2ec
--- /dev/null
+++ b/coregrind/m_replacemalloc/.svn/entries
@@ -0,0 +1,52 @@
+8
+
+dir
+9703
+svn://svn.valgrind.org/valgrind/trunk/coregrind/m_replacemalloc
+svn://svn.valgrind.org/valgrind
+
+
+
+2009-03-15T23:25:38.213170Z
+9416
+njn
+has-props
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+a5019735-40e9-0310-863c-91ae7b9d1cf9
+
+vg_replace_malloc.c
+file
+
+
+
+
+2009-04-30T16:44:03.000000Z
+668390256967085938a92b45f269e8ba
+2009-03-15T23:25:38.213170Z
+9416
+njn
+
+replacemalloc_core.c
+file
+
+
+
+
+2009-03-13T17:30:22.000000Z
+9398a475146fb7a1371b9f917e1d2691
+2009-03-10T22:02:09.669944Z
+9344
+njn
+
diff --git a/coregrind/m_replacemalloc/.svn/format b/coregrind/m_replacemalloc/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/coregrind/m_replacemalloc/.svn/format
@@ -0,0 +1 @@
+8
diff --git a/coregrind/m_replacemalloc/.svn/text-base/replacemalloc_core.c.svn-base b/coregrind/m_replacemalloc/.svn/text-base/replacemalloc_core.c.svn-base
new file mode 100644
index 0000000..fbae2bc
--- /dev/null
+++ b/coregrind/m_replacemalloc/.svn/text-base/replacemalloc_core.c.svn-base
@@ -0,0 +1,118 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Malloc replacement. replacemalloc_core.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2009 Julian Seward
+ jseward@acm.org
+
+ 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.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_mallocfree.h"
+#include "pub_core_options.h"
+#include "pub_core_replacemalloc.h"
+
+/*------------------------------------------------------------*/
+/*--- Command line options ---*/
+/*------------------------------------------------------------*/
+
+/* Nb: the allocator always rounds blocks up to a multiple of
+ VG_MIN_MALLOC_SZB.
+*/
+
+/* DEBUG: print malloc details? default: NO */
+Bool VG_(clo_trace_malloc) = False;
+
+/* Minimum alignment in functions that don't specify alignment explicitly.
+ default: 0, i.e. use VG_MIN_MALLOC_SZB. */
+UInt VG_(clo_alignment) = VG_MIN_MALLOC_SZB;
+
+
+Bool VG_(replacement_malloc_process_cmd_line_option)(Char* arg)
+{
+ if VG_INT_CLO(arg, "--alignment", VG_(clo_alignment)) {
+ if (VG_(clo_alignment) < VG_MIN_MALLOC_SZB ||
+ VG_(clo_alignment) > 4096 ||
+ VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */)
+ {
+ VG_(message)(Vg_UserMsg,
+ "Invalid --alignment= setting. "
+ "Should be a power of 2, >= %d, <= 4096.", VG_MIN_MALLOC_SZB);
+ VG_(err_bad_option)("--alignment");
+ }
+ }
+
+ else if VG_BOOL_CLO(arg, "--trace-malloc", VG_(clo_trace_malloc)) {}
+ else
+ return False;
+
+ return True;
+}
+
+void VG_(replacement_malloc_print_usage)(void)
+{
+ VG_(printf)(
+" --alignment=<number> set minimum alignment of allocations [%d]\n",
+ VG_MIN_MALLOC_SZB
+ );
+}
+
+void VG_(replacement_malloc_print_debug_usage)(void)
+{
+ VG_(printf)(
+" --trace-malloc=no|yes show client malloc details? [no]\n"
+ );
+}
+
+/*------------------------------------------------------------*/
+/*--- Useful functions ---*/
+/*------------------------------------------------------------*/
+
+void* VG_(cli_malloc) ( SizeT align, SizeT nbytes )
+{
+ // 'align' should be valid (ie. big enough and a power of two) by now.
+ // VG_(arena_memalign)() will abort if it's not.
+ if (VG_MIN_MALLOC_SZB == align)
+ return VG_(arena_malloc) ( VG_AR_CLIENT, "replacemalloc.cm.1",
+ nbytes );
+ else
+ return VG_(arena_memalign) ( VG_AR_CLIENT, "replacemalloc.cm.2",
+ align, nbytes );
+}
+
+void VG_(cli_free) ( void* p )
+{
+ VG_(arena_free) ( VG_AR_CLIENT, p );
+}
+
+Bool VG_(addr_is_in_block)( Addr a, Addr start, SizeT size, SizeT rz_szB )
+{
+ return ( start - rz_szB <= a && a < start + size + rz_szB );
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_replacemalloc/.svn/text-base/vg_replace_malloc.c.svn-base b/coregrind/m_replacemalloc/.svn/text-base/vg_replace_malloc.c.svn-base
new file mode 100644
index 0000000..3de33f9
--- /dev/null
+++ b/coregrind/m_replacemalloc/.svn/text-base/vg_replace_malloc.c.svn-base
@@ -0,0 +1,643 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Replacements for malloc() et al, which run on the simulated ---*/
+/*--- CPU. vg_replace_malloc.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2009 Julian Seward
+ jseward@acm.org
+
+ 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.
+*/
+
+/* ---------------------------------------------------------------------
+ ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
+
+ These functions are drop-in replacements for malloc() and friends.
+ They have global scope, but are not intended to be called directly.
+ See pub_core_redir.h for the gory details.
+
+ This file can be linked into the vg_preload_<tool>.so file for any tool
+ that wishes to know about calls to malloc(). The tool must define all
+ the functions that will be called via 'info'.
+
+ It is called vg_replace_malloc.c because this filename appears in stack
+ traces, so we want the name to be (hopefully!) meaningful to users.
+ ------------------------------------------------------------------ */
+
+#include "pub_core_basics.h"
+#include "pub_core_vki.h" // VKI_EINVAL, VKI_ENOMEM
+#include "pub_core_clreq.h" // for VALGRIND_INTERNAL_PRINTF,
+ // VALGRIND_NON_SIMD_CALL[12]
+#include "pub_core_debuginfo.h" // needed for pub_core_redir.h :(
+#include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
+#include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_*
+#include "pub_core_replacemalloc.h"
+
+
+/* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
+ mangling, could be supported properly by the redirects in this
+ module. Except we can't because it doesn't put its allocation
+ functions in libpgc.so but instead hardwires them into the
+ compilation unit holding main(), which makes them impossible to
+ intercept directly. Fortunately those fns seem to route everything
+ through to malloc/free.
+
+ mid-06: could be improved, since we can now intercept in the main
+ executable too.
+*/
+
+__attribute__ ((__noreturn__))
+extern void _exit(int);
+
+/* Apparently it is necessary to make ourselves free of any dependency
+ on memcpy() on ppc32-aix5; else programs linked with -brtl fail.
+ memcpy() is used by gcc for a struct assignment in mallinfo()
+ below. Add the following conservative implementation (memmove,
+ really). */
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+__attribute__((weak))
+void *memcpy(void *destV, const void *srcV, unsigned long n)
+{
+ unsigned char* src = (unsigned char*)srcV;
+ unsigned char* dest = (unsigned char*)destV;
+ unsigned long i;
+ if (dest < src) {
+ for (i = 0; i < n; i++)
+ dest[i] = src[i];
+ }
+ if (dest > src) {
+ for (i = n; i > 0; i--)
+ dest[i-1] = src[i-1];
+ }
+ return dest;
+}
+#endif
+
+
+/*------------------------------------------------------------*/
+/*--- Replacing malloc() et al ---*/
+/*------------------------------------------------------------*/
+
+/* This struct is initially empty. Before the first use of any of
+ these functions, we make a client request which fills in the
+ fields.
+*/
+static struct vg_mallocfunc_info info;
+static int init_done;
+
+/* Startup hook - called as init section */
+static void init(void) __attribute__((constructor));
+
+#define MALLOC_TRACE(format, args...) \
+ if (info.clo_trace_malloc) \
+ VALGRIND_INTERNAL_PRINTF(format, ## args )
+
+/* Below are new versions of malloc, __builtin_new, free,
+ __builtin_delete, calloc, realloc, memalign, and friends.
+
+ None of these functions are called directly - they are not meant to
+ be found by the dynamic linker. But ALL client calls to malloc()
+ and friends wind up here eventually. They get called because
+ vg_replace_malloc installs a bunch of code redirects which causes
+ Valgrind to use these functions rather than the ones they're
+ replacing.
+*/
+
+
+/*---------------------- malloc ----------------------*/
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to allocate memory. If that fails, return NULL.
+*/
+#define ALLOC_or_NULL(soname, fnname, vg_replacement) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
+ { \
+ void* v; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
+ \
+ v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
+ MALLOC_TRACE(" = %p", v ); \
+ return v; \
+ }
+
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to allocate memory. If that fails, it bombs the
+ system.
+*/
+#define ALLOC_or_BOMB(soname, fnname, vg_replacement) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n) \
+ { \
+ void* v; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
+ \
+ v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
+ MALLOC_TRACE(" = %p", v ); \
+ if (NULL == v) { \
+ VALGRIND_PRINTF_BACKTRACE( \
+ "new/new[] failed and should throw an exception, but Valgrind\n" \
+ " cannot throw exceptions and so is aborting instead. Sorry."); \
+ _exit(1); \
+ } \
+ return v; \
+ }
+
+// Each of these lines generates a replacement function:
+// (from_so, from_fn, v's replacement)
+
+// malloc
+ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
+ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_common, malloc);
+#endif
+
+
+/*---------------------- new ----------------------*/
+
+// operator new(unsigned int), not mangled (for gcc 2.96)
+ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, builtin_new, __builtin_new);
+ALLOC_or_BOMB(VG_Z_LIBC_SONAME, builtin_new, __builtin_new);
+
+ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_new, __builtin_new);
+ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_new, __builtin_new);
+
+// operator new(unsigned int), GNU mangling
+#if VG_WORDSIZE == 4
+ ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
+ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
+#endif
+
+// operator new(unsigned long), GNU mangling
+#if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5)
+ ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
+ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
+#endif
+
+// operator new(unsigned long), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __nw__FUl, __builtin_new);
+#endif
+
+
+/*---------------------- new nothrow ----------------------*/
+
+// operator new(unsigned, std::nothrow_t const&), GNU mangling
+#if VG_WORDSIZE == 4
+ ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
+ ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
+#endif
+
+// operator new(unsigned long, std::nothrow_t const&), GNU mangling
+#if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
+ ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
+#endif
+
+// operator new(unsigned long, std::nothrow_t const&), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_NULL(VG_Z_LIBC_DOT_A, __nw__FUlRCQ2_3std9nothrow_t, __builtin_new);
+#endif
+
+
+/*---------------------- new [] ----------------------*/
+
+// operator new[](unsigned int), not mangled (for gcc 2.96)
+ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_new, __builtin_vec_new );
+ALLOC_or_BOMB(VG_Z_LIBC_SONAME, __builtin_vec_new, __builtin_vec_new );
+
+// operator new[](unsigned int), GNU mangling
+#if VG_WORDSIZE == 4
+ ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
+ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
+#endif
+
+// operator new[](unsigned long), GNU mangling
+#if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
+ ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
+#endif
+
+// operator new[](unsigned long), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __vn__FUl, __builtin_vec_new);
+#endif
+
+
+/*---------------------- new [] nothrow ----------------------*/
+
+// operator new[](unsigned, std::nothrow_t const&), GNU mangling
+#if VG_WORDSIZE == 4
+ ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
+ ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
+#endif
+
+// operator new[](unsigned long, std::nothrow_t const&), GNU mangling
+#if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
+ ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
+#endif
+
+// operator new [](unsigned long, std::nothrow_t const&), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ ALLOC_or_BOMB(VG_Z_LIBC_DOT_A, __vn__FUlRCQ2_3std9nothrow_t, __builtin_vec_new );
+#endif
+
+
+/*---------------------- free ----------------------*/
+
+/* Generate a replacement for 'fnname' in object 'soname', which calls
+ 'vg_replacement' to free previously allocated memory.
+*/
+#define FREE(soname, fnname, vg_replacement) \
+ \
+ void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p); \
+ void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p) \
+ { \
+ if (!init_done) init(); \
+ MALLOC_TRACE(#vg_replacement "(%p)", p ); \
+ if (p == NULL) \
+ return; \
+ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
+ }
+
+// free
+FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
+FREE(VG_Z_LIBC_SONAME, free, free );
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+FREE(VG_Z_LIBC_SONAME, free_common, free );
+#endif
+
+
+/*---------------------- cfree ----------------------*/
+
+// cfree
+FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
+FREE(VG_Z_LIBC_SONAME, cfree, free );
+
+
+/*---------------------- delete ----------------------*/
+// operator delete(void*), not mangled (for gcc 2.96)
+FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_delete, __builtin_delete );
+FREE(VG_Z_LIBC_SONAME, __builtin_delete, __builtin_delete );
+
+// operator delete(void*), GNU mangling
+FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
+FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
+
+// operator delete(void*), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+FREE(VG_Z_LIBC_DOT_A, __dl__FPv, __builtin_delete );
+#endif
+
+
+/*---------------------- delete nothrow ----------------------*/
+
+// operator delete(void*, std::nothrow_t const&), GNU mangling
+FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+
+
+/*---------------------- delete [] ----------------------*/
+// operator delete[](void*), not mangled (for gcc 2.96)
+FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
+FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
+
+// operator delete[](void*), GNU mangling
+FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
+FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
+
+// operator delete[](void*), ARM/cfront mangling
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+FREE(VG_Z_LIBC_DOT_A, __vd__FPv, __builtin_vec_delete );
+#endif
+
+
+/*---------------------- delete [] nothrow ----------------------*/
+
+// operator delete[](void*, std::nothrow_t const&), GNU mangling
+FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
+FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
+
+
+/*---------------------- calloc ----------------------*/
+
+#define CALLOC(soname, fnname) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ) \
+ { \
+ void* v; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
+ \
+ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
+ MALLOC_TRACE(" = %p", v ); \
+ return v; \
+ }
+
+CALLOC(VG_Z_LIBC_SONAME, calloc);
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+CALLOC(VG_Z_LIBC_SONAME, calloc_common);
+#endif
+
+
+/*---------------------- realloc ----------------------*/
+
+#define REALLOC(soname, fnname) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size );\
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size ) \
+ { \
+ void* v; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
+ \
+ if (ptrV == NULL) \
+ /* We need to call a malloc-like function; so let's use \
+ one which we know exists. */ \
+ return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
+ if (new_size <= 0) { \
+ VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
+ MALLOC_TRACE(" = 0"); \
+ return NULL; \
+ } \
+ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
+ MALLOC_TRACE(" = %p", v ); \
+ return v; \
+ }
+
+REALLOC(VG_Z_LIBC_SONAME, realloc);
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+REALLOC(VG_Z_LIBC_SONAME, realloc_common);
+#endif
+
+
+/*---------------------- memalign ----------------------*/
+
+#define MEMALIGN(soname, fnname) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ) \
+ { \
+ void* v; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE("memalign(al %llu, size %llu)", \
+ (ULong)alignment, (ULong)n ); \
+ \
+ /* Round up to minimum alignment if necessary. */ \
+ if (alignment < VG_MIN_MALLOC_SZB) \
+ alignment = VG_MIN_MALLOC_SZB; \
+ \
+ /* Round up to nearest power-of-two if necessary (like glibc). */ \
+ while (0 != (alignment & (alignment - 1))) alignment++; \
+ \
+ v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
+ MALLOC_TRACE(" = %p", v ); \
+ return v; \
+ }
+
+MEMALIGN(VG_Z_LIBC_SONAME, memalign);
+
+
+/*---------------------- valloc ----------------------*/
+
+static int local__getpagesize ( void ) {
+# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ return 4096; /* kludge - toc problems prevent calling getpagesize() */
+# else
+ extern int getpagesize (void);
+ return getpagesize();
+# endif
+}
+
+#define VALLOC(soname, fnname) \
+ \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
+ void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ) \
+ { \
+ static int pszB = 0; \
+ if (pszB == 0) \
+ pszB = local__getpagesize(); \
+ return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
+ ((SizeT)pszB, size); \
+ }
+
+VALLOC(VG_Z_LIBC_SONAME, valloc);
+
+
+/*---------------------- mallopt ----------------------*/
+
+/* Various compatibility wrapper functions, for glibc and libstdc++. */
+
+#define MALLOPT(soname, fnname) \
+ \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ); \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ) \
+ { \
+ /* In glibc-2.2.4, 1 denotes a successful return value for \
+ mallopt */ \
+ return 1; \
+ }
+
+MALLOPT(VG_Z_LIBC_SONAME, mallopt);
+
+
+/*---------------------- malloc_trim ----------------------*/
+// Documentation says:
+// malloc_trim(size_t pad);
+//
+// If possible, gives memory back to the system (via negative arguments to
+// sbrk) if there is unused memory at the `high' end of the malloc pool.
+// You can call this after freeing large blocks of memory to potentially
+// reduce the system-level memory requirements of a program. However, it
+// cannot guarantee to reduce memory. Under some allocation patterns,
+// some large free blocks of memory will be locked between two used
+// chunks, so they cannot be given back to the system.
+//
+// The `pad' argument to malloc_trim represents the amount of free
+// trailing space to leave untrimmed. If this argument is zero, only the
+// minimum amount of memory to maintain internal data structures will be
+// left (one page or less). Non-zero arguments can be supplied to maintain
+// enough trailing space to service future expected allocations without
+// having to re-obtain memory from the system.
+//
+// Malloc_trim returns 1 if it actually released any memory, else 0. On
+// systems that do not support "negative sbrks", it will always return 0.
+//
+// For simplicity, we always return 0.
+#define MALLOC_TRIM(soname, fnname) \
+ \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ); \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ) \
+ { \
+ /* 0 denotes that malloc_trim() either wasn't able \
+ to do anything, or was not implemented */ \
+ return 0; \
+ }
+
+MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
+
+
+/*---------------------- posix_memalign ----------------------*/
+
+#define POSIX_MEMALIGN(soname, fnname) \
+ \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
+ SizeT alignment, SizeT size ); \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
+ SizeT alignment, SizeT size ) \
+ { \
+ void *mem; \
+ \
+ /* Test whether the alignment argument is valid. It must be \
+ a power of two multiple of sizeof (void *). */ \
+ if (alignment % sizeof (void *) != 0 \
+ || (alignment & (alignment - 1)) != 0) \
+ return VKI_EINVAL; \
+ \
+ mem = VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign)(alignment, size); \
+ \
+ if (mem != NULL) { \
+ *memptr = mem; \
+ return 0; \
+ } \
+ \
+ return VKI_ENOMEM; \
+ }
+
+POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
+#if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+/* 27 Nov 07: it appears that xlc links into executables, a
+ posix_memalign, which calls onwards to memalign_common, with the
+ same args. */
+POSIX_MEMALIGN(VG_Z_LIBC_SONAME, memalign_common);
+#endif
+
+
+/*---------------------- malloc_usable_size ----------------------*/
+
+#define MALLOC_USABLE_SIZE(soname, fnname) \
+ \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ); \
+ int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ) \
+ { \
+ SizeT pszB; \
+ \
+ if (!init_done) init(); \
+ MALLOC_TRACE("malloc_usable_size(%p)", p ); \
+ if (NULL == p) \
+ return 0; \
+ \
+ pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
+ MALLOC_TRACE(" = %llu", (ULong)pszB ); \
+ \
+ return pszB; \
+ }
+
+MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
+
+
+/*---------------------- (unimplemented) ----------------------*/
+
+/* Bomb out if we get any of these. */
+
+static void panic(const char *str)
+{
+ VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s", str);
+ _exit(99);
+ *(int *)0 = 'x';
+}
+
+#define PANIC(soname, fnname) \
+ \
+ void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ { \
+ panic(#fnname); \
+ }
+
+PANIC(VG_Z_LIBC_SONAME, pvalloc);
+PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
+PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
+
+#define MALLOC_STATS(soname, fnname) \
+ \
+ void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
+ void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ { \
+ /* Valgrind's malloc_stats implementation does nothing. */ \
+ }
+
+MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
+
+
+/*---------------------- mallinfo ----------------------*/
+
+// mi must be static; if it is auto then Memcheck thinks it is
+// uninitialised when used by the caller of this function, because Memcheck
+// doesn't know that the call to mallinfo fills in mi.
+#define MALLINFO(soname, fnname) \
+ \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
+ struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ) \
+ { \
+ static struct vg_mallinfo mi; \
+ if (!init_done) init(); \
+ MALLOC_TRACE("mallinfo()"); \
+ (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
+ return mi; \
+ }
+
+MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
+
+
+/* All the code in here is unused until this function is called */
+
+static void init(void)
+{
+ int res;
+
+ if (init_done)
+ return;
+
+ init_done = 1;
+
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
+ 0, 0, 0, 0);
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end vg_replace_malloc.c ---*/
+/*--------------------------------------------------------------------*/