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-2015 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 CREATE_ZONE
     98    10230 ZONE_FROM_PTR
     99    10240 ZONE_CHECK
    100    10250 ZONE_REGISTER
    101    10260 ZONE_UNREGISTER
    102    10270 ZONE_SET_NAME
    103    10280 ZONE_GET_NAME
    104 */
    105 
    106 /* 2 Apr 05: the Portland Group compiler, which uses cfront/ARM style
    107    mangling, could be supported properly by the redirects in this
    108    module.  Except we can't because it doesn't put its allocation
    109    functions in libpgc.so but instead hardwires them into the
    110    compilation unit holding main(), which makes them impossible to
    111    intercept directly.  Fortunately those fns seem to route everything
    112    through to malloc/free.
    113 
    114    mid-06: could be improved, since we can now intercept in the main
    115    executable too.
    116 */
    117 
    118 
    119 
    120 /* Call here to exit if we can't continue.  On Android we can't call
    121    _exit for some reason, so we have to blunt-instrument it. */
    122 __attribute__ ((__noreturn__))
    123 static inline void my_exit ( int x )
    124 {
    125 #  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
    126       || defined(VGPV_arm64_linux_android)
    127    __asm__ __volatile__(".word 0xFFFFFFFF");
    128    while (1) {}
    129 #  elif defined(VGPV_x86_linux_android)
    130    __asm__ __volatile__("ud2");
    131    while (1) {}
    132 #  else
    133    extern __attribute__ ((__noreturn__)) void _exit(int status);
    134    _exit(x);
    135 #  endif
    136 }
    137 
    138 /* Same problem with getpagesize. */
    139 static inline int my_getpagesize ( void )
    140 {
    141 #  if defined(VGPV_arm_linux_android) \
    142       || defined(VGPV_x86_linux_android) \
    143       || defined(VGPV_mips32_linux_android) \
    144       || defined(VGPV_arm64_linux_android)
    145    return 4096; /* kludge - link failure on Android, for some reason */
    146 #  else
    147    extern int getpagesize (void);
    148    return getpagesize();
    149 #  endif
    150 }
    151 
    152 
    153 /* Compute the high word of the double-length unsigned product of U
    154    and V.  This is for calloc argument overflow checking; see comments
    155    below.  Algorithm as described in Hacker's Delight, chapter 8. */
    156 static UWord umulHW ( UWord u, UWord v )
    157 {
    158    UWord u0, v0, w0, rHi;
    159    UWord u1, v1, w1,w2,t;
    160    UWord halfMask  = sizeof(UWord)==4 ? (UWord)0xFFFF
    161                                       : (UWord)0xFFFFFFFFULL;
    162    UWord halfShift = sizeof(UWord)==4 ? 16 : 32;
    163    u0  = u & halfMask;
    164    u1  = u >> halfShift;
    165    v0  = v & halfMask;
    166    v1  = v >> halfShift;
    167    w0  = u0 * v0;
    168    t   = u1 * v0 + (w0 >> halfShift);
    169    w1  = t & halfMask;
    170    w2  = t >> halfShift;
    171    w1  = u0 * v1 + w1;
    172    rHi = u1 * v1 + w2 + (w1 >> halfShift);
    173    return rHi;
    174 }
    175 
    176 
    177 /*------------------------------------------------------------*/
    178 /*--- Replacing malloc() et al                             ---*/
    179 /*------------------------------------------------------------*/
    180 
    181 /* This struct is initially empty.  Before the first use of any of
    182    these functions, we make a client request which fills in the
    183    fields.
    184 */
    185 static struct vg_mallocfunc_info info;
    186 static int init_done;
    187 #define DO_INIT if (UNLIKELY(!init_done)) init()
    188 
    189 /* Startup hook - called as init section */
    190 __attribute__((constructor))
    191 static void init(void);
    192 
    193 #define MALLOC_TRACE(format, args...)  \
    194    if (info.clo_trace_malloc) {        \
    195       VALGRIND_INTERNAL_PRINTF(format, ## args ); }
    196 
    197 /* Below are new versions of malloc, __builtin_new, free,
    198    __builtin_delete, calloc, realloc, memalign, and friends.
    199 
    200    None of these functions are called directly - they are not meant to
    201    be found by the dynamic linker.  But ALL client calls to malloc()
    202    and friends wind up here eventually.  They get called because
    203    vg_replace_malloc installs a bunch of code redirects which causes
    204    Valgrind to use these functions rather than the ones they're
    205    replacing.
    206 */
    207 
    208 /* The replacement functions are running on the simulated CPU.
    209    The code on the simulated CPU does not necessarily use
    210    all arguments. E.g. args can be ignored and/or only given
    211    to a NON SIMD call.
    212    The definedness of such 'unused' arguments will not be verified
    213    by memcheck.
    214    The macro 'TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED' allows
    215    memcheck to detect such errors for the otherwise unused args.
    216    Apart of allowing memcheck to detect an error, the macro
    217    TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED has no effect and
    218    has a minimal cost for other tools replacing malloc functions.
    219 */
    220 #define TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(x) \
    221    if ((ULong)x == 0) __asm__ __volatile__( "" ::: "memory" )
    222 
    223 /*---------------------- malloc ----------------------*/
    224 
    225 /* Generate a replacement for 'fnname' in object 'soname', which calls
    226    'vg_replacement' to allocate memory.  If that fails, return NULL.
    227 */
    228 #define ALLOC_or_NULL(soname, fnname, vg_replacement) \
    229    \
    230    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n); \
    231    void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n)  \
    232    { \
    233       void* v; \
    234       \
    235       DO_INIT; \
    236       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
    237       MALLOC_TRACE(#fnname "(%llu)", (ULong)n ); \
    238       \
    239       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    240       MALLOC_TRACE(" = %p\n", v ); \
    241       return v; \
    242    }
    243 
    244 #define ZONEALLOC_or_NULL(soname, fnname, vg_replacement) \
    245    \
    246    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n); \
    247    void* VG_REPLACE_FUNCTION_EZU(10020,soname,fnname) (void *zone, SizeT n)  \
    248    { \
    249       void* v; \
    250       \
    251       DO_INIT; \
    252       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	\
    253       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n);                   \
    254       MALLOC_TRACE(#fnname "(%p, %llu)", zone, (ULong)n ); \
    255       \
    256       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    257       MALLOC_TRACE(" = %p\n", v ); \
    258       return v; \
    259    }
    260 
    261 
    262 /* Generate a replacement for 'fnname' in object 'soname', which calls
    263    'vg_replacement' to allocate memory.  If that fails, it bombs the
    264    system.
    265 */
    266 #define ALLOC_or_BOMB(soname, fnname, vg_replacement)  \
    267    \
    268    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n); \
    269    void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n)  \
    270    { \
    271       void* v; \
    272       \
    273       DO_INIT; \
    274       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n);           \
    275       MALLOC_TRACE(#fnname "(%llu)", (ULong)n );        \
    276       \
    277       v = (void*)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, n ); \
    278       MALLOC_TRACE(" = %p\n", v ); \
    279       if (NULL == v) { \
    280          VALGRIND_PRINTF( \
    281             "new/new[] failed and should throw an exception, but Valgrind\n"); \
    282          VALGRIND_PRINTF_BACKTRACE( \
    283             "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
    284             my_exit(1); \
    285       } \
    286       return v; \
    287    }
    288 
    289 // Each of these lines generates a replacement function:
    290 //     (from_so, from_fn,  v's replacement)
    291 // For some lines, we will also define a replacement function
    292 // whose only purpose is to be a soname synonym place holder
    293 // that can be replaced using --soname-synonyms.
    294 #define SO_SYN_MALLOC VG_SO_SYN(somalloc)
    295 
    296 // malloc
    297 #if defined(VGO_linux)
    298  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
    299  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    300  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
    301 
    302 #elif defined(VGO_darwin)
    303  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    304  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
    305  ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME,  malloc_zone_malloc, malloc);
    306  ZONEALLOC_or_NULL(SO_SYN_MALLOC,     malloc_zone_malloc, malloc);
    307 
    308 #elif defined(VGO_solaris)
    309  ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc,      malloc);
    310  ALLOC_or_NULL(VG_Z_LIBC_SONAME,      malloc,      malloc);
    311  ALLOC_or_NULL(VG_Z_LIBUMEM_SO_1,     malloc,      malloc);
    312  ALLOC_or_NULL(SO_SYN_MALLOC,         malloc,      malloc);
    313 
    314 #endif
    315 
    316 
    317 /*---------------------- new ----------------------*/
    318 
    319 #if defined(VGO_linux)
    320  // operator new(unsigned int), not mangled (for gcc 2.96)
    321  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  builtin_new,    __builtin_new);
    322  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       builtin_new,    __builtin_new);
    323  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_new,  __builtin_new);
    324  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_new,  __builtin_new);
    325  // operator new(unsigned int), GNU mangling
    326  #if VG_WORDSIZE == 4
    327   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    328   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
    329   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
    330  #endif
    331  // operator new(unsigned long), GNU mangling
    332  #if VG_WORDSIZE == 8
    333   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    334   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
    335   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
    336  #endif
    337 
    338 #elif defined(VGO_darwin)
    339  // operator new(unsigned int), GNU mangling
    340  #if VG_WORDSIZE == 4
    341   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    342   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwj,          __builtin_new);
    343  #endif
    344  // operator new(unsigned long), GNU mangling
    345  #if 1 // FIXME: is this right?
    346   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    347   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znwm,          __builtin_new);
    348  #endif
    349 
    350 #elif defined(VGO_solaris)
    351  // operator new(unsigned int), GNU mangling
    352  #if VG_WORDSIZE == 4
    353   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj,          __builtin_new);
    354   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwj,          __builtin_new);
    355  #endif
    356  // operator new(unsigned long), GNU mangling
    357  #if VG_WORDSIZE == 8
    358   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm,          __builtin_new);
    359   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znwm,          __builtin_new);
    360  #endif
    361 
    362 #endif
    363 
    364 
    365 /*---------------------- new nothrow ----------------------*/
    366 
    367 #if defined(VGO_linux)
    368  // operator new(unsigned, std::nothrow_t const&), GNU mangling
    369  #if VG_WORDSIZE == 4
    370   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    371   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
    372   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
    373  #endif
    374  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    375  #if VG_WORDSIZE == 8
    376   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    377   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
    378   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
    379  #endif
    380 
    381 #elif defined(VGO_darwin)
    382  // operator new(unsigned, std::nothrow_t const&), GNU mangling
    383  #if VG_WORDSIZE == 4
    384   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    385   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwjRKSt9nothrow_t,  __builtin_new);
    386  #endif
    387  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    388  #if 1 // FIXME: is this right?
    389   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    390   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnwmRKSt9nothrow_t,  __builtin_new);
    391  #endif
    392 
    393 #elif defined(VGO_solaris)
    394  // operator new(unsigned, std::nothrow_t const&), GNU mangling
    395  #if VG_WORDSIZE == 4
    396   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t,  __builtin_new);
    397   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwjRKSt9nothrow_t,  __builtin_new);
    398  #endif
    399  // operator new(unsigned long, std::nothrow_t const&), GNU mangling
    400  #if VG_WORDSIZE == 8
    401   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t,  __builtin_new);
    402   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnwmRKSt9nothrow_t,  __builtin_new);
    403  #endif
    404 
    405 #endif
    406 
    407 
    408 /*---------------------- new [] ----------------------*/
    409 
    410 #if defined(VGO_linux)
    411  // operator new[](unsigned int), not mangled (for gcc 2.96)
    412  ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME,  __builtin_vec_new, __builtin_vec_new );
    413  ALLOC_or_BOMB(VG_Z_LIBC_SONAME,       __builtin_vec_new, __builtin_vec_new );
    414  // operator new[](unsigned int), GNU mangling
    415  #if VG_WORDSIZE == 4
    416   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    417   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
    418   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
    419  #endif
    420  // operator new[](unsigned long), GNU mangling
    421  #if VG_WORDSIZE == 8
    422   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    423   ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
    424   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
    425  #endif
    426 
    427 #elif defined(VGO_darwin)
    428  // operator new[](unsigned int), GNU mangling
    429  #if VG_WORDSIZE == 4
    430   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    431   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znaj,             __builtin_vec_new );
    432  #endif
    433  // operator new[](unsigned long), GNU mangling
    434  #if 1 // FIXME: is this right?
    435   //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    436   //ALLOC_or_BOMB(VG_Z_LIBC_SONAME,      _Znam,             __builtin_vec_new );
    437  #endif
    438 
    439 #elif defined(VGO_solaris)
    440  // operator new[](unsigned int), GNU mangling
    441  #if VG_WORDSIZE == 4
    442   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj,             __builtin_vec_new );
    443   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znaj,             __builtin_vec_new );
    444  #endif
    445  // operator new[](unsigned long), GNU mangling
    446  #if VG_WORDSIZE == 8
    447   ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam,             __builtin_vec_new );
    448   ALLOC_or_BOMB(SO_SYN_MALLOC,         _Znam,             __builtin_vec_new );
    449  #endif
    450 
    451 #endif
    452 
    453 
    454 /*---------------------- new [] nothrow ----------------------*/
    455 
    456 #if defined(VGO_linux)
    457  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    458  #if VG_WORDSIZE == 4
    459   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    460   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
    461   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
    462  #endif
    463  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    464  #if VG_WORDSIZE == 8
    465   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    466   ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
    467   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
    468  #endif
    469 
    470 #elif defined(VGO_darwin)
    471  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    472  #if VG_WORDSIZE == 4
    473   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    474   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnajRKSt9nothrow_t, __builtin_vec_new );
    475  #endif
    476  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    477  #if 1 // FIXME: is this right?
    478   //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    479   //ALLOC_or_NULL(VG_Z_LIBC_SONAME,      _ZnamRKSt9nothrow_t, __builtin_vec_new );
    480  #endif
    481 
    482 #elif defined(VGO_solaris)
    483  // operator new[](unsigned, std::nothrow_t const&), GNU mangling
    484  #if VG_WORDSIZE == 4
    485   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
    486   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnajRKSt9nothrow_t, __builtin_vec_new );
    487  #endif
    488  // operator new[](unsigned long, std::nothrow_t const&), GNU mangling
    489  #if VG_WORDSIZE == 8
    490   ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
    491   ALLOC_or_NULL(SO_SYN_MALLOC,         _ZnamRKSt9nothrow_t, __builtin_vec_new );
    492  #endif
    493 
    494 #endif
    495 
    496 
    497 /*---------------------- free ----------------------*/
    498 
    499 /* Generate a replacement for 'fnname' in object 'soname', which calls
    500    'vg_replacement' to free previously allocated memory.
    501 */
    502 #define ZONEFREE(soname, fnname, vg_replacement) \
    503    \
    504    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p); \
    505    void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p)  \
    506    { \
    507       DO_INIT; \
    508       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	\
    509       MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
    510       if (p == NULL)  \
    511          return; \
    512       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    513    }
    514 
    515 #define FREE(soname, fnname, vg_replacement) \
    516    \
    517    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p); \
    518    void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p)  \
    519    { \
    520       DO_INIT; \
    521       MALLOC_TRACE(#fnname "(%p)\n", p ); \
    522       if (p == NULL)  \
    523          return; \
    524       (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
    525    }
    526 
    527 
    528 #if defined(VGO_linux)
    529  FREE(VG_Z_LIBSTDCXX_SONAME,  free,                 free );
    530  FREE(VG_Z_LIBC_SONAME,       free,                 free );
    531  FREE(SO_SYN_MALLOC,          free,                 free );
    532 
    533 #elif defined(VGO_darwin)
    534  FREE(VG_Z_LIBC_SONAME,       free,                 free );
    535  FREE(SO_SYN_MALLOC,          free,                 free );
    536  ZONEFREE(VG_Z_LIBC_SONAME,   malloc_zone_free,     free );
    537  ZONEFREE(SO_SYN_MALLOC,      malloc_zone_free,     free );
    538 
    539 #elif defined(VGO_solaris)
    540  FREE(VG_Z_LIBC_SONAME,       free,                 free );
    541  FREE(VG_Z_LIBUMEM_SO_1,      free,                 free );
    542  FREE(SO_SYN_MALLOC,          free,                 free );
    543 
    544 #endif
    545 
    546 
    547 /*---------------------- cfree ----------------------*/
    548 
    549 // cfree
    550 #if defined(VGO_linux)
    551  FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
    552  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    553  FREE(SO_SYN_MALLOC,          cfree,                free );
    554 
    555 #elif defined(VGO_darwin)
    556  //FREE(VG_Z_LIBSTDCXX_SONAME,  cfree,                free );
    557  //FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    558 
    559 #elif defined(VGO_solaris)
    560  FREE(VG_Z_LIBC_SONAME,       cfree,                free );
    561  /* libumem does not implement cfree(). */
    562  //FREE(VG_Z_LIBUMEM_SO_1,      cfree,                free );
    563  FREE(SO_SYN_MALLOC,          cfree,                free );
    564 
    565 #endif
    566 
    567 
    568 /*---------------------- delete ----------------------*/
    569 
    570 #if defined(VGO_linux)
    571  // operator delete(void*), not mangled (for gcc 2.96)
    572  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_delete,     __builtin_delete );
    573  FREE(VG_Z_LIBC_SONAME,        __builtin_delete,     __builtin_delete );
    574  // operator delete(void*), GNU mangling
    575  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    576  FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
    577  FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
    578 
    579 #elif defined(VGO_darwin)
    580  // operator delete(void*), GNU mangling
    581  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    582  //FREE(VG_Z_LIBC_SONAME,       _ZdlPv,               __builtin_delete );
    583 
    584 #elif defined(VGO_solaris)
    585  // operator delete(void*), GNU mangling
    586  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdlPv,               __builtin_delete );
    587  FREE(SO_SYN_MALLOC,          _ZdlPv,               __builtin_delete );
    588 
    589 #endif
    590 
    591 
    592 /*---------------------- delete nothrow ----------------------*/
    593 
    594 #if defined(VGO_linux)
    595  // operator delete(void*, std::nothrow_t const&), GNU mangling
    596  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    597  FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    598  FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    599 
    600 #elif defined(VGO_darwin)
    601  // operator delete(void*, std::nothrow_t const&), GNU mangling
    602  //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    603  //FREE(VG_Z_LIBC_SONAME,      _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    604 
    605 #elif defined(VGO_solaris)
    606  // operator delete(void*, std::nothrow_t const&), GNU mangling
    607  FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    608  FREE(SO_SYN_MALLOC,         _ZdlPvRKSt9nothrow_t,  __builtin_delete );
    609 
    610 #endif
    611 
    612 
    613 /*---------------------- delete [] ----------------------*/
    614 
    615 #if defined(VGO_linux)
    616  // operator delete[](void*), not mangled (for gcc 2.96)
    617  FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
    618  FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
    619  // operator delete[](void*), GNU mangling
    620  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    621  FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
    622  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
    623 
    624 #elif defined(VGO_darwin)
    625  // operator delete[](void*), not mangled (for gcc 2.96)
    626  //FREE(VG_Z_LIBSTDCXX_SONAME,   __builtin_vec_delete, __builtin_vec_delete );
    627  //FREE(VG_Z_LIBC_SONAME,        __builtin_vec_delete, __builtin_vec_delete );
    628  // operator delete[](void*), GNU mangling
    629  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    630  //FREE(VG_Z_LIBC_SONAME,       _ZdaPv,               __builtin_vec_delete );
    631 
    632 #elif defined(VGO_solaris)
    633  // operator delete[](void*), GNU mangling
    634  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
    635  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
    636 
    637 #endif
    638 
    639 
    640 /*---------------------- delete [] nothrow ----------------------*/
    641 
    642 #if defined(VGO_linux)
    643  // operator delete[](void*, std::nothrow_t const&), GNU mangling
    644  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    645  FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    646  FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    647 
    648 #elif defined(VGO_darwin)
    649  // operator delete[](void*, std::nothrow_t const&), GNU mangling
    650  //FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    651  //FREE(VG_Z_LIBC_SONAME,       _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    652 
    653 #elif defined(VGO_solaris)
    654  // operator delete[](void*, std::nothrow_t const&), GNU mangling
    655  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    656  FREE(SO_SYN_MALLOC,          _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
    657 
    658 #endif
    659 
    660 
    661 /*---------------------- calloc ----------------------*/
    662 
    663 #define ZONECALLOC(soname, fnname) \
    664    \
    665    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
    666             ( void *zone, SizeT nmemb, SizeT size ); \
    667    void* VG_REPLACE_FUNCTION_EZU(10060,soname,fnname) \
    668             ( void *zone, SizeT nmemb, SizeT size )  \
    669    { \
    670       void* v; \
    671       \
    672       DO_INIT; \
    673       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \
    674       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \
    675       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
    676       MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
    677       \
    678       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    679       MALLOC_TRACE(" = %p\n", v ); \
    680       return v; \
    681    }
    682 
    683 #define CALLOC(soname, fnname) \
    684    \
    685    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
    686             ( SizeT nmemb, SizeT size ); \
    687    void* VG_REPLACE_FUNCTION_EZU(10070,soname,fnname) \
    688             ( SizeT nmemb, SizeT size )  \
    689    { \
    690       void* v; \
    691       \
    692       DO_INIT; \
    693       MALLOC_TRACE("calloc(%llu,%llu)", (ULong)nmemb, (ULong)size ); \
    694       \
    695       /* Protect against overflow.  See bug 24078. (that bug number is
    696          invalid.  Which one really?) */ \
    697       /* But don't use division, since that produces an external symbol
    698          reference on ARM, in the form of a call to __aeabi_uidiv.  It's
    699          normally OK, because ld.so manages to resolve it to something in the
    700          executable, or one of its shared objects.  But that isn't guaranteed
    701          to be the case, and it has been observed to fail in rare cases, eg:
    702             echo x | valgrind /bin/sed -n "s/.*-\>\ //p"
    703          So instead compute the high word of the product and check it is zero. */ \
    704       if (umulHW(size, nmemb) != 0) return NULL; \
    705       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
    706       MALLOC_TRACE(" = %p\n", v ); \
    707       return v; \
    708    }
    709 
    710 #if defined(VGO_linux)
    711  CALLOC(VG_Z_LIBC_SONAME, calloc);
    712  CALLOC(SO_SYN_MALLOC,    calloc);
    713 
    714 #elif defined(VGO_darwin)
    715  CALLOC(VG_Z_LIBC_SONAME, calloc);
    716  CALLOC(SO_SYN_MALLOC,    calloc);
    717  ZONECALLOC(VG_Z_LIBC_SONAME, malloc_zone_calloc);
    718  ZONECALLOC(SO_SYN_MALLOC,    malloc_zone_calloc);
    719 
    720 #elif defined(VGO_solaris)
    721  CALLOC(VG_Z_LIBC_SONAME,      calloc);
    722  CALLOC(VG_Z_LIBUMEM_SO_1,     calloc);
    723  CALLOC(SO_SYN_MALLOC,         calloc);
    724 
    725 #endif
    726 
    727 
    728 /*---------------------- realloc ----------------------*/
    729 
    730 #define ZONEREALLOC(soname, fnname) \
    731    \
    732    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
    733             ( void *zone, void* ptrV, SizeT new_size ); \
    734    void* VG_REPLACE_FUNCTION_EZU(10080,soname,fnname) \
    735             ( void *zone, void* ptrV, SizeT new_size ) \
    736    { \
    737       void* v; \
    738       \
    739       DO_INIT; \
    740       MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
    741       \
    742       if (ptrV == NULL) \
    743          /* We need to call a malloc-like function; so let's use \
    744             one which we know exists. GrP fixme use zonemalloc instead? */ \
    745          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
    746                    (new_size); \
    747       if (new_size <= 0) { \
    748          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
    749          MALLOC_TRACE(" = 0\n"); \
    750          return NULL; \
    751       } \
    752       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    753       MALLOC_TRACE(" = %p\n", v ); \
    754       return v; \
    755    }
    756 
    757 #define REALLOC(soname, fnname) \
    758    \
    759    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
    760             ( void* ptrV, SizeT new_size );\
    761    void* VG_REPLACE_FUNCTION_EZU(10090,soname,fnname) \
    762             ( void* ptrV, SizeT new_size ) \
    763    { \
    764       void* v; \
    765       \
    766       DO_INIT; \
    767       MALLOC_TRACE("realloc(%p,%llu)", ptrV, (ULong)new_size ); \
    768       \
    769       if (ptrV == NULL) \
    770          /* We need to call a malloc-like function; so let's use \
    771             one which we know exists. */ \
    772          return VG_REPLACE_FUNCTION_EZU(10010,VG_Z_LIBC_SONAME,malloc) \
    773                    (new_size); \
    774       if (new_size <= 0) { \
    775          VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \
    776          MALLOC_TRACE(" = 0\n"); \
    777          return NULL; \
    778       } \
    779       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, new_size ); \
    780       MALLOC_TRACE(" = %p\n", v ); \
    781       return v; \
    782    }
    783 
    784 #if defined(VGO_linux)
    785  REALLOC(VG_Z_LIBC_SONAME, realloc);
    786  REALLOC(SO_SYN_MALLOC,    realloc);
    787 
    788 #elif defined(VGO_darwin)
    789  REALLOC(VG_Z_LIBC_SONAME, realloc);
    790  REALLOC(SO_SYN_MALLOC,    realloc);
    791  ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc);
    792  ZONEREALLOC(SO_SYN_MALLOC,    malloc_zone_realloc);
    793 
    794 #elif defined(VGO_solaris)
    795  REALLOC(VG_Z_LIBC_SONAME,      realloc);
    796  REALLOC(VG_Z_LIBUMEM_SO_1,     realloc);
    797  REALLOC(SO_SYN_MALLOC,         realloc);
    798 
    799 #endif
    800 
    801 
    802 /*---------------------- memalign ----------------------*/
    803 
    804 #define ZONEMEMALIGN(soname, fnname) \
    805    \
    806    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
    807             ( void *zone, SizeT alignment, SizeT n ); \
    808    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
    809             ( void *zone, SizeT alignment, SizeT n ) \
    810    { \
    811       void* v; \
    812       \
    813       DO_INIT; \
    814       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	\
    815       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
    816       MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
    817                    zone, (ULong)alignment, (ULong)n );  \
    818       \
    819       /* Round up to minimum alignment if necessary. */ \
    820       if (alignment < VG_MIN_MALLOC_SZB) \
    821          alignment = VG_MIN_MALLOC_SZB; \
    822       \
    823       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    824       while (0 != (alignment & (alignment - 1))) alignment++; \
    825       \
    826       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    827       MALLOC_TRACE(" = %p\n", v ); \
    828       return v; \
    829    }
    830 
    831 #define MEMALIGN(soname, fnname) \
    832    \
    833    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
    834             ( SizeT alignment, SizeT n ); \
    835    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
    836             ( SizeT alignment, SizeT n )  \
    837    { \
    838       void* v; \
    839       \
    840       DO_INIT; \
    841       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
    842       MALLOC_TRACE("memalign(al %llu, size %llu)", \
    843                    (ULong)alignment, (ULong)n ); \
    844       \
    845       /* Round up to minimum alignment if necessary. */ \
    846       if (alignment < VG_MIN_MALLOC_SZB) \
    847          alignment = VG_MIN_MALLOC_SZB; \
    848       \
    849       /* Round up to nearest power-of-two if necessary (like glibc). */ \
    850       while (0 != (alignment & (alignment - 1))) alignment++; \
    851       \
    852       v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \
    853       MALLOC_TRACE(" = %p\n", v ); \
    854       return v; \
    855    }
    856 
    857 #if defined(VGO_linux)
    858  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
    859  MEMALIGN(SO_SYN_MALLOC,    memalign);
    860 
    861 #elif defined(VGO_darwin)
    862  MEMALIGN(VG_Z_LIBC_SONAME, memalign);
    863  MEMALIGN(SO_SYN_MALLOC,    memalign);
    864  ZONEMEMALIGN(VG_Z_LIBC_SONAME, malloc_zone_memalign);
    865  ZONEMEMALIGN(SO_SYN_MALLOC,    malloc_zone_memalign);
    866 
    867 #elif defined(VGO_solaris)
    868  MEMALIGN(VG_Z_LIBC_SONAME,      memalign);
    869  MEMALIGN(VG_Z_LIBUMEM_SO_1,     memalign);
    870  MEMALIGN(SO_SYN_MALLOC,         memalign);
    871 
    872 #endif
    873 
    874 
    875 /*---------------------- valloc ----------------------*/
    876 
    877 #define VALLOC(soname, fnname) \
    878    \
    879    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ); \
    880    void* VG_REPLACE_FUNCTION_EZU(10120,soname,fnname) ( SizeT size ) \
    881    { \
    882       static int pszB = 0; \
    883       if (pszB == 0) \
    884          pszB = my_getpagesize(); \
    885       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
    886                 ((SizeT)pszB, size); \
    887    }
    888 
    889 #define ZONEVALLOC(soname, fnname) \
    890    \
    891    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
    892             ( void *zone, SizeT size ); \
    893    void* VG_REPLACE_FUNCTION_EZU(10130,soname,fnname) \
    894             ( void *zone, SizeT size )  \
    895    { \
    896       static int pszB = 0; \
    897       if (pszB == 0) \
    898          pszB = my_getpagesize(); \
    899       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);	      \
    900       return VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
    901                 ((SizeT)pszB, size); \
    902    }
    903 
    904 #if defined(VGO_linux)
    905  VALLOC(VG_Z_LIBC_SONAME, valloc);
    906  VALLOC(SO_SYN_MALLOC, valloc);
    907 
    908 #elif defined(VGO_darwin)
    909  VALLOC(VG_Z_LIBC_SONAME, valloc);
    910  VALLOC(SO_SYN_MALLOC, valloc);
    911  ZONEVALLOC(VG_Z_LIBC_SONAME, malloc_zone_valloc);
    912  ZONEVALLOC(SO_SYN_MALLOC,    malloc_zone_valloc);
    913 
    914 #elif defined(VGO_solaris)
    915  VALLOC(VG_Z_LIBC_SONAME,      valloc);
    916  VALLOC(VG_Z_LIBUMEM_SO_1,     valloc);
    917  VALLOC(SO_SYN_MALLOC,         valloc);
    918 
    919 #endif
    920 
    921 
    922 /*---------------------- mallopt ----------------------*/
    923 
    924 /* Various compatibility wrapper functions, for glibc and libstdc++. */
    925 
    926 #define MALLOPT(soname, fnname) \
    927    \
    928    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ); \
    929    int VG_REPLACE_FUNCTION_EZU(10140,soname,fnname) ( int cmd, int value ) \
    930    { \
    931       /* In glibc-2.2.4, 1 denotes a successful return value for \
    932          mallopt */ \
    933       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(cmd); \
    934       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(value); \
    935       return 1; \
    936    }
    937 
    938 #if defined(VGO_linux)
    939  MALLOPT(VG_Z_LIBC_SONAME, mallopt);
    940  MALLOPT(SO_SYN_MALLOC,    mallopt);
    941 
    942 #elif defined(VGO_darwin)
    943  //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
    944 
    945 #endif
    946 
    947 
    948 /*---------------------- malloc_trim ----------------------*/
    949 // Documentation says:
    950 //   malloc_trim(size_t pad);
    951 //
    952 //   If possible, gives memory back to the system (via negative arguments to
    953 //   sbrk) if there is unused memory at the `high' end of the malloc pool.
    954 //   You can call this after freeing large blocks of memory to potentially
    955 //   reduce the system-level memory requirements of a program. However, it
    956 //   cannot guarantee to reduce memory.  Under some allocation patterns,
    957 //   some large free blocks of memory will be locked between two used
    958 //   chunks, so they cannot be given back to the system.
    959 //
    960 //   The `pad' argument to malloc_trim represents the amount of free
    961 //   trailing space to leave untrimmed. If this argument is zero, only the
    962 //   minimum amount of memory to maintain internal data structures will be
    963 //   left (one page or less). Non-zero arguments can be supplied to maintain
    964 //   enough trailing space to service future expected allocations without
    965 //   having to re-obtain memory from the system.
    966 //
    967 //   Malloc_trim returns 1 if it actually released any memory, else 0. On
    968 //   systems that do not support "negative sbrks", it will always return 0.
    969 //
    970 // For simplicity, we always return 0.
    971 #define MALLOC_TRIM(soname, fnname) \
    972    \
    973    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ); \
    974    int VG_REPLACE_FUNCTION_EZU(10150,soname,fnname) ( SizeT pad ) \
    975    { \
    976       /* 0 denotes that malloc_trim() either wasn't able \
    977          to do anything, or was not implemented */ \
    978       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(pad); \
    979       return 0; \
    980    }
    981 
    982 #if defined(VGO_linux)
    983  MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
    984  MALLOC_TRIM(SO_SYN_MALLOC,    malloc_trim);
    985 
    986 #elif defined(VGO_darwin)
    987  //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
    988 
    989 #endif
    990 
    991 
    992 /*---------------------- posix_memalign ----------------------*/
    993 
    994 #define POSIX_MEMALIGN(soname, fnname) \
    995    \
    996    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
    997           ( void **memptr, SizeT alignment, SizeT size ); \
    998    int VG_REPLACE_FUNCTION_EZU(10160,soname,fnname) \
    999           ( void **memptr, SizeT alignment, SizeT size ) \
   1000    { \
   1001       void *mem; \
   1002       \
   1003       /* Test whether the alignment argument is valid.  It must be \
   1004          a power of two multiple of sizeof (void *).  */ \
   1005       if (alignment % sizeof (void *) != 0 \
   1006           || (alignment & (alignment - 1)) != 0) \
   1007          return VKI_EINVAL; \
   1008       \
   1009       mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \
   1010                (alignment, size); \
   1011       \
   1012       if (mem != NULL) { \
   1013         *memptr = mem; \
   1014         return 0; \
   1015       } \
   1016       \
   1017       return VKI_ENOMEM; \
   1018    }
   1019 
   1020 #if defined(VGO_linux)
   1021  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
   1022  POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
   1023 
   1024 #elif defined(VGO_darwin)
   1025  //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
   1026 
   1027 #elif defined(VGO_solaris)
   1028  POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
   1029  POSIX_MEMALIGN(SO_SYN_MALLOC,    posix_memalign);
   1030 
   1031 #endif
   1032 
   1033 
   1034 /*---------------------- malloc_usable_size ----------------------*/
   1035 
   1036 #define MALLOC_USABLE_SIZE(soname, fnname) \
   1037    \
   1038    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ); \
   1039    SizeT VG_REPLACE_FUNCTION_EZU(10170,soname,fnname) ( void* p ) \
   1040    {  \
   1041       SizeT pszB; \
   1042       \
   1043       DO_INIT; \
   1044       MALLOC_TRACE("malloc_usable_size(%p)", p ); \
   1045       if (NULL == p) \
   1046          return 0; \
   1047       \
   1048       pszB = (SizeT)VALGRIND_NON_SIMD_CALL1( info.tl_malloc_usable_size, p ); \
   1049       MALLOC_TRACE(" = %llu\n", (ULong)pszB ); \
   1050       \
   1051       return pszB; \
   1052    }
   1053 
   1054 #if defined(VGO_linux)
   1055  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
   1056  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
   1057  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
   1058  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
   1059 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
   1060      || defined(VGPV_mips32_linux_android)
   1061   MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
   1062   MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
   1063 # endif
   1064 
   1065 #elif defined(VGO_darwin)
   1066  //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
   1067  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
   1068  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
   1069 
   1070 #endif
   1071 
   1072 
   1073 /*---------------------- (unimplemented) ----------------------*/
   1074 
   1075 /* Bomb out if we get any of these. */
   1076 
   1077 static void panic(const char *str) __attribute__((unused));
   1078 static void panic(const char *str)
   1079 {
   1080    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
   1081    my_exit(1);
   1082 }
   1083 
   1084 #define PANIC(soname, fnname) \
   1085    \
   1086    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void ); \
   1087    void VG_REPLACE_FUNCTION_EZU(10180,soname,fnname) ( void )  \
   1088    { \
   1089       panic(#fnname); \
   1090    }
   1091 
   1092 #if defined(VGO_linux)
   1093  PANIC(VG_Z_LIBC_SONAME, pvalloc);
   1094  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
   1095  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
   1096 
   1097 #elif defined(VGO_darwin)
   1098  PANIC(VG_Z_LIBC_SONAME, pvalloc);
   1099  PANIC(VG_Z_LIBC_SONAME, malloc_get_state);
   1100  PANIC(VG_Z_LIBC_SONAME, malloc_set_state);
   1101 
   1102 #endif
   1103 
   1104 
   1105 #define MALLOC_STATS(soname, fnname) \
   1106    \
   1107    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void ); \
   1108    void VG_REPLACE_FUNCTION_EZU(10190,soname,fnname) ( void )  \
   1109    { \
   1110       /* Valgrind's malloc_stats implementation does nothing. */ \
   1111    }
   1112 
   1113 #if defined(VGO_linux)
   1114  MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
   1115  MALLOC_STATS(SO_SYN_MALLOC,    malloc_stats);
   1116 
   1117 #elif defined(VGO_darwin)
   1118  //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
   1119 
   1120 #endif
   1121 
   1122 
   1123 /*---------------------- mallinfo ----------------------*/
   1124 
   1125 // mi must be static;  if it is auto then Memcheck thinks it is
   1126 // uninitialised when used by the caller of this function, because Memcheck
   1127 // doesn't know that the call to mallinfo fills in mi.
   1128 #define MALLINFO(soname, fnname) \
   1129    \
   1130    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ); \
   1131    struct vg_mallinfo VG_REPLACE_FUNCTION_EZU(10200,soname,fnname) ( void ) \
   1132    { \
   1133       static struct vg_mallinfo mi; \
   1134       DO_INIT; \
   1135       MALLOC_TRACE("mallinfo()\n"); \
   1136       (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
   1137       return mi; \
   1138    }
   1139 
   1140 #if defined(VGO_linux)
   1141  MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
   1142  MALLINFO(SO_SYN_MALLOC,    mallinfo);
   1143 
   1144 #elif defined(VGO_darwin)
   1145  //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
   1146 
   1147 #endif
   1148 
   1149 
   1150 /*------------------ Darwin zone stuff ------------------*/
   1151 
   1152 #if defined(VGO_darwin)
   1153 
   1154 static size_t my_malloc_size ( void* zone, void* ptr )
   1155 {
   1156    /* Implement "malloc_size" by handing the request through to the
   1157       tool's .tl_usable_size method. */
   1158    DO_INIT;
   1159    TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone);
   1160    TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) ptr);
   1161    size_t res = (size_t)VALGRIND_NON_SIMD_CALL1(
   1162                            info.tl_malloc_usable_size, ptr);
   1163    return res;
   1164 }
   1165 
   1166 /* Note that the (void*) casts below are a kludge which stops
   1167    compilers complaining about the fact that the replacement
   1168    functions aren't really of the right type. */
   1169 static vki_malloc_zone_t vg_default_zone = {
   1170     NULL, // reserved1
   1171     NULL, // reserved2
   1172     (void*)my_malloc_size, // JRS fixme: is this right?
   1173     (void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
   1174     (void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
   1175     (void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
   1176     (void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
   1177     (void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
   1178     NULL, // GrP fixme: destroy
   1179     "ValgrindMallocZone",
   1180     NULL, // batch_malloc
   1181     NULL, // batch_free
   1182     NULL, // GrP fixme: introspect
   1183     2,  // version (GrP fixme 3?)
   1184     (void*)VG_REPLACE_FUNCTION_EZU(10100,VG_Z_LIBC_SONAME,malloc_zone_memalign), // DDD: this field exists in Mac OS 10.6+
   1185     NULL, /* free_definite_size */
   1186     NULL, /* pressure_relief */
   1187 };
   1188 
   1189 
   1190 #define DEFAULT_ZONE(soname, fnname) \
   1191    \
   1192    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
   1193    void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void )  \
   1194    { \
   1195       return &vg_default_zone; \
   1196    }
   1197 
   1198 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
   1199 DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_zone);
   1200 DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_purgeable_zone);
   1201 DEFAULT_ZONE(SO_SYN_MALLOC,    malloc_default_purgeable_zone);
   1202 
   1203 
   1204 #define CREATE_ZONE(soname, fnname) \
   1205    \
   1206    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl); \
   1207    void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(size_t sz, unsigned fl)  \
   1208    { \
   1209       return &vg_default_zone; \
   1210    }
   1211 CREATE_ZONE(VG_Z_LIBC_SONAME, malloc_create_zone);
   1212 
   1213 
   1214 #define ZONE_FROM_PTR(soname, fnname) \
   1215    \
   1216    void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr ); \
   1217    void *VG_REPLACE_FUNCTION_EZU(10230,soname,fnname) ( void* ptr )  \
   1218    { \
   1219       return &vg_default_zone; \
   1220    }
   1221 
   1222 ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
   1223 ZONE_FROM_PTR(SO_SYN_MALLOC,    malloc_zone_from_ptr);
   1224 
   1225 
   1226 // GrP fixme bypass libc's use of zone->introspect->check
   1227 #define ZONE_CHECK(soname, fnname) \
   1228    \
   1229    int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone); \
   1230    int VG_REPLACE_FUNCTION_EZU(10240,soname,fnname)(void* zone)  \
   1231    { \
   1232       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
   1233       panic(#fnname); \
   1234       return 1; \
   1235    }
   1236 
   1237 ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
   1238 ZONE_CHECK(SO_SYN_MALLOC,    malloc_zone_check);
   1239 
   1240 
   1241 #define ZONE_REGISTER(soname, fnname) \
   1242    \
   1243    void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone); \
   1244    void VG_REPLACE_FUNCTION_EZU(10250,soname,fnname)(void* zone)  \
   1245    { \
   1246       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
   1247    }
   1248 
   1249 ZONE_REGISTER(VG_Z_LIBC_SONAME, malloc_zone_register);
   1250 ZONE_REGISTER(SO_SYN_MALLOC,    malloc_zone_register);
   1251 
   1252 
   1253 #define ZONE_UNREGISTER(soname, fnname) \
   1254    \
   1255    void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone); \
   1256    void VG_REPLACE_FUNCTION_EZU(10260,soname,fnname)(void* zone)  \
   1257    { \
   1258       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
   1259    }
   1260 
   1261 ZONE_UNREGISTER(VG_Z_LIBC_SONAME, malloc_zone_unregister);
   1262 ZONE_UNREGISTER(SO_SYN_MALLOC,    malloc_zone_unregister);
   1263 
   1264 
   1265 #define ZONE_SET_NAME(soname, fnname) \
   1266    \
   1267    void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm); \
   1268    void VG_REPLACE_FUNCTION_EZU(10270,soname,fnname)(void* zone, char* nm)  \
   1269    { \
   1270       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
   1271    }
   1272 
   1273 ZONE_SET_NAME(VG_Z_LIBC_SONAME, malloc_set_zone_name);
   1274 ZONE_SET_NAME(SO_SYN_MALLOC,    malloc_set_zone_name);
   1275 
   1276 
   1277 #define ZONE_GET_NAME(soname, fnname) \
   1278    \
   1279    const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone); \
   1280    const char* VG_REPLACE_FUNCTION_EZU(10280,soname,fnname)(void* zone)  \
   1281    { \
   1282       TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(zone); \
   1283       return vg_default_zone.zone_name; \
   1284    }
   1285 
   1286 ZONE_GET_NAME(VG_Z_LIBC_SONAME, malloc_get_zone_name);
   1287 ZONE_GET_NAME(SO_SYN_MALLOC,    malloc_get_zone_name);
   1288 
   1289 #endif /* defined(VGO_darwin) */
   1290 
   1291 
   1292 /*------------------ (startup related) ------------------*/
   1293 
   1294 /* All the code in here is unused until this function is called */
   1295 
   1296 __attribute__((constructor))
   1297 static void init(void)
   1298 {
   1299    // This doesn't look thread-safe, but it should be ok... Bart says:
   1300    //
   1301    //   Every program I know of calls malloc() at least once before calling
   1302    //   pthread_create().  So init_done gets initialized before any thread is
   1303    //   created, and is only read when multiple threads are active
   1304    //   simultaneously.  Such an access pattern is safe.
   1305    //
   1306    //   If the assignment to the variable init_done would be triggering a race
   1307    //   condition, both DRD and Helgrind would report this race.
   1308    //
   1309    //   By the way, although the init() function in
   1310    //   coregrind/m_replacemalloc/vg_replace_malloc.c has been declared
   1311    //   __attribute__((constructor)), it is not safe to remove the variable
   1312    //   init_done. This is because it is possible that malloc() and hence
   1313    //   init() gets called before shared library initialization finished.
   1314    //
   1315    if (init_done)
   1316       return;
   1317 
   1318    init_done = 1;
   1319 
   1320    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__GET_MALLOCFUNCS, &info,
   1321                                    0, 0, 0, 0);
   1322 }
   1323 
   1324 /*--------------------------------------------------------------------*/
   1325 /*--- end                                                          ---*/
   1326 /*--------------------------------------------------------------------*/
   1327