vg_replace_strmem.c revision 366cefb68a2b15558ed1ddcda74c675d3ac39948
19c7779b64eacf264ee427b97ae0df8596b1960ccbart
29c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
39c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Replacements for strcpy(), memcpy() et al, which run on the  ---*/
49c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- simulated CPU.                                               ---*/
5f2a68aa6deb788304b9c100ecd4dec41f5064b8cphilippe/*---                                          vg_replace_strmem.c ---*/
69c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
79c7779b64eacf264ee427b97ae0df8596b1960ccbart
89c7779b64eacf264ee427b97ae0df8596b1960ccbart/*
99c7779b64eacf264ee427b97ae0df8596b1960ccbart   This file is part of Valgrind.
109c7779b64eacf264ee427b97ae0df8596b1960ccbart
119c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copyright (C) 2000-2013 Julian Seward
129c7779b64eacf264ee427b97ae0df8596b1960ccbart      jseward@acm.org
139c7779b64eacf264ee427b97ae0df8596b1960ccbart
149c7779b64eacf264ee427b97ae0df8596b1960ccbart   This program is free software; you can redistribute it and/or
159c7779b64eacf264ee427b97ae0df8596b1960ccbart   modify it under the terms of the GNU General Public License as
169c7779b64eacf264ee427b97ae0df8596b1960ccbart   published by the Free Software Foundation; either version 2 of the
179c7779b64eacf264ee427b97ae0df8596b1960ccbart   License, or (at your option) any later version.
189c7779b64eacf264ee427b97ae0df8596b1960ccbart
199c7779b64eacf264ee427b97ae0df8596b1960ccbart   This program is distributed in the hope that it will be useful, but
209c7779b64eacf264ee427b97ae0df8596b1960ccbart   WITHOUT ANY WARRANTY; without even the implied warranty of
219c7779b64eacf264ee427b97ae0df8596b1960ccbart   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
229c7779b64eacf264ee427b97ae0df8596b1960ccbart   General Public License for more details.
239c7779b64eacf264ee427b97ae0df8596b1960ccbart
249c7779b64eacf264ee427b97ae0df8596b1960ccbart   You should have received a copy of the GNU General Public License
259c7779b64eacf264ee427b97ae0df8596b1960ccbart   along with this program; if not, write to the Free Software
269c7779b64eacf264ee427b97ae0df8596b1960ccbart   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
279c7779b64eacf264ee427b97ae0df8596b1960ccbart   02111-1307, USA.
289c7779b64eacf264ee427b97ae0df8596b1960ccbart
299c7779b64eacf264ee427b97ae0df8596b1960ccbart   The GNU General Public License is contained in the file COPYING.
309c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
319c7779b64eacf264ee427b97ae0df8596b1960ccbart
329c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_basics.h"
339c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_poolalloc.h"
349c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_hashtable.h"
359c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_redir.h"
369c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_tooliface.h"
379c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_clreq.h"
389c7779b64eacf264ee427b97ae0df8596b1960ccbart
399c7779b64eacf264ee427b97ae0df8596b1960ccbart/* ---------------------------------------------------------------------
409c7779b64eacf264ee427b97ae0df8596b1960ccbart   We have our own versions of these functions for two reasons:
419c7779b64eacf264ee427b97ae0df8596b1960ccbart   (a) it allows us to do overlap checking
429c7779b64eacf264ee427b97ae0df8596b1960ccbart   (b) some of the normal versions are hyper-optimised, which fools
439c7779b64eacf264ee427b97ae0df8596b1960ccbart       Memcheck and cause spurious value warnings.  Our versions are
449c7779b64eacf264ee427b97ae0df8596b1960ccbart       simpler.
459c7779b64eacf264ee427b97ae0df8596b1960ccbart   (c) the glibc SSE-variants can read past the end of the input data
469c7779b64eacf264ee427b97ae0df8596b1960ccbart       ranges. This can cause false-positive Memcheck / Helgrind / DRD
479c7779b64eacf264ee427b97ae0df8596b1960ccbart       reports.
489c7779b64eacf264ee427b97ae0df8596b1960ccbart
499c7779b64eacf264ee427b97ae0df8596b1960ccbart   Note that overenthusiastic use of PLT bypassing by the glibc people also
509c7779b64eacf264ee427b97ae0df8596b1960ccbart   means that we need to patch multiple versions of some of the functions to
519c7779b64eacf264ee427b97ae0df8596b1960ccbart   our own implementations.
529c7779b64eacf264ee427b97ae0df8596b1960ccbart
539c7779b64eacf264ee427b97ae0df8596b1960ccbart   THEY RUN ON THE SIMD CPU!
549c7779b64eacf264ee427b97ae0df8596b1960ccbart   ------------------------------------------------------------------ */
559c7779b64eacf264ee427b97ae0df8596b1960ccbart
569c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Assignment of behavioural equivalence class tags: 2NNNP is intended
579c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be reserved for str/mem intercepts.  Current usage:
589c7779b64eacf264ee427b97ae0df8596b1960ccbart
599c7779b64eacf264ee427b97ae0df8596b1960ccbart   20010 STRRCHR
609c7779b64eacf264ee427b97ae0df8596b1960ccbart   20020 STRCHR
619c7779b64eacf264ee427b97ae0df8596b1960ccbart   20030 STRCAT
629c7779b64eacf264ee427b97ae0df8596b1960ccbart   20040 STRNCAT
639c7779b64eacf264ee427b97ae0df8596b1960ccbart   20050 STRLCAT
649c7779b64eacf264ee427b97ae0df8596b1960ccbart   20060 STRNLEN
659c7779b64eacf264ee427b97ae0df8596b1960ccbart   20070 STRLEN
669c7779b64eacf264ee427b97ae0df8596b1960ccbart   20080 STRCPY
679c7779b64eacf264ee427b97ae0df8596b1960ccbart   20090 STRNCPY
689c7779b64eacf264ee427b97ae0df8596b1960ccbart   20100 STRLCPY
699c7779b64eacf264ee427b97ae0df8596b1960ccbart   20110 STRNCMP
709c7779b64eacf264ee427b97ae0df8596b1960ccbart   20120 STRCASECMP
719c7779b64eacf264ee427b97ae0df8596b1960ccbart   20130 STRNCASECMP
729c7779b64eacf264ee427b97ae0df8596b1960ccbart   20140 STRCASECMP_L
739c7779b64eacf264ee427b97ae0df8596b1960ccbart   20150 STRNCASECMP_L
749c7779b64eacf264ee427b97ae0df8596b1960ccbart   20160 STRCMP
759c7779b64eacf264ee427b97ae0df8596b1960ccbart   20170 MEMCHR
769c7779b64eacf264ee427b97ae0df8596b1960ccbart
779c7779b64eacf264ee427b97ae0df8596b1960ccbart   20180 MEMCPY    if there's a conflict between memcpy and
789c7779b64eacf264ee427b97ae0df8596b1960ccbart   20181 MEMMOVE   memmove, prefer memmove
799c7779b64eacf264ee427b97ae0df8596b1960ccbart
809c7779b64eacf264ee427b97ae0df8596b1960ccbart   20190 MEMCMP
819c7779b64eacf264ee427b97ae0df8596b1960ccbart   20200 STPCPY
829c7779b64eacf264ee427b97ae0df8596b1960ccbart   20210 MEMSET
839c7779b64eacf264ee427b97ae0df8596b1960ccbart   2022P unused (was previously MEMMOVE)
849c7779b64eacf264ee427b97ae0df8596b1960ccbart   20230 BCOPY
859c7779b64eacf264ee427b97ae0df8596b1960ccbart   20240 GLIBC25___MEMMOVE_CHK
869c7779b64eacf264ee427b97ae0df8596b1960ccbart   20250 GLIBC232_STRCHRNUL
879c7779b64eacf264ee427b97ae0df8596b1960ccbart   20260 GLIBC232_RAWMEMCHR
889c7779b64eacf264ee427b97ae0df8596b1960ccbart   20270 GLIBC25___STRCPY_CHK
899c7779b64eacf264ee427b97ae0df8596b1960ccbart   20280 GLIBC25___STPCPY_CHK
909c7779b64eacf264ee427b97ae0df8596b1960ccbart   20290 GLIBC25_MEMPCPY
919c7779b64eacf264ee427b97ae0df8596b1960ccbart   20300 GLIBC26___MEMCPY_CHK
929c7779b64eacf264ee427b97ae0df8596b1960ccbart   20310 STRSTR
939c7779b64eacf264ee427b97ae0df8596b1960ccbart   20320 STRPBRK
949c7779b64eacf264ee427b97ae0df8596b1960ccbart   20330 STRCSPN
959c7779b64eacf264ee427b97ae0df8596b1960ccbart   20340 STRSPN
969c7779b64eacf264ee427b97ae0df8596b1960ccbart   20350 STRCASESTR
979c7779b64eacf264ee427b97ae0df8596b1960ccbart   20360 MEMRCHR
989c7779b64eacf264ee427b97ae0df8596b1960ccbart   20370 WCSLEN
999c7779b64eacf264ee427b97ae0df8596b1960ccbart   20380 WCSCMP
1009c7779b64eacf264ee427b97ae0df8596b1960ccbart   20390 WCSCPY
1019c7779b64eacf264ee427b97ae0df8596b1960ccbart   20400 WCSCHR
1029c7779b64eacf264ee427b97ae0df8596b1960ccbart   20410 WCSRCHR
1039c7779b64eacf264ee427b97ae0df8596b1960ccbart   20420 STPNCPY
1049c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
1059c7779b64eacf264ee427b97ae0df8596b1960ccbart
1069c7779b64eacf264ee427b97ae0df8596b1960ccbart
1079c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Figure out if [dst .. dst+dstlen-1] overlaps with
1089c7779b64eacf264ee427b97ae0df8596b1960ccbart                 [src .. src+srclen-1].
1099c7779b64eacf264ee427b97ae0df8596b1960ccbart   We assume that the address ranges do not wrap around
1109c7779b64eacf264ee427b97ae0df8596b1960ccbart   (which is safe since on Linux addresses >= 0xC0000000
1119c7779b64eacf264ee427b97ae0df8596b1960ccbart   are not accessible and the program will segfault in this
1129c7779b64eacf264ee427b97ae0df8596b1960ccbart   circumstance, presumably).
1139c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
1149c7779b64eacf264ee427b97ae0df8596b1960ccbartstatic inline
1159c7779b64eacf264ee427b97ae0df8596b1960ccbartBool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
1169c7779b64eacf264ee427b97ae0df8596b1960ccbart{
1179c7779b64eacf264ee427b97ae0df8596b1960ccbart   Addr loS, hiS, loD, hiD;
1189c7779b64eacf264ee427b97ae0df8596b1960ccbart
1199c7779b64eacf264ee427b97ae0df8596b1960ccbart   if (dstlen == 0 || srclen == 0)
1209c7779b64eacf264ee427b97ae0df8596b1960ccbart      return False;
1219c7779b64eacf264ee427b97ae0df8596b1960ccbart
1229c7779b64eacf264ee427b97ae0df8596b1960ccbart   loS = (Addr)src;
1239c7779b64eacf264ee427b97ae0df8596b1960ccbart   loD = (Addr)dst;
1249c7779b64eacf264ee427b97ae0df8596b1960ccbart   hiS = loS + srclen - 1;
1259c7779b64eacf264ee427b97ae0df8596b1960ccbart   hiD = loD + dstlen - 1;
1269c7779b64eacf264ee427b97ae0df8596b1960ccbart
1279c7779b64eacf264ee427b97ae0df8596b1960ccbart   /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
1289c7779b64eacf264ee427b97ae0df8596b1960ccbart   if (loS < loD) {
1299c7779b64eacf264ee427b97ae0df8596b1960ccbart      return !(hiS < loD);
1309c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1319c7779b64eacf264ee427b97ae0df8596b1960ccbart   else if (loD < loS) {
1329c7779b64eacf264ee427b97ae0df8596b1960ccbart      return !(hiD < loS);
1339c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1349c7779b64eacf264ee427b97ae0df8596b1960ccbart   else {
1359c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* They start at same place.  Since we know neither of them has
1369c7779b64eacf264ee427b97ae0df8596b1960ccbart         zero length, they must overlap. */
1379c7779b64eacf264ee427b97ae0df8596b1960ccbart      return True;
1389c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1399c7779b64eacf264ee427b97ae0df8596b1960ccbart}
1409c7779b64eacf264ee427b97ae0df8596b1960ccbart
1419c7779b64eacf264ee427b97ae0df8596b1960ccbart
1429c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Call here to exit if we can't continue.  On Android we can't call
1439c7779b64eacf264ee427b97ae0df8596b1960ccbart   _exit for some reason, so we have to blunt-instrument it. */
1449c7779b64eacf264ee427b97ae0df8596b1960ccbart__attribute__ ((__noreturn__))
1459c7779b64eacf264ee427b97ae0df8596b1960ccbartstatic inline void my_exit ( int x )
1469c7779b64eacf264ee427b97ae0df8596b1960ccbart{
1479c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
14826ed419d60369d0545510eba0832566e24452e1esewardj      || defined(VGPV_arm64_linux_android)
1499c7779b64eacf264ee427b97ae0df8596b1960ccbart   __asm__ __volatile__(".word 0xFFFFFFFF");
1509c7779b64eacf264ee427b97ae0df8596b1960ccbart   while (1) {}
1519c7779b64eacf264ee427b97ae0df8596b1960ccbart#  elif defined(VGPV_x86_linux_android)
1529c7779b64eacf264ee427b97ae0df8596b1960ccbart   __asm__ __volatile__("ud2");
1539c7779b64eacf264ee427b97ae0df8596b1960ccbart   while (1) {}
1549c7779b64eacf264ee427b97ae0df8596b1960ccbart#  else
1559c7779b64eacf264ee427b97ae0df8596b1960ccbart   extern __attribute__ ((__noreturn__)) void _exit(int status);
1569c7779b64eacf264ee427b97ae0df8596b1960ccbart   _exit(x);
1579c7779b64eacf264ee427b97ae0df8596b1960ccbart#  endif
1589c7779b64eacf264ee427b97ae0df8596b1960ccbart}
1599c7779b64eacf264ee427b97ae0df8596b1960ccbart
1609c7779b64eacf264ee427b97ae0df8596b1960ccbart
1619c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a macro rather than a function because we don't want to have an
1629c7779b64eacf264ee427b97ae0df8596b1960ccbart// extra function in the stack trace.
1639c7779b64eacf264ee427b97ae0df8596b1960ccbart#ifndef RECORD_OVERLAP_ERROR
1649c7779b64eacf264ee427b97ae0df8596b1960ccbart#define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
1659c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
1669c7779b64eacf264ee427b97ae0df8596b1960ccbart#ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
1679c7779b64eacf264ee427b97ae0df8596b1960ccbart#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
1689c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
1699c7779b64eacf264ee427b97ae0df8596b1960ccbart
1709c7779b64eacf264ee427b97ae0df8596b1960ccbart
1719c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strrchr ----------------------*/
1729c7779b64eacf264ee427b97ae0df8596b1960ccbart
1739c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRRCHR(soname, fnname) \
1749c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
1759c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
1769c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
1779c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar ch = (HChar)c;   \
1789c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* p = s;       \
1799c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* last = NULL; \
1809c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
1819c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == ch) last = p; \
18270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(HChar *,last);    \
1839c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
1849c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
1859c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1869c7779b64eacf264ee427b97ae0df8596b1960ccbart
1879c7779b64eacf264ee427b97ae0df8596b1960ccbart// Apparently rindex() is the same thing as strrchr()
1889c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
1899c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
1909c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   rindex)
1919c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
1929c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse2)
1939c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse2_no_bsf)
1949c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse42)
1959c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
1969c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
1979c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
1989c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
1999c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2009c7779b64eacf264ee427b97ae0df8596b1960ccbart
2019c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2029c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
2039c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_LIBC_SONAME,   rindex)
2049c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_DYLD,          strrchr)
2059c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_DYLD,          rindex)
2069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME, strrchr)
2079951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
208eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  STRRCHR(libsystemZucZddylib, strrchr)
209eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
2109c7779b64eacf264ee427b97ae0df8596b1960ccbart
2119c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2129c7779b64eacf264ee427b97ae0df8596b1960ccbart
2139c7779b64eacf264ee427b97ae0df8596b1960ccbart
2149c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strchr ----------------------*/
2159c7779b64eacf264ee427b97ae0df8596b1960ccbart
2169c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCHR(soname, fnname) \
2179c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
2189c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
2199c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2209c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar  ch = (HChar)c ; \
2219c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* p  = s;   \
2229c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
22370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == ch) return CONST_CAST(HChar *,p);  \
2249c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
2259c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
2269c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
2279c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
2289c7779b64eacf264ee427b97ae0df8596b1960ccbart
2299c7779b64eacf264ee427b97ae0df8596b1960ccbart// Apparently index() is the same thing as strchr()
2309c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
2319c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          strchr)
2329c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
2339c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __strchr_sse2)
2349c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __strchr_sse2_no_bsf)
2359c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          index)
2369c7779b64eacf264ee427b97ae0df8596b1960ccbart# if !defined(VGP_x86_linux)
2379c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
2389c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_SO_2,        index)
2399c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
2409c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
2419c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
2429c7779b64eacf264ee427b97ae0df8596b1960ccbart
2439c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME, strchr)
245c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# if DARWIN_VERS == DARWIN_10_9
246c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCHR(libsystemZuplatformZddylib, _platform_strchr)
247c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
2489951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# if DARWIN_VERS == DARWIN_10_10
2499951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  /* _platform_strchr$VARIANT$Generic */
2509951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
251366cefb68a2b15558ed1ddcda74c675d3ac39948rhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
2529951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# endif
2539c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2549c7779b64eacf264ee427b97ae0df8596b1960ccbart
2559c7779b64eacf264ee427b97ae0df8596b1960ccbart
2569c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcat ----------------------*/
2579c7779b64eacf264ee427b97ae0df8596b1960ccbart
2589c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCAT(soname, fnname) \
2599c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2609c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
2619c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2629c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
2639c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2649c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
2659c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
2669c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
2679c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
2689c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
2699c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2709c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This is a bit redundant, I think;  any overlap and the strcat will */ \
2719c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* go forever... or until a seg fault occurs. */ \
2729c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
2739c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
2749c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
2759c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
2769c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
2779c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2789c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
2799c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
2809c7779b64eacf264ee427b97ae0df8596b1960ccbart
2819c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
2829c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, strcat)
2839c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
2849c7779b64eacf264ee427b97ae0df8596b1960ccbart
2859c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2869c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCAT(VG_Z_LIBC_SONAME, strcat)
2879c7779b64eacf264ee427b97ae0df8596b1960ccbart
2889c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2899c7779b64eacf264ee427b97ae0df8596b1960ccbart
2909c7779b64eacf264ee427b97ae0df8596b1960ccbart
2919c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncat ----------------------*/
2929c7779b64eacf264ee427b97ae0df8596b1960ccbart
2939c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCAT(soname, fnname) \
2949c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
2959c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
2969c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
2979c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
2989c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2999c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3009c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
3019c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3029c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3039c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
3049c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
3059c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0;                                       /* always add null   */ \
3069c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3079c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3089c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3099c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3109c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3119c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
3129c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3139c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
3149c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3159c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3169c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3179c7779b64eacf264ee427b97ae0df8596b1960ccbart
3189c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3199c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCAT(VG_Z_LIBC_SONAME, strncat)
3209c7779b64eacf264ee427b97ae0df8596b1960ccbart
3219c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3229c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_LIBC_SONAME, strncat)
3239c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_DYLD,        strncat)
3249c7779b64eacf264ee427b97ae0df8596b1960ccbart
3259c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3269c7779b64eacf264ee427b97ae0df8596b1960ccbart
3279c7779b64eacf264ee427b97ae0df8596b1960ccbart
3289c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcat ----------------------*/
3299c7779b64eacf264ee427b97ae0df8596b1960ccbart
3309c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
3319c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be nul-terminated after the copy, unless n <= strlen(dst_orig).
3329c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns min(n, strlen(dst_orig)) + strlen(src_orig).
3339c7779b64eacf264ee427b97ae0df8596b1960ccbart   Truncation occurred if retval >= n.
3349c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
3359c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCAT(soname, fnname) \
3369c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3379c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ); \
3389c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3399c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ) \
3409c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3419c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3429c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
3439c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3449c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3459c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *dst) { m++; dst++; } \
3469c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (m < n) { \
3479c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
3489c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (m < n-1 && *src) { m++; *dst++ = *src++; } \
3499c7779b64eacf264ee427b97ae0df8596b1960ccbart         *dst = 0; \
3509c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
3519c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* No space to copy anything to dst. m == n */ \
3529c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
3539c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
3549c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) { m++; src++; } \
3559c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3569c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3579c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3589c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3599c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
3609c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3619c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
3629c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3639c7779b64eacf264ee427b97ae0df8596b1960ccbart      return m; \
3649c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3659c7779b64eacf264ee427b97ae0df8596b1960ccbart
3669c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3679c7779b64eacf264ee427b97ae0df8596b1960ccbart
3689c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3699c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
3709c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_DYLD,        strlcat)
3719c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCAT(VG_Z_LIBC_SONAME, strlcat)
3729c7779b64eacf264ee427b97ae0df8596b1960ccbart
3739c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3749c7779b64eacf264ee427b97ae0df8596b1960ccbart
3759c7779b64eacf264ee427b97ae0df8596b1960ccbart
3769c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strnlen ----------------------*/
3779c7779b64eacf264ee427b97ae0df8596b1960ccbart
3789c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNLEN(soname, fnname) \
3799c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
3809c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ); \
3819c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
3829c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ) \
3839c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3849c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
3859c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (i < n && str[i] != 0) i++; \
3869c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
3879c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3889c7779b64eacf264ee427b97ae0df8596b1960ccbart
3899c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3909c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, strnlen)
3919c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
3929c7779b64eacf264ee427b97ae0df8596b1960ccbart
3939c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
394aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
395aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNLEN(libsystemZucZddylib, strnlen)
396aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
3979c7779b64eacf264ee427b97ae0df8596b1960ccbart
3989c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3999c7779b64eacf264ee427b97ae0df8596b1960ccbart
4009c7779b64eacf264ee427b97ae0df8596b1960ccbart
4019c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlen ----------------------*/
4029c7779b64eacf264ee427b97ae0df8596b1960ccbart
4039c7779b64eacf264ee427b97ae0df8596b1960ccbart// Note that this replacement often doesn't get used because gcc inlines
4049c7779b64eacf264ee427b97ae0df8596b1960ccbart// calls to strlen() with its own built-in version.  This can be very
4059c7779b64eacf264ee427b97ae0df8596b1960ccbart// confusing if you aren't expecting it.  Other small functions in
4069c7779b64eacf264ee427b97ae0df8596b1960ccbart// this file may also be inline by gcc.
4079c7779b64eacf264ee427b97ae0df8596b1960ccbart
4089c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLEN(soname, fnname) \
4099c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4109c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str ); \
4119c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4129c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str )  \
4139c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4149c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4159c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
4169c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4179c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4189c7779b64eacf264ee427b97ae0df8596b1960ccbart
4199c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4209c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          strlen)
4219c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
4229c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2)
4239c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2_no_bsf)
4249c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse42)
4259c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
4269c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
42726ed419d60369d0545510eba0832566e24452e1esewardj# if defined(VGPV_arm_linux_android) \
42826ed419d60369d0545510eba0832566e24452e1esewardj     || defined(VGPV_x86_linux_android) \
4299c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
4309c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
4319c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
4329c7779b64eacf264ee427b97ae0df8596b1960ccbart
4339c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4349c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME, strlen)
435312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
436c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRLEN(libsystemZucZddylib, strlen)
437c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
4389c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4399c7779b64eacf264ee427b97ae0df8596b1960ccbart
4409c7779b64eacf264ee427b97ae0df8596b1960ccbart
4419c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy ----------------------*/
4429c7779b64eacf264ee427b97ae0df8596b1960ccbart
4439c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCPY(soname, fnname) \
4449c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4459c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ); \
4469c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4479c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ) \
4489c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4499c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
4509c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
4519c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4529c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
4539c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
4549c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4559c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
4569c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
4579c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
4589c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
4599c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
4609c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
4619c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
4629c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4639c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
4649c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4659c7779b64eacf264ee427b97ae0df8596b1960ccbart
4669c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4679c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
4689c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
4699c7779b64eacf264ee427b97ae0df8596b1960ccbart
4709c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4719c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
472aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
473aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRCPY(libsystemZucZddylib, strcpy)
474aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
4759c7779b64eacf264ee427b97ae0df8596b1960ccbart
4769c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4779c7779b64eacf264ee427b97ae0df8596b1960ccbart
4789c7779b64eacf264ee427b97ae0df8596b1960ccbart
4799c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncpy ----------------------*/
4809c7779b64eacf264ee427b97ae0df8596b1960ccbart
4819c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCPY(soname, fnname) \
4829c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
4839c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
4849c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
4859c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
4869c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4879c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
4889c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
4899c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
4909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4919c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
4929c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
4939c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
4949c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
4959c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
4969c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
4979c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4989c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
4999c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5009c7779b64eacf264ee427b97ae0df8596b1960ccbart
5019c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5029c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
5049c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
5059c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
5069c7779b64eacf264ee427b97ae0df8596b1960ccbart
5079c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5089c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
509312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
510aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNCPY(libsystemZucZddylib, strncpy)
511aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5129c7779b64eacf264ee427b97ae0df8596b1960ccbart
5139c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5149c7779b64eacf264ee427b97ae0df8596b1960ccbart
5159c7779b64eacf264ee427b97ae0df8596b1960ccbart
5169c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcpy ----------------------*/
5179c7779b64eacf264ee427b97ae0df8596b1960ccbart
5189c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
5199c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns strlen(src). Does not zero-fill the remainder of dst. */
5209c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCPY(soname, fnname) \
5219c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5229c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ); \
5239c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5249c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ) \
5259c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5269c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5279c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
5289c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5299c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5309c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n-1 && *src) { m++; *dst++ = *src++; } \
5319c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* m non-nul bytes have now been copied, and m <= n-1. */ \
5329c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5339c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5359c7779b64eacf264ee427b97ae0df8596b1960ccbart          RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
5369c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Nul-terminate dst. */ \
5379c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (n > 0) *dst = 0; \
5389c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting strlen(src). */ \
5399c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) src++; \
5409c7779b64eacf264ee427b97ae0df8596b1960ccbart      return src - src_orig; \
5419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5429c7779b64eacf264ee427b97ae0df8596b1960ccbart
5439c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5449c7779b64eacf264ee427b97ae0df8596b1960ccbart
5459c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
5469c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
5479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
5489c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5499c7779b64eacf264ee427b97ae0df8596b1960ccbart
5509c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5519c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
5529c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_DYLD,        strlcpy)
5539c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
5549c7779b64eacf264ee427b97ae0df8596b1960ccbart
5559c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5569c7779b64eacf264ee427b97ae0df8596b1960ccbart
5579c7779b64eacf264ee427b97ae0df8596b1960ccbart
5589c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncmp ----------------------*/
5599c7779b64eacf264ee427b97ae0df8596b1960ccbart
5609c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCMP(soname, fnname) \
5619c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
5629c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
5639c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
5649c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
5659c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5669c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
5679c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
5689c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
5699c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
5709c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
5719c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
5729c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
5739c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
5749c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
5759c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
5769c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
5779c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
5789c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5799c7779b64eacf264ee427b97ae0df8596b1960ccbart
5809c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5819c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, strncmp)
5829c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
5839c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
5849c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
5859c7779b64eacf264ee427b97ae0df8596b1960ccbart
5869c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5879c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
5883c02a92c9b27d0c1a68becbadcf003be3ef3a4e2sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
589798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
590798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj# endif
5919c7779b64eacf264ee427b97ae0df8596b1960ccbart
5929c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5939c7779b64eacf264ee427b97ae0df8596b1960ccbart
5949c7779b64eacf264ee427b97ae0df8596b1960ccbart
5959c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp ----------------------*/
5969c7779b64eacf264ee427b97ae0df8596b1960ccbart
5979c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP(soname, fnname) \
5989c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
5999c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
6009c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6019c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
6029c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6039c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
6049c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
6059c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
6069c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6079c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower(*(const UChar *)s1); \
6089c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower(*(const UChar *)s2); \
6099c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
6109c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
6119c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
6129c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6139c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
6149c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
6159c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
6169c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6179c7779b64eacf264ee427b97ae0df8596b1960ccbart
6189c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
61926ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
62026ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
62126ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
62226ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
6239c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6249c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
6259c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
6269c7779b64eacf264ee427b97ae0df8596b1960ccbart
6279c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6289c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6299c7779b64eacf264ee427b97ae0df8596b1960ccbart
6309c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6319c7779b64eacf264ee427b97ae0df8596b1960ccbart
6329c7779b64eacf264ee427b97ae0df8596b1960ccbart
6339c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp ----------------------*/
6349c7779b64eacf264ee427b97ae0df8596b1960ccbart
6359c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP(soname, fnname) \
6369c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
6379c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
6389c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
6399c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
6409c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6419c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
6429c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
6439c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6449c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
6459c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
6469c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
6479c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
6489c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6499c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
6509c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower(*(const UChar*)s2)) return -1; \
6519c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
6529c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower(*(const UChar *)s2)) return 1; \
6539c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6549c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
6559c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6569c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6579c7779b64eacf264ee427b97ae0df8596b1960ccbart
6589c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
65926ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
66026ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
66126ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
66226ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
6639c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
6649c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
6659c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
6669c7779b64eacf264ee427b97ae0df8596b1960ccbart
6679c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6689c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
6699c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_DYLD,        strncasecmp)
6709c7779b64eacf264ee427b97ae0df8596b1960ccbart
6719c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6729c7779b64eacf264ee427b97ae0df8596b1960ccbart
6739c7779b64eacf264ee427b97ae0df8596b1960ccbart
6749c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp_l ----------------------*/
6759c7779b64eacf264ee427b97ae0df8596b1960ccbart
6769c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP_L(soname, fnname) \
6779c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
6789c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ); \
6799c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
6809c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ) \
6819c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6829c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak)); \
6839c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
6849c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
6859c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6869c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower_l(*(const UChar *)s1, locale); \
6879c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower_l(*(const UChar *)s2, locale); \
6889c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
6899c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
6909c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
6919c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6929c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
6939c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
6949c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
6959c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6969c7779b64eacf264ee427b97ae0df8596b1960ccbart
6979c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
6989c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
6999c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
7009c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
7019c7779b64eacf264ee427b97ae0df8596b1960ccbart
7029c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7039c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7049c7779b64eacf264ee427b97ae0df8596b1960ccbart
7059c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7069c7779b64eacf264ee427b97ae0df8596b1960ccbart
7079c7779b64eacf264ee427b97ae0df8596b1960ccbart
7089c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp_l ----------------------*/
7099c7779b64eacf264ee427b97ae0df8596b1960ccbart
7109c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP_L(soname, fnname) \
7119c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7129c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
7139c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7149c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
7159c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7169c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak));    \
7179c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7189c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7199c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7209c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7219c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7229c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7239c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7249c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7259c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower_l(*(const UChar *)s2, locale)) return -1; \
7269c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7279c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower_l(*(const UChar *)s2, locale)) return 1; \
7289c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7299c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
7309c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7319c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7329c7779b64eacf264ee427b97ae0df8596b1960ccbart
7339c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
7349c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
7359c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
7369c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
7379c7779b64eacf264ee427b97ae0df8596b1960ccbart
7389c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7399c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
7409c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
7419c7779b64eacf264ee427b97ae0df8596b1960ccbart
7429c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7439c7779b64eacf264ee427b97ae0df8596b1960ccbart
7449c7779b64eacf264ee427b97ae0df8596b1960ccbart
7459c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcmp ----------------------*/
7469c7779b64eacf264ee427b97ae0df8596b1960ccbart
7479c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCMP(soname, fnname) \
7489c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
7499c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
7509c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
7519c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
7529c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7539c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
7549c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
7559c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7569c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *(const UChar *)s1; \
7579c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *(const UChar *)s2; \
7589c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
7599c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
7609c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
7619c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7629c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
7639c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
7649c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
7659c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7669c7779b64eacf264ee427b97ae0df8596b1960ccbart
7679c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
7689c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          strcmp)
7699c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
7709c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse2)
7719c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse42)
7729c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
7739c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD64_SO_1,            strcmp)
7749c6b05db45362b1afb981aa8298ab12ab4027b1adejanj# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7759c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
7769c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
7779c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
7789c7779b64eacf264ee427b97ae0df8596b1960ccbart
7799c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7809c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME, strcmp)
781312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
782c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
783c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
7849c7779b64eacf264ee427b97ae0df8596b1960ccbart
7859c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7869c7779b64eacf264ee427b97ae0df8596b1960ccbart
7879c7779b64eacf264ee427b97ae0df8596b1960ccbart
7889c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memchr ----------------------*/
7899c7779b64eacf264ee427b97ae0df8596b1960ccbart
7909c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCHR(soname, fnname) \
7919c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
7929c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
7939c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
7949c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
7959c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7969c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
7979c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
79870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
7999c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
80070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
8019c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
8029c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8039c7779b64eacf264ee427b97ae0df8596b1960ccbart
8049c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8059c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, memchr)
8069c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
8079c7779b64eacf264ee427b97ae0df8596b1960ccbart
8089c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
809aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
810798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  MEMCHR(VG_Z_DYLD,                   memchr)
811aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
812aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
813312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_10
814a95abead5600e5b0e7a430d4d373aad7e267e35csewardj  MEMCHR(VG_Z_DYLD,                   memchr)
815312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memchr$VARIANT$Generic */
816312bcb109bfb6899086dda47b02a5436f26516d4sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
817312bcb109bfb6899086dda47b02a5436f26516d4sewardj# endif
8189c7779b64eacf264ee427b97ae0df8596b1960ccbart
8199c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8209c7779b64eacf264ee427b97ae0df8596b1960ccbart
8219c7779b64eacf264ee427b97ae0df8596b1960ccbart
8229c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memrchr ----------------------*/
8239c7779b64eacf264ee427b97ae0df8596b1960ccbart
8249c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMRCHR(soname, fnname) \
8259c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
8269c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
8279c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
8289c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
8299c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8309c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
8319c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
83270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
8339c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
83470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
8359c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
8369c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8379c7779b64eacf264ee427b97ae0df8596b1960ccbart
8389c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8399c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
8409c7779b64eacf264ee427b97ae0df8596b1960ccbart
8419c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8429c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
8439c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_DYLD,        memrchr)
8449c7779b64eacf264ee427b97ae0df8596b1960ccbart
8459c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8469c7779b64eacf264ee427b97ae0df8596b1960ccbart
8479c7779b64eacf264ee427b97ae0df8596b1960ccbart
8489c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcpy ----------------------*/
8499c7779b64eacf264ee427b97ae0df8596b1960ccbart
8509c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
8519c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
8529c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
8539c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
8549c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
8559c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8569c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (do_ol_check && is_overlap(dst, src, len, len)) \
8579c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
8589c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
8599c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WS = sizeof(UWord); /* 8 or 4 */ \
8609c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WM = WS - 1;        /* 7 or 3 */ \
8619c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
8629c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len > 0) { \
8639c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (dst < src || !is_overlap(dst, src, len, len)) { \
8649c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8659c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying backwards. */ \
8669c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
8679c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = (Addr)dst; \
8689c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = (Addr)src; \
8699c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
8709c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
8719c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
8729c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Pull up to a UWord boundary. */ \
8739c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
8749c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
8759c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
8769c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
8779c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
8789c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
8799c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
8809c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
8819c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
8829c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
8839c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
8849c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
8859c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
8869c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
8879c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
8889c7779b64eacf264ee427b97ae0df8596b1960ccbart               { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
8899c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8909c7779b64eacf264ee427b97ae0df8596b1960ccbart         } else if (dst > src) { \
8919c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8929c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
8939c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = ((Addr)dst) + n; \
8949c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = ((Addr)src) + n; \
8959c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
8969c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying forwards. */ \
8979c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
8989c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
8999c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Back down to a UWord boundary. */ \
9009c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9019c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9029c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9039c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9049c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
9059c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9069c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9079c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9089c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9099c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9109c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9119c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
9129c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9139c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9149c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
9159c7779b64eacf264ee427b97ae0df8596b1960ccbart               { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9169c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9179c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
9189c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
9199c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9209c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
9219c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
9229c7779b64eacf264ee427b97ae0df8596b1960ccbart
9239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE(soname, fnname)  \
9249c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
9259c7779b64eacf264ee427b97ae0df8596b1960ccbart
9269c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCPY(soname, fnname) \
9279c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
9289c7779b64eacf264ee427b97ae0df8596b1960ccbart
9299c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
9309c7779b64eacf264ee427b97ae0df8596b1960ccbart /* For older memcpy we have to use memmove-like semantics and skip
9319c7779b64eacf264ee427b97ae0df8596b1960ccbart    the overlap check; sigh; see #275284. */
9329c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
9339c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
9349c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
9359c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __GI_memcpy)
9369c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __memcpy_sse2)
9379c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
9389c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
9399c7779b64eacf264ee427b97ae0df8596b1960ccbart /* icc9 blats these around all over the place.  Not only in the main
9409c7779b64eacf264ee427b97ae0df8596b1960ccbart    executable but various .so's.  They are highly tuned and read
9419c7779b64eacf264ee427b97ae0df8596b1960ccbart    memory beyond the source boundary (although work correctly and
9429c7779b64eacf264ee427b97ae0df8596b1960ccbart    never go across page boundaries), so give errors when run
9439c7779b64eacf264ee427b97ae0df8596b1960ccbart    natively, at least for misaligned source arg.  Just intercepting
9449c7779b64eacf264ee427b97ae0df8596b1960ccbart    in the exe only until we understand more about the problem.  See
9459c7779b64eacf264ee427b97ae0df8596b1960ccbart    http://bugs.kde.org/show_bug.cgi?id=139776
9469c7779b64eacf264ee427b97ae0df8596b1960ccbart */
9479c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(NONE, ZuintelZufastZumemcpy)
9489c7779b64eacf264ee427b97ae0df8596b1960ccbart
9499c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
9509c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
9519c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
9529c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
9539c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
9549c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
9559c7779b64eacf264ee427b97ae0df8596b1960ccbart
9569c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9579c7779b64eacf264ee427b97ae0df8596b1960ccbart
9589c7779b64eacf264ee427b97ae0df8596b1960ccbart
9599c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcmp ----------------------*/
9609c7779b64eacf264ee427b97ae0df8596b1960ccbart
9619c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCMP(soname, fnname) \
9629c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
9639c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n ); \
9649c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
9659c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n )  \
9669c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
967094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
968094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WM = WS - 1;        /* 7 or 3 */ \
96911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s1A = (Addr)s1V; \
97011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s2A = (Addr)s2V; \
97111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
97211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      if (((s1A | s2A) & WM) == 0) { \
97311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* Both areas are word aligned.  Skip over the */ \
97411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* equal prefix as fast as possible. */ \
97511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         while (n >= WS) { \
97611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w1 = *(UWord*)s1A; \
97711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w2 = *(UWord*)s2A; \
97811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            if (w1 != w2) break; \
97911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s1A += WS; \
98011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s2A += WS; \
98111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            n -= WS; \
98211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         } \
98311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      } \
98411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
98511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s1 = (const UChar*) s1A; \
98611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s2 = (const UChar*) s2A; \
9879c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9889c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n != 0) { \
98911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar a0 = s1[0]; \
99011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar b0 = s2[0]; \
9919c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1 += 1; \
9929c7779b64eacf264ee427b97ae0df8596b1960ccbart         s2 += 1; \
99311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         int res = ((int)a0) - ((int)b0); \
9949c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (res != 0) \
9959c7779b64eacf264ee427b97ae0df8596b1960ccbart            return res; \
9969c7779b64eacf264ee427b97ae0df8596b1960ccbart         n -= 1; \
9979c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
9989c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
9999c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10009c7779b64eacf264ee427b97ae0df8596b1960ccbart
10019c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10029c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, memcmp)
10039c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
10049c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
10059c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
10069c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, bcmp)
10079c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LD_SO_1,     bcmp)
10089c7779b64eacf264ee427b97ae0df8596b1960ccbart
10099c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
1010312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
1011aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1012aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
10139c7779b64eacf264ee427b97ae0df8596b1960ccbart
10149c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10159c7779b64eacf264ee427b97ae0df8596b1960ccbart
10169c7779b64eacf264ee427b97ae0df8596b1960ccbart
10179c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy ----------------------*/
10189c7779b64eacf264ee427b97ae0df8596b1960ccbart
10199c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy SRC to DEST, returning the address of the terminating '\0' in
10209c7779b64eacf264ee427b97ae0df8596b1960ccbart   DEST. (minor variant of strcpy) */
10219c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPCPY(soname, fnname) \
10229c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
10239c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
10249c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
10259c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
10269c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
10279c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
10289c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
10299c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10309c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
10319c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
10329c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10339c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
10349c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
10359c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
10369c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
10379c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
10389c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
10399c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
10409c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10419c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
10429c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10439c7779b64eacf264ee427b97ae0df8596b1960ccbart
10449c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10459c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
10469c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
10479c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2)
10489c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2_unaligned)
10499c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
10509c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
10519c7779b64eacf264ee427b97ae0df8596b1960ccbart
10529c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10539c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
10549c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_DYLD,                 stpcpy)
10559c7779b64eacf264ee427b97ae0df8596b1960ccbart
10569c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10579c7779b64eacf264ee427b97ae0df8596b1960ccbart
10589c7779b64eacf264ee427b97ae0df8596b1960ccbart
10599c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpncpy ----------------------*/
10609c7779b64eacf264ee427b97ae0df8596b1960ccbart
10619c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPNCPY(soname, fnname) \
10629c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
10639c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
10649c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
10659c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
10669c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
10679c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
10689c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_str  = dst; \
10699c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
10709c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10719c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
10729c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
10739c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
10749c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
10759c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
10769c7779b64eacf264ee427b97ae0df8596b1960ccbart      dst_str = dst; \
10779c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
10789c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10799c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_str; \
10809c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10819c7779b64eacf264ee427b97ae0df8596b1960ccbart
10829c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10839c7779b64eacf264ee427b97ae0df8596b1960ccbart STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
10849c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10859c7779b64eacf264ee427b97ae0df8596b1960ccbart
10869c7779b64eacf264ee427b97ae0df8596b1960ccbart
10879c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memset ----------------------*/
10889c7779b64eacf264ee427b97ae0df8596b1960ccbart
10899c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Why are we bothering to intercept this?  It seems entirely
10909c7779b64eacf264ee427b97ae0df8596b1960ccbart   pointless. */
10919c7779b64eacf264ee427b97ae0df8596b1960ccbart
10929c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMSET(soname, fnname) \
10939c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
10949c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n); \
10959c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
10969c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n) \
10979c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
10989c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (sizeof(void*) == 8) { \
10999c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr  a  = (Addr)s;   \
11009c7779b64eacf264ee427b97ae0df8596b1960ccbart         ULong c8 = (c & 0xFF); \
11019c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 8) | c8; \
11029c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 16) | c8; \
11039c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 32) | c8; \
11049c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 7) != 0 && n >= 1) \
11059c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
11069c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 8) \
11079c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(ULong*)a = c8; a += 8; n -= 8; } \
11089c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
11099c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
11109c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
11119c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
11129c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr a  = (Addr)s;   \
11139c7779b64eacf264ee427b97ae0df8596b1960ccbart         UInt c4 = (c & 0xFF); \
11149c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 8) | c4; \
11159c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 16) | c4; \
11169c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 3) != 0 && n >= 1) \
11179c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
11189c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 4) \
11199c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UInt*)a = c4; a += 4; n -= 4; } \
11209c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
11219c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
11229c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
11239c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
11249c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11259c7779b64eacf264ee427b97ae0df8596b1960ccbart
11269c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11279c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
11289c7779b64eacf264ee427b97ae0df8596b1960ccbart
11299c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11309c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_LIBC_SONAME, memset)
11319c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_DYLD,        memset)
11329c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
11339c7779b64eacf264ee427b97ae0df8596b1960ccbart
11349c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11359c7779b64eacf264ee427b97ae0df8596b1960ccbart
11369c7779b64eacf264ee427b97ae0df8596b1960ccbart
11379c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memmove ----------------------*/
11389c7779b64eacf264ee427b97ae0df8596b1960ccbart
11399c7779b64eacf264ee427b97ae0df8596b1960ccbart/* memmove -- use the MEMMOVE defn above. */
11409c7779b64eacf264ee427b97ae0df8596b1960ccbart
11419c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11429c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memmove)
11439c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
11449c7779b64eacf264ee427b97ae0df8596b1960ccbart
11459c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11469c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
11479c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMMOVE(VG_Z_LIBC_SONAME, memmove)
11489c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
11499c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
11509c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
1151312bcb109bfb6899086dda47b02a5436f26516d4sewardj# if DARWIN_VERS == DARWIN_10_9 || DARWIN_VERS == DARWIN_10_10
1152312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memmove$VARIANT$Ivybridge */
1153eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1154eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
11559c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11569c7779b64eacf264ee427b97ae0df8596b1960ccbart
11579c7779b64eacf264ee427b97ae0df8596b1960ccbart
11589c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- bcopy ----------------------*/
11599c7779b64eacf264ee427b97ae0df8596b1960ccbart
11609c7779b64eacf264ee427b97ae0df8596b1960ccbart#define BCOPY(soname, fnname) \
11619c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
11629c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n); \
11639c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
11649c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n) \
11659c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11669c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
11679c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV; \
11689c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
11699c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
11709c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
11719c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
11729c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
11739c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
11749c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
11759c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
11769c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
11779c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
11789c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11799c7779b64eacf264ee427b97ae0df8596b1960ccbart
11809c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11819c7779b64eacf264ee427b97ae0df8596b1960ccbart BCOPY(VG_Z_LIBC_SONAME, bcopy)
11829c7779b64eacf264ee427b97ae0df8596b1960ccbart
11839c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11849c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_LIBC_SONAME, bcopy)
11859c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_DYLD,        bcopy)
11869c7779b64eacf264ee427b97ae0df8596b1960ccbart
11879c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11889c7779b64eacf264ee427b97ae0df8596b1960ccbart
11899c7779b64eacf264ee427b97ae0df8596b1960ccbart
11909c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memmove_chk --------------------*/
11919c7779b64eacf264ee427b97ae0df8596b1960ccbart
11929c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc 2.5 variant of memmove which checks the dest is big enough.
11939c7779b64eacf264ee427b97ae0df8596b1960ccbart   There is no specific part of glibc that this is copied from. */
11949c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
11959c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
11969c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
11979c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
11989c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
11999c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12009c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
12019c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV;        \
12029c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
12039c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (destlen < n) \
12049c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
12059c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
12069c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12079c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
12089c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12099c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
12109c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
12119c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12129c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
12139c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12149c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
12159c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
12169c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
12179c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memmove_chk: buffer overflow detected ***: " \
12189c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
12199c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
12209c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
12219c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
12229c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12239c7779b64eacf264ee427b97ae0df8596b1960ccbart
12249c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12259c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
12269c7779b64eacf264ee427b97ae0df8596b1960ccbart
12279c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12289c7779b64eacf264ee427b97ae0df8596b1960ccbart
12299c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12309c7779b64eacf264ee427b97ae0df8596b1960ccbart
12319c7779b64eacf264ee427b97ae0df8596b1960ccbart
12329c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- strchrnul --------------------*/
12339c7779b64eacf264ee427b97ae0df8596b1960ccbart
12349c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S or the final NUL byte.  */
12359c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_STRCHRNUL(soname, fnname) \
12369c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
12379c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in); \
12389c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
12399c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in) \
12409c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
124170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      HChar c = (HChar) c_in; \
124270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const HChar* char_ptr = s; \
12439c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
124470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr);  \
124570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr);  \
12469c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
12479c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12489c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12499c7779b64eacf264ee427b97ae0df8596b1960ccbart
12509c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12519c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
12529c7779b64eacf264ee427b97ae0df8596b1960ccbart
12539c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12549c7779b64eacf264ee427b97ae0df8596b1960ccbart
12559c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12569c7779b64eacf264ee427b97ae0df8596b1960ccbart
12579c7779b64eacf264ee427b97ae0df8596b1960ccbart
12589c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- rawmemchr ----------------------*/
12599c7779b64eacf264ee427b97ae0df8596b1960ccbart
12609c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S.  */
12619c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_RAWMEMCHR(soname, fnname) \
12621ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
12631ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in); \
12641ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
12651ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in) \
12669c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12671ef205bfce335a8d54b6b188e83254b92c52d7adflorian      UChar c = (UChar) c_in; \
12681ef205bfce335a8d54b6b188e83254b92c52d7adflorian      const UChar* char_ptr = s; \
12699c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
127070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
12719c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
12729c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12739c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12749c7779b64eacf264ee427b97ae0df8596b1960ccbart
12759c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined (VGO_linux)
12769c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
12779c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
12789c7779b64eacf264ee427b97ae0df8596b1960ccbart
12799c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12809c7779b64eacf264ee427b97ae0df8596b1960ccbart
12819c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12829c7779b64eacf264ee427b97ae0df8596b1960ccbart
12839c7779b64eacf264ee427b97ae0df8596b1960ccbart
12849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy_chk ----------------------*/
12859c7779b64eacf264ee427b97ae0df8596b1960ccbart
12869c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of strcpy that checks the dest is big enough.
12879c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-strcpy_chk.c. */
12889c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STRCPY_CHK(soname,fnname) \
12899c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
12909c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
12919c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
12929c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
12939c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12949c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* ret = dst; \
12959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
12969c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
12979c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
12989c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
12999c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
13009c7779b64eacf264ee427b97ae0df8596b1960ccbart      return ret; \
13019c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
13029c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
13039c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** strcpy_chk: buffer overflow detected ***: " \
13049c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
13059c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
13069c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
13079c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
13089c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13099c7779b64eacf264ee427b97ae0df8596b1960ccbart
13109c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13119c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
13129c7779b64eacf264ee427b97ae0df8596b1960ccbart
13139c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13149c7779b64eacf264ee427b97ae0df8596b1960ccbart
13159c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13169c7779b64eacf264ee427b97ae0df8596b1960ccbart
13179c7779b64eacf264ee427b97ae0df8596b1960ccbart
13189c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy_chk ----------------------*/
13199c7779b64eacf264ee427b97ae0df8596b1960ccbart
13209c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of stpcpy that checks the dest is big enough.
13219c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
13229c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STPCPY_CHK(soname,fnname) \
13239c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
13249c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
13259c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
13269c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
13279c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13289c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
13299c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
13309c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
13319c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
13329c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
13339c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst - 1; \
13349c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
13359c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
13369c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** stpcpy_chk: buffer overflow detected ***: " \
13379c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
13389c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
13399c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
13409c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
13419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13429c7779b64eacf264ee427b97ae0df8596b1960ccbart
13439c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13449c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
13459c7779b64eacf264ee427b97ae0df8596b1960ccbart
13469c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13479c7779b64eacf264ee427b97ae0df8596b1960ccbart
13489c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13499c7779b64eacf264ee427b97ae0df8596b1960ccbart
13509c7779b64eacf264ee427b97ae0df8596b1960ccbart
13519c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- mempcpy ----------------------*/
13529c7779b64eacf264ee427b97ae0df8596b1960ccbart
13539c7779b64eacf264ee427b97ae0df8596b1960ccbart/* mempcpy */
13549c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25_MEMPCPY(soname, fnname) \
13559c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
13569c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
13579c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
13589c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
13599c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13609c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT len_saved = len; \
13619c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
13629c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
13639c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
13649c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
13659c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
13669c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
13679c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
13689c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
136909041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = (char *)dst + len - 1; \
137009041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = (const char *)src + len - 1; \
13719c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
13729c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
13739c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
13749c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
137509041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = dst; \
137609041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = src; \
13779c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
13789c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
13799c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
13809c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13819c7779b64eacf264ee427b97ae0df8596b1960ccbart      return (void*)( ((char*)dst) + len_saved ); \
13829c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13839c7779b64eacf264ee427b97ae0df8596b1960ccbart
13849c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13859c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1386a9176d9640606a083a6e9b97515b15f631de5059mjw GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
13879c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
1388f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1389f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
13909c7779b64eacf264ee427b97ae0df8596b1960ccbart
13919c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13929c7779b64eacf264ee427b97ae0df8596b1960ccbart //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
13939c7779b64eacf264ee427b97ae0df8596b1960ccbart
13949c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13959c7779b64eacf264ee427b97ae0df8596b1960ccbart
13969c7779b64eacf264ee427b97ae0df8596b1960ccbart
13979c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memcpy_chk --------------------*/
13989c7779b64eacf264ee427b97ae0df8596b1960ccbart
13999c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC26___MEMCPY_CHK(soname, fnname) \
14009c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
14019c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ); \
14029c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
14039c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ) \
14049c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14059c7779b64eacf264ee427b97ae0df8596b1960ccbart      register HChar *d; \
14069c7779b64eacf264ee427b97ae0df8596b1960ccbart      register const HChar *s; \
14079c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14089c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dstlen < len) goto badness; \
14099c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14109c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
14119c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
14129c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14139c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
14149c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
14159c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14169c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
14179c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst + len - 1; \
14189c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src + len - 1; \
14199c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
14209c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
14219c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14229c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
14239c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst; \
14249c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src; \
14259c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
14269c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
14279c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14289c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
14299c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
14309c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14319c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14329c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memcpy_chk: buffer overflow detected ***: " \
14339c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
14349c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
14359c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14369c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14379c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14389c7779b64eacf264ee427b97ae0df8596b1960ccbart
14399c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14409c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
14419c7779b64eacf264ee427b97ae0df8596b1960ccbart
14429c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14439c7779b64eacf264ee427b97ae0df8596b1960ccbart
14449c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14459c7779b64eacf264ee427b97ae0df8596b1960ccbart
14469c7779b64eacf264ee427b97ae0df8596b1960ccbart
14479c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strstr ----------------------*/
14489c7779b64eacf264ee427b97ae0df8596b1960ccbart
14499c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSTR(soname, fnname) \
14509c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
14519c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
14529c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
14539c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
14549c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14559c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
14569c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle; \
14579c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14589c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
14599c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
14609c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
14619c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14629c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
146370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);         \
14649c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14659c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
14669c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar n0 = n[0]; \
14679c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14689c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
14699c7779b64eacf264ee427b97ae0df8596b1960ccbart         const HChar hh = *h; \
14709c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
14719c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
14729c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
14739c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
14749c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
14759c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (n[i] != h[i]) \
14769c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
14779c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14789c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
14799c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
148070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);          \
14819c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
14829c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
14839c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
14849c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14859c7779b64eacf264ee427b97ae0df8596b1960ccbart
14869c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14879c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          strstr)
14889c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse2)
14899c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse42)
14909c7779b64eacf264ee427b97ae0df8596b1960ccbart
14919c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14929c7779b64eacf264ee427b97ae0df8596b1960ccbart
14939c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14949c7779b64eacf264ee427b97ae0df8596b1960ccbart
14959c7779b64eacf264ee427b97ae0df8596b1960ccbart
14969c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strpbrk ----------------------*/
14979c7779b64eacf264ee427b97ae0df8596b1960ccbart
14989c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRPBRK(soname, fnname) \
14999c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
15009c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
15019c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
15029c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
15039c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15049c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
15059c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* accept = acceptV; \
15069c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15079c7779b64eacf264ee427b97ae0df8596b1960ccbart      /*  find the length of 'accept', not including terminating zero */ \
15089c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
15099c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
15109c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15119c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, fail immediately. */ \
15129c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return NULL; \
15139c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15149c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nacc >= 1); */ \
15159c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
15169c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
15179c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
15189c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
15199c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
15209c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
15219c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
152270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian              return CONST_CAST(HChar *,s);       \
15239c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15249c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
15259c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15269c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15279c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
15289c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15299c7779b64eacf264ee427b97ae0df8596b1960ccbart
15309c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15319c7779b64eacf264ee427b97ae0df8596b1960ccbart STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
15329c7779b64eacf264ee427b97ae0df8596b1960ccbart
15339c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15349c7779b64eacf264ee427b97ae0df8596b1960ccbart
15359c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15369c7779b64eacf264ee427b97ae0df8596b1960ccbart
15379c7779b64eacf264ee427b97ae0df8596b1960ccbart
15389c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcspn ----------------------*/
15399c7779b64eacf264ee427b97ae0df8596b1960ccbart
15409c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCSPN(soname, fnname) \
15419c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
15429c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV); \
15439c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
15449c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV) \
15459c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15469c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
15479c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* reject = rejectV; \
15489c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15499c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'reject', not including terminating zero */ \
15509c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nrej = 0; \
15519c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (reject[nrej]) nrej++; \
15529c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15539c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
15549c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
15559c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
15569c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
15579c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
15589c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
15599c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nrej; i++) { \
15609c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == reject[i]) \
15619c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
15629c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15639c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nrej); */ \
15649c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i < nrej) \
15659c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
15669c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
15679c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
15689c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15699c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15709c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
15719c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15729c7779b64eacf264ee427b97ae0df8596b1960ccbart
15739c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15749c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
15759c7779b64eacf264ee427b97ae0df8596b1960ccbart
15769c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15779c7779b64eacf264ee427b97ae0df8596b1960ccbart
15789c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15799c7779b64eacf264ee427b97ae0df8596b1960ccbart
15809c7779b64eacf264ee427b97ae0df8596b1960ccbart
15819c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strspn ----------------------*/
15829c7779b64eacf264ee427b97ae0df8596b1960ccbart
15839c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSPN(soname, fnname) \
15849c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
15859c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
15869c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
15879c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
15889c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15899c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* s = (const UChar *)sV;        \
15909c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* accept = (const UChar *)acceptV;     \
15919c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15929c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'accept', not including terminating zero */ \
15939c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
15949c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
15959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return 0; \
15969c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15979c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
15989c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
15999c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16009c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16019c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16029c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16039c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
16049c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
16059c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16069c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16079c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nacc); */ \
16089c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nacc) \
16099c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16109c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16119c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
16129c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16139c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16149c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
16159c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16169c7779b64eacf264ee427b97ae0df8596b1960ccbart
16179c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16189c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSPN(VG_Z_LIBC_SONAME,          strspn)
16199c7779b64eacf264ee427b97ae0df8596b1960ccbart
16209c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16219c7779b64eacf264ee427b97ae0df8596b1960ccbart
16229c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16239c7779b64eacf264ee427b97ae0df8596b1960ccbart
16249c7779b64eacf264ee427b97ae0df8596b1960ccbart
16259c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasestr ----------------------*/
16269c7779b64eacf264ee427b97ae0df8596b1960ccbart
16279c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASESTR(soname, fnname) \
16289c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
16299c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
16309c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
16319c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
16329c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16339c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
16349c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
16359c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle;   \
16369c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16379c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
16389c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
16399c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
16409c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16419c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
164270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);       \
16439c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16449c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
16459c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar n0 = tolower(n[0]);                 \
16469c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16479c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16489c7779b64eacf264ee427b97ae0df8596b1960ccbart         UChar hh = tolower(*h);    \
16499c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
16509c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
16519c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16529c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16539c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
16549c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (tolower(n[i]) != tolower(h[i]))  \
16559c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16569c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16579c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
16589c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
165970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);    \
16609c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16619c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
16629c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16639c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16649c7779b64eacf264ee427b97ae0df8596b1960ccbart
16659c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
166626ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
166726ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
166826ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
166926ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
16709c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
16719c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
16729c7779b64eacf264ee427b97ae0df8596b1960ccbart
16739c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16749c7779b64eacf264ee427b97ae0df8596b1960ccbart
16759c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16769c7779b64eacf264ee427b97ae0df8596b1960ccbart
16779c7779b64eacf264ee427b97ae0df8596b1960ccbart
16789c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcslen ----------------------*/
16799c7779b64eacf264ee427b97ae0df8596b1960ccbart
16809c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strlen.  Unfortunately
16819c7779b64eacf264ee427b97ae0df8596b1960ccbart// we don't have wchar_t available here, but it looks like
16829c7779b64eacf264ee427b97ae0df8596b1960ccbart// a 32 bit int on Linux.  I don't know if that is also
16839c7779b64eacf264ee427b97ae0df8596b1960ccbart// valid on MacOSX.
16849c7779b64eacf264ee427b97ae0df8596b1960ccbart
16859c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSLEN(soname, fnname) \
16869c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
16879c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str ); \
16889c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
16899c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str )  \
16909c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16919c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
16929c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
16939c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
16949c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16959c7779b64eacf264ee427b97ae0df8596b1960ccbart
16969c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16979c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
16989c7779b64eacf264ee427b97ae0df8596b1960ccbart
16999c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17009c7779b64eacf264ee427b97ae0df8596b1960ccbart
17019c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17029c7779b64eacf264ee427b97ae0df8596b1960ccbart
17039c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscmp ----------------------*/
17049c7779b64eacf264ee427b97ae0df8596b1960ccbart
17059c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcmp.  We don't
17069c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
17079c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide and wcscmp uses signed
17089c7779b64eacf264ee427b97ae0df8596b1960ccbart// comparison, not unsigned as in strcmp function.
17099c7779b64eacf264ee427b97ae0df8596b1960ccbart
17109c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCMP(soname, fnname) \
17119c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
17129c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ); \
17139c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
17149c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ) \
17159c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17169c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c1; \
17179c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c2; \
17189c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
17199c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *s1; \
17209c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *s2; \
17219c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
17229c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
17239c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
17249c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17259c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 < c2) return -1; \
17269c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 > c2) return 1; \
17279c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
17289c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17299c7779b64eacf264ee427b97ae0df8596b1960ccbart
17309c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17319c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCMP(VG_Z_LIBC_SONAME,          wcscmp)
17329c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17339c7779b64eacf264ee427b97ae0df8596b1960ccbart
17349c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscpy ----------------------*/
17359c7779b64eacf264ee427b97ae0df8596b1960ccbart
17369c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcpy.  We don't
17379c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
17389c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
17399c7779b64eacf264ee427b97ae0df8596b1960ccbart
17409c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCPY(soname, fnname) \
17419c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
17429c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ); \
17439c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
17449c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ) \
17459c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17469c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Int* src_orig = src; \
17479c7779b64eacf264ee427b97ae0df8596b1960ccbart            Int* dst_orig = dst; \
17489c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17499c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
17509c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
17519c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17529c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
17539c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
17549c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
17559c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
17569c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
17579c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
17589c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
17599c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17609c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
17619c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17629c7779b64eacf264ee427b97ae0df8596b1960ccbart
17639c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17649c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
17659c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17669c7779b64eacf264ee427b97ae0df8596b1960ccbart
17679c7779b64eacf264ee427b97ae0df8596b1960ccbart
17689c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcschr ----------------------*/
17699c7779b64eacf264ee427b97ae0df8596b1960ccbart
17709c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strchr.  We don't
17719c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
17729c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
17739c7779b64eacf264ee427b97ae0df8596b1960ccbart
17749c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCHR(soname, fnname) \
17759c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
17769c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
17779c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
177870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
17799c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
178070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == c) return CONST_CAST(Int *,p);  \
17819c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
17829c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
17839c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17849c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17859c7779b64eacf264ee427b97ae0df8596b1960ccbart
17869c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17879c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCHR(VG_Z_LIBC_SONAME,          wcschr)
17889c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17899c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcsrchr ----------------------*/
17909c7779b64eacf264ee427b97ae0df8596b1960ccbart
17919c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strrchr.  We don't
17929c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
17939c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
17949c7779b64eacf264ee427b97ae0df8596b1960ccbart
17959c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSRCHR(soname, fnname) \
17969c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
17979c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
17989c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
179970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
180070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* last = NULL; \
18019c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
18029c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == c) last = p; \
180370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(Int *,last);  \
18049c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
18059c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18069c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18079c7779b64eacf264ee427b97ae0df8596b1960ccbart
18089c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18099c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
18109c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18119c7779b64eacf264ee427b97ae0df8596b1960ccbart
18129c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
18139c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Improve definedness checking of process environment  ---*/
18149c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
18159c7779b64eacf264ee427b97ae0df8596b1960ccbart
18169c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18179c7779b64eacf264ee427b97ae0df8596b1960ccbart
18189c7779b64eacf264ee427b97ae0df8596b1960ccbart/* If these wind up getting generated via a macro, so that multiple
18199c7779b64eacf264ee427b97ae0df8596b1960ccbart   versions of each function exist (as above), use the _EZU variants
18209c7779b64eacf264ee427b97ae0df8596b1960ccbart   to assign equivalance class tags. */
18219c7779b64eacf264ee427b97ae0df8596b1960ccbart
18229c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- putenv ----------------------*/
18239c7779b64eacf264ee427b97ae0df8596b1960ccbart
18249c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
18259c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
18269c7779b64eacf264ee427b97ae0df8596b1960ccbart{
18279c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
18289c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
18299c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = string;
18309c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
18319c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
18329c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
18339c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
18349c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
18359c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
18369c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, string);
18379c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
18389c7779b64eacf264ee427b97ae0df8596b1960ccbart}
18399c7779b64eacf264ee427b97ae0df8596b1960ccbart
18409c7779b64eacf264ee427b97ae0df8596b1960ccbart
18419c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- unsetenv ----------------------*/
18429c7779b64eacf264ee427b97ae0df8596b1960ccbart
18439c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
18449c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
18459c7779b64eacf264ee427b97ae0df8596b1960ccbart{
18469c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
18479c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
18489c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = name;
18499c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
18509c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
18519c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
18529c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
18539c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
18549c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
18559c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, name);
18569c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
18579c7779b64eacf264ee427b97ae0df8596b1960ccbart}
18589c7779b64eacf264ee427b97ae0df8596b1960ccbart
18599c7779b64eacf264ee427b97ae0df8596b1960ccbart
18609c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- setenv ----------------------*/
18619c7779b64eacf264ee427b97ae0df8596b1960ccbart
18629c7779b64eacf264ee427b97ae0df8596b1960ccbart/* setenv */
18639c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
18649c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite);
18659c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
18669c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite)
18679c7779b64eacf264ee427b97ae0df8596b1960ccbart{
18689c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
18699c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
18709c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p;
18719c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
18729c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
18739c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
18749c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (name)
18759c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = name; *p; p++)
18769c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
18779c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (value)
18789c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = value; *p; p++)
18799c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
18809c7779b64eacf264ee427b97ae0df8596b1960ccbart    (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
18819c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_WWW(result, fn, name, value, overwrite);
18829c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
18839c7779b64eacf264ee427b97ae0df8596b1960ccbart}
18849c7779b64eacf264ee427b97ae0df8596b1960ccbart
18859c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif /* defined(VGO_linux) */
18869c7779b64eacf264ee427b97ae0df8596b1960ccbart
18879c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
18889c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- end                                                          ---*/
18899c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
1890