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-2010 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 
     74 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
     75    mangling, could be supported properly by the redirects in this
     76    module.  Except we can't because it doesn't put its allocation
     77    functions in libpgc.so but instead hardwires them into the
     78    compilation unit holding main(), which makes them impossible to
     79    intercept directly.  Fortunately those fns seem to route everything
     80    through to malloc/free.
     81 
     82    mid-06: could be improved, since we can now intercept in the main
     83    executable too.
     84 */
     85 
     86 __attribute__ ((__noreturn__))
     87 extern void _exit(int);
     88 
     89 /* Apparently it is necessary to make ourselves free of any dependency
     90    on memcpy() on ppc32-aix5; else programs linked with -brtl fail.
     91    memcpy() is used by gcc for a struct assignment in mallinfo()
     92    below.  Add the following conservative implementation (memmove,
     93    really). */
     94 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
     95 __attribute__((weak))
     96 void *memcpy(void *destV, const void *srcV, unsigned long n)
     97 {
     98    unsigned char* src = (unsigned char*)srcV;
     99    unsigned char* dest = (unsigned char*)destV;
    100    unsigned long  i;
    101    if (dest < src) {
    102       for (i = 0; i < n; i++)
    103          dest[i] = src[i];
    104    }
    105    if (dest > src) {
    106       for (i = n; i > 0; i--)
    107          dest[i-1] = src[i-1];
    108    }
    109    return dest;
    110 }
    111 #endif
    112 
    113 
    114 /* Compute the high word of the double-length unsigned product of U
    115    and V.  This is for calloc argument overflow checking; see comments
    116    below.  Algorithm as described in Hacker's Delight, chapter 8. */
    117 static UWord umulHW ( UWord u, UWord v )
    118 {
    119    UWord u0, v0, w0, rHi;
    120    UWord u1, v1, w1,w2,t;
    121    UWord halfMask  = sizeof(UWord)==4 ? (UWord)0xFFFF
    122                                       : (UWord)0xFFFFFFFFULL;
    123    UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
    124    u0  = u & halfMask;
    125    u1  = u >> halfShift;
    126    v0  = v & halfMask;
    127    v1  = v >> halfShift;
    128    w0  = u0 * v0;
    129    t   = u1 * v0 + (w0 >> halfShift);
    130    w1  = t & halfMask;
    131    w2  = t >> halfShift;
    132    w1  = u0 * v1 + w1;
    133    rHi = u1 * v1 + w2 + (w1 >> halfShift);
    134    return rHi;
    135 }
    136 
    137 
    138 /*------------------------------------------------------------*/
    139 /*--- Replacing malloc() et al                             ---*/
    140 /*------------------------------------------------------------*/
    141 
    142 /* This struct is initially empty.  Before the first use of any of
    143    these functions, we make a client request which fills in the
    144    fields.
    145 */
    146 static struct vg_mallocfunc_info info;
    147 static int init_done;
    148 
    149 /* Startup hook - called as init section */
    150 __attribute__((constructor))
    151 static void init(void);
    152 
    153 #define MALLOC_TRACE(format, args...)  \
    154    if (info.clo_trace_malloc) {        \
    155       VALGRIND_INTERNAL_PRINTF(format, ## args ); }
    156 
    157 /* Below are new versions of malloc, __builtin_new, free,
    158    __builtin_delete, calloc, realloc, memalign, and friends.
    159 
    160    None of these functions are called directly - they are not meant to
    161    be found by the dynamic linker.  But ALL client calls to malloc()
    162    and friends wind up here eventually.  They get called because
    163    vg_replace_malloc installs a bunch of code redirects which causes
    164    Valgrind to use these functions rather than the ones they're
    165    replacing.
    166 */
    167 
    168 
    169 /*---------------------- malloc ----------------------*/
    170 
    171 /* Generate a replacement for 'fnname' in object 'soname', which calls
    172    'vg_replacement' to allocate memory.  If that fails, return NULL.
    173 */
    174 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
    175    \
    176    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
    177    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n)  \
    178    { \
    179       void* v; \
    180       \
    181       if (!init_done) init(); \
    182       MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
    183       \
    184       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    185       MALLOC_TRACE(" = %p\n", v ); \
    186       return v; \
    187    }
    188 
    189 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
    190    \
    191    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n); \
    192    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, SizeT n)  \
    193    { \
    194       void* v; \
    195       \
    196       if (!init_done) init(); \
    197       MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
    198       \
    199       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    200       MALLOC_TRACE(" = %p\n", v ); \
    201       return v; \
    202    }
    203 
    204 
    205 /* Generate a replacement for 'fnname' in object 'soname', which calls
    206    'vg_replacement' to allocate memory.  If that fails, it bombs the
    207    system.
    208 */
    209 #define ALLOC_or_BOMB(soname, fnname, vg_replacement)  \
    210    \
    211    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n); \
    212    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (SizeT n)  \
    213    { \
    214       void* v; \
    215       \
    216       if (!init_done) init(); \
    217       MALLOC_TRACE(#fnname "(%llu)", (ULong)n );        \
    218       \
    219       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    220       MALLOC_TRACE(" = %p\n", v ); \
    221       if (NULL == v) { \
    222          VALGRIND_PRINTF( \
    223             "new/new[] failed and should throw an exception, but Valgrind\n"); \
    224          VALGRIND_PRINTF_BACKTRACE( \
    225             "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
    226             _exit(1); \
    227       } \
    228       return v; \
    229    }
    230 
    231 // Each of these lines generates a replacement function:
    232 //     (from_so, from_fn,  v's replacement)
    233 
    234 // malloc
    235 ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
    236 ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    237 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    238 ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc_common, malloc);
    239 #elif defined(VGO_darwin)
    240 ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
    241 #endif
    242 
    243 
    244 /*---------------------- new ----------------------*/
    245 
    246 // operator new(unsigned int), not mangled (for gcc 2.96)
    247 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
    248 ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
    249 
    250 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
    251 ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
    252 
    253 // operator new(unsigned int), GNU mangling
    254 #if VG_WORDSIZE == 4
    255  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    256  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
    257 #endif
    258 
    259 // operator new(unsigned long), GNU mangling
    260 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGO_darwin)
    261  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    262  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
    263 #endif
    264 
    265 // operator new(unsigned long), ARM/cfront mangling
    266 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    267  ALLOC_or_BOMB(VG_Z_LIBC_DOT_A,       __nw__FUl,      __builtin_new);
    268 #endif
    269 
    270 
    271 /*---------------------- new nothrow ----------------------*/
    272 // operator new(unsigned, std::nothrow_t const&), GNU mangling
    273 
    274 #if VG_WORDSIZE == 4
    275  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    276  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
    277 #endif
    278 
    279 // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    280 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
    281  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    282  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
    283 #endif
    284 
    285 // operator new(unsigned long, std::nothrow_t const&), ARM/cfront mangling
    286 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    287  ALLOC_or_NULL(VG_Z_LIBC_DOT_A,    __nw__FUlRCQ2_3std9nothrow_t, __builtin_new);
    288 #endif
    289 
    290 
    291 /*---------------------- new [] ----------------------*/
    292 
    293 // operator new[](unsigned int), not mangled (for gcc 2.96)
    294 ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
    295 ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
    296 
    297 // operator new[](unsigned int), GNU mangling
    298 #if VG_WORDSIZE == 4
    299  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    300  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
    301 #endif
    302 
    303 // operator new[](unsigned long), GNU mangling
    304 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
    305  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    306  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
    307 #endif
    308 
    309 // operator new[](unsigned long), ARM/cfront mangling
    310 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    311  ALLOC_or_BOMB(VG_Z_LIBC_DOT_A,       __vn__FUl,         __builtin_vec_new);
    312 #endif
    313 
    314 
    315 /*---------------------- new [] nothrow ----------------------*/
    316 
    317 // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    318 #if VG_WORDSIZE == 4
    319  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    320  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
    321 #endif
    322 
    323 // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    324 #if VG_WORDSIZE == 8 || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(VGO_darwin)
    325  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    326  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
    327 #endif
    328 
    329 // operator new [](unsigned long, std::nothrow_t const&), ARM/cfront mangling
    330 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    331  ALLOC_or_BOMB(VG_Z_LIBC_DOT_A,   __vn__FUlRCQ2_3std9nothrow_t, __builtin_vec_new );
    332 #endif
    333 
    334 
    335 /*---------------------- free ----------------------*/
    336 
    337 /* Generate a replacement for 'fnname' in object 'soname', which calls
    338    'vg_replacement' to free previously allocated memory.
    339 */
    340 #define ZONEFREE(soname, fnname, vg_replacement) \
    341    \
    342    void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p); \
    343    void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *zone, void *p)  \
    344    { \
    345       if (!init_done) init(); \
    346       MALLOC_TRACE(#vg_replacement "(%p, %p)\n", zone, p ); \
    347       if (p == NULL)  \
    348          return; \
    349       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    350    }
    351 
    352 #define FREE(soname, fnname, vg_replacement) \
    353    \
    354    void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p); \
    355    void VG_REPLACE_FUNCTION_ZU(soname,fnname) (void *p)  \
    356    { \
    357       if (!init_done) init(); \
    358       MALLOC_TRACE(#vg_replacement "(%p)\n", p ); \
    359       if (p == NULL)  \
    360          return; \
    361       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    362    }
    363 
    364 // free
    365 FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
    366 FREE(VG_Z_LIBC_SONAME,       free,                 free );
    367 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    368 FREE(VG_Z_LIBC_SONAME,       free_common,          free );
    369 #elif defined(VGO_darwin)
    370 ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
    371 #endif
    372 
    373 
    374 /*---------------------- cfree ----------------------*/
    375 
    376 // cfree
    377 FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
    378 FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    379 
    380 
    381 /*---------------------- delete ----------------------*/
    382 // operator delete(void*), not mangled (for gcc 2.96)
    383 FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
    384 FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
    385 
    386 // operator delete(void*), GNU mangling
    387 FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    388 FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
    389 
    390 // operator delete(void*), ARM/cfront mangling
    391 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    392 FREE(VG_Z_LIBC_DOT_A,        __dl__FPv,            __builtin_delete );
    393 #endif
    394 
    395 
    396 /*---------------------- delete nothrow ----------------------*/
    397 
    398 // operator delete(void*, std::nothrow_t const&), GNU mangling
    399 FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    400 FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    401 
    402 
    403 /*---------------------- delete [] ----------------------*/
    404 // operator delete[](void*), not mangled (for gcc 2.96)
    405 FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
    406 FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
    407 
    408 // operator delete[](void*), GNU mangling
    409 FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    410 FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
    411 
    412 // operator delete[](void*), ARM/cfront mangling
    413 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    414 FREE(VG_Z_LIBC_DOT_A,        __vd__FPv,            __builtin_vec_delete );
    415 #endif
    416 
    417 
    418 /*---------------------- delete [] nothrow ----------------------*/
    419 
    420 // operator delete[](void*, std::nothrow_t const&), GNU mangling
    421 FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    422 FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    423 
    424 
    425 /*---------------------- calloc ----------------------*/
    426 
    427 #define ZONECALLOC(soname, fnname) \
    428    \
    429    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size ); \
    430    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT nmemb, SizeT size )  \
    431    { \
    432       void* v; \
    433       \
    434       if (!init_done) init(); \
    435       MALLOC_TRACE("calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
    436       \
    437       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    438       MALLOC_TRACE(" = %p\n", v ); \
    439       return v; \
    440    }
    441 
    442 #define CALLOC(soname, fnname) \
    443    \
    444    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size ); \
    445    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT nmemb, SizeT size )  \
    446    { \
    447       void* v; \
    448       \
    449       if (!init_done) init(); \
    450       MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
    451       \
    452       /* Protect against overflow.  See bug 24078. (that bug number is
    453          invalid.  Which one really?) */ \
    454       /* But don't use division, since that produces an external symbol
    455          reference on ARM, in the form of a call to __aeabi_uidiv.  It's
    456          normally OK, because ld.so manages to resolve it to something in the
    457          executable, or one of its shared objects.  But that isn't guaranteed
    458          to be the case, and it has been observed to fail in rare cases, eg:
    459             echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
    460          So instead compute the high word of the product and check it is zero. */ \
    461       if (umulHW(size, nmemb) != 0) return NULL; \
    462       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    463       MALLOC_TRACE(" = %p\n", v ); \
    464       return v; \
    465    }
    466 
    467 CALLOC(VG_Z_LIBC_SONAME, calloc);
    468 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    469 CALLOC(VG_Z_LIBC_SONAME, calloc_common);
    470 #elif defined(VGO_darwin)
    471 ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
    472 #endif
    473 
    474 
    475 /*---------------------- realloc ----------------------*/
    476 
    477 #define ZONEREALLOC(soname, fnname) \
    478    \
    479    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size );\
    480    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, void* ptrV, SizeT new_size ) \
    481    { \
    482       void* v; \
    483       \
    484       if (!init_done) init(); \
    485       MALLOC_TRACE("realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
    486       \
    487       if (ptrV == NULL) \
    488          /* We need to call a malloc-like function; so let's use \
    489             one which we know exists. GrP fixme use zonemalloc instead? */ \
    490          return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
    491       if (new_size <= 0) { \
    492          VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
    493          MALLOC_TRACE(" = 0\n"); \
    494          return NULL; \
    495       } \
    496       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    497       MALLOC_TRACE(" = %p\n", v ); \
    498       return v; \
    499    }
    500 
    501 #define REALLOC(soname, fnname) \
    502    \
    503    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size );\
    504    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void* ptrV, SizeT new_size ) \
    505    { \
    506       void* v; \
    507       \
    508       if (!init_done) init(); \
    509       MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
    510       \
    511       if (ptrV == NULL) \
    512          /* We need to call a malloc-like function; so let's use \
    513             one which we know exists. */ \
    514          return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,malloc) (new_size); \
    515       if (new_size <= 0) { \
    516          VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,free)(ptrV); \
    517          MALLOC_TRACE(" = 0\n"); \
    518          return NULL; \
    519       } \
    520       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    521       MALLOC_TRACE(" = %p\n", v ); \
    522       return v; \
    523    }
    524 
    525 REALLOC(VG_Z_LIBC_SONAME, realloc);
    526 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    527 REALLOC(VG_Z_LIBC_SONAME, realloc_common);
    528 #elif defined(VGO_darwin)
    529 ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
    530 #endif
    531 
    532 
    533 /*---------------------- memalign ----------------------*/
    534 
    535 #define ZONEMEMALIGN(soname, fnname) \
    536    \
    537    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ); \
    538    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT alignment, SizeT n ) \
    539    { \
    540       void* v; \
    541       \
    542       if (!init_done) init(); \
    543       MALLOC_TRACE("memalign(%p, al %llu, size %llu)", \
    544                    zone, (ULong)alignment, (ULong)n );  \
    545       \
    546       /* Round up to minimum alignment if necessary. */ \
    547       if (alignment < VG_MIN_MALLOC_SZB) \
    548          alignment = VG_MIN_MALLOC_SZB; \
    549       \
    550       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    551       while (0 != (alignment & (alignment - 1))) alignment++; \
    552       \
    553       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    554       MALLOC_TRACE(" = %p\n", v ); \
    555       return v; \
    556    }
    557 
    558 #define MEMALIGN(soname, fnname) \
    559    \
    560    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n ); \
    561    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT alignment, SizeT n )  \
    562    { \
    563       void* v; \
    564       \
    565       if (!init_done) init(); \
    566       MALLOC_TRACE("memalign(al %llu, size %llu)", \
    567                    (ULong)alignment, (ULong)n ); \
    568       \
    569       /* Round up to minimum alignment if necessary. */ \
    570       if (alignment < VG_MIN_MALLOC_SZB) \
    571          alignment = VG_MIN_MALLOC_SZB; \
    572       \
    573       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    574       while (0 != (alignment & (alignment - 1))) alignment++; \
    575       \
    576       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    577       MALLOC_TRACE(" = %p\n", v ); \
    578       return v; \
    579    }
    580 
    581 MEMALIGN(VG_Z_LIBC_SONAME, memalign);
    582 #if defined(VGO_darwin)
    583 ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
    584 #endif
    585 
    586 
    587 /*---------------------- valloc ----------------------*/
    588 
    589 static int local__getpagesize ( void ) {
    590 #  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) || defined(ANDROID)
    591    return 4096; /* kludge - toc problems prevent calling getpagesize() */
    592 #  else
    593    extern int getpagesize (void);
    594    return getpagesize();
    595 #  endif
    596 }
    597 
    598 #define VALLOC(soname, fnname) \
    599    \
    600    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
    601    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size )  \
    602    { \
    603       static int pszB = 0; \
    604       if (pszB == 0) \
    605          pszB = local__getpagesize(); \
    606       return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
    607                 ((SizeT)pszB, size); \
    608    }
    609 
    610 #define ZONEVALLOC(soname, fnname) \
    611    \
    612    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size ); \
    613    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size )  \
    614    { \
    615       static int pszB = 0; \
    616       if (pszB == 0) \
    617          pszB = local__getpagesize(); \
    618       return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
    619                 ((SizeT)pszB, size); \
    620    }
    621 
    622 VALLOC(VG_Z_LIBC_SONAME, valloc);
    623 #if defined(VGO_darwin)
    624 ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
    625 #endif
    626 
    627 
    628 /*---------------------- mallopt ----------------------*/
    629 
    630 /* Various compatibility wrapper functions, for glibc and libstdc++. */
    631 
    632 #define MALLOPT(soname, fnname) \
    633    \
    634    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value ); \
    635    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( int cmd, int value )  \
    636    { \
    637       /* In glibc-2.2.4, 1 denotes a successful return value for \
    638          mallopt */ \
    639       return 1; \
    640    }
    641 
    642 MALLOPT(VG_Z_LIBC_SONAME, mallopt);
    643 
    644 
    645 /*---------------------- malloc_trim ----------------------*/
    646 // Documentation says:
    647 //   malloc_trim(size_t pad);
    648 //
    649 //   If possible, gives memory back to the system (via negative arguments to
    650 //   sbrk) if there is unused memory at the `high' end of the malloc pool.
    651 //   You can call this after freeing large blocks of memory to potentially
    652 //   reduce the system-level memory requirements of a program. However, it
    653 //   cannot guarantee to reduce memory.  Under some allocation patterns,
    654 //   some large free blocks of memory will be locked between two used
    655 //   chunks, so they cannot be given back to the system.
    656 //
    657 //   The `pad' argument to malloc_trim represents the amount of free
    658 //   trailing space to leave untrimmed. If this argument is zero, only the
    659 //   minimum amount of memory to maintain internal data structures will be
    660 //   left (one page or less). Non-zero arguments can be supplied to maintain
    661 //   enough trailing space to service future expected allocations without
    662 //   having to re-obtain memory from the system.
    663 //
    664 //   Malloc_trim returns 1 if it actually released any memory, else 0. On
    665 //   systems that do not support "negative sbrks", it will always return 0.
    666 //
    667 // For simplicity, we always return 0.
    668 #define MALLOC_TRIM(soname, fnname) \
    669    \
    670    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad ); \
    671    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( SizeT pad )  \
    672    { \
    673       /* 0 denotes that malloc_trim() either wasn't able \
    674          to do anything, or was not implemented */ \
    675       return 0; \
    676    }
    677 
    678 MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
    679 
    680 
    681 /*---------------------- posix_memalign ----------------------*/
    682 
    683 #define POSIX_MEMALIGN(soname, fnname) \
    684    \
    685    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
    686                                                  SizeT alignment, SizeT size ); \
    687    int VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void **memptr, \
    688                                                  SizeT alignment, SizeT size )  \
    689    { \
    690       void *mem; \
    691       \
    692       /* Test whether the alignment argument is valid.  It must be \
    693          a power of two multiple of sizeof (void *).  */ \
    694       if (alignment % sizeof (void *) != 0 \
    695           || (alignment & (alignment - 1)) != 0) \
    696          return VKI_EINVAL; \
    697       \
    698       /* Round up to minimum alignment if necessary. */ \
    699       if (alignment < VG_MIN_MALLOC_SZB) \
    700          alignment = VG_MIN_MALLOC_SZB; \
    701       \
    702       mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size); \
    703       \
    704       if (mem != NULL) { \
    705         *memptr = mem; \
    706         return 0; \
    707       } \
    708       \
    709       return VKI_ENOMEM; \
    710    }
    711 
    712 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
    713 #if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    714 /* 27 Nov 07: it appears that xlc links into executables, a
    715    posix_memalign, which calls onwards to memalign_common, with the
    716    same args. */
    717 POSIX_MEMALIGN(VG_Z_LIBC_SONAME, memalign_common);
    718 #endif
    719 
    720 
    721 /*---------------------- malloc_usable_size ----------------------*/
    722 
    723 #define MALLOC_USABLE_SIZE(soname, fnname) \
    724    \
    725    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p ); \
    726    SizeT VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void* p )  \
    727    {  \
    728       SizeT pszB; \
    729       \
    730       if (!init_done) init(); \
    731       MALLOC_TRACE("malloc_usable_size(%p)", p ); \
    732       if (NULL == p) \
    733          return 0; \
    734       \
    735       pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
    736       MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
    737       \
    738       return pszB; \
    739    }
    740 
    741 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
    742 MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
    743 
    744 
    745 /*---------------------- (unimplemented) ----------------------*/
    746 
    747 /* Bomb out if we get any of these. */
    748 
    749 static void panic(const char *str)
    750 {
    751    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
    752    _exit(99);
    753    *(volatile int *)0 = 'x';
    754 }
    755 
    756 #define PANIC(soname, fnname) \
    757    \
    758    void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
    759    void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void )  \
    760    { \
    761       panic(#fnname); \
    762    }
    763 
    764 PANIC(VG_Z_LIBC_SONAME, pvalloc);
    765 PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
    766 PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
    767 
    768 #define MALLOC_STATS(soname, fnname) \
    769    \
    770    void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
    771    void VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void )  \
    772    { \
    773       /* Valgrind's malloc_stats implementation does nothing. */ \
    774    }
    775 
    776 MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
    777 
    778 
    779 /*---------------------- mallinfo ----------------------*/
    780 
    781 // mi must be static;  if it is auto then Memcheck thinks it is
    782 // uninitialised when used by the caller of this function, because Memcheck
    783 // doesn't know that the call to mallinfo fills in mi.
    784 #define MALLINFO(soname, fnname) \
    785    \
    786    struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
    787    struct vg_mallinfo VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void )  \
    788    { \
    789       static struct vg_mallinfo mi; \
    790       if (!init_done) init(); \
    791       MALLOC_TRACE("mallinfo()\n"); \
    792       (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
    793       return mi; \
    794    }
    795 
    796 MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
    797 
    798 
    799 #if defined(VGO_darwin)
    800 
    801 static vki_malloc_zone_t vg_default_zone = {
    802     NULL, // reserved
    803     NULL, // reserved
    804     NULL, // GrP fixme malloc_size
    805     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_malloc),
    806     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_calloc),
    807     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_valloc),
    808     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_free),
    809     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_realloc),
    810     NULL, // GrP fixme destroy
    811     "ValgrindMallocZone",
    812     NULL, // batch_malloc
    813     NULL, // batch_free
    814     NULL, // GrP fixme introspect
    815     2,  // version (GrP fixme 3?)
    816     // DDD: this field exists in Mac OS 10.6, but not 10.5.
    817     #if 0
    818     (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_memalign)
    819     #endif
    820 };
    821 
    822 #define DEFAULT_ZONE(soname, fnname) \
    823    \
    824    void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void ); \
    825    void *VG_REPLACE_FUNCTION_ZU(soname, fnname) ( void )  \
    826    { \
    827       return &vg_default_zone; \
    828    }
    829 
    830 #if defined(VGO_darwin)
    831 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
    832 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
    833 #endif
    834 
    835 // GrP fixme bypass libc's use of zone->introspect->check
    836 #define ZONE_CHECK(soname, fnname) \
    837                                    \
    838    int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone); \
    839    int VG_REPLACE_FUNCTION_ZU(soname, fnname)(void* zone)  \
    840    { \
    841       return 1; \
    842    }
    843 
    844 #if defined(VGO_darwin)
    845 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
    846 #endif
    847 
    848 #endif
    849 
    850 void I_WRAP_SONAME_FNNAME_ZZ(NONE, StopForDebuggerInit) (void *arg);
    851 void I_WRAP_SONAME_FNNAME_ZZ(NONE, StopForDebuggerInit) (void *arg) {
    852   OrigFn fn;
    853   VALGRIND_GET_ORIG_FN(fn);
    854   CALL_FN_v_W(fn, arg);
    855   int res;
    856   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_MEM_START, arg, 0, 0, 0, 0);
    857 }
    858 
    859 int I_WRAP_SONAME_FNNAME_ZZ(NONE, GioMemoryFileSnapshotCtor) (void *a, char *file);
    860 int I_WRAP_SONAME_FNNAME_ZZ(NONE, GioMemoryFileSnapshotCtor) (void *a, char *file) {
    861   OrigFn fn;
    862   int ret;
    863   VALGRIND_GET_ORIG_FN(fn);
    864   CALL_FN_W_WW(ret, fn, a, file);
    865   int res;
    866   VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__NACL_FILE, file, 0, 0, 0, 0);
    867   return ret;
    868 }
    869 
    870 /* Handle tcmalloc (http://code.google.com/p/google-perftools/) */
    871 
    872 /* tc_ functions (used when tcmalloc is running in release mode) */
    873 ALLOC_or_NULL(NONE,tc_malloc,malloc);
    874 ALLOC_or_BOMB(NONE,tc_new,__builtin_new);
    875 ALLOC_or_NULL(NONE,tc_new_nothrow,__builtin_new);
    876 ALLOC_or_BOMB(NONE,tc_newarray,__builtin_vec_new);
    877 ALLOC_or_NULL(NONE,tc_newarray_nothrow,__builtin_vec_new);
    878 FREE(NONE,tc_free,free);
    879 FREE(NONE,tc_cfree,free);
    880 FREE(NONE,tc_delete,__builtin_delete);
    881 FREE(NONE,tc_delete_nothrow,__builtin_delete);
    882 FREE(NONE,tc_deletearray,__builtin_vec_delete);
    883 FREE(NONE,tc_deletearray_nothrow,__builtin_vec_delete);
    884 CALLOC(NONE,tc_calloc);
    885 REALLOC(NONE,tc_realloc);
    886 VALLOC(NONE,tc_valloc);
    887 MEMALIGN(NONE,tc_memalign);
    888 MALLOPT(NONE,tc_mallopt);
    889 POSIX_MEMALIGN(NONE,tc_posix_memalign);
    890 MALLOC_USABLE_SIZE(NONE,tc_malloc_size);
    891 MALLINFO(NONE,tc_mallinfo);
    892 
    893 /* Python */
    894 ALLOC_or_NULL(NONE, PyObject_Malloc,   malloc);
    895 FREE(NONE,          PyObject_Free,     free);
    896 REALLOC(NONE,       PyObject_Realloc);
    897 
    898 /* Interceptors for custom malloc functions in user code
    899    (NONE, malloc). We need these to intercept tcmalloc in debug builds.
    900    TODO(kcc): get rid of these once we have tc_malloc/tc_new/etc
    901    in tcmalloc's debugallocation.cc
    902  */
    903 ALLOC_or_NULL(NONE,  malloc,               malloc);
    904 ALLOC_or_BOMB(NONE,  _Znwj,                __builtin_new);
    905 ALLOC_or_BOMB(NONE,  _Znwm,                __builtin_new);
    906 ALLOC_or_NULL(NONE,  _ZnwjRKSt9nothrow_t,  __builtin_new);
    907 ALLOC_or_NULL(NONE,  _ZnwmRKSt9nothrow_t,  __builtin_new);
    908 ALLOC_or_BOMB(NONE,  _Znaj,                __builtin_vec_new);
    909 ALLOC_or_BOMB(NONE,  _Znam,                __builtin_vec_new);
    910 ALLOC_or_NULL(NONE,  _ZnajRKSt9nothrow_t,  __builtin_vec_new);
    911 ALLOC_or_NULL(NONE,  _ZnamRKSt9nothrow_t,  __builtin_vec_new);
    912 FREE(NONE,  free,                 free );
    913 FREE(NONE,  cfree,                free );
    914 FREE(NONE,  _ZdlPv,               __builtin_delete );
    915 FREE(NONE,  _ZdlPvRKSt9nothrow_t, __builtin_delete );
    916 FREE(NONE,  _ZdaPv,               __builtin_vec_delete );
    917 FREE(NONE,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    918 CALLOC(NONE,   calloc);
    919 REALLOC(NONE,  realloc);
    920 MEMALIGN(NONE, memalign);
    921 VALLOC(NONE,   valloc);
    922 MALLOPT(NONE,  mallopt);
    923 MALLOC_TRIM(NONE,            malloc_trim);
    924 POSIX_MEMALIGN(NONE,         posix_memalign);
    925 MALLOC_USABLE_SIZE(NONE,     malloc_usable_size);
    926 MALLINFO(NONE,               mallinfo);
    927 
    928 // TODO(kcc): these are interceptors for bash's malloc.
    929 // The bash interpretor has functions malloc() and sh_malloc()
    930 // as well as free() and sh_free(). And sometimes they are called
    931 // inconsistently (malloc, then sh_free).
    932 // So, if we intercept malloc/free, we also need to intercept
    933 // sh_malloc/sh_free.
    934 //
    935 // Standard valgrind does not intercept user's malloc, so it does not have this
    936 // problem.
    937 //
    938 // Get rid of these once we are able to intercept tcmalloc
    939 // w/o intercepting (NONE,malloc)
    940 ALLOC_or_NULL(NONE,       sh_malloc,   malloc);
    941 FREE(NONE,                sh_free,     free );
    942 FREE(NONE,                sh_cfree,    free );
    943 CALLOC(NONE,              sh_calloc);
    944 REALLOC(NONE,             sh_realloc);
    945 MEMALIGN(NONE,            sh_memalign);
    946 VALLOC(NONE,              sh_valloc);
    947 
    948 /*------- alternative to RUNNING_ON_VALGRIND client request -----*/
    949 
    950 #define ANN_FUNC0(ret_ty, f) \
    951     ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void); \
    952     ret_ty I_WRAP_SONAME_FNNAME_ZZ(NONE,f)(void)
    953 
    954 ANN_FUNC0(int, RunningOnValgrind) { return 1; }
    955 
    956 
    957 /* All the code in here is unused until this function is called */
    958 
    959 __attribute__((constructor))
    960 static void init(void)
    961 {
    962    int res;
    963 
    964    // This doesn't look thread-safe, but it should be ok... Bart says:
    965    //
    966    //   Every program I know of calls malloc() at least once before calling
    967    //   pthread_create().  So init_done gets initialized before any thread is
    968    //   created, and is only read when multiple threads are active
    969    //   simultaneously.  Such an access pattern is safe.
    970    //
    971    //   If the assignment to the variable init_done would be triggering a race
    972    //   condition, both DRD and Helgrind would report this race.
    973    //
    974    //   By the way, although the init() function in
    975    //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
    976    //   __attribute__((constructor)), it is not safe to remove the variable
    977    //   init_done. This is because it is possible that malloc() and hence
    978    //   init() gets called before shared library initialization finished.
    979    //
    980    if (init_done)
    981       return;
    982 
    983    init_done = 1;
    984 
    985    VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
    986                               0, 0, 0, 0);
    987 }
    988 
    989 /*--------------------------------------------------------------------*/
    990 /*--- end                                                          ---*/
    991 /*--------------------------------------------------------------------*/
    992