Home | History | Annotate | Download | only in m_replacemalloc
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Replacements for malloc() et al, which run on the simulated  ---*/
      4 /*--- CPU.                                     vg_replace_malloc.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2011 Julian Seward
     12       jseward (at) acm.org
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 /* ---------------------------------------------------------------------
     33    ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
     34 
     35    These functions are drop-in replacements for malloc() and friends.
     36    They have global scope, but are not intended to be called directly.
     37    See pub_core_redir.h for the gory details.
     38 
     39    This file can be linked into the vg_preload_<tool>.so file for any tool
     40    that wishes to know about calls to malloc().  The tool must define all
     41    the functions that will be called via 'info'.
     42 
     43    It is called vg_replace_malloc.c because this filename appears in stack
     44    traces, so we want the name to be (hopefully!) meaningful to users.
     45 
     46    IMPORTANT: this file must not contain any floating point code, nor
     47    any integer division.  This is because on ARM these can cause calls
     48    to helper functions, which will be unresolved within this .so.
     49    Although it is usually the case that the client's ld.so instance
     50    can bind them at runtime to the relevant functions in the client
     51    executable, there is no guarantee of this; and so the client may
     52    die via a runtime link failure.  Hence the only safe approach is to
     53    avoid such function calls in the first place.  See "#define CALLOC"
     54    below for a specific example.
     55 
     56    A useful command is
     57       for f in `find . -name "*preload*.so*"` ; \
     58           do nm -A $f | grep " U " ; \
     59       done
     60 
     61    to see all the undefined symbols in all the preload shared objects.
     62    ------------------------------------------------------------------ */
     63 
     64 #include "pub_core_basics.h"
     65 #include "pub_core_vki.h"           // VKI_EINVAL, VKI_ENOMEM
     66 #include "pub_core_clreq.h"         // for VALGRIND_INTERNAL_PRINTF,
     67                                     //   VALGRIND_NON_SIMD_CALL[12]
     68 #include "pub_core_debuginfo.h"     // needed for pub_core_redir.h :(
     69 #include "pub_core_mallocfree.h"    // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT
     70 #include "pub_core_redir.h"         // for VG_REPLACE_FUNCTION_*
     71 #include "pub_core_replacemalloc.h"
     72 
     73 /* Assignment of behavioural equivalence class tags: 1NNNP is intended
     74    to be reserved for the Valgrind core.  Current usage:
     75 
     76    10010 ALLOC_or_NULL
     77    10020 ZONEALLOC_or_NULL
     78    10030 ALLOC_or_BOMB
     79    10040 ZONEFREE
     80    10050 FREE
     81    10060 ZONECALLOC
     82    10070 CALLOC
     83    10080 ZONEREALLOC
     84    10090 REALLOC
     85    10100 ZONEMEMALIGN
     86    10110 MEMALIGN
     87    10120 VALLOC
     88    10130 ZONEVALLOC
     89    10140 MALLOPT
     90    10150 MALLOC_TRIM
     91    10160 POSIX_MEMALIGN
     92    10170 MALLOC_USABLE_SIZE
     93    10180 PANIC
     94    10190 MALLOC_STATS
     95    10200 MALLINFO
     96    10210 DEFAULT_ZONE
     97    10220 ZONE_CHECK
     98 */
     99 
    100 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
    101    mangling, could be supported properly by the redirects in this
    102    module.  Except we can't because it doesn't put its allocation
    103    functions in libpgc.so but instead hardwires them into the
    104    compilation unit holding main(), which makes them impossible to
    105    intercept directly.  Fortunately those fns seem to route everything
    106    through to malloc/free.
    107 
    108    mid-06: could be improved, since we can now intercept in the main
    109    executable too.
    110 */
    111 
    112 
    113 
    114 /* Call here to exit if we can't continue.  On Android we can't call
    115    _exit for some reason, so we have to blunt-instrument it. */
    116 __attribute__ ((__noreturn__))
    117 static inline void my_exit ( int x )
    118 {
    119 #  if defined(VGPV_arm_linux_android)
    120    __asm__ __volatile__(".word 0xFFFFFFFF");
    121    while (1) {}
    122 #  else
    123    extern __attribute__ ((__noreturn__)) void _exit(int status);
    124    _exit(x);
    125 #  endif
    126 }
    127 
    128 /* Same problem with getpagesize. */
    129 static inline int my_getpagesize ( void )
    130 {
    131 #  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    132    return 4096; /* kludge - link failure on Android, for some reason */
    133 #  else
    134    extern int getpagesize (void);
    135    return getpagesize();
    136 #  endif
    137 }
    138 
    139 
    140 /* Compute the high word of the double-length unsigned product of U
    141    and V.  This is for calloc argument overflow checking; see comments
    142    below.  Algorithm as described in Hacker's Delight, chapter 8. */
    143 static UWord umulHW ( UWord u, UWord v )
    144 {
    145    UWord u0, v0, w0, rHi;
    146    UWord u1, v1, w1,w2,t;
    147    UWord halfMask  = sizeof(UWord)==4 ? (UWord)0xFFFF
    148                                       : (UWord)0xFFFFFFFFULL;
    149    UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
    150    u0  = u & halfMask;
    151    u1  = u >> halfShift;
    152    v0  = v & halfMask;
    153    v1  = v >> halfShift;
    154    w0  = u0 * v0;
    155    t   = u1 * v0 + (w0 >> halfShift);
    156    w1  = t & halfMask;
    157    w2  = t >> halfShift;
    158    w1  = u0 * v1 + w1;
    159    rHi = u1 * v1 + w2 + (w1 >> halfShift);
    160    return rHi;
    161 }
    162 
    163 
    164 /*------------------------------------------------------------*/
    165 /*--- Replacing malloc() et al                             ---*/
    166 /*------------------------------------------------------------*/
    167 
    168 /* This struct is initially empty.  Before the first use of any of
    169    these functions, we make a client request which fills in the
    170    fields.
    171 */
    172 static struct vg_mallocfunc_info info;
    173 static int init_done;
    174 
    175 /* Startup hook - called as init section */
    176 __attribute__((constructor))
    177 static void init(void);
    178 
    179 #define MALLOC_TRACE(format, args...)  \
    180    if (info.clo_trace_malloc) {        \
    181       VALGRIND_INTERNAL_PRINTF(format, ## args ); }
    182 
    183 /* Below are new versions of malloc, __builtin_new, free,
    184    __builtin_delete, calloc, realloc, memalign, and friends.
    185 
    186    None of these functions are called directly - they are not meant to
    187    be found by the dynamic linker.  But ALL client calls to malloc()
    188    and friends wind up here eventually.  They get called because
    189    vg_replace_malloc installs a bunch of code redirects which causes
    190    Valgrind to use these functions rather than the ones they're
    191    replacing.
    192 */
    193 
    194 
    195 /*---------------------- malloc ----------------------*/
    196 
    197 /* Generate a replacement for 'fnname' in object 'soname', which calls
    198    'vg_replacement' to allocate memory.  If that fails, return NULL.
    199 */
    200 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
    201    \
    202    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
    203    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n)  \
    204    { \
    205       void* v; \
    206       \
    207       if (!init_done) init(); \
    208       MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
    209       \
    210       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    211       MALLOC_TRACE(" = %p\n", v ); \
    212       return v; \
    213    }
    214 
    215 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
    216    \
    217    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
    218    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n)  \
    219    { \
    220       void* v; \
    221       \
    222       if (!init_done) init(); \
    223       MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
    224       \
    225       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    226       MALLOC_TRACE(" = %p\n", v ); \
    227       return v; \
    228    }
    229 
    230 
    231 /* Generate a replacement for 'fnname' in object 'soname', which calls
    232    'vg_replacement' to allocate memory.  If that fails, it bombs the
    233    system.
    234 */
    235 #define ALLOC_or_BOMB(soname, fnname, vg_replacement)  \
    236    \
    237    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
    238    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n)  \
    239    { \
    240       void* v; \
    241       \
    242       if (!init_done) init(); \
    243       MALLOC_TRACE(#fnname "(%llu)", (ULong)n );        \
    244       \
    245       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    246       MALLOC_TRACE(" = %p\n", v ); \
    247       if (NULL == v) { \
    248          VALGRIND_PRINTF( \
    249             "new/new[] failed and should throw an exception, but Valgrind\n"); \
    250          VALGRIND_PRINTF_BACKTRACE( \
    251             "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
    252             my_exit(1); \
    253       } \
    254       return v; \
    255    }
    256 
    257 // Each of these lines generates a replacement function:
    258 //     (from_so, from_fn,  v's replacement)
    259 
    260 // malloc
    261 #if defined(VGO_linux)
    262  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
    263  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    264 
    265 #elif defined(VGO_darwin)
    266  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    267  ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
    268 
    269 #endif
    270 
    271 
    272 /*---------------------- new ----------------------*/
    273 
    274 #if defined(VGO_linux)
    275  // operator new(unsigned int), not mangled (for gcc 2.96)
    276  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
    277  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
    278  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
    279  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
    280  // operator new(unsigned int), GNU mangling
    281  #if VG_WORDSIZE == 4
    282   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    283   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
    284  #endif
    285  // operator new(unsigned long), GNU mangling
    286  #if VG_WORDSIZE == 8
    287   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    288   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
    289  #endif
    290 
    291 #elif defined(VGO_darwin)
    292  // glider: hereafter we uncomment the interceptors for operator new
    293  // and operator delete, see https://bugs.kde.org/show_bug.cgi?id=286849
    294  // operator new(unsigned int), GNU mangling
    295  #if VG_WORDSIZE == 4
    296   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    297   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
    298  #endif
    299  // operator new(unsigned long), GNU mangling
    300  #if 1 // FIXME: is this right?
    301   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    302   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
    303  #endif
    304 
    305 #endif
    306 
    307 /*---------------------- new nothrow ----------------------*/
    308 // operator new(unsigned, std::nothrow_t const&), GNU mangling
    309 
    310 #if defined(VGO_linux)
    311  // operator new(unsigned, std::nothrow_t const&), GNU mangling
    312  #if VG_WORDSIZE == 4
    313   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    314   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
    315  #endif
    316  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    317  #if VG_WORDSIZE == 8
    318   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    319   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
    320  #endif
    321 #elif defined(VGO_darwin)
    322  // operator new(unsigned, std::nothrow_t const&), GNU mangling
    323  #if VG_WORDSIZE == 4
    324   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    325   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
    326  #endif
    327  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    328  #if 1 // FIXME: is this right?
    329   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    330   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
    331  #endif
    332 #endif
    333 
    334 
    335 /*---------------------- new [] ----------------------*/
    336 
    337 #if defined(VGO_linux)
    338  // operator new[](unsigned int), not mangled (for gcc 2.96)
    339  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
    340  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
    341  // operator new[](unsigned int), GNU mangling
    342  #if VG_WORDSIZE == 4
    343   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    344   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
    345  #endif
    346  // operator new[](unsigned long), GNU mangling
    347  #if VG_WORDSIZE == 8
    348   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    349   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
    350  #endif
    351 
    352 #elif defined(VGO_darwin)
    353  // operator new[](unsigned int), GNU mangling
    354  #if VG_WORDSIZE == 4
    355   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    356   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
    357  #endif
    358  // operator new[](unsigned long), GNU mangling
    359  #if 1 // FIXME: is this right?
    360   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    361   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
    362  #endif
    363 
    364 #endif
    365 
    366 
    367 /*---------------------- new [] nothrow ----------------------*/
    368 
    369 #if defined(VGO_linux)
    370  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    371  #if VG_WORDSIZE == 4
    372   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    373   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
    374  #endif
    375  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    376  #if VG_WORDSIZE == 8
    377   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    378   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
    379  #endif
    380 #elif defined(VGO_darwin)
    381  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    382  #if VG_WORDSIZE == 4
    383   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    384   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
    385  #endif
    386  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    387  #if 1 // FIXME: is this right?
    388   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    389   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
    390  #endif
    391 
    392 #endif
    393 
    394 
    395 /*---------------------- free ----------------------*/
    396 
    397 /* Generate a replacement for 'fnname' in object 'soname', which calls
    398    'vg_replacement' to free previously allocated memory.
    399 */
    400 #define ZONEFREE(soname, fnname, vg_replacement) \
    401    \
    402    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
    403    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p)  \
    404    { \
    405       if (!init_done) init(); \
    406       MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
    407       if (p == NULL)  \
    408          return; \
    409       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    410    }
    411 
    412 #define FREE(soname, fnname, vg_replacement) \
    413    \
    414    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
    415    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p)  \
    416    { \
    417       if (!init_done) init(); \
    418       MALLOC_TRACE(#fnname "(%p)\n", p ); \
    419       if (p == NULL)  \
    420          return; \
    421       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    422    }
    423 
    424 #if defined(VGO_linux)
    425  FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
    426  FREE(VG_Z_LIBC_SONAME,       free,                 free );
    427 
    428 #elif defined(VGO_darwin)
    429  FREE(VG_Z_LIBC_SONAME,       free,                 free );
    430  ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
    431 
    432 #endif
    433 
    434 
    435 /*---------------------- cfree ----------------------*/
    436 
    437 // cfree
    438 #if defined(VGO_linux)
    439  FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
    440  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    441 
    442 #elif defined(VGO_darwin)
    443  //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
    444  //FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    445 
    446 #endif
    447 
    448 
    449 /*---------------------- delete ----------------------*/
    450 
    451 #if defined(VGO_linux)
    452  // operator delete(void*), not mangled (for gcc 2.96)
    453  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
    454  FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
    455  // operator delete(void*), GNU mangling
    456  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    457  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
    458 
    459 #elif defined(VGO_darwin)
    460  // operator delete(void*), GNU mangling
    461  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    462  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
    463 
    464 #endif
    465 
    466 
    467 /*---------------------- delete nothrow ----------------------*/
    468 
    469 #if defined(VGO_linux)
    470  // operator delete(void*, std::nothrow_t const&), GNU mangling
    471  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    472  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    473 
    474 #elif defined(VGO_darwin)
    475  // operator delete(void*, std::nothrow_t const&), GNU mangling
    476  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    477  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    478 
    479 #endif
    480 
    481 
    482 /*---------------------- delete [] ----------------------*/
    483 
    484 #if defined(VGO_linux)
    485  // operator delete[](void*), not mangled (for gcc 2.96)
    486  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
    487  FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
    488  // operator delete[](void*), GNU mangling
    489  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    490  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
    491 
    492 #elif defined(VGO_darwin)
    493  // operator delete[](void*), not mangled (for gcc 2.96)
    494  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
    495  FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
    496  // operator delete[](void*), GNU mangling
    497  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    498  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
    499 
    500 #endif
    501 
    502 
    503 /*---------------------- delete [] nothrow ----------------------*/
    504 
    505 #if defined(VGO_linux)
    506  // operator delete[](void*, std::nothrow_t const&), GNU mangling
    507  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    508  FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    509 
    510 #elif defined(VGO_darwin)
    511  // operator delete[](void*, std::nothrow_t const&), GNU mangling
    512 FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    513 FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    514 
    515 #endif
    516 
    517 
    518 /*---------------------- calloc ----------------------*/
    519 
    520 #define ZONECALLOC(soname, fnname) \
    521    \
    522    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
    523             ( void *zone, SizeT nmemb, SizeT size ); \
    524    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
    525             ( void *zone, SizeT nmemb, SizeT size )  \
    526    { \
    527       void* v; \
    528       \
    529       if (!init_done) init(); \
    530       MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
    531       \
    532       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    533       MALLOC_TRACE(" = %p\n", v ); \
    534       return v; \
    535    }
    536 
    537 #define CALLOC(soname, fnname) \
    538    \
    539    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
    540             ( SizeT nmemb, SizeT size ); \
    541    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
    542             ( SizeT nmemb, SizeT size )  \
    543    { \
    544       void* v; \
    545       \
    546       if (!init_done) init(); \
    547       MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
    548       \
    549       /* Protect against overflow.  See bug 24078. (that bug number is
    550          invalid.  Which one really?) */ \
    551       /* But don't use division, since that produces an external symbol
    552          reference on ARM, in the form of a call to __aeabi_uidiv.  It's
    553          normally OK, because ld.so manages to resolve it to something in the
    554          executable, or one of its shared objects.  But that isn't guaranteed
    555          to be the case, and it has been observed to fail in rare cases, eg:
    556             echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
    557          So instead compute the high word of the product and check it is zero. */ \
    558       if (umulHW(size, nmemb) != 0) return NULL; \
    559       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    560       MALLOC_TRACE(" = %p\n", v ); \
    561       return v; \
    562    }
    563 
    564 #if defined(VGO_linux)
    565  CALLOC(VG_Z_LIBC_SONAME, calloc);
    566 
    567 #elif defined(VGO_darwin)
    568  CALLOC(VG_Z_LIBC_SONAME, calloc);
    569  ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
    570 
    571 #endif
    572 
    573 
    574 /*---------------------- realloc ----------------------*/
    575 
    576 #define ZONEREALLOC(soname, fnname) \
    577    \
    578    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
    579             ( void *zone, void* ptrV, SizeT new_size ); \
    580    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
    581             ( void *zone, void* ptrV, SizeT new_size ) \
    582    { \
    583       void* v; \
    584       \
    585       if (!init_done) init(); \
    586       MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
    587       \
    588       if (ptrV == NULL) \
    589          /* We need to call a malloc-like function; so let's use \
    590             one which we know exists. GrP fixme use zonemalloc instead? */ \
    591          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
    592                    (new_size); \
    593       if (new_size <= 0) { \
    594          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
    595          MALLOC_TRACE(" = 0\n"); \
    596          return NULL; \
    597       } \
    598       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    599       MALLOC_TRACE(" = %p\n", v ); \
    600       return v; \
    601    }
    602 
    603 #define REALLOC(soname, fnname) \
    604    \
    605    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
    606             ( void* ptrV, SizeT new_size );\
    607    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
    608             ( void* ptrV, SizeT new_size ) \
    609    { \
    610       void* v; \
    611       \
    612       if (!init_done) init(); \
    613       MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
    614       \
    615       if (ptrV == NULL) \
    616          /* We need to call a malloc-like function; so let's use \
    617             one which we know exists. */ \
    618          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
    619                    (new_size); \
    620       if (new_size <= 0) { \
    621          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
    622          MALLOC_TRACE(" = 0\n"); \
    623          return NULL; \
    624       } \
    625       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    626       MALLOC_TRACE(" = %p\n", v ); \
    627       return v; \
    628    }
    629 
    630 #if defined(VGO_linux)
    631  REALLOC(VG_Z_LIBC_SONAME, realloc);
    632 
    633 #elif defined(VGO_darwin)
    634  REALLOC(VG_Z_LIBC_SONAME, realloc);
    635  ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
    636 
    637 #endif
    638 
    639 
    640 /*---------------------- memalign ----------------------*/
    641 
    642 #define ZONEMEMALIGN(soname, fnname) \
    643    \
    644    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
    645             ( void *zone, SizeT alignment, SizeT n ); \
    646    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
    647             ( void *zone, SizeT alignment, SizeT n ) \
    648    { \
    649       void* v; \
    650       \
    651       if (!init_done) init(); \
    652       MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
    653                    zone, (ULong)alignment, (ULong)n );  \
    654       \
    655       /* Round up to minimum alignment if necessary. */ \
    656       if (alignment < VG_MIN_MALLOC_SZB) \
    657          alignment = VG_MIN_MALLOC_SZB; \
    658       \
    659       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    660       while (0 != (alignment & (alignment - 1))) alignment++; \
    661       \
    662       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    663       MALLOC_TRACE(" = %p\n", v ); \
    664       return v; \
    665    }
    666 
    667 #define MEMALIGN(soname, fnname) \
    668    \
    669    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
    670             ( SizeT alignment, SizeT n ); \
    671    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
    672             ( SizeT alignment, SizeT n )  \
    673    { \
    674       void* v; \
    675       \
    676       if (!init_done) init(); \
    677       MALLOC_TRACE("memalign(al %llu, size %llu)", \
    678                    (ULong)alignment, (ULong)n ); \
    679       \
    680       /* Round up to minimum alignment if necessary. */ \
    681       if (alignment < VG_MIN_MALLOC_SZB) \
    682          alignment = VG_MIN_MALLOC_SZB; \
    683       \
    684       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    685       while (0 != (alignment & (alignment - 1))) alignment++; \
    686       \
    687       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    688       MALLOC_TRACE(" = %p\n", v ); \
    689       return v; \
    690    }
    691 
    692 #if defined(VGO_linux)
    693  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
    694 
    695 #elif defined(VGO_darwin)
    696  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
    697  ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
    698 
    699 #endif
    700 
    701 
    702 /*---------------------- valloc ----------------------*/
    703 
    704 #define VALLOC(soname, fnname) \
    705    \
    706    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
    707    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
    708    { \
    709       static int pszB = 0; \
    710       if (pszB == 0) \
    711          pszB = my_getpagesize(); \
    712       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
    713                 ((SizeT)pszB, size); \
    714    }
    715 
    716 #define ZONEVALLOC(soname, fnname) \
    717    \
    718    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
    719             ( void *zone, SizeT size ); \
    720    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
    721             ( void *zone, SizeT size )  \
    722    { \
    723       static int pszB = 0; \
    724       if (pszB == 0) \
    725          pszB = my_getpagesize(); \
    726       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
    727                 ((SizeT)pszB, size); \
    728    }
    729 
    730 #if defined(VGO_linux)
    731  VALLOC(VG_Z_LIBC_SONAME, valloc);
    732 
    733 #elif defined(VGO_darwin)
    734  VALLOC(VG_Z_LIBC_SONAME, valloc);
    735  ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
    736 
    737 #endif
    738 
    739 
    740 /*---------------------- mallopt ----------------------*/
    741 
    742 /* Various compatibility wrapper functions, for glibc and libstdc++. */
    743 
    744 #define MALLOPT(soname, fnname) \
    745    \
    746    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
    747    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
    748    { \
    749       /* In glibc-2.2.4, 1 denotes a successful return value for \
    750          mallopt */ \
    751       return 1; \
    752    }
    753 
    754 #if defined(VGO_linux)
    755  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
    756 
    757 #elif defined(VGO_darwin)
    758  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
    759 
    760 #endif
    761 
    762 
    763 /*---------------------- malloc_trim ----------------------*/
    764 // Documentation says:
    765 //   malloc_trim(size_t pad);
    766 //
    767 //   If possible, gives memory back to the system (via negative arguments to
    768 //   sbrk) if there is unused memory at the `high' end of the malloc pool.
    769 //   You can call this after freeing large blocks of memory to potentially
    770 //   reduce the system-level memory requirements of a program. However, it
    771 //   cannot guarantee to reduce memory.  Under some allocation patterns,
    772 //   some large free blocks of memory will be locked between two used
    773 //   chunks, so they cannot be given back to the system.
    774 //
    775 //   The `pad' argument to malloc_trim represents the amount of free
    776 //   trailing space to leave untrimmed. If this argument is zero, only the
    777 //   minimum amount of memory to maintain internal data structures will be
    778 //   left (one page or less). Non-zero arguments can be supplied to maintain
    779 //   enough trailing space to service future expected allocations without
    780 //   having to re-obtain memory from the system.
    781 //
    782 //   Malloc_trim returns 1 if it actually released any memory, else 0. On
    783 //   systems that do not support "negative sbrks", it will always return 0.
    784 //
    785 // For simplicity, we always return 0.
    786 #define MALLOC_TRIM(soname, fnname) \
    787    \
    788    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
    789    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
    790    { \
    791       /* 0 denotes that malloc_trim() either wasn't able \
    792          to do anything, or was not implemented */ \
    793       return 0; \
    794    }
    795 
    796 #if defined(VGO_linux)
    797  MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
    798 
    799 #elif defined(VGO_darwin)
    800  //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
    801 
    802 #endif
    803 
    804 
    805 /*---------------------- posix_memalign ----------------------*/
    806 
    807 #define POSIX_MEMALIGN(soname, fnname) \
    808    \
    809    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
    810           ( void **memptr, SizeT alignment, SizeT size ); \
    811    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
    812           ( void **memptr, SizeT alignment, SizeT size ) \
    813    { \
    814       void *mem; \
    815       \
    816       /* Test whether the alignment argument is valid.  It must be \
    817          a power of two multiple of sizeof (void *).  */ \
    818       if (alignment % sizeof (void *) != 0 \
    819           || (alignment & (alignment - 1)) != 0) \
    820          return VKI_EINVAL; \
    821       \
    822       /* Round up to minimum alignment if necessary. */ \
    823       if (alignment < VG_MIN_MALLOC_SZB) \
    824          alignment = VG_MIN_MALLOC_SZB; \
    825       \
    826       mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size); \
    827       \
    828       if (mem != NULL) { \
    829         *memptr = mem; \
    830         return 0; \
    831       } \
    832       \
    833       return VKI_ENOMEM; \
    834    }
    835 
    836 #if defined(VGO_linux)
    837  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
    838 
    839 #elif defined(VGO_darwin)
    840  //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
    841 
    842 #endif
    843 
    844 
    845 /*---------------------- malloc_usable_size ----------------------*/
    846 
    847 #define MALLOC_USABLE_SIZE(soname, fnname) \
    848    \
    849    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
    850    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
    851    {  \
    852       SizeT pszB; \
    853       \
    854       if (!init_done) init(); \
    855       MALLOC_TRACE("malloc_usable_size(%p)", p ); \
    856       if (NULL == p) \
    857          return 0; \
    858       \
    859       pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
    860       MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
    861       \
    862       return pszB; \
    863    }
    864 
    865 #if defined(VGO_linux)
    866  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
    867  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
    868 
    869 #elif defined(VGO_darwin)
    870  //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
    871  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
    872 
    873 #endif
    874 
    875 
    876 /*---------------------- (unimplemented) ----------------------*/
    877 
    878 /* Bomb out if we get any of these. */
    879 
    880 static void panic(const char *str)
    881 {
    882    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
    883    my_exit(99);
    884    *(volatile int *)0 = 'x';
    885 }
    886 
    887 #define PANIC(soname, fnname) \
    888    \
    889    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
    890    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void )  \
    891    { \
    892       panic(#fnname); \
    893    }
    894 
    895 #if defined(VGO_linux)
    896  PANIC(VG_Z_LIBC_SONAME, pvalloc);
    897  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
    898  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
    899 
    900 #elif defined(VGO_darwin)
    901  PANIC(VG_Z_LIBC_SONAME, pvalloc);
    902  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
    903  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
    904 
    905 #endif
    906 
    907 
    908 #define MALLOC_STATS(soname, fnname) \
    909    \
    910    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
    911    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void )  \
    912    { \
    913       /* Valgrind's malloc_stats implementation does nothing. */ \
    914    }
    915 
    916 #if defined(VGO_linux)
    917  MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
    918 
    919 #elif defined(VGO_darwin)
    920  //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
    921 
    922 #endif
    923 
    924 
    925 /*---------------------- mallinfo ----------------------*/
    926 
    927 // mi must be static;  if it is auto then Memcheck thinks it is
    928 // uninitialised when used by the caller of this function, because Memcheck
    929 // doesn't know that the call to mallinfo fills in mi.
    930 #define MALLINFO(soname, fnname) \
    931    \
    932    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
    933    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
    934    { \
    935       static struct vg_mallinfo mi; \
    936       if (!init_done) init(); \
    937       MALLOC_TRACE("mallinfo()\n"); \
    938       (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
    939       return mi; \
    940    }
    941 
    942 #if defined(VGO_linux)
    943  MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
    944 
    945 #elif defined(VGO_darwin)
    946  //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
    947 
    948 #endif
    949 
    950 
    951 /*------------------ Darwin zone stuff ------------------*/
    952 
    953 
    954 #if defined(VGO_darwin)
    955 
    956 static vki_malloc_zone_t vg_default_zone = {
    957     NULL, // reserved1
    958     NULL, // reserved2
    959     NULL, // GrP fixme: malloc_size
    960     (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
    961     (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
    962     (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
    963     (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
    964     (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
    965     NULL, // GrP fixme: destroy
    966     "ValgrindMallocZone",
    967     NULL, // batch_malloc
    968     NULL, // batch_free
    969     NULL, // GrP fixme: introspect
    970     2,  // version (GrP fixme 3?)
    971     NULL, /* memalign */   // DDD: this field exists in Mac OS 10.6, but not 10.5.
    972     NULL, /* free_definite_size */
    973     NULL, /* pressure_relief */
    974 };
    975 
    976 #define DEFAULT_ZONE(soname, fnname) \
    977    \
    978    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
    979    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void )  \
    980    { \
    981       return &vg_default_zone; \
    982    }
    983 
    984 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
    985 
    986 #define ZONE_FROM_PTR(soname, fnname) \
    987    \
    988    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \
    989    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr )  \
    990    { \
    991       return &vg_default_zone; \
    992    }
    993 
    994 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
    995 
    996 
    997 // GrP fixme bypass libc's use of zone->introspect->check
    998 #define ZONE_CHECK(soname, fnname) \
    999    \
   1000    int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \
   1001    int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone)  \
   1002    { \
   1003       return 1; \
   1004    }
   1005 
   1006 //ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
   1007 
   1008 #endif /* defined(VGO_darwin) */
   1009 
   1010 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start);
   1011 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClSandboxMemoryStartForValgrind) (void *mem_start) {
   1012   OrigFn fn;
   1013   VALGRIND_GET_ORIG_FN(fn);
   1014   CALL_FN_v_W(fn, mem_start);
   1015   int res;
   1016   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MEM_START, mem_start, 0, 0, 0, 0);
   1017 }
   1018 
   1019 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file);
   1020 int I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileNameForValgrind) (char *file) {
   1021   OrigFn fn;
   1022   int ret;
   1023   VALGRIND_GET_ORIG_FN(fn);
   1024   CALL_FN_W_W(ret, fn, file);
   1025   int res;
   1026   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_FILE, file, 0, 0, 0, 0);
   1027   return ret;
   1028 }
   1029 
   1030 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset);
   1031 void I_WRAP_SONAME_FNNAME_ZZ(NONE, NaClFileMappingForValgrind) (UWord vma, UWord size, UWord file_offset) {
   1032   OrigFn fn;
   1033   VALGRIND_GET_ORIG_FN(fn);
   1034   CALL_FN_v_WWW(fn, vma, size, file_offset);
   1035   int res;
   1036   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MMAP, vma, size, file_offset, 0, 0);
   1037 }
   1038 
   1039 /* Handle tcmalloc (http://code.google.com/p/google-perftools/) */
   1040 
   1041 /* tc_ functions (used when tcmalloc is running in release mode) */
   1042 ALLOC_or_NULL(NONE,tc_malloc,malloc);
   1043 ALLOC_or_BOMB(NONE,tc_new,__builtin_new);
   1044 ALLOC_or_NULL(NONE,tc_new_nothrow,__builtin_new);
   1045 ALLOC_or_BOMB(NONE,tc_newarray,__builtin_vec_new);
   1046 ALLOC_or_NULL(NONE,tc_newarray_nothrow,__builtin_vec_new);
   1047 FREE(NONE,tc_free,free);
   1048 FREE(NONE,tc_cfree,free);
   1049 FREE(NONE,tc_delete,__builtin_delete);
   1050 FREE(NONE,tc_delete_nothrow,__builtin_delete);
   1051 FREE(NONE,tc_deletearray,__builtin_vec_delete);
   1052 FREE(NONE,tc_deletearray_nothrow,__builtin_vec_delete);
   1053 CALLOC(NONE,tc_calloc);
   1054 REALLOC(NONE,tc_realloc);
   1055 VALLOC(NONE,tc_valloc);
   1056 MEMALIGN(NONE,tc_memalign);
   1057 MALLOPT(NONE,tc_mallopt);
   1058 POSIX_MEMALIGN(NONE,tc_posix_memalign);
   1059 MALLOC_USABLE_SIZE(NONE,tc_malloc_size);
   1060 MALLINFO(NONE,tc_mallinfo);
   1061 
   1062 /* Python */
   1063 ALLOC_or_NULL(NONE, PyObject_Malloc,   malloc);
   1064 FREE(NONE,          PyObject_Free,     free);
   1065 REALLOC(NONE,       PyObject_Realloc);
   1066 
   1067 /* Interceptors for custom malloc functions in user code
   1068    (NONE, malloc). We need these to intercept tcmalloc in debug builds.
   1069    TODO(kcc): get rid of these once we have tc_malloc/tc_new/etc
   1070    in tcmalloc's debugallocation.cc
   1071  */
   1072 ALLOC_or_NULL(NONE,  malloc,               malloc);
   1073 ALLOC_or_BOMB(NONE,  _Znwj,                __builtin_new);
   1074 ALLOC_or_BOMB(NONE,  _Znwm,                __builtin_new);
   1075 ALLOC_or_NULL(NONE,  _ZnwjRKSt9nothrow_t,  __builtin_new);
   1076 ALLOC_or_NULL(NONE,  _ZnwmRKSt9nothrow_t,  __builtin_new);
   1077 ALLOC_or_BOMB(NONE,  _Znaj,                __builtin_vec_new);
   1078 ALLOC_or_BOMB(NONE,  _Znam,                __builtin_vec_new);
   1079 ALLOC_or_NULL(NONE,  _ZnajRKSt9nothrow_t,  __builtin_vec_new);
   1080 ALLOC_or_NULL(NONE,  _ZnamRKSt9nothrow_t,  __builtin_vec_new);
   1081 FREE(NONE,  free,                 free );
   1082 FREE(NONE,  cfree,                free );
   1083 FREE(NONE,  _ZdlPv,               __builtin_delete );
   1084 FREE(NONE,  _ZdlPvRKSt9nothrow_t, __builtin_delete );
   1085 FREE(NONE,  _ZdaPv,               __builtin_vec_delete );
   1086 FREE(NONE,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
   1087 CALLOC(NONE,   calloc);
   1088 REALLOC(NONE,  realloc);
   1089 MEMALIGN(NONE, memalign);
   1090 VALLOC(NONE,   valloc);
   1091 MALLOPT(NONE,  mallopt);
   1092 MALLOC_TRIM(NONE,            malloc_trim);
   1093 POSIX_MEMALIGN(NONE,         posix_memalign);
   1094 MALLOC_USABLE_SIZE(NONE,     malloc_usable_size);
   1095 MALLINFO(NONE,               mallinfo);
   1096 
   1097 // TODO(kcc): these are interceptors for bash's malloc.
   1098 // The bash interpretor has functions malloc() and sh_malloc()
   1099 // as well as free() and sh_free(). And sometimes they are called
   1100 // inconsistently (malloc, then sh_free).
   1101 // So, if we intercept malloc/free, we also need to intercept
   1102 // sh_malloc/sh_free.
   1103 //
   1104 // Standard valgrind does not intercept user's malloc, so it does not have this
   1105 // problem.
   1106 //
   1107 // Get rid of these once we are able to intercept tcmalloc
   1108 // w/o intercepting (NONE,malloc)
   1109 ALLOC_or_NULL(NONE,       sh_malloc,   malloc);
   1110 FREE(NONE,                sh_free,     free );
   1111 FREE(NONE,                sh_cfree,    free );
   1112 CALLOC(NONE,              sh_calloc);
   1113 REALLOC(NONE,             sh_realloc);
   1114 MEMALIGN(NONE,            sh_memalign);
   1115 VALLOC(NONE,              sh_valloc);
   1116 
   1117 /*------- alternative to RUNNING_ON_VALGRIND client request -----*/
   1118 
   1119 #define ANN_FUNC0(ret_ty, f) \
   1120     ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void); \
   1121     ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void)
   1122 
   1123 ANN_FUNC0(int, RunningOnValgrind) { return 1; }
   1124 
   1125 /*------------------ (startup related) ------------------*/
   1126 
   1127 /* All the code in here is unused until this function is called */
   1128 
   1129 __attribute__((constructor))
   1130 static void init(void)
   1131 {
   1132 
   1133    // This doesn't look thread-safe, but it should be ok... Bart says:
   1134    //
   1135    //   Every program I know of calls malloc() at least once before calling
   1136    //   pthread_create().  So init_done gets initialized before any thread is
   1137    //   created, and is only read when multiple threads are active
   1138    //   simultaneously.  Such an access pattern is safe.
   1139    //
   1140    //   If the assignment to the variable init_done would be triggering a race
   1141    //   condition, both DRD and Helgrind would report this race.
   1142    //
   1143    //   By the way, although the init() function in
   1144    //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
   1145    //   __attribute__((constructor)), it is not safe to remove the variable
   1146    //   init_done. This is because it is possible that malloc() and hence
   1147    //   init() gets called before shared library initialization finished.
   1148    //
   1149    if (init_done)
   1150       return;
   1151 
   1152    init_done = 1;
   1153 
   1154    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
   1155                                    0, 0, 0, 0);
   1156 }
   1157 
   1158 /*--------------------------------------------------------------------*/
   1159 /*--- end                                                          ---*/
   1160 /*--------------------------------------------------------------------*/
   1161