vg_replace_strmem.c revision e4fcda3d77cb2304a0feb9f5658c1f316fc3369f
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
11b3a1e4bffbdbbf38304f216af405009868f43628sewardj   Copyright (C) 2000-2015 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
1068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_solaris)
1078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*
1088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   Detour functions in the libc and the runtime linker. If a function isn't
1098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   much optimized (and no overlap checking is necessary) then redir the
1108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   function only in the libc. This way we can keep stacktraces in the tests
1118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   consistent.
1128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj*/
1138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif
1148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
1159c7779b64eacf264ee427b97ae0df8596b1960ccbart
1169c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Figure out if [dst .. dst+dstlen-1] overlaps with
1179c7779b64eacf264ee427b97ae0df8596b1960ccbart                 [src .. src+srclen-1].
1189c7779b64eacf264ee427b97ae0df8596b1960ccbart   We assume that the address ranges do not wrap around
1199c7779b64eacf264ee427b97ae0df8596b1960ccbart   (which is safe since on Linux addresses >= 0xC0000000
1209c7779b64eacf264ee427b97ae0df8596b1960ccbart   are not accessible and the program will segfault in this
1219c7779b64eacf264ee427b97ae0df8596b1960ccbart   circumstance, presumably).
1229c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
1239c7779b64eacf264ee427b97ae0df8596b1960ccbartstatic inline
1249c7779b64eacf264ee427b97ae0df8596b1960ccbartBool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
1259c7779b64eacf264ee427b97ae0df8596b1960ccbart{
1269c7779b64eacf264ee427b97ae0df8596b1960ccbart   Addr loS, hiS, loD, hiD;
1279c7779b64eacf264ee427b97ae0df8596b1960ccbart
1289c7779b64eacf264ee427b97ae0df8596b1960ccbart   if (dstlen == 0 || srclen == 0)
1299c7779b64eacf264ee427b97ae0df8596b1960ccbart      return False;
1309c7779b64eacf264ee427b97ae0df8596b1960ccbart
1319c7779b64eacf264ee427b97ae0df8596b1960ccbart   loS = (Addr)src;
1329c7779b64eacf264ee427b97ae0df8596b1960ccbart   loD = (Addr)dst;
1339c7779b64eacf264ee427b97ae0df8596b1960ccbart   hiS = loS + srclen - 1;
1349c7779b64eacf264ee427b97ae0df8596b1960ccbart   hiD = loD + dstlen - 1;
1359c7779b64eacf264ee427b97ae0df8596b1960ccbart
1369c7779b64eacf264ee427b97ae0df8596b1960ccbart   /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */
1379c7779b64eacf264ee427b97ae0df8596b1960ccbart   if (loS < loD) {
1389c7779b64eacf264ee427b97ae0df8596b1960ccbart      return !(hiS < loD);
1399c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1409c7779b64eacf264ee427b97ae0df8596b1960ccbart   else if (loD < loS) {
1419c7779b64eacf264ee427b97ae0df8596b1960ccbart      return !(hiD < loS);
1429c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1439c7779b64eacf264ee427b97ae0df8596b1960ccbart   else {
1449c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* They start at same place.  Since we know neither of them has
1459c7779b64eacf264ee427b97ae0df8596b1960ccbart         zero length, they must overlap. */
1469c7779b64eacf264ee427b97ae0df8596b1960ccbart      return True;
1479c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1489c7779b64eacf264ee427b97ae0df8596b1960ccbart}
1499c7779b64eacf264ee427b97ae0df8596b1960ccbart
1509c7779b64eacf264ee427b97ae0df8596b1960ccbart
1519c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Call here to exit if we can't continue.  On Android we can't call
1529c7779b64eacf264ee427b97ae0df8596b1960ccbart   _exit for some reason, so we have to blunt-instrument it. */
1539c7779b64eacf264ee427b97ae0df8596b1960ccbart__attribute__ ((__noreturn__))
1549c7779b64eacf264ee427b97ae0df8596b1960ccbartstatic inline void my_exit ( int x )
1559c7779b64eacf264ee427b97ae0df8596b1960ccbart{
1569c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
15726ed419d60369d0545510eba0832566e24452e1esewardj      || defined(VGPV_arm64_linux_android)
1589c7779b64eacf264ee427b97ae0df8596b1960ccbart   __asm__ __volatile__(".word 0xFFFFFFFF");
1599c7779b64eacf264ee427b97ae0df8596b1960ccbart   while (1) {}
1609c7779b64eacf264ee427b97ae0df8596b1960ccbart#  elif defined(VGPV_x86_linux_android)
1619c7779b64eacf264ee427b97ae0df8596b1960ccbart   __asm__ __volatile__("ud2");
1629c7779b64eacf264ee427b97ae0df8596b1960ccbart   while (1) {}
1639c7779b64eacf264ee427b97ae0df8596b1960ccbart#  else
1649c7779b64eacf264ee427b97ae0df8596b1960ccbart   extern __attribute__ ((__noreturn__)) void _exit(int status);
1659c7779b64eacf264ee427b97ae0df8596b1960ccbart   _exit(x);
1669c7779b64eacf264ee427b97ae0df8596b1960ccbart#  endif
1679c7779b64eacf264ee427b97ae0df8596b1960ccbart}
1689c7779b64eacf264ee427b97ae0df8596b1960ccbart
1699c7779b64eacf264ee427b97ae0df8596b1960ccbart
1709c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a macro rather than a function because we don't want to have an
1719c7779b64eacf264ee427b97ae0df8596b1960ccbart// extra function in the stack trace.
1729c7779b64eacf264ee427b97ae0df8596b1960ccbart#ifndef RECORD_OVERLAP_ERROR
1739c7779b64eacf264ee427b97ae0df8596b1960ccbart#define RECORD_OVERLAP_ERROR(s, src, dst, len) do { } while (0)
1749c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
1759c7779b64eacf264ee427b97ae0df8596b1960ccbart#ifndef VALGRIND_CHECK_VALUE_IS_DEFINED
1769c7779b64eacf264ee427b97ae0df8596b1960ccbart#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) 1
1779c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
1789c7779b64eacf264ee427b97ae0df8596b1960ccbart
1799c7779b64eacf264ee427b97ae0df8596b1960ccbart
1809c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strrchr ----------------------*/
1819c7779b64eacf264ee427b97ae0df8596b1960ccbart
1829c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRRCHR(soname, fnname) \
1839c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
1849c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
1859c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
1869c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar ch = (HChar)c;   \
1879c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* p = s;       \
1889c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* last = NULL; \
1899c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
1909c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == ch) last = p; \
19170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(HChar *,last);    \
1929c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
1939c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
1949c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
1959c7779b64eacf264ee427b97ae0df8596b1960ccbart
1969c7779b64eacf264ee427b97ae0df8596b1960ccbart// Apparently rindex() is the same thing as strrchr()
1979c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
1989c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
1999c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   rindex)
2009c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
2019c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse2)
2029c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse2_no_bsf)
2039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME,   __strrchr_sse42)
2049c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
2059c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
2069c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
2079c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
2089c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2099c7779b64eacf264ee427b97ae0df8596b1960ccbart
2109c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2119c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
2129c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_LIBC_SONAME,   rindex)
2139c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_DYLD,          strrchr)
2149c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRRCHR(VG_Z_DYLD,          rindex)
2159c7779b64eacf264ee427b97ae0df8596b1960ccbart STRRCHR(VG_Z_LIBC_SONAME, strrchr)
2169090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
217eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  STRRCHR(libsystemZucZddylib, strrchr)
218eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
2199c7779b64eacf264ee427b97ae0df8596b1960ccbart
2208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
2218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
2228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRRCHR(VG_Z_LIBC_SONAME,   rindex)
2238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRRCHR(VG_Z_LD_SO_1,       strrchr)
2248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2259c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2269c7779b64eacf264ee427b97ae0df8596b1960ccbart
2279c7779b64eacf264ee427b97ae0df8596b1960ccbart
2289c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strchr ----------------------*/
2299c7779b64eacf264ee427b97ae0df8596b1960ccbart
2309c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCHR(soname, fnname) \
2319c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \
2329c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \
2339c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2349c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar  ch = (HChar)c ; \
2359c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* p  = s;   \
2369c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
23770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == ch) return CONST_CAST(HChar *,p);  \
2389c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
2399c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
2409c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
2419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
2429c7779b64eacf264ee427b97ae0df8596b1960ccbart
2439c7779b64eacf264ee427b97ae0df8596b1960ccbart// Apparently index() is the same thing as strchr()
2449c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
2459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          strchr)
2469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
2479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __strchr_sse2)
2489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          __strchr_sse2_no_bsf)
2499c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME,          index)
2509c7779b64eacf264ee427b97ae0df8596b1960ccbart# if !defined(VGP_x86_linux)
2519c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_SO_2,        strchr)
2529c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_SO_2,        index)
2539c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
2549c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
2559c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
2569c7779b64eacf264ee427b97ae0df8596b1960ccbart
2579c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2589c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME, strchr)
259c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# if DARWIN_VERS == DARWIN_10_9
260c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCHR(libsystemZuplatformZddylib, _platform_strchr)
261c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
2629090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_10
2639951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  /* _platform_strchr$VARIANT$Generic */
2649951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
265e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  /* _platform_strchr$VARIANT$Haswell */
266366cefb68a2b15558ed1ddcda74c675d3ac39948rhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
2679951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# endif
2688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
2708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          strchr)
2718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          index)
2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LD_SO_1,              strchr)
2738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2749c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2759c7779b64eacf264ee427b97ae0df8596b1960ccbart
2769c7779b64eacf264ee427b97ae0df8596b1960ccbart
2779c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcat ----------------------*/
2789c7779b64eacf264ee427b97ae0df8596b1960ccbart
2799c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCAT(soname, fnname) \
2809c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2819c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
2829c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2839c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
2849c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2859c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
2869c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
2879c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
2889c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
2899c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
2909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2919c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This is a bit redundant, I think;  any overlap and the strcat will */ \
2929c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* go forever... or until a seg fault occurs. */ \
2939c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
2949c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
2959c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
2969c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
2979c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
2989c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2999c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3009c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3019c7779b64eacf264ee427b97ae0df8596b1960ccbart
3029c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, strcat)
3049c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
3059c7779b64eacf264ee427b97ae0df8596b1960ccbart
3069c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3079c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCAT(VG_Z_LIBC_SONAME, strcat)
3089c7779b64eacf264ee427b97ae0df8596b1960ccbart
3098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LIBC_SONAME, strcat)
3118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LD_SO_1,     strcat)
3128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3139c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3149c7779b64eacf264ee427b97ae0df8596b1960ccbart
3159c7779b64eacf264ee427b97ae0df8596b1960ccbart
3169c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncat ----------------------*/
3179c7779b64eacf264ee427b97ae0df8596b1960ccbart
3189c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCAT(soname, fnname) \
3199c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3209c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
3219c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3229c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
3239c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3249c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3259c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
3269c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3279c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3289c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
3299c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
3309c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0;                                       /* always add null   */ \
3319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3329c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3339c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3359c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3369c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
3379c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3389c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
3399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3409c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3429c7779b64eacf264ee427b97ae0df8596b1960ccbart
3439c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCAT(VG_Z_LIBC_SONAME, strncat)
3459c7779b64eacf264ee427b97ae0df8596b1960ccbart
3469c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3479c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_LIBC_SONAME, strncat)
3489c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_DYLD,        strncat)
3499c7779b64eacf264ee427b97ae0df8596b1960ccbart
3508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCAT(VG_Z_LIBC_SONAME, strncat)
3528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3539c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3549c7779b64eacf264ee427b97ae0df8596b1960ccbart
3559c7779b64eacf264ee427b97ae0df8596b1960ccbart
3569c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcat ----------------------*/
3579c7779b64eacf264ee427b97ae0df8596b1960ccbart
3589c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
3599c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be nul-terminated after the copy, unless n <= strlen(dst_orig).
3609c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns min(n, strlen(dst_orig)) + strlen(src_orig).
3619c7779b64eacf264ee427b97ae0df8596b1960ccbart   Truncation occurred if retval >= n.
3629c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
3639c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCAT(soname, fnname) \
3649c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3659c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ); \
3669c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3679c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ) \
3689c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3699c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3709c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
3719c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3729c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3739c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *dst) { m++; dst++; } \
3749c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (m < n) { \
3759c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
3769c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (m < n-1 && *src) { m++; *dst++ = *src++; } \
3779c7779b64eacf264ee427b97ae0df8596b1960ccbart         *dst = 0; \
3789c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
3799c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* No space to copy anything to dst. m == n */ \
3809c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
3819c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
3829c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) { m++; src++; } \
3839c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3849c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3859c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3869c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3879c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
3889c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3899c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
3909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3919c7779b64eacf264ee427b97ae0df8596b1960ccbart      return m; \
3929c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3939c7779b64eacf264ee427b97ae0df8596b1960ccbart
3949c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3959c7779b64eacf264ee427b97ae0df8596b1960ccbart
3969c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3979c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
3989c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_DYLD,        strlcat)
3999c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4009c7779b64eacf264ee427b97ae0df8596b1960ccbart
4018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4049c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4059c7779b64eacf264ee427b97ae0df8596b1960ccbart
4069c7779b64eacf264ee427b97ae0df8596b1960ccbart
4079c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strnlen ----------------------*/
4089c7779b64eacf264ee427b97ae0df8596b1960ccbart
4099c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNLEN(soname, fnname) \
4109c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4119c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ); \
4129c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4139c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ) \
4149c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4159c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4169c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (i < n && str[i] != 0) i++; \
4179c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4189c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4199c7779b64eacf264ee427b97ae0df8596b1960ccbart
4209c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4219c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4229c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
4239c7779b64eacf264ee427b97ae0df8596b1960ccbart
4249c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
425aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
426aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNLEN(libsystemZucZddylib, strnlen)
427aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
4289c7779b64eacf264ee427b97ae0df8596b1960ccbart
4298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4329c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4339c7779b64eacf264ee427b97ae0df8596b1960ccbart
4349c7779b64eacf264ee427b97ae0df8596b1960ccbart
4359c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlen ----------------------*/
4369c7779b64eacf264ee427b97ae0df8596b1960ccbart
4379c7779b64eacf264ee427b97ae0df8596b1960ccbart// Note that this replacement often doesn't get used because gcc inlines
4389c7779b64eacf264ee427b97ae0df8596b1960ccbart// calls to strlen() with its own built-in version.  This can be very
4399c7779b64eacf264ee427b97ae0df8596b1960ccbart// confusing if you aren't expecting it.  Other small functions in
4409c7779b64eacf264ee427b97ae0df8596b1960ccbart// this file may also be inline by gcc.
4419c7779b64eacf264ee427b97ae0df8596b1960ccbart
4429c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLEN(soname, fnname) \
4439c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4449c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str ); \
4459c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4469c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str )  \
4479c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4489c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4499c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
4509c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4519c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4529c7779b64eacf264ee427b97ae0df8596b1960ccbart
4539c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4549c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          strlen)
4559c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
4569c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2)
4579c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2_no_bsf)
4589c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse42)
4599c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
4609c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
46126ed419d60369d0545510eba0832566e24452e1esewardj# if defined(VGPV_arm_linux_android) \
46226ed419d60369d0545510eba0832566e24452e1esewardj     || defined(VGPV_x86_linux_android) \
4639c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
4649c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
4659c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
4669c7779b64eacf264ee427b97ae0df8596b1960ccbart
4679c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4689c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME, strlen)
4699090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
470c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRLEN(libsystemZucZddylib, strlen)
471c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
4728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LIBC_SONAME,          strlen)
4758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LD_SO_1,              strlen)
4768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4779c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4789c7779b64eacf264ee427b97ae0df8596b1960ccbart
4799c7779b64eacf264ee427b97ae0df8596b1960ccbart
4809c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy ----------------------*/
4819c7779b64eacf264ee427b97ae0df8596b1960ccbart
4829c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCPY(soname, fnname) \
4839c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4849c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ); \
4859c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4869c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ) \
4879c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4889c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
4899c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
4909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4919c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
4929c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
4939c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4949c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
4959c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
4969c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
4979c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
4989c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
4999c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
5009c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
5019c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5029c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5039c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5049c7779b64eacf264ee427b97ae0df8596b1960ccbart
5059c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
5079c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
5089c7779b64eacf264ee427b97ae0df8596b1960ccbart
5099c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5109c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
511aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
512aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRCPY(libsystemZucZddylib, strcpy)
513aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5149c7779b64eacf264ee427b97ae0df8596b1960ccbart
5158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LIBC_SONAME, strcpy)
5178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LD_SO_1,     strcpy)
5188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5199c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5209c7779b64eacf264ee427b97ae0df8596b1960ccbart
5219c7779b64eacf264ee427b97ae0df8596b1960ccbart
5229c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncpy ----------------------*/
5239c7779b64eacf264ee427b97ae0df8596b1960ccbart
5249c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCPY(soname, fnname) \
5259c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5269c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
5279c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5289c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
5299c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5309c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5319c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
5329c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5339c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5349c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
5359c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5369c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5379c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5389c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
5399c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
5409c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5419c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5429c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5439c7779b64eacf264ee427b97ae0df8596b1960ccbart
5449c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
5479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
5489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
5499c7779b64eacf264ee427b97ae0df8596b1960ccbart
5509c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5519c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5529090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
553aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNCPY(libsystemZucZddylib, strncpy)
554aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5559c7779b64eacf264ee427b97ae0df8596b1960ccbart
5568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LD_SO_1,     strncpy)
5598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5609c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5619c7779b64eacf264ee427b97ae0df8596b1960ccbart
5629c7779b64eacf264ee427b97ae0df8596b1960ccbart
5639c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcpy ----------------------*/
5649c7779b64eacf264ee427b97ae0df8596b1960ccbart
5659c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
5669c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns strlen(src). Does not zero-fill the remainder of dst. */
5679c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCPY(soname, fnname) \
5689c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5699c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ); \
5709c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5719c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ) \
5729c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5739c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5749c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
5759c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5769c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
5788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      \
5799c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n-1 && *src) { m++; *dst++ = *src++; } \
5809c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* m non-nul bytes have now been copied, and m <= n-1. */ \
5819c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5829c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5839c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5849c7779b64eacf264ee427b97ae0df8596b1960ccbart          RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
5859c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Nul-terminate dst. */ \
5869c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (n > 0) *dst = 0; \
5879c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting strlen(src). */ \
5889c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) src++; \
5899c7779b64eacf264ee427b97ae0df8596b1960ccbart      return src - src_orig; \
5909c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5919c7779b64eacf264ee427b97ae0df8596b1960ccbart
5929c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5939c7779b64eacf264ee427b97ae0df8596b1960ccbart
5949c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
5959c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
5968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
5979c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
5989c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5999c7779b64eacf264ee427b97ae0df8596b1960ccbart
6009c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
6029c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6039c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_DYLD,        strlcpy)
6049c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6059c7779b64eacf264ee427b97ae0df8596b1960ccbart
6068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* special case for n == 0 which is undocumented but heavily used */
6088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
6098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    if (n == 0) { \
6108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       while (*src) src++; \
6118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       return src - src_orig; \
6128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    }
6138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6169c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6179c7779b64eacf264ee427b97ae0df8596b1960ccbart
6189c7779b64eacf264ee427b97ae0df8596b1960ccbart
6199c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncmp ----------------------*/
6209c7779b64eacf264ee427b97ae0df8596b1960ccbart
6219c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCMP(soname, fnname) \
6229c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6239c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
6249c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6259c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
6269c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6279c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
6289c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6299c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
6309c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
6319c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
6329c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
6339c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6349c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
6359c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
6369c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6379c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
6389c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6399c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6409c7779b64eacf264ee427b97ae0df8596b1960ccbart
6419c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
6429c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6439c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
6449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
6459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
6469c7779b64eacf264ee427b97ae0df8596b1960ccbart
6479c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
6499090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
650798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
651798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj# endif
6529c7779b64eacf264ee427b97ae0df8596b1960ccbart
6538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6569c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6579c7779b64eacf264ee427b97ae0df8596b1960ccbart
6589c7779b64eacf264ee427b97ae0df8596b1960ccbart
6599c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp ----------------------*/
6609c7779b64eacf264ee427b97ae0df8596b1960ccbart
6619c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP(soname, fnname) \
6629c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6639c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
6649c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6659c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
6669c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6679c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
6689c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
6699c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
6709c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6719c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower(*(const UChar *)s1); \
6729c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower(*(const UChar *)s2); \
6739c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
6749c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
6759c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
6769c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6779c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
6789c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
6799c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
6809c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6819c7779b64eacf264ee427b97ae0df8596b1960ccbart
6829c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
68326ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
68426ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
68526ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
68626ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
6879c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6889c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
6899c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
6909c7779b64eacf264ee427b97ae0df8596b1960ccbart
6919c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6929c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6939c7779b64eacf264ee427b97ae0df8596b1960ccbart
6948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6979c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6989c7779b64eacf264ee427b97ae0df8596b1960ccbart
6999c7779b64eacf264ee427b97ae0df8596b1960ccbart
7009c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp ----------------------*/
7019c7779b64eacf264ee427b97ae0df8596b1960ccbart
7029c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP(soname, fnname) \
7039c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7049c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
7059c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7069c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
7079c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7089c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
7099c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7109c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7119c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7129c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7139c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7149c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7159c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7169c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7179c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower(*(const UChar*)s2)) return -1; \
7189c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7199c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower(*(const UChar *)s2)) return 1; \
7209c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7219c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
7229c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7239c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7249c7779b64eacf264ee427b97ae0df8596b1960ccbart
7259c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
72626ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
72726ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
72826ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
72926ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
7309c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7319c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
7329c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
7339c7779b64eacf264ee427b97ae0df8596b1960ccbart
7349c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7359c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7369c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_DYLD,        strncasecmp)
7379c7779b64eacf264ee427b97ae0df8596b1960ccbart
7388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7419c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7429c7779b64eacf264ee427b97ae0df8596b1960ccbart
7439c7779b64eacf264ee427b97ae0df8596b1960ccbart
7449c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp_l ----------------------*/
7459c7779b64eacf264ee427b97ae0df8596b1960ccbart
7469c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP_L(soname, fnname) \
7479c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7489c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ); \
7499c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7509c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ) \
7519c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7529c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak)); \
7539c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
7549c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
7559c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7569c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower_l(*(const UChar *)s1, locale); \
7579c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower_l(*(const UChar *)s2, locale); \
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 STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7699c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
7709c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
7719c7779b64eacf264ee427b97ae0df8596b1960ccbart
7729c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7739c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7749c7779b64eacf264ee427b97ae0df8596b1960ccbart
7758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7779c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7789c7779b64eacf264ee427b97ae0df8596b1960ccbart
7799c7779b64eacf264ee427b97ae0df8596b1960ccbart
7809c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp_l ----------------------*/
7819c7779b64eacf264ee427b97ae0df8596b1960ccbart
7829c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP_L(soname, fnname) \
7839c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7849c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
7859c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7869c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
7879c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7889c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak));    \
7899c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7909c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7919c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7929c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7939c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7949c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7959c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7969c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7979c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower_l(*(const UChar *)s2, locale)) return -1; \
7989c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7999c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower_l(*(const UChar *)s2, locale)) return 1; \
8009c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8019c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
8029c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8039c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8049c7779b64eacf264ee427b97ae0df8596b1960ccbart
8059c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8079c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
8089c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
8099c7779b64eacf264ee427b97ae0df8596b1960ccbart
8109c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8119c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8129c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
8139c7779b64eacf264ee427b97ae0df8596b1960ccbart
8148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8169c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8179c7779b64eacf264ee427b97ae0df8596b1960ccbart
8189c7779b64eacf264ee427b97ae0df8596b1960ccbart
8199c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcmp ----------------------*/
8209c7779b64eacf264ee427b97ae0df8596b1960ccbart
8219c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCMP(soname, fnname) \
8229c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8239c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
8249c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8259c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
8269c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8279c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
8289c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
8299c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
8309c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *(const UChar *)s1; \
8319c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *(const UChar *)s2; \
8329c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
8339c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
8349c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
8359c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8369c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
8379c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
8389c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
8399c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8409c7779b64eacf264ee427b97ae0df8596b1960ccbart
8419c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8429c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8439c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
8449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse2)
8459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse42)
8469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
8479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD64_SO_1,            strcmp)
8489c6b05db45362b1afb981aa8298ab12ab4027b1adejanj# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8499c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
8509c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
8519c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
8529c7779b64eacf264ee427b97ae0df8596b1960ccbart
8539c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8549c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME, strcmp)
8559090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
856c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
857c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
8589c7779b64eacf264ee427b97ae0df8596b1960ccbart
8598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LD_SO_1,              strcmp)
8628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8639c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8649c7779b64eacf264ee427b97ae0df8596b1960ccbart
8659c7779b64eacf264ee427b97ae0df8596b1960ccbart
8669c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memchr ----------------------*/
8679c7779b64eacf264ee427b97ae0df8596b1960ccbart
8689c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCHR(soname, fnname) \
8699c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8709c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
8719c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8729c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
8739c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8749c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
8759c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
87670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
8779c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
87870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
8799c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
8809c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8819c7779b64eacf264ee427b97ae0df8596b1960ccbart
8829c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8839c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, memchr)
8849c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
8859c7779b64eacf264ee427b97ae0df8596b1960ccbart
8869c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
887aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
888798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  MEMCHR(VG_Z_DYLD,                   memchr)
889aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
890aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
8919090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_10
892a95abead5600e5b0e7a430d4d373aad7e267e35csewardj  MEMCHR(VG_Z_DYLD,                   memchr)
893312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memchr$VARIANT$Generic */
894312bcb109bfb6899086dda47b02a5436f26516d4sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
895e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  /* _platform_memchr$VARIANT$Haswell */
896e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
897312bcb109bfb6899086dda47b02a5436f26516d4sewardj# endif
8989c7779b64eacf264ee427b97ae0df8596b1960ccbart
8998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
9008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCHR(VG_Z_LIBC_SONAME, memchr)
9018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
9029c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9039c7779b64eacf264ee427b97ae0df8596b1960ccbart
9049c7779b64eacf264ee427b97ae0df8596b1960ccbart
9059c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memrchr ----------------------*/
9069c7779b64eacf264ee427b97ae0df8596b1960ccbart
9079c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMRCHR(soname, fnname) \
9089c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9099c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
9109c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9119c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
9129c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9139c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
9149c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
91570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
9169c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
91770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
9189c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
9199c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
9209c7779b64eacf264ee427b97ae0df8596b1960ccbart
9219c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
9229c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9239c7779b64eacf264ee427b97ae0df8596b1960ccbart
9249c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
9259c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9269c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_DYLD,        memrchr)
9279c7779b64eacf264ee427b97ae0df8596b1960ccbart
9288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
9298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
9309c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9319c7779b64eacf264ee427b97ae0df8596b1960ccbart
9329c7779b64eacf264ee427b97ae0df8596b1960ccbart
9339c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcpy ----------------------*/
9349c7779b64eacf264ee427b97ae0df8596b1960ccbart
9359c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
9369c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9379c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
9389c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9399c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
9409c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9419c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (do_ol_check && is_overlap(dst, src, len, len)) \
9429c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
9439c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9449c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WS = sizeof(UWord); /* 8 or 4 */ \
9459c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WM = WS - 1;        /* 7 or 3 */ \
9469c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9479c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len > 0) { \
9489c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (dst < src || !is_overlap(dst, src, len, len)) { \
9499c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9509c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying backwards. */ \
9519c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9529c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = (Addr)dst; \
9539c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = (Addr)src; \
9549c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9559c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9569c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9579c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Pull up to a UWord boundary. */ \
9589c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9599c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9609c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9619c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9629c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
9639c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9649c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9659c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9669c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9679c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9689c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9699c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
9709c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9719c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9729c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
9739c7779b64eacf264ee427b97ae0df8596b1960ccbart               { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9749c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9759c7779b64eacf264ee427b97ae0df8596b1960ccbart         } else if (dst > src) { \
9769c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9779c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9789c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = ((Addr)dst) + n; \
9799c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = ((Addr)src) + n; \
9809c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9819c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying forwards. */ \
9829c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9839c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9849c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Back down to a UWord boundary. */ \
9859c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9869c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9879c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9889c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9899c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
9909c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9919c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9929c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9939c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9949c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9959c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9969c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
9979c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9989c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9999c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
10009c7779b64eacf264ee427b97ae0df8596b1960ccbart               { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
10019c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
10029c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
10039c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10049c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10059c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
10069c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10079c7779b64eacf264ee427b97ae0df8596b1960ccbart
10089c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE(soname, fnname)  \
10099c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
10109c7779b64eacf264ee427b97ae0df8596b1960ccbart
10119c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCPY(soname, fnname) \
10129c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
10139c7779b64eacf264ee427b97ae0df8596b1960ccbart
10149c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10159c7779b64eacf264ee427b97ae0df8596b1960ccbart /* For older memcpy we have to use memmove-like semantics and skip
10169c7779b64eacf264ee427b97ae0df8596b1960ccbart    the overlap check; sigh; see #275284. */
10179c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
10189c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
10199c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
10209c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __GI_memcpy)
10219c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __memcpy_sse2)
10229c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
10239c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
10249c7779b64eacf264ee427b97ae0df8596b1960ccbart /* icc9 blats these around all over the place.  Not only in the main
10259c7779b64eacf264ee427b97ae0df8596b1960ccbart    executable but various .so's.  They are highly tuned and read
10269c7779b64eacf264ee427b97ae0df8596b1960ccbart    memory beyond the source boundary (although work correctly and
10279c7779b64eacf264ee427b97ae0df8596b1960ccbart    never go across page boundaries), so give errors when run
10289c7779b64eacf264ee427b97ae0df8596b1960ccbart    natively, at least for misaligned source arg.  Just intercepting
10299c7779b64eacf264ee427b97ae0df8596b1960ccbart    in the exe only until we understand more about the problem.  See
10309c7779b64eacf264ee427b97ae0df8596b1960ccbart    http://bugs.kde.org/show_bug.cgi?id=139776
10319c7779b64eacf264ee427b97ae0df8596b1960ccbart */
10329c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(NONE, ZuintelZufastZumemcpy)
10339c7779b64eacf264ee427b97ae0df8596b1960ccbart
10349c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10359c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
10369c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
10379c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
10389c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
10399c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
10409c7779b64eacf264ee427b97ae0df8596b1960ccbart
10418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
10428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
10438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LD_SO_1,      memcpy)
10448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
10459c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10469c7779b64eacf264ee427b97ae0df8596b1960ccbart
10479c7779b64eacf264ee427b97ae0df8596b1960ccbart
10489c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcmp ----------------------*/
10499c7779b64eacf264ee427b97ae0df8596b1960ccbart
10509c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCMP(soname, fnname) \
10519c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10529c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n ); \
10539c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10549c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n )  \
10559c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
1056094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1057094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WM = WS - 1;        /* 7 or 3 */ \
105811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s1A = (Addr)s1V; \
105911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s2A = (Addr)s2V; \
106011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
106111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      if (((s1A | s2A) & WM) == 0) { \
106211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* Both areas are word aligned.  Skip over the */ \
106311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* equal prefix as fast as possible. */ \
106411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         while (n >= WS) { \
106511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w1 = *(UWord*)s1A; \
106611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w2 = *(UWord*)s2A; \
106711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            if (w1 != w2) break; \
106811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s1A += WS; \
106911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s2A += WS; \
107011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            n -= WS; \
107111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         } \
107211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      } \
107311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
107411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s1 = (const UChar*) s1A; \
107511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s2 = (const UChar*) s2A; \
10769c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10779c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n != 0) { \
107811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar a0 = s1[0]; \
107911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar b0 = s2[0]; \
10809c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1 += 1; \
10819c7779b64eacf264ee427b97ae0df8596b1960ccbart         s2 += 1; \
108211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         int res = ((int)a0) - ((int)b0); \
10839c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (res != 0) \
10849c7779b64eacf264ee427b97ae0df8596b1960ccbart            return res; \
10859c7779b64eacf264ee427b97ae0df8596b1960ccbart         n -= 1; \
10869c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10879c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
10889c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10899c7779b64eacf264ee427b97ae0df8596b1960ccbart
10909c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10919c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, memcmp)
10929c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
10939c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
10949c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
10959c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, bcmp)
10969c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LD_SO_1,     bcmp)
10979c7779b64eacf264ee427b97ae0df8596b1960ccbart
10989c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10999090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1100aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1101aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
11029c7779b64eacf264ee427b97ae0df8596b1960ccbart
11038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, memcmp)
11058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, bcmp)
11068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LD_SO_1,     memcmp)
11078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11089c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11099c7779b64eacf264ee427b97ae0df8596b1960ccbart
11109c7779b64eacf264ee427b97ae0df8596b1960ccbart
11119c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy ----------------------*/
11129c7779b64eacf264ee427b97ae0df8596b1960ccbart
11139c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy SRC to DEST, returning the address of the terminating '\0' in
11149c7779b64eacf264ee427b97ae0df8596b1960ccbart   DEST. (minor variant of strcpy) */
11159c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPCPY(soname, fnname) \
11169c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11179c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
11189c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11199c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
11209c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11219c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11229c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
11239c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11249c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
11259c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
11269c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11279c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
11289c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
11299c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
11309c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
11319c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
11329c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
11339c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
11349c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11359c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
11369c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11379c7779b64eacf264ee427b97ae0df8596b1960ccbart
11389c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11399c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11409c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
11419c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2)
11429c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2_unaligned)
11439c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
11449c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
11459c7779b64eacf264ee427b97ae0df8596b1960ccbart
11469c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11479c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11489c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_DYLD,                 stpcpy)
11499c7779b64eacf264ee427b97ae0df8596b1960ccbart
11508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11539c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11549c7779b64eacf264ee427b97ae0df8596b1960ccbart
11559c7779b64eacf264ee427b97ae0df8596b1960ccbart
11569c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpncpy ----------------------*/
11579c7779b64eacf264ee427b97ae0df8596b1960ccbart
11589c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPNCPY(soname, fnname) \
11599c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11609c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
11619c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11629c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
11639c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11649c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11659c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_str  = dst; \
11669c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
11679c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11689c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
11699c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
11709c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
11719c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
11729c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
11739c7779b64eacf264ee427b97ae0df8596b1960ccbart      dst_str = dst; \
11749c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
11759c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11769c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_str; \
11779c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11789c7779b64eacf264ee427b97ae0df8596b1960ccbart
11799c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11809c7779b64eacf264ee427b97ae0df8596b1960ccbart STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
11819c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11829c7779b64eacf264ee427b97ae0df8596b1960ccbart
11839c7779b64eacf264ee427b97ae0df8596b1960ccbart
11849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memset ----------------------*/
11859c7779b64eacf264ee427b97ae0df8596b1960ccbart
11869c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Why are we bothering to intercept this?  It seems entirely
11879c7779b64eacf264ee427b97ae0df8596b1960ccbart   pointless. */
11889c7779b64eacf264ee427b97ae0df8596b1960ccbart
11899c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMSET(soname, fnname) \
11909c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
11919c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n); \
11929c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
11939c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n) \
11949c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (sizeof(void*) == 8) { \
11969c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr  a  = (Addr)s;   \
11979c7779b64eacf264ee427b97ae0df8596b1960ccbart         ULong c8 = (c & 0xFF); \
11989c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 8) | c8; \
11999c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 16) | c8; \
12009c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 32) | c8; \
12019c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 7) != 0 && n >= 1) \
12029c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12039c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 8) \
12049c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(ULong*)a = c8; a += 8; n -= 8; } \
12059c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12069c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12079c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12089c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
12099c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr a  = (Addr)s;   \
12109c7779b64eacf264ee427b97ae0df8596b1960ccbart         UInt c4 = (c & 0xFF); \
12119c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 8) | c4; \
12129c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 16) | c4; \
12139c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 3) != 0 && n >= 1) \
12149c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12159c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 4) \
12169c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UInt*)a = c4; a += 4; n -= 4; } \
12179c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12189c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12199c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12209c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12219c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12229c7779b64eacf264ee427b97ae0df8596b1960ccbart
12239c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12249c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12259c7779b64eacf264ee427b97ae0df8596b1960ccbart
12269c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12279c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_LIBC_SONAME, memset)
12289c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_DYLD,        memset)
12299c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12309c7779b64eacf264ee427b97ae0df8596b1960ccbart
12318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMSET(VG_Z_LIBC_SONAME, memset)
12338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12349c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12359c7779b64eacf264ee427b97ae0df8596b1960ccbart
12369c7779b64eacf264ee427b97ae0df8596b1960ccbart
12379c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memmove ----------------------*/
12389c7779b64eacf264ee427b97ae0df8596b1960ccbart
12399c7779b64eacf264ee427b97ae0df8596b1960ccbart/* memmove -- use the MEMMOVE defn above. */
12409c7779b64eacf264ee427b97ae0df8596b1960ccbart
12419c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12429c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12439c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1244b97cf8e9a718e61a540e63001d4c9346773c630emjw /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1245b97cf8e9a718e61a540e63001d4c9346773c630emjw    arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1246b97cf8e9a718e61a540e63001d4c9346773c630emjw    to call memcpy.  */
1247b97cf8e9a718e61a540e63001d4c9346773c630emjw MEMMOVE(VG_Z_LD64_SO_1, memmove)
12489c7779b64eacf264ee427b97ae0df8596b1960ccbart
12499c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12509c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
12519c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12529c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
12539c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
12549c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
12559090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1256312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memmove$VARIANT$Ivybridge */
1257eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1258eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
12598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LD_SO_1,     memmove)
12638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12649c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12659c7779b64eacf264ee427b97ae0df8596b1960ccbart
12669c7779b64eacf264ee427b97ae0df8596b1960ccbart
12679c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- bcopy ----------------------*/
12689c7779b64eacf264ee427b97ae0df8596b1960ccbart
12699c7779b64eacf264ee427b97ae0df8596b1960ccbart#define BCOPY(soname, fnname) \
12709c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12719c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n); \
12729c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12739c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n) \
12749c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12759c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
12769c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV; \
12779c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
12789c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
12799c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12809c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
12819c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12829c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
12839c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
12849c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12859c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
12869c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12879c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12889c7779b64eacf264ee427b97ae0df8596b1960ccbart
12899c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12909c7779b64eacf264ee427b97ae0df8596b1960ccbart BCOPY(VG_Z_LIBC_SONAME, bcopy)
12919c7779b64eacf264ee427b97ae0df8596b1960ccbart
12929c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12939c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_LIBC_SONAME, bcopy)
12949c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_DYLD,        bcopy)
12959c7779b64eacf264ee427b97ae0df8596b1960ccbart
12968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_darwin)
12978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj BCOPY(VG_Z_LIBC_SONAME, bcopy)
12988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12999c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13009c7779b64eacf264ee427b97ae0df8596b1960ccbart
13019c7779b64eacf264ee427b97ae0df8596b1960ccbart
13029c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memmove_chk --------------------*/
13039c7779b64eacf264ee427b97ae0df8596b1960ccbart
13049c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc 2.5 variant of memmove which checks the dest is big enough.
13059c7779b64eacf264ee427b97ae0df8596b1960ccbart   There is no specific part of glibc that this is copied from. */
13069c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
13079c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13089c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
13099c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13109c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
13119c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13129c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
13139c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV;        \
13149c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
13159c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (destlen < n) \
13169c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
13179c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
13189c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13199c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
13209c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13219c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
13229c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
13239c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13249c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
13259c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13269c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
13279c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
13289c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
13299c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memmove_chk: buffer overflow detected ***: " \
13309c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
133177ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
13329c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
13339c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
13349c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13359c7779b64eacf264ee427b97ae0df8596b1960ccbart
13369c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13379c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
13389c7779b64eacf264ee427b97ae0df8596b1960ccbart
13399c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13409c7779b64eacf264ee427b97ae0df8596b1960ccbart
13418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13439c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13449c7779b64eacf264ee427b97ae0df8596b1960ccbart
13459c7779b64eacf264ee427b97ae0df8596b1960ccbart
13469c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- strchrnul --------------------*/
13479c7779b64eacf264ee427b97ae0df8596b1960ccbart
13489c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S or the final NUL byte.  */
13499c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_STRCHRNUL(soname, fnname) \
13509c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13519c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in); \
13529c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13539c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in) \
13549c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
135570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      HChar c = (HChar) c_in; \
135670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const HChar* char_ptr = s; \
13579c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
135870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr);  \
135970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr);  \
13609c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
13619c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13629c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13639c7779b64eacf264ee427b97ae0df8596b1960ccbart
13649c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13659c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
13669c7779b64eacf264ee427b97ae0df8596b1960ccbart
13679c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13689c7779b64eacf264ee427b97ae0df8596b1960ccbart
13698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13719c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13729c7779b64eacf264ee427b97ae0df8596b1960ccbart
13739c7779b64eacf264ee427b97ae0df8596b1960ccbart
13749c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- rawmemchr ----------------------*/
13759c7779b64eacf264ee427b97ae0df8596b1960ccbart
13769c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S.  */
13779c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_RAWMEMCHR(soname, fnname) \
13781ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13791ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in); \
13801ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13811ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in) \
13829c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13831ef205bfce335a8d54b6b188e83254b92c52d7adflorian      UChar c = (UChar) c_in; \
13841ef205bfce335a8d54b6b188e83254b92c52d7adflorian      const UChar* char_ptr = s; \
13859c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
138670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
13879c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
13889c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13899c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13909c7779b64eacf264ee427b97ae0df8596b1960ccbart
13919c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined (VGO_linux)
13929c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
13939c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
13949c7779b64eacf264ee427b97ae0df8596b1960ccbart
13959c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13969c7779b64eacf264ee427b97ae0df8596b1960ccbart
13978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13999c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14009c7779b64eacf264ee427b97ae0df8596b1960ccbart
14019c7779b64eacf264ee427b97ae0df8596b1960ccbart
14029c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy_chk ----------------------*/
14039c7779b64eacf264ee427b97ae0df8596b1960ccbart
14049c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of strcpy that checks the dest is big enough.
14059c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-strcpy_chk.c. */
14069c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STRCPY_CHK(soname,fnname) \
14079c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14089c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14099c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14109c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14119c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14129c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* ret = dst; \
14139c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14149c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14159c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14169c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14179c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14189c7779b64eacf264ee427b97ae0df8596b1960ccbart      return ret; \
14199c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14209c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14219c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** strcpy_chk: buffer overflow detected ***: " \
14229c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
142377ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
14249c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14259c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14269c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14279c7779b64eacf264ee427b97ae0df8596b1960ccbart
14289c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14299c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
14309c7779b64eacf264ee427b97ae0df8596b1960ccbart
14319c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14329c7779b64eacf264ee427b97ae0df8596b1960ccbart
14338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14359c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14369c7779b64eacf264ee427b97ae0df8596b1960ccbart
14379c7779b64eacf264ee427b97ae0df8596b1960ccbart
14389c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy_chk ----------------------*/
14399c7779b64eacf264ee427b97ae0df8596b1960ccbart
14409c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of stpcpy that checks the dest is big enough.
14419c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
14429c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STPCPY_CHK(soname,fnname) \
14439c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14449c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14459c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14469c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14479c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14489c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14499c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14509c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14519c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14529c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14539c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst - 1; \
14549c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14559c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14569c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** stpcpy_chk: buffer overflow detected ***: " \
14579c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
145877ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
14599c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14609c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14619c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14629c7779b64eacf264ee427b97ae0df8596b1960ccbart
14639c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14649c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
14659c7779b64eacf264ee427b97ae0df8596b1960ccbart
14669c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14679c7779b64eacf264ee427b97ae0df8596b1960ccbart
14688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14709c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14719c7779b64eacf264ee427b97ae0df8596b1960ccbart
14729c7779b64eacf264ee427b97ae0df8596b1960ccbart
14739c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- mempcpy ----------------------*/
14749c7779b64eacf264ee427b97ae0df8596b1960ccbart
14759c7779b64eacf264ee427b97ae0df8596b1960ccbart/* mempcpy */
14769c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25_MEMPCPY(soname, fnname) \
14779c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14789c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
14799c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14809c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
14819c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14829c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT len_saved = len; \
14839c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14849c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
14859c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
14869c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14879c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
14889c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
14899c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14909c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
149109041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = (char *)dst + len - 1; \
149209041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = (const char *)src + len - 1; \
14939c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
14949c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
14959c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14969c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
149709041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = dst; \
149809041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = src; \
14999c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15009c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
15019c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15029c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15039c7779b64eacf264ee427b97ae0df8596b1960ccbart      return (void*)( ((char*)dst) + len_saved ); \
15049c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15059c7779b64eacf264ee427b97ae0df8596b1960ccbart
15069c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15079c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1508a9176d9640606a083a6e9b97515b15f631de5059mjw GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
15099c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
1510f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1511f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
15129c7779b64eacf264ee427b97ae0df8596b1960ccbart
15139c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15149c7779b64eacf264ee427b97ae0df8596b1960ccbart //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
15159c7779b64eacf264ee427b97ae0df8596b1960ccbart
15168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15189c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15199c7779b64eacf264ee427b97ae0df8596b1960ccbart
15209c7779b64eacf264ee427b97ae0df8596b1960ccbart
15219c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memcpy_chk --------------------*/
15229c7779b64eacf264ee427b97ae0df8596b1960ccbart
15239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC26___MEMCPY_CHK(soname, fnname) \
15249c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15259c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ); \
15269c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15279c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ) \
15289c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15299c7779b64eacf264ee427b97ae0df8596b1960ccbart      register HChar *d; \
15309c7779b64eacf264ee427b97ae0df8596b1960ccbart      register const HChar *s; \
15319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15329c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dstlen < len) goto badness; \
15339c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
15359c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
15369c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15379c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
15389c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
15399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15409c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
15419c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst + len - 1; \
15429c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src + len - 1; \
15439c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15449c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
15459c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15469c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
15479c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst; \
15489c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src; \
15499c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15509c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
15519c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15529c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15539c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
15549c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
15559c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
15569c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memcpy_chk: buffer overflow detected ***: " \
15579c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
155877ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
15599c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
15609c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
15619c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15629c7779b64eacf264ee427b97ae0df8596b1960ccbart
15639c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15649c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
15659c7779b64eacf264ee427b97ae0df8596b1960ccbart
15669c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15679c7779b64eacf264ee427b97ae0df8596b1960ccbart
15688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15709c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15719c7779b64eacf264ee427b97ae0df8596b1960ccbart
15729c7779b64eacf264ee427b97ae0df8596b1960ccbart
15739c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strstr ----------------------*/
15749c7779b64eacf264ee427b97ae0df8596b1960ccbart
15759c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSTR(soname, fnname) \
15769c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15779c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
15789c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15799c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
15809c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15819c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
15829c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle; \
15839c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15849c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
15859c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
15869c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
15879c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15889c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
158970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);         \
15909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15919c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
15929c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar n0 = n[0]; \
15939c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15949c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
15959c7779b64eacf264ee427b97ae0df8596b1960ccbart         const HChar hh = *h; \
15969c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
15979c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
15989c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
15999c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16009c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
16019c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (n[i] != h[i]) \
16029c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16039c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16049c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
16059c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
160670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);          \
16079c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16089c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
16099c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16109c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16119c7779b64eacf264ee427b97ae0df8596b1960ccbart
16129c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16139c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          strstr)
16149c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse2)
16159c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse42)
16169c7779b64eacf264ee427b97ae0df8596b1960ccbart
16179c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16189c7779b64eacf264ee427b97ae0df8596b1960ccbart
16198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSTR(VG_Z_LIBC_SONAME,          strstr)
16218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16229c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16239c7779b64eacf264ee427b97ae0df8596b1960ccbart
16249c7779b64eacf264ee427b97ae0df8596b1960ccbart
16259c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strpbrk ----------------------*/
16269c7779b64eacf264ee427b97ae0df8596b1960ccbart
16279c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRPBRK(soname, fnname) \
16289c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16299c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
16309c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16319c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
16329c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16339c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16349c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* accept = acceptV; \
16359c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16369c7779b64eacf264ee427b97ae0df8596b1960ccbart      /*  find the length of 'accept', not including terminating zero */ \
16379c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
16389c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
16399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16409c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, fail immediately. */ \
16419c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return NULL; \
16429c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16439c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nacc >= 1); */ \
16449c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16459c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16469c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16479c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16489c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16499c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
16509c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
165170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian              return CONST_CAST(HChar *,s);       \
16529c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16539c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16549c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16559c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16569c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
16579c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16589c7779b64eacf264ee427b97ae0df8596b1960ccbart
16599c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16609c7779b64eacf264ee427b97ae0df8596b1960ccbart STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16619c7779b64eacf264ee427b97ae0df8596b1960ccbart
16629c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16639c7779b64eacf264ee427b97ae0df8596b1960ccbart
16648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16679c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16689c7779b64eacf264ee427b97ae0df8596b1960ccbart
16699c7779b64eacf264ee427b97ae0df8596b1960ccbart
16709c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcspn ----------------------*/
16719c7779b64eacf264ee427b97ae0df8596b1960ccbart
16729c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCSPN(soname, fnname) \
16739c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16749c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV); \
16759c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16769c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV) \
16779c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16789c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16799c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* reject = rejectV; \
16809c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16819c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'reject', not including terminating zero */ \
16829c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nrej = 0; \
16839c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (reject[nrej]) nrej++; \
16849c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16859c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
16869c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16879c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16889c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16899c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16909c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16919c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nrej; i++) { \
16929c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == reject[i]) \
16939c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16949c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16959c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nrej); */ \
16969c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i < nrej) \
16979c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16989c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16999c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
17009c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17019c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17029c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17039c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17049c7779b64eacf264ee427b97ae0df8596b1960ccbart
17059c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
17079c7779b64eacf264ee427b97ae0df8596b1960ccbart
17089c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17099c7779b64eacf264ee427b97ae0df8596b1960ccbart
17108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
17128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17139c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17149c7779b64eacf264ee427b97ae0df8596b1960ccbart
17159c7779b64eacf264ee427b97ae0df8596b1960ccbart
17169c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strspn ----------------------*/
17179c7779b64eacf264ee427b97ae0df8596b1960ccbart
17189c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSPN(soname, fnname) \
17199c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17209c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
17219c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17229c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
17239c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17249c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* s = (const UChar *)sV;        \
17259c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* accept = (const UChar *)acceptV;     \
17269c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17279c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'accept', not including terminating zero */ \
17289c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
17299c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
17309c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return 0; \
17319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17329c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
17339c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17349c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17359c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
17369c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
17379c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17389c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
17399c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
17409c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17419c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17429c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nacc); */ \
17439c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nacc) \
17449c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17459c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
17469c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
17479c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17489c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17499c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17509c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17519c7779b64eacf264ee427b97ae0df8596b1960ccbart
17529c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17539c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSPN(VG_Z_LIBC_SONAME,          strspn)
17549c7779b64eacf264ee427b97ae0df8596b1960ccbart
17559c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17569c7779b64eacf264ee427b97ae0df8596b1960ccbart
17578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSPN(VG_Z_LIBC_SONAME,          strspn)
17598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17609c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17619c7779b64eacf264ee427b97ae0df8596b1960ccbart
17629c7779b64eacf264ee427b97ae0df8596b1960ccbart
17639c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasestr ----------------------*/
17649c7779b64eacf264ee427b97ae0df8596b1960ccbart
17659c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASESTR(soname, fnname) \
17669c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17679c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
17689c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17699c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
17709c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17719c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
17729c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
17739c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle;   \
17749c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17759c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
17769c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
17779c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
17789c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17799c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
178070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);       \
17819c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17829c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
17839c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar n0 = tolower(n[0]);                 \
17849c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17859c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17869c7779b64eacf264ee427b97ae0df8596b1960ccbart         UChar hh = tolower(*h);    \
17879c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
17889c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
17899c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
17909c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17919c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
17929c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (tolower(n[i]) != tolower(h[i]))  \
17939c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17949c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17959c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
17969c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
179770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);    \
17989c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
17999c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
18009c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18019c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18029c7779b64eacf264ee427b97ae0df8596b1960ccbart
18039c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
180426ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
180526ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
180626ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
180726ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
18089c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18099c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
18109c7779b64eacf264ee427b97ae0df8596b1960ccbart
18119c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18129c7779b64eacf264ee427b97ae0df8596b1960ccbart
18138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18169c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18179c7779b64eacf264ee427b97ae0df8596b1960ccbart
18189c7779b64eacf264ee427b97ae0df8596b1960ccbart
18199c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcslen ----------------------*/
18209c7779b64eacf264ee427b97ae0df8596b1960ccbart
18219c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strlen.  Unfortunately
18229c7779b64eacf264ee427b97ae0df8596b1960ccbart// we don't have wchar_t available here, but it looks like
18239c7779b64eacf264ee427b97ae0df8596b1960ccbart// a 32 bit int on Linux.  I don't know if that is also
18249c7779b64eacf264ee427b97ae0df8596b1960ccbart// valid on MacOSX.
18259c7779b64eacf264ee427b97ae0df8596b1960ccbart
18269c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSLEN(soname, fnname) \
18279c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18289c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str ); \
18299c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18309c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str )  \
18319c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18329c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
18339c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
18349c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
18359c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18369c7779b64eacf264ee427b97ae0df8596b1960ccbart
18379c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18389c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18399c7779b64eacf264ee427b97ae0df8596b1960ccbart
18409c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18419c7779b64eacf264ee427b97ae0df8596b1960ccbart
18428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18459c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18469c7779b64eacf264ee427b97ae0df8596b1960ccbart
18479c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscmp ----------------------*/
18489c7779b64eacf264ee427b97ae0df8596b1960ccbart
18499c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcmp.  We don't
18509c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
18519c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide and wcscmp uses signed
18529c7779b64eacf264ee427b97ae0df8596b1960ccbart// comparison, not unsigned as in strcmp function.
18539c7779b64eacf264ee427b97ae0df8596b1960ccbart
18549c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCMP(soname, fnname) \
18559c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18569c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ); \
18579c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18589c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ) \
18599c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18609c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c1; \
18619c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c2; \
18629c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
18639c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *s1; \
18649c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *s2; \
18659c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
18669c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
18679c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
18689c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18699c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 < c2) return -1; \
18709c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 > c2) return 1; \
18719c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
18729c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18739c7779b64eacf264ee427b97ae0df8596b1960ccbart
18749c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18759c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCMP(VG_Z_LIBC_SONAME,          wcscmp)
18769c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18779c7779b64eacf264ee427b97ae0df8596b1960ccbart
18789c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscpy ----------------------*/
18799c7779b64eacf264ee427b97ae0df8596b1960ccbart
18809c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcpy.  We don't
18819c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
18829c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
18839c7779b64eacf264ee427b97ae0df8596b1960ccbart
18849c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCPY(soname, fnname) \
18859c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
18869c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ); \
18879c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
18889c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ) \
18899c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18909c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Int* src_orig = src; \
18919c7779b64eacf264ee427b97ae0df8596b1960ccbart            Int* dst_orig = dst; \
18929c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18939c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
18949c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
18959c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18969c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
18979c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
18989c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
18999c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
19009c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
19019c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
19029c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
19039c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
19049c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
19059c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19069c7779b64eacf264ee427b97ae0df8596b1960ccbart
19079c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19089c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
19099c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19109c7779b64eacf264ee427b97ae0df8596b1960ccbart
19119c7779b64eacf264ee427b97ae0df8596b1960ccbart
19129c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcschr ----------------------*/
19139c7779b64eacf264ee427b97ae0df8596b1960ccbart
19149c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strchr.  We don't
19159c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19169c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19179c7779b64eacf264ee427b97ae0df8596b1960ccbart
19189c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCHR(soname, fnname) \
19199c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
19209c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
19219c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
192270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
19239c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
192470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == c) return CONST_CAST(Int *,p);  \
19259c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
19269c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19279c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19289c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19299c7779b64eacf264ee427b97ae0df8596b1960ccbart
19309c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19319c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCHR(VG_Z_LIBC_SONAME,          wcschr)
19329c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19339c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcsrchr ----------------------*/
19349c7779b64eacf264ee427b97ae0df8596b1960ccbart
19359c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strrchr.  We don't
19369c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19379c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19389c7779b64eacf264ee427b97ae0df8596b1960ccbart
19399c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSRCHR(soname, fnname) \
19409c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
19419c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
19429c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
194370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
194470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* last = NULL; \
19459c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
19469c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == c) last = p; \
194770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(Int *,last);  \
19489c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19499c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19509c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19519c7779b64eacf264ee427b97ae0df8596b1960ccbart
19529c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19539c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
19549c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19559c7779b64eacf264ee427b97ae0df8596b1960ccbart
19569c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19579c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Improve definedness checking of process environment  ---*/
19589c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19599c7779b64eacf264ee427b97ae0df8596b1960ccbart
19609c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19619c7779b64eacf264ee427b97ae0df8596b1960ccbart
19629c7779b64eacf264ee427b97ae0df8596b1960ccbart/* If these wind up getting generated via a macro, so that multiple
19639c7779b64eacf264ee427b97ae0df8596b1960ccbart   versions of each function exist (as above), use the _EZU variants
19649c7779b64eacf264ee427b97ae0df8596b1960ccbart   to assign equivalance class tags. */
19659c7779b64eacf264ee427b97ae0df8596b1960ccbart
19669c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- putenv ----------------------*/
19679c7779b64eacf264ee427b97ae0df8596b1960ccbart
19689c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
19699c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
19709c7779b64eacf264ee427b97ae0df8596b1960ccbart{
19719c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
19729c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
19739c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = string;
19749c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
19759c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
19769c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
19779c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
19789c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
19799c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
19809c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, string);
19819c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
19829c7779b64eacf264ee427b97ae0df8596b1960ccbart}
19839c7779b64eacf264ee427b97ae0df8596b1960ccbart
19849c7779b64eacf264ee427b97ae0df8596b1960ccbart
19859c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- unsetenv ----------------------*/
19869c7779b64eacf264ee427b97ae0df8596b1960ccbart
19879c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
19889c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
19899c7779b64eacf264ee427b97ae0df8596b1960ccbart{
19909c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
19919c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
19929c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = name;
19939c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
19949c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
19959c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
19969c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
19979c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
19989c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
19999c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, name);
20009c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20019c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20029c7779b64eacf264ee427b97ae0df8596b1960ccbart
20039c7779b64eacf264ee427b97ae0df8596b1960ccbart
20049c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- setenv ----------------------*/
20059c7779b64eacf264ee427b97ae0df8596b1960ccbart
20069c7779b64eacf264ee427b97ae0df8596b1960ccbart/* setenv */
20079c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20089c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite);
20099c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20109c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite)
20119c7779b64eacf264ee427b97ae0df8596b1960ccbart{
20129c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
20139c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
20149c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p;
20159c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
20169c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
20179c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
20189c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (name)
20199c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = name; *p; p++)
20209c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20219c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (value)
20229c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = value; *p; p++)
20239c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20249c7779b64eacf264ee427b97ae0df8596b1960ccbart    (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
20259c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_WWW(result, fn, name, value, overwrite);
20269c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20279c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20289c7779b64eacf264ee427b97ae0df8596b1960ccbart
20299c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif /* defined(VGO_linux) */
20309c7779b64eacf264ee427b97ae0df8596b1960ccbart
20319c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
20329c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- end                                                          ---*/
20339c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
2034