vg_replace_strmem.c revision 8eb8bab992e3998c33770b0cdb16059a8b918a06
19c7779b64eacf264ee427b97ae0df8596b1960ccbart
29c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
39c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Replacements for strcpy(), memcpy() et al, which run on the  ---*/
49c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- simulated CPU.                                               ---*/
5f2a68aa6deb788304b9c100ecd4dec41f5064b8cphilippe/*---                                          vg_replace_strmem.c ---*/
69c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
79c7779b64eacf264ee427b97ae0df8596b1960ccbart
89c7779b64eacf264ee427b97ae0df8596b1960ccbart/*
99c7779b64eacf264ee427b97ae0df8596b1960ccbart   This file is part of Valgrind.
109c7779b64eacf264ee427b97ae0df8596b1960ccbart
119c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copyright (C) 2000-2013 Julian Seward
129c7779b64eacf264ee427b97ae0df8596b1960ccbart      jseward@acm.org
139c7779b64eacf264ee427b97ae0df8596b1960ccbart
149c7779b64eacf264ee427b97ae0df8596b1960ccbart   This program is free software; you can redistribute it and/or
159c7779b64eacf264ee427b97ae0df8596b1960ccbart   modify it under the terms of the GNU General Public License as
169c7779b64eacf264ee427b97ae0df8596b1960ccbart   published by the Free Software Foundation; either version 2 of the
179c7779b64eacf264ee427b97ae0df8596b1960ccbart   License, or (at your option) any later version.
189c7779b64eacf264ee427b97ae0df8596b1960ccbart
199c7779b64eacf264ee427b97ae0df8596b1960ccbart   This program is distributed in the hope that it will be useful, but
209c7779b64eacf264ee427b97ae0df8596b1960ccbart   WITHOUT ANY WARRANTY; without even the implied warranty of
219c7779b64eacf264ee427b97ae0df8596b1960ccbart   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
229c7779b64eacf264ee427b97ae0df8596b1960ccbart   General Public License for more details.
239c7779b64eacf264ee427b97ae0df8596b1960ccbart
249c7779b64eacf264ee427b97ae0df8596b1960ccbart   You should have received a copy of the GNU General Public License
259c7779b64eacf264ee427b97ae0df8596b1960ccbart   along with this program; if not, write to the Free Software
269c7779b64eacf264ee427b97ae0df8596b1960ccbart   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
279c7779b64eacf264ee427b97ae0df8596b1960ccbart   02111-1307, USA.
289c7779b64eacf264ee427b97ae0df8596b1960ccbart
299c7779b64eacf264ee427b97ae0df8596b1960ccbart   The GNU General Public License is contained in the file COPYING.
309c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
319c7779b64eacf264ee427b97ae0df8596b1960ccbart
329c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_basics.h"
339c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_poolalloc.h"
349c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_hashtable.h"
359c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_redir.h"
369c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_tooliface.h"
379c7779b64eacf264ee427b97ae0df8596b1960ccbart#include "pub_tool_clreq.h"
389c7779b64eacf264ee427b97ae0df8596b1960ccbart
399c7779b64eacf264ee427b97ae0df8596b1960ccbart/* ---------------------------------------------------------------------
409c7779b64eacf264ee427b97ae0df8596b1960ccbart   We have our own versions of these functions for two reasons:
419c7779b64eacf264ee427b97ae0df8596b1960ccbart   (a) it allows us to do overlap checking
429c7779b64eacf264ee427b97ae0df8596b1960ccbart   (b) some of the normal versions are hyper-optimised, which fools
439c7779b64eacf264ee427b97ae0df8596b1960ccbart       Memcheck and cause spurious value warnings.  Our versions are
449c7779b64eacf264ee427b97ae0df8596b1960ccbart       simpler.
459c7779b64eacf264ee427b97ae0df8596b1960ccbart   (c) the glibc SSE-variants can read past the end of the input data
469c7779b64eacf264ee427b97ae0df8596b1960ccbart       ranges. This can cause false-positive Memcheck / Helgrind / DRD
479c7779b64eacf264ee427b97ae0df8596b1960ccbart       reports.
489c7779b64eacf264ee427b97ae0df8596b1960ccbart
499c7779b64eacf264ee427b97ae0df8596b1960ccbart   Note that overenthusiastic use of PLT bypassing by the glibc people also
509c7779b64eacf264ee427b97ae0df8596b1960ccbart   means that we need to patch multiple versions of some of the functions to
519c7779b64eacf264ee427b97ae0df8596b1960ccbart   our own implementations.
529c7779b64eacf264ee427b97ae0df8596b1960ccbart
539c7779b64eacf264ee427b97ae0df8596b1960ccbart   THEY RUN ON THE SIMD CPU!
549c7779b64eacf264ee427b97ae0df8596b1960ccbart   ------------------------------------------------------------------ */
559c7779b64eacf264ee427b97ae0df8596b1960ccbart
569c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Assignment of behavioural equivalence class tags: 2NNNP is intended
579c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be reserved for str/mem intercepts.  Current usage:
589c7779b64eacf264ee427b97ae0df8596b1960ccbart
599c7779b64eacf264ee427b97ae0df8596b1960ccbart   20010 STRRCHR
609c7779b64eacf264ee427b97ae0df8596b1960ccbart   20020 STRCHR
619c7779b64eacf264ee427b97ae0df8596b1960ccbart   20030 STRCAT
629c7779b64eacf264ee427b97ae0df8596b1960ccbart   20040 STRNCAT
639c7779b64eacf264ee427b97ae0df8596b1960ccbart   20050 STRLCAT
649c7779b64eacf264ee427b97ae0df8596b1960ccbart   20060 STRNLEN
659c7779b64eacf264ee427b97ae0df8596b1960ccbart   20070 STRLEN
669c7779b64eacf264ee427b97ae0df8596b1960ccbart   20080 STRCPY
679c7779b64eacf264ee427b97ae0df8596b1960ccbart   20090 STRNCPY
689c7779b64eacf264ee427b97ae0df8596b1960ccbart   20100 STRLCPY
699c7779b64eacf264ee427b97ae0df8596b1960ccbart   20110 STRNCMP
709c7779b64eacf264ee427b97ae0df8596b1960ccbart   20120 STRCASECMP
719c7779b64eacf264ee427b97ae0df8596b1960ccbart   20130 STRNCASECMP
729c7779b64eacf264ee427b97ae0df8596b1960ccbart   20140 STRCASECMP_L
739c7779b64eacf264ee427b97ae0df8596b1960ccbart   20150 STRNCASECMP_L
749c7779b64eacf264ee427b97ae0df8596b1960ccbart   20160 STRCMP
759c7779b64eacf264ee427b97ae0df8596b1960ccbart   20170 MEMCHR
769c7779b64eacf264ee427b97ae0df8596b1960ccbart
779c7779b64eacf264ee427b97ae0df8596b1960ccbart   20180 MEMCPY    if there's a conflict between memcpy and
789c7779b64eacf264ee427b97ae0df8596b1960ccbart   20181 MEMMOVE   memmove, prefer memmove
799c7779b64eacf264ee427b97ae0df8596b1960ccbart
809c7779b64eacf264ee427b97ae0df8596b1960ccbart   20190 MEMCMP
819c7779b64eacf264ee427b97ae0df8596b1960ccbart   20200 STPCPY
829c7779b64eacf264ee427b97ae0df8596b1960ccbart   20210 MEMSET
839c7779b64eacf264ee427b97ae0df8596b1960ccbart   2022P unused (was previously MEMMOVE)
849c7779b64eacf264ee427b97ae0df8596b1960ccbart   20230 BCOPY
859c7779b64eacf264ee427b97ae0df8596b1960ccbart   20240 GLIBC25___MEMMOVE_CHK
869c7779b64eacf264ee427b97ae0df8596b1960ccbart   20250 GLIBC232_STRCHRNUL
879c7779b64eacf264ee427b97ae0df8596b1960ccbart   20260 GLIBC232_RAWMEMCHR
889c7779b64eacf264ee427b97ae0df8596b1960ccbart   20270 GLIBC25___STRCPY_CHK
899c7779b64eacf264ee427b97ae0df8596b1960ccbart   20280 GLIBC25___STPCPY_CHK
909c7779b64eacf264ee427b97ae0df8596b1960ccbart   20290 GLIBC25_MEMPCPY
919c7779b64eacf264ee427b97ae0df8596b1960ccbart   20300 GLIBC26___MEMCPY_CHK
929c7779b64eacf264ee427b97ae0df8596b1960ccbart   20310 STRSTR
939c7779b64eacf264ee427b97ae0df8596b1960ccbart   20320 STRPBRK
949c7779b64eacf264ee427b97ae0df8596b1960ccbart   20330 STRCSPN
959c7779b64eacf264ee427b97ae0df8596b1960ccbart   20340 STRSPN
969c7779b64eacf264ee427b97ae0df8596b1960ccbart   20350 STRCASESTR
979c7779b64eacf264ee427b97ae0df8596b1960ccbart   20360 MEMRCHR
989c7779b64eacf264ee427b97ae0df8596b1960ccbart   20370 WCSLEN
999c7779b64eacf264ee427b97ae0df8596b1960ccbart   20380 WCSCMP
1009c7779b64eacf264ee427b97ae0df8596b1960ccbart   20390 WCSCPY
1019c7779b64eacf264ee427b97ae0df8596b1960ccbart   20400 WCSCHR
1029c7779b64eacf264ee427b97ae0df8596b1960ccbart   20410 WCSRCHR
1039c7779b64eacf264ee427b97ae0df8596b1960ccbart   20420 STPNCPY
1049c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
1059c7779b64eacf264ee427b97ae0df8596b1960ccbart
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)
265366cefb68a2b15558ed1ddcda74c675d3ac39948rhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
2669951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# endif
2678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          strchr)
2708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          index)
2718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LD_SO_1,              strchr)
2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2739c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2749c7779b64eacf264ee427b97ae0df8596b1960ccbart
2759c7779b64eacf264ee427b97ae0df8596b1960ccbart
2769c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcat ----------------------*/
2779c7779b64eacf264ee427b97ae0df8596b1960ccbart
2789c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCAT(soname, fnname) \
2799c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2809c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
2819c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2829c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
2839c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2849c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
2859c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
2869c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
2879c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
2889c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
2899c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2909c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This is a bit redundant, I think;  any overlap and the strcat will */ \
2919c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* go forever... or until a seg fault occurs. */ \
2929c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
2939c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
2949c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
2959c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
2969c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
2979c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2989c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
2999c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3009c7779b64eacf264ee427b97ae0df8596b1960ccbart
3019c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3029c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, strcat)
3039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
3049c7779b64eacf264ee427b97ae0df8596b1960ccbart
3059c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3069c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCAT(VG_Z_LIBC_SONAME, strcat)
3079c7779b64eacf264ee427b97ae0df8596b1960ccbart
3088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LIBC_SONAME, strcat)
3108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LD_SO_1,     strcat)
3118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3129c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3139c7779b64eacf264ee427b97ae0df8596b1960ccbart
3149c7779b64eacf264ee427b97ae0df8596b1960ccbart
3159c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncat ----------------------*/
3169c7779b64eacf264ee427b97ae0df8596b1960ccbart
3179c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCAT(soname, fnname) \
3189c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3199c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
3209c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3219c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
3229c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3239c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3249c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
3259c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3269c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3279c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
3289c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
3299c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0;                                       /* always add null   */ \
3309c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3319c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3329c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3339c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3349c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3359c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
3369c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3379c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
3389c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3399c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3409c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3419c7779b64eacf264ee427b97ae0df8596b1960ccbart
3429c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3439c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCAT(VG_Z_LIBC_SONAME, strncat)
3449c7779b64eacf264ee427b97ae0df8596b1960ccbart
3459c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3469c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_LIBC_SONAME, strncat)
3479c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_DYLD,        strncat)
3489c7779b64eacf264ee427b97ae0df8596b1960ccbart
3498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCAT(VG_Z_LIBC_SONAME, strncat)
3518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3529c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3539c7779b64eacf264ee427b97ae0df8596b1960ccbart
3549c7779b64eacf264ee427b97ae0df8596b1960ccbart
3559c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcat ----------------------*/
3569c7779b64eacf264ee427b97ae0df8596b1960ccbart
3579c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
3589c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be nul-terminated after the copy, unless n <= strlen(dst_orig).
3599c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns min(n, strlen(dst_orig)) + strlen(src_orig).
3609c7779b64eacf264ee427b97ae0df8596b1960ccbart   Truncation occurred if retval >= n.
3619c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
3629c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCAT(soname, fnname) \
3639c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3649c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ); \
3659c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3669c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ) \
3679c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3689c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3699c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
3709c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3719c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3729c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *dst) { m++; dst++; } \
3739c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (m < n) { \
3749c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
3759c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (m < n-1 && *src) { m++; *dst++ = *src++; } \
3769c7779b64eacf264ee427b97ae0df8596b1960ccbart         *dst = 0; \
3779c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
3789c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* No space to copy anything to dst. m == n */ \
3799c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
3809c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
3819c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) { m++; src++; } \
3829c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3839c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3849c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3859c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3869c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
3879c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3889c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
3899c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3909c7779b64eacf264ee427b97ae0df8596b1960ccbart      return m; \
3919c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3929c7779b64eacf264ee427b97ae0df8596b1960ccbart
3939c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3949c7779b64eacf264ee427b97ae0df8596b1960ccbart
3959c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3969c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
3979c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_DYLD,        strlcat)
3989c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCAT(VG_Z_LIBC_SONAME, strlcat)
3999c7779b64eacf264ee427b97ae0df8596b1960ccbart
4008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4039c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4049c7779b64eacf264ee427b97ae0df8596b1960ccbart
4059c7779b64eacf264ee427b97ae0df8596b1960ccbart
4069c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strnlen ----------------------*/
4079c7779b64eacf264ee427b97ae0df8596b1960ccbart
4089c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNLEN(soname, fnname) \
4099c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4109c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ); \
4119c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4129c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ) \
4139c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4149c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4159c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (i < n && str[i] != 0) i++; \
4169c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4179c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4189c7779b64eacf264ee427b97ae0df8596b1960ccbart
4199c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4209c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4219c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
4229c7779b64eacf264ee427b97ae0df8596b1960ccbart
4239c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
424aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
425aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNLEN(libsystemZucZddylib, strnlen)
426aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
4279c7779b64eacf264ee427b97ae0df8596b1960ccbart
4288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4319c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4329c7779b64eacf264ee427b97ae0df8596b1960ccbart
4339c7779b64eacf264ee427b97ae0df8596b1960ccbart
4349c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlen ----------------------*/
4359c7779b64eacf264ee427b97ae0df8596b1960ccbart
4369c7779b64eacf264ee427b97ae0df8596b1960ccbart// Note that this replacement often doesn't get used because gcc inlines
4379c7779b64eacf264ee427b97ae0df8596b1960ccbart// calls to strlen() with its own built-in version.  This can be very
4389c7779b64eacf264ee427b97ae0df8596b1960ccbart// confusing if you aren't expecting it.  Other small functions in
4399c7779b64eacf264ee427b97ae0df8596b1960ccbart// this file may also be inline by gcc.
4409c7779b64eacf264ee427b97ae0df8596b1960ccbart
4419c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLEN(soname, fnname) \
4429c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4439c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str ); \
4449c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4459c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str )  \
4469c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4479c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4489c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
4499c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4509c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4519c7779b64eacf264ee427b97ae0df8596b1960ccbart
4529c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4539c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          strlen)
4549c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
4559c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2)
4569c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2_no_bsf)
4579c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse42)
4589c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
4599c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
46026ed419d60369d0545510eba0832566e24452e1esewardj# if defined(VGPV_arm_linux_android) \
46126ed419d60369d0545510eba0832566e24452e1esewardj     || defined(VGPV_x86_linux_android) \
4629c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
4639c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
4649c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
4659c7779b64eacf264ee427b97ae0df8596b1960ccbart
4669c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4679c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME, strlen)
4689090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
469c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRLEN(libsystemZucZddylib, strlen)
470c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
4718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LIBC_SONAME,          strlen)
4748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LD_SO_1,              strlen)
4758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4769c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4779c7779b64eacf264ee427b97ae0df8596b1960ccbart
4789c7779b64eacf264ee427b97ae0df8596b1960ccbart
4799c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy ----------------------*/
4809c7779b64eacf264ee427b97ae0df8596b1960ccbart
4819c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCPY(soname, fnname) \
4829c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4839c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ); \
4849c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4859c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ) \
4869c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4879c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
4889c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
4899c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4909c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
4919c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
4929c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4939c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
4949c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
4959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
4969c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
4979c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
4989c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
4999c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
5009c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5019c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5029c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5039c7779b64eacf264ee427b97ae0df8596b1960ccbart
5049c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5059c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
5069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
5079c7779b64eacf264ee427b97ae0df8596b1960ccbart
5089c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5099c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
510aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
511aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRCPY(libsystemZucZddylib, strcpy)
512aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5139c7779b64eacf264ee427b97ae0df8596b1960ccbart
5148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LIBC_SONAME, strcpy)
5168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LD_SO_1,     strcpy)
5178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5189c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5199c7779b64eacf264ee427b97ae0df8596b1960ccbart
5209c7779b64eacf264ee427b97ae0df8596b1960ccbart
5219c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncpy ----------------------*/
5229c7779b64eacf264ee427b97ae0df8596b1960ccbart
5239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCPY(soname, fnname) \
5249c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5259c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
5269c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5279c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
5289c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5299c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5309c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
5319c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5329c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5339c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
5349c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5359c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5369c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5379c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
5389c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
5399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5409c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5429c7779b64eacf264ee427b97ae0df8596b1960ccbart
5439c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
5469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
5479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
5489c7779b64eacf264ee427b97ae0df8596b1960ccbart
5499c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5509c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5519090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
552aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNCPY(libsystemZucZddylib, strncpy)
553aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5549c7779b64eacf264ee427b97ae0df8596b1960ccbart
5558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LD_SO_1,     strncpy)
5588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5599c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5609c7779b64eacf264ee427b97ae0df8596b1960ccbart
5619c7779b64eacf264ee427b97ae0df8596b1960ccbart
5629c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcpy ----------------------*/
5639c7779b64eacf264ee427b97ae0df8596b1960ccbart
5649c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
5659c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns strlen(src). Does not zero-fill the remainder of dst. */
5669c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCPY(soname, fnname) \
5679c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5689c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ); \
5699c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5709c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ) \
5719c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5729c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5739c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
5749c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5759c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
5778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      \
5789c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n-1 && *src) { m++; *dst++ = *src++; } \
5799c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* m non-nul bytes have now been copied, and m <= n-1. */ \
5809c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5819c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5829c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5839c7779b64eacf264ee427b97ae0df8596b1960ccbart          RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
5849c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Nul-terminate dst. */ \
5859c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (n > 0) *dst = 0; \
5869c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting strlen(src). */ \
5879c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) src++; \
5889c7779b64eacf264ee427b97ae0df8596b1960ccbart      return src - src_orig; \
5899c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5909c7779b64eacf264ee427b97ae0df8596b1960ccbart
5919c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5929c7779b64eacf264ee427b97ae0df8596b1960ccbart
5939c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
5949c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
5958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
5969c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
5979c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5989c7779b64eacf264ee427b97ae0df8596b1960ccbart
5999c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
6019c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6029c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_DYLD,        strlcpy)
6039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6049c7779b64eacf264ee427b97ae0df8596b1960ccbart
6058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* special case for n == 0 which is undocumented but heavily used */
6078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
6088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    if (n == 0) { \
6098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       while (*src) src++; \
6108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       return src - src_orig; \
6118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    }
6128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6159c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6169c7779b64eacf264ee427b97ae0df8596b1960ccbart
6179c7779b64eacf264ee427b97ae0df8596b1960ccbart
6189c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncmp ----------------------*/
6199c7779b64eacf264ee427b97ae0df8596b1960ccbart
6209c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCMP(soname, fnname) \
6219c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6229c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
6239c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6249c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
6259c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6269c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
6279c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6289c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
6299c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
6309c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
6319c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
6329c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6339c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
6349c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
6359c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6369c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
6379c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6389c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6399c7779b64eacf264ee427b97ae0df8596b1960ccbart
6409c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
6419c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6429c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
6439c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
6449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
6459c7779b64eacf264ee427b97ae0df8596b1960ccbart
6469c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
6489090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
649798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
650798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj# endif
6519c7779b64eacf264ee427b97ae0df8596b1960ccbart
6528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6559c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6569c7779b64eacf264ee427b97ae0df8596b1960ccbart
6579c7779b64eacf264ee427b97ae0df8596b1960ccbart
6589c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp ----------------------*/
6599c7779b64eacf264ee427b97ae0df8596b1960ccbart
6609c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP(soname, fnname) \
6619c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6629c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
6639c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6649c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
6659c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6669c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
6679c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
6689c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
6699c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6709c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower(*(const UChar *)s1); \
6719c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower(*(const UChar *)s2); \
6729c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
6739c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
6749c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
6759c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6769c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
6779c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
6789c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
6799c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6809c7779b64eacf264ee427b97ae0df8596b1960ccbart
6819c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
68226ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
68326ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
68426ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
68526ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
6869c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6879c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
6889c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
6899c7779b64eacf264ee427b97ae0df8596b1960ccbart
6909c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6919c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6929c7779b64eacf264ee427b97ae0df8596b1960ccbart
6938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6969c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6979c7779b64eacf264ee427b97ae0df8596b1960ccbart
6989c7779b64eacf264ee427b97ae0df8596b1960ccbart
6999c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp ----------------------*/
7009c7779b64eacf264ee427b97ae0df8596b1960ccbart
7019c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP(soname, fnname) \
7029c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7039c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
7049c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7059c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
7069c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7079c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
7089c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7099c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7109c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7119c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7129c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7139c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7149c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7159c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7169c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower(*(const UChar*)s2)) return -1; \
7179c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7189c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower(*(const UChar *)s2)) return 1; \
7199c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7209c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
7219c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7229c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7239c7779b64eacf264ee427b97ae0df8596b1960ccbart
7249c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
72526ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
72626ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
72726ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
72826ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
7299c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7309c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
7319c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
7329c7779b64eacf264ee427b97ae0df8596b1960ccbart
7339c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7349c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7359c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_DYLD,        strncasecmp)
7369c7779b64eacf264ee427b97ae0df8596b1960ccbart
7378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7409c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7419c7779b64eacf264ee427b97ae0df8596b1960ccbart
7429c7779b64eacf264ee427b97ae0df8596b1960ccbart
7439c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp_l ----------------------*/
7449c7779b64eacf264ee427b97ae0df8596b1960ccbart
7459c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP_L(soname, fnname) \
7469c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7479c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ); \
7489c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7499c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ) \
7509c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7519c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak)); \
7529c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
7539c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
7549c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7559c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower_l(*(const UChar *)s1, locale); \
7569c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower_l(*(const UChar *)s2, locale); \
7579c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
7589c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
7599c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
7609c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7619c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
7629c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
7639c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
7649c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7659c7779b64eacf264ee427b97ae0df8596b1960ccbart
7669c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
7679c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7689c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
7699c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
7709c7779b64eacf264ee427b97ae0df8596b1960ccbart
7719c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7729c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7739c7779b64eacf264ee427b97ae0df8596b1960ccbart
7748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7769c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7779c7779b64eacf264ee427b97ae0df8596b1960ccbart
7789c7779b64eacf264ee427b97ae0df8596b1960ccbart
7799c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp_l ----------------------*/
7809c7779b64eacf264ee427b97ae0df8596b1960ccbart
7819c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP_L(soname, fnname) \
7829c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7839c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
7849c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7859c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
7869c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7879c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak));    \
7889c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7899c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7909c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7919c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7929c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7939c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7949c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7959c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7969c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower_l(*(const UChar *)s2, locale)) return -1; \
7979c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
7989c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower_l(*(const UChar *)s2, locale)) return 1; \
7999c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8009c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
8019c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8029c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8039c7779b64eacf264ee427b97ae0df8596b1960ccbart
8049c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8059c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8069c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
8079c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
8089c7779b64eacf264ee427b97ae0df8596b1960ccbart
8099c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8109c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8119c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
8129c7779b64eacf264ee427b97ae0df8596b1960ccbart
8138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8159c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8169c7779b64eacf264ee427b97ae0df8596b1960ccbart
8179c7779b64eacf264ee427b97ae0df8596b1960ccbart
8189c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcmp ----------------------*/
8199c7779b64eacf264ee427b97ae0df8596b1960ccbart
8209c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCMP(soname, fnname) \
8219c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8229c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
8239c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8249c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
8259c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8269c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
8279c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
8289c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
8299c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *(const UChar *)s1; \
8309c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *(const UChar *)s2; \
8319c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
8329c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
8339c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
8349c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8359c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
8369c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
8379c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
8389c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8399c7779b64eacf264ee427b97ae0df8596b1960ccbart
8409c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8419c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8429c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
8439c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse2)
8449c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse42)
8459c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
8469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD64_SO_1,            strcmp)
8479c6b05db45362b1afb981aa8298ab12ab4027b1adejanj# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8489c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
8499c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
8509c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
8519c7779b64eacf264ee427b97ae0df8596b1960ccbart
8529c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8539c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME, strcmp)
8549090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
855c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
856c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
8579c7779b64eacf264ee427b97ae0df8596b1960ccbart
8588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LD_SO_1,              strcmp)
8618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8629c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8639c7779b64eacf264ee427b97ae0df8596b1960ccbart
8649c7779b64eacf264ee427b97ae0df8596b1960ccbart
8659c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memchr ----------------------*/
8669c7779b64eacf264ee427b97ae0df8596b1960ccbart
8679c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCHR(soname, fnname) \
8689c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8699c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
8709c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8719c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
8729c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8739c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
8749c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
87570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
8769c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
87770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
8789c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
8799c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8809c7779b64eacf264ee427b97ae0df8596b1960ccbart
8819c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8829c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, memchr)
8839c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
8849c7779b64eacf264ee427b97ae0df8596b1960ccbart
8859c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
886aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
887798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  MEMCHR(VG_Z_DYLD,                   memchr)
888aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
889aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
8909090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_10
891a95abead5600e5b0e7a430d4d373aad7e267e35csewardj  MEMCHR(VG_Z_DYLD,                   memchr)
892312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memchr$VARIANT$Generic */
893312bcb109bfb6899086dda47b02a5436f26516d4sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
894312bcb109bfb6899086dda47b02a5436f26516d4sewardj# endif
8959c7779b64eacf264ee427b97ae0df8596b1960ccbart
8968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCHR(VG_Z_LIBC_SONAME, memchr)
8988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8999c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9009c7779b64eacf264ee427b97ae0df8596b1960ccbart
9019c7779b64eacf264ee427b97ae0df8596b1960ccbart
9029c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memrchr ----------------------*/
9039c7779b64eacf264ee427b97ae0df8596b1960ccbart
9049c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMRCHR(soname, fnname) \
9059c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9069c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
9079c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9089c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
9099c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9109c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
9119c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
91270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
9139c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
91470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
9159c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
9169c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
9179c7779b64eacf264ee427b97ae0df8596b1960ccbart
9189c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
9199c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9209c7779b64eacf264ee427b97ae0df8596b1960ccbart
9219c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
9229c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9239c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_DYLD,        memrchr)
9249c7779b64eacf264ee427b97ae0df8596b1960ccbart
9258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
9268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
9279c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9289c7779b64eacf264ee427b97ae0df8596b1960ccbart
9299c7779b64eacf264ee427b97ae0df8596b1960ccbart
9309c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcpy ----------------------*/
9319c7779b64eacf264ee427b97ae0df8596b1960ccbart
9329c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
9339c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9349c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
9359c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9369c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
9379c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9389c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (do_ol_check && is_overlap(dst, src, len, len)) \
9399c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
9409c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9419c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WS = sizeof(UWord); /* 8 or 4 */ \
9429c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WM = WS - 1;        /* 7 or 3 */ \
9439c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9449c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len > 0) { \
9459c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (dst < src || !is_overlap(dst, src, len, len)) { \
9469c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9479c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying backwards. */ \
9489c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9499c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = (Addr)dst; \
9509c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = (Addr)src; \
9519c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9529c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9539c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9549c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Pull up to a UWord boundary. */ \
9559c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9569c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9579c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9589c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9599c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
9609c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9619c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9629c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9639c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9649c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9659c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9669c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
9679c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9689c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9699c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
9709c7779b64eacf264ee427b97ae0df8596b1960ccbart               { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9719c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9729c7779b64eacf264ee427b97ae0df8596b1960ccbart         } else if (dst > src) { \
9739c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9749c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9759c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = ((Addr)dst) + n; \
9769c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = ((Addr)src) + n; \
9779c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9789c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying forwards. */ \
9799c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9809c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9819c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Back down to a UWord boundary. */ \
9829c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9839c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9849c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9859c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9869c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
9879c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9889c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9899c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9909c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9919c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9929c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9939c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
9949c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9959c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9969c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
9979c7779b64eacf264ee427b97ae0df8596b1960ccbart               { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9989c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9999c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
10009c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10019c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10029c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
10039c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10049c7779b64eacf264ee427b97ae0df8596b1960ccbart
10059c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE(soname, fnname)  \
10069c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
10079c7779b64eacf264ee427b97ae0df8596b1960ccbart
10089c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCPY(soname, fnname) \
10099c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
10109c7779b64eacf264ee427b97ae0df8596b1960ccbart
10119c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10129c7779b64eacf264ee427b97ae0df8596b1960ccbart /* For older memcpy we have to use memmove-like semantics and skip
10139c7779b64eacf264ee427b97ae0df8596b1960ccbart    the overlap check; sigh; see #275284. */
10149c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
10159c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
10169c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
10179c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __GI_memcpy)
10189c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __memcpy_sse2)
10199c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
10209c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
10219c7779b64eacf264ee427b97ae0df8596b1960ccbart /* icc9 blats these around all over the place.  Not only in the main
10229c7779b64eacf264ee427b97ae0df8596b1960ccbart    executable but various .so's.  They are highly tuned and read
10239c7779b64eacf264ee427b97ae0df8596b1960ccbart    memory beyond the source boundary (although work correctly and
10249c7779b64eacf264ee427b97ae0df8596b1960ccbart    never go across page boundaries), so give errors when run
10259c7779b64eacf264ee427b97ae0df8596b1960ccbart    natively, at least for misaligned source arg.  Just intercepting
10269c7779b64eacf264ee427b97ae0df8596b1960ccbart    in the exe only until we understand more about the problem.  See
10279c7779b64eacf264ee427b97ae0df8596b1960ccbart    http://bugs.kde.org/show_bug.cgi?id=139776
10289c7779b64eacf264ee427b97ae0df8596b1960ccbart */
10299c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(NONE, ZuintelZufastZumemcpy)
10309c7779b64eacf264ee427b97ae0df8596b1960ccbart
10319c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10329c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
10339c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
10349c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
10359c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
10369c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
10379c7779b64eacf264ee427b97ae0df8596b1960ccbart
10388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
10398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
10408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LD_SO_1,      memcpy)
10418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
10429c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10439c7779b64eacf264ee427b97ae0df8596b1960ccbart
10449c7779b64eacf264ee427b97ae0df8596b1960ccbart
10459c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcmp ----------------------*/
10469c7779b64eacf264ee427b97ae0df8596b1960ccbart
10479c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCMP(soname, fnname) \
10489c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10499c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n ); \
10509c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10519c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n )  \
10529c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
1053094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1054094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WM = WS - 1;        /* 7 or 3 */ \
105511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s1A = (Addr)s1V; \
105611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s2A = (Addr)s2V; \
105711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
105811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      if (((s1A | s2A) & WM) == 0) { \
105911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* Both areas are word aligned.  Skip over the */ \
106011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* equal prefix as fast as possible. */ \
106111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         while (n >= WS) { \
106211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w1 = *(UWord*)s1A; \
106311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w2 = *(UWord*)s2A; \
106411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            if (w1 != w2) break; \
106511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s1A += WS; \
106611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s2A += WS; \
106711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            n -= WS; \
106811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         } \
106911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      } \
107011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
107111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s1 = (const UChar*) s1A; \
107211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s2 = (const UChar*) s2A; \
10739c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10749c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n != 0) { \
107511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar a0 = s1[0]; \
107611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar b0 = s2[0]; \
10779c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1 += 1; \
10789c7779b64eacf264ee427b97ae0df8596b1960ccbart         s2 += 1; \
107911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         int res = ((int)a0) - ((int)b0); \
10809c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (res != 0) \
10819c7779b64eacf264ee427b97ae0df8596b1960ccbart            return res; \
10829c7779b64eacf264ee427b97ae0df8596b1960ccbart         n -= 1; \
10839c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10849c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
10859c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10869c7779b64eacf264ee427b97ae0df8596b1960ccbart
10879c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10889c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, memcmp)
10899c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
10909c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
10919c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
10929c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, bcmp)
10939c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LD_SO_1,     bcmp)
10949c7779b64eacf264ee427b97ae0df8596b1960ccbart
10959c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10969090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1097aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1098aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
10999c7779b64eacf264ee427b97ae0df8596b1960ccbart
11008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, memcmp)
11028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, bcmp)
11038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LD_SO_1,     memcmp)
11048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11059c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11069c7779b64eacf264ee427b97ae0df8596b1960ccbart
11079c7779b64eacf264ee427b97ae0df8596b1960ccbart
11089c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy ----------------------*/
11099c7779b64eacf264ee427b97ae0df8596b1960ccbart
11109c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy SRC to DEST, returning the address of the terminating '\0' in
11119c7779b64eacf264ee427b97ae0df8596b1960ccbart   DEST. (minor variant of strcpy) */
11129c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPCPY(soname, fnname) \
11139c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11149c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
11159c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11169c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
11179c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11189c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11199c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
11209c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11219c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
11229c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
11239c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11249c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
11259c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
11269c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
11279c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
11289c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
11299c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
11309c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
11319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11329c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
11339c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11349c7779b64eacf264ee427b97ae0df8596b1960ccbart
11359c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11369c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11379c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
11389c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2)
11399c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2_unaligned)
11409c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
11419c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
11429c7779b64eacf264ee427b97ae0df8596b1960ccbart
11439c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11449c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11459c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_DYLD,                 stpcpy)
11469c7779b64eacf264ee427b97ae0df8596b1960ccbart
11478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11509c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11519c7779b64eacf264ee427b97ae0df8596b1960ccbart
11529c7779b64eacf264ee427b97ae0df8596b1960ccbart
11539c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpncpy ----------------------*/
11549c7779b64eacf264ee427b97ae0df8596b1960ccbart
11559c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPNCPY(soname, fnname) \
11569c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11579c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
11589c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11599c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
11609c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11619c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11629c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_str  = dst; \
11639c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
11649c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11659c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
11669c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
11679c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
11689c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
11699c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
11709c7779b64eacf264ee427b97ae0df8596b1960ccbart      dst_str = dst; \
11719c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
11729c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11739c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_str; \
11749c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11759c7779b64eacf264ee427b97ae0df8596b1960ccbart
11769c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11779c7779b64eacf264ee427b97ae0df8596b1960ccbart STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
11789c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11799c7779b64eacf264ee427b97ae0df8596b1960ccbart
11809c7779b64eacf264ee427b97ae0df8596b1960ccbart
11819c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memset ----------------------*/
11829c7779b64eacf264ee427b97ae0df8596b1960ccbart
11839c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Why are we bothering to intercept this?  It seems entirely
11849c7779b64eacf264ee427b97ae0df8596b1960ccbart   pointless. */
11859c7779b64eacf264ee427b97ae0df8596b1960ccbart
11869c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMSET(soname, fnname) \
11879c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
11889c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n); \
11899c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
11909c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n) \
11919c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11929c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (sizeof(void*) == 8) { \
11939c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr  a  = (Addr)s;   \
11949c7779b64eacf264ee427b97ae0df8596b1960ccbart         ULong c8 = (c & 0xFF); \
11959c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 8) | c8; \
11969c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 16) | c8; \
11979c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 32) | c8; \
11989c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 7) != 0 && n >= 1) \
11999c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12009c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 8) \
12019c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(ULong*)a = c8; a += 8; n -= 8; } \
12029c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12039c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12049c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12059c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
12069c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr a  = (Addr)s;   \
12079c7779b64eacf264ee427b97ae0df8596b1960ccbart         UInt c4 = (c & 0xFF); \
12089c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 8) | c4; \
12099c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 16) | c4; \
12109c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 3) != 0 && n >= 1) \
12119c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12129c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 4) \
12139c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UInt*)a = c4; a += 4; n -= 4; } \
12149c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12159c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12169c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12179c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12189c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12199c7779b64eacf264ee427b97ae0df8596b1960ccbart
12209c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12219c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12229c7779b64eacf264ee427b97ae0df8596b1960ccbart
12239c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12249c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_LIBC_SONAME, memset)
12259c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_DYLD,        memset)
12269c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12279c7779b64eacf264ee427b97ae0df8596b1960ccbart
12288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMSET(VG_Z_LIBC_SONAME, memset)
12308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12319c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12329c7779b64eacf264ee427b97ae0df8596b1960ccbart
12339c7779b64eacf264ee427b97ae0df8596b1960ccbart
12349c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memmove ----------------------*/
12359c7779b64eacf264ee427b97ae0df8596b1960ccbart
12369c7779b64eacf264ee427b97ae0df8596b1960ccbart/* memmove -- use the MEMMOVE defn above. */
12379c7779b64eacf264ee427b97ae0df8596b1960ccbart
12389c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12399c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12409c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1241b97cf8e9a718e61a540e63001d4c9346773c630emjw /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1242b97cf8e9a718e61a540e63001d4c9346773c630emjw    arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1243b97cf8e9a718e61a540e63001d4c9346773c630emjw    to call memcpy.  */
1244b97cf8e9a718e61a540e63001d4c9346773c630emjw MEMMOVE(VG_Z_LD64_SO_1, memmove)
12459c7779b64eacf264ee427b97ae0df8596b1960ccbart
12469c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12479c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
12489c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12499c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
12509c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
12519c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
12529090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1253312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memmove$VARIANT$Ivybridge */
1254eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1255eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
12568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LD_SO_1,     memmove)
12608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12619c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12629c7779b64eacf264ee427b97ae0df8596b1960ccbart
12639c7779b64eacf264ee427b97ae0df8596b1960ccbart
12649c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- bcopy ----------------------*/
12659c7779b64eacf264ee427b97ae0df8596b1960ccbart
12669c7779b64eacf264ee427b97ae0df8596b1960ccbart#define BCOPY(soname, fnname) \
12679c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12689c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n); \
12699c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12709c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n) \
12719c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12729c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
12739c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV; \
12749c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
12759c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
12769c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12779c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
12789c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12799c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
12809c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
12819c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12829c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
12839c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12849c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12859c7779b64eacf264ee427b97ae0df8596b1960ccbart
12869c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12879c7779b64eacf264ee427b97ae0df8596b1960ccbart BCOPY(VG_Z_LIBC_SONAME, bcopy)
12889c7779b64eacf264ee427b97ae0df8596b1960ccbart
12899c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12909c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_LIBC_SONAME, bcopy)
12919c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_DYLD,        bcopy)
12929c7779b64eacf264ee427b97ae0df8596b1960ccbart
12938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_darwin)
12948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj BCOPY(VG_Z_LIBC_SONAME, bcopy)
12958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12969c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12979c7779b64eacf264ee427b97ae0df8596b1960ccbart
12989c7779b64eacf264ee427b97ae0df8596b1960ccbart
12999c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memmove_chk --------------------*/
13009c7779b64eacf264ee427b97ae0df8596b1960ccbart
13019c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc 2.5 variant of memmove which checks the dest is big enough.
13029c7779b64eacf264ee427b97ae0df8596b1960ccbart   There is no specific part of glibc that this is copied from. */
13039c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
13049c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13059c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
13069c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13079c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
13089c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13099c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
13109c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV;        \
13119c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
13129c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (destlen < n) \
13139c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
13149c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
13159c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13169c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
13179c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13189c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
13199c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
13209c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13219c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
13229c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13239c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
13249c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
13259c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
13269c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memmove_chk: buffer overflow detected ***: " \
13279c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
13289c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
13299c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
13309c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
13319c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13329c7779b64eacf264ee427b97ae0df8596b1960ccbart
13339c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13349c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
13359c7779b64eacf264ee427b97ae0df8596b1960ccbart
13369c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13379c7779b64eacf264ee427b97ae0df8596b1960ccbart
13388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13409c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13419c7779b64eacf264ee427b97ae0df8596b1960ccbart
13429c7779b64eacf264ee427b97ae0df8596b1960ccbart
13439c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- strchrnul --------------------*/
13449c7779b64eacf264ee427b97ae0df8596b1960ccbart
13459c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S or the final NUL byte.  */
13469c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_STRCHRNUL(soname, fnname) \
13479c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13489c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in); \
13499c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13509c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in) \
13519c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
135270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      HChar c = (HChar) c_in; \
135370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const HChar* char_ptr = s; \
13549c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
135570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr);  \
135670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr);  \
13579c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
13589c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13599c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13609c7779b64eacf264ee427b97ae0df8596b1960ccbart
13619c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13629c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
13639c7779b64eacf264ee427b97ae0df8596b1960ccbart
13649c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13659c7779b64eacf264ee427b97ae0df8596b1960ccbart
13668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13689c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13699c7779b64eacf264ee427b97ae0df8596b1960ccbart
13709c7779b64eacf264ee427b97ae0df8596b1960ccbart
13719c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- rawmemchr ----------------------*/
13729c7779b64eacf264ee427b97ae0df8596b1960ccbart
13739c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S.  */
13749c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_RAWMEMCHR(soname, fnname) \
13751ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13761ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in); \
13771ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13781ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in) \
13799c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13801ef205bfce335a8d54b6b188e83254b92c52d7adflorian      UChar c = (UChar) c_in; \
13811ef205bfce335a8d54b6b188e83254b92c52d7adflorian      const UChar* char_ptr = s; \
13829c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
138370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
13849c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
13859c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13869c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13879c7779b64eacf264ee427b97ae0df8596b1960ccbart
13889c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined (VGO_linux)
13899c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
13909c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
13919c7779b64eacf264ee427b97ae0df8596b1960ccbart
13929c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13939c7779b64eacf264ee427b97ae0df8596b1960ccbart
13948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13969c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13979c7779b64eacf264ee427b97ae0df8596b1960ccbart
13989c7779b64eacf264ee427b97ae0df8596b1960ccbart
13999c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy_chk ----------------------*/
14009c7779b64eacf264ee427b97ae0df8596b1960ccbart
14019c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of strcpy that checks the dest is big enough.
14029c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-strcpy_chk.c. */
14039c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STRCPY_CHK(soname,fnname) \
14049c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14059c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14069c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14079c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14089c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14099c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* ret = dst; \
14109c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14119c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14129c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14139c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14149c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14159c7779b64eacf264ee427b97ae0df8596b1960ccbart      return ret; \
14169c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14179c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14189c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** strcpy_chk: buffer overflow detected ***: " \
14199c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
14209c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
14219c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14229c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14239c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14249c7779b64eacf264ee427b97ae0df8596b1960ccbart
14259c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14269c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
14279c7779b64eacf264ee427b97ae0df8596b1960ccbart
14289c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14299c7779b64eacf264ee427b97ae0df8596b1960ccbart
14308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14329c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14339c7779b64eacf264ee427b97ae0df8596b1960ccbart
14349c7779b64eacf264ee427b97ae0df8596b1960ccbart
14359c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy_chk ----------------------*/
14369c7779b64eacf264ee427b97ae0df8596b1960ccbart
14379c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of stpcpy that checks the dest is big enough.
14389c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
14399c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STPCPY_CHK(soname,fnname) \
14409c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14419c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14429c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14439c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14449c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14459c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14469c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14479c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14489c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14499c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14509c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst - 1; \
14519c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14529c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14539c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** stpcpy_chk: buffer overflow detected ***: " \
14549c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
14559c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
14569c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14579c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14589c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14599c7779b64eacf264ee427b97ae0df8596b1960ccbart
14609c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14619c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
14629c7779b64eacf264ee427b97ae0df8596b1960ccbart
14639c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14649c7779b64eacf264ee427b97ae0df8596b1960ccbart
14658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14679c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14689c7779b64eacf264ee427b97ae0df8596b1960ccbart
14699c7779b64eacf264ee427b97ae0df8596b1960ccbart
14709c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- mempcpy ----------------------*/
14719c7779b64eacf264ee427b97ae0df8596b1960ccbart
14729c7779b64eacf264ee427b97ae0df8596b1960ccbart/* mempcpy */
14739c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25_MEMPCPY(soname, fnname) \
14749c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14759c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
14769c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14779c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
14789c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14799c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT len_saved = len; \
14809c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14819c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
14829c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
14839c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14849c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
14859c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
14869c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
14879c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
148809041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = (char *)dst + len - 1; \
148909041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = (const char *)src + len - 1; \
14909c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
14919c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
14929c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14939c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
149409041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = dst; \
149509041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = src; \
14969c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
14979c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
14989c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
14999c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15009c7779b64eacf264ee427b97ae0df8596b1960ccbart      return (void*)( ((char*)dst) + len_saved ); \
15019c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15029c7779b64eacf264ee427b97ae0df8596b1960ccbart
15039c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15049c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1505a9176d9640606a083a6e9b97515b15f631de5059mjw GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
15069c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
1507f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1508f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
15099c7779b64eacf264ee427b97ae0df8596b1960ccbart
15109c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15119c7779b64eacf264ee427b97ae0df8596b1960ccbart //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
15129c7779b64eacf264ee427b97ae0df8596b1960ccbart
15138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15159c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15169c7779b64eacf264ee427b97ae0df8596b1960ccbart
15179c7779b64eacf264ee427b97ae0df8596b1960ccbart
15189c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memcpy_chk --------------------*/
15199c7779b64eacf264ee427b97ae0df8596b1960ccbart
15209c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC26___MEMCPY_CHK(soname, fnname) \
15219c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15229c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ); \
15239c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15249c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ) \
15259c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15269c7779b64eacf264ee427b97ae0df8596b1960ccbart      register HChar *d; \
15279c7779b64eacf264ee427b97ae0df8596b1960ccbart      register const HChar *s; \
15289c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15299c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dstlen < len) goto badness; \
15309c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15319c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
15329c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
15339c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
15359c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
15369c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15379c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
15389c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst + len - 1; \
15399c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src + len - 1; \
15409c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15419c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
15429c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15439c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
15449c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst; \
15459c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src; \
15469c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15479c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
15489c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15499c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15509c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
15519c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
15529c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
15539c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memcpy_chk: buffer overflow detected ***: " \
15549c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
15559c7779b64eacf264ee427b97ae0df8596b1960ccbart     my_exit(127); \
15569c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
15579c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
15589c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15599c7779b64eacf264ee427b97ae0df8596b1960ccbart
15609c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15619c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
15629c7779b64eacf264ee427b97ae0df8596b1960ccbart
15639c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15649c7779b64eacf264ee427b97ae0df8596b1960ccbart
15658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15679c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15689c7779b64eacf264ee427b97ae0df8596b1960ccbart
15699c7779b64eacf264ee427b97ae0df8596b1960ccbart
15709c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strstr ----------------------*/
15719c7779b64eacf264ee427b97ae0df8596b1960ccbart
15729c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSTR(soname, fnname) \
15739c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15749c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
15759c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15769c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
15779c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15789c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
15799c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle; \
15809c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15819c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
15829c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
15839c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
15849c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15859c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
158670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);         \
15879c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15889c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
15899c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar n0 = n[0]; \
15909c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15919c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
15929c7779b64eacf264ee427b97ae0df8596b1960ccbart         const HChar hh = *h; \
15939c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
15949c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
15959c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
15969c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
15979c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
15989c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (n[i] != h[i]) \
15999c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16009c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16019c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
16029c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
160370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);          \
16049c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16059c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
16069c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16079c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16089c7779b64eacf264ee427b97ae0df8596b1960ccbart
16099c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16109c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          strstr)
16119c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse2)
16129c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse42)
16139c7779b64eacf264ee427b97ae0df8596b1960ccbart
16149c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16159c7779b64eacf264ee427b97ae0df8596b1960ccbart
16168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSTR(VG_Z_LIBC_SONAME,          strstr)
16188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16199c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16209c7779b64eacf264ee427b97ae0df8596b1960ccbart
16219c7779b64eacf264ee427b97ae0df8596b1960ccbart
16229c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strpbrk ----------------------*/
16239c7779b64eacf264ee427b97ae0df8596b1960ccbart
16249c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRPBRK(soname, fnname) \
16259c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16269c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
16279c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16289c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
16299c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16309c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16319c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* accept = acceptV; \
16329c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16339c7779b64eacf264ee427b97ae0df8596b1960ccbart      /*  find the length of 'accept', not including terminating zero */ \
16349c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
16359c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
16369c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16379c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, fail immediately. */ \
16389c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return NULL; \
16399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16409c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nacc >= 1); */ \
16419c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16429c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16439c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16449c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16459c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16469c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
16479c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
164870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian              return CONST_CAST(HChar *,s);       \
16499c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16509c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16519c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16529c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16539c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
16549c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16559c7779b64eacf264ee427b97ae0df8596b1960ccbart
16569c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16579c7779b64eacf264ee427b97ae0df8596b1960ccbart STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16589c7779b64eacf264ee427b97ae0df8596b1960ccbart
16599c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16609c7779b64eacf264ee427b97ae0df8596b1960ccbart
16618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16649c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16659c7779b64eacf264ee427b97ae0df8596b1960ccbart
16669c7779b64eacf264ee427b97ae0df8596b1960ccbart
16679c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcspn ----------------------*/
16689c7779b64eacf264ee427b97ae0df8596b1960ccbart
16699c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCSPN(soname, fnname) \
16709c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16719c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV); \
16729c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16739c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV) \
16749c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16759c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16769c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* reject = rejectV; \
16779c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16789c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'reject', not including terminating zero */ \
16799c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nrej = 0; \
16809c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (reject[nrej]) nrej++; \
16819c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16829c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
16839c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16849c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16859c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16869c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16879c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16889c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nrej; i++) { \
16899c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == reject[i]) \
16909c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16919c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16929c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nrej); */ \
16939c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i < nrej) \
16949c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16959c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16969c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
16979c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16989c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16999c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17009c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17019c7779b64eacf264ee427b97ae0df8596b1960ccbart
17029c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
17049c7779b64eacf264ee427b97ae0df8596b1960ccbart
17059c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17069c7779b64eacf264ee427b97ae0df8596b1960ccbart
17078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
17098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17109c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17119c7779b64eacf264ee427b97ae0df8596b1960ccbart
17129c7779b64eacf264ee427b97ae0df8596b1960ccbart
17139c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strspn ----------------------*/
17149c7779b64eacf264ee427b97ae0df8596b1960ccbart
17159c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSPN(soname, fnname) \
17169c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17179c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
17189c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17199c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
17209c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17219c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* s = (const UChar *)sV;        \
17229c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* accept = (const UChar *)acceptV;     \
17239c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17249c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'accept', not including terminating zero */ \
17259c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
17269c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
17279c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return 0; \
17289c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17299c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
17309c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17319c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17329c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
17339c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
17349c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17359c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
17369c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
17379c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17389c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17399c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nacc); */ \
17409c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nacc) \
17419c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17429c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
17439c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
17449c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17459c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17469c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17479c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17489c7779b64eacf264ee427b97ae0df8596b1960ccbart
17499c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17509c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSPN(VG_Z_LIBC_SONAME,          strspn)
17519c7779b64eacf264ee427b97ae0df8596b1960ccbart
17529c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17539c7779b64eacf264ee427b97ae0df8596b1960ccbart
17548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSPN(VG_Z_LIBC_SONAME,          strspn)
17568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17579c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17589c7779b64eacf264ee427b97ae0df8596b1960ccbart
17599c7779b64eacf264ee427b97ae0df8596b1960ccbart
17609c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasestr ----------------------*/
17619c7779b64eacf264ee427b97ae0df8596b1960ccbart
17629c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASESTR(soname, fnname) \
17639c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17649c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
17659c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17669c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
17679c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17689c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
17699c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
17709c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle;   \
17719c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17729c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
17739c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
17749c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
17759c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17769c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
177770a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);       \
17789c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17799c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
17809c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar n0 = tolower(n[0]);                 \
17819c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17829c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17839c7779b64eacf264ee427b97ae0df8596b1960ccbart         UChar hh = tolower(*h);    \
17849c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
17859c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
17869c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
17879c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17889c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
17899c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (tolower(n[i]) != tolower(h[i]))  \
17909c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17919c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17929c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
17939c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
179470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);    \
17959c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
17969c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
17979c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17989c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17999c7779b64eacf264ee427b97ae0df8596b1960ccbart
18009c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
180126ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
180226ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
180326ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
180426ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
18059c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18069c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
18079c7779b64eacf264ee427b97ae0df8596b1960ccbart
18089c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18099c7779b64eacf264ee427b97ae0df8596b1960ccbart
18108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18139c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18149c7779b64eacf264ee427b97ae0df8596b1960ccbart
18159c7779b64eacf264ee427b97ae0df8596b1960ccbart
18169c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcslen ----------------------*/
18179c7779b64eacf264ee427b97ae0df8596b1960ccbart
18189c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strlen.  Unfortunately
18199c7779b64eacf264ee427b97ae0df8596b1960ccbart// we don't have wchar_t available here, but it looks like
18209c7779b64eacf264ee427b97ae0df8596b1960ccbart// a 32 bit int on Linux.  I don't know if that is also
18219c7779b64eacf264ee427b97ae0df8596b1960ccbart// valid on MacOSX.
18229c7779b64eacf264ee427b97ae0df8596b1960ccbart
18239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSLEN(soname, fnname) \
18249c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18259c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str ); \
18269c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18279c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str )  \
18289c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18299c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
18309c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
18319c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
18329c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18339c7779b64eacf264ee427b97ae0df8596b1960ccbart
18349c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18359c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18369c7779b64eacf264ee427b97ae0df8596b1960ccbart
18379c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18389c7779b64eacf264ee427b97ae0df8596b1960ccbart
18398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18429c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18439c7779b64eacf264ee427b97ae0df8596b1960ccbart
18449c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscmp ----------------------*/
18459c7779b64eacf264ee427b97ae0df8596b1960ccbart
18469c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcmp.  We don't
18479c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
18489c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide and wcscmp uses signed
18499c7779b64eacf264ee427b97ae0df8596b1960ccbart// comparison, not unsigned as in strcmp function.
18509c7779b64eacf264ee427b97ae0df8596b1960ccbart
18519c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCMP(soname, fnname) \
18529c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18539c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ); \
18549c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18559c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ) \
18569c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18579c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c1; \
18589c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c2; \
18599c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
18609c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *s1; \
18619c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *s2; \
18629c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
18639c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
18649c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
18659c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18669c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 < c2) return -1; \
18679c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 > c2) return 1; \
18689c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
18699c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18709c7779b64eacf264ee427b97ae0df8596b1960ccbart
18719c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18729c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCMP(VG_Z_LIBC_SONAME,          wcscmp)
18739c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18749c7779b64eacf264ee427b97ae0df8596b1960ccbart
18759c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscpy ----------------------*/
18769c7779b64eacf264ee427b97ae0df8596b1960ccbart
18779c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcpy.  We don't
18789c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
18799c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
18809c7779b64eacf264ee427b97ae0df8596b1960ccbart
18819c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCPY(soname, fnname) \
18829c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
18839c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ); \
18849c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
18859c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ) \
18869c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18879c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Int* src_orig = src; \
18889c7779b64eacf264ee427b97ae0df8596b1960ccbart            Int* dst_orig = dst; \
18899c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18909c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
18919c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
18929c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18939c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
18949c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
18959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
18969c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
18979c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
18989c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
18999c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
19009c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
19019c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
19029c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19039c7779b64eacf264ee427b97ae0df8596b1960ccbart
19049c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19059c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
19069c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19079c7779b64eacf264ee427b97ae0df8596b1960ccbart
19089c7779b64eacf264ee427b97ae0df8596b1960ccbart
19099c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcschr ----------------------*/
19109c7779b64eacf264ee427b97ae0df8596b1960ccbart
19119c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strchr.  We don't
19129c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19139c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19149c7779b64eacf264ee427b97ae0df8596b1960ccbart
19159c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCHR(soname, fnname) \
19169c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
19179c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
19189c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
191970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
19209c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
192170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == c) return CONST_CAST(Int *,p);  \
19229c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
19239c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19249c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19259c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19269c7779b64eacf264ee427b97ae0df8596b1960ccbart
19279c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19289c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCHR(VG_Z_LIBC_SONAME,          wcschr)
19299c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19309c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcsrchr ----------------------*/
19319c7779b64eacf264ee427b97ae0df8596b1960ccbart
19329c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strrchr.  We don't
19339c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19349c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19359c7779b64eacf264ee427b97ae0df8596b1960ccbart
19369c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSRCHR(soname, fnname) \
19379c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
19389c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
19399c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
194070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
194170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* last = NULL; \
19429c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
19439c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == c) last = p; \
194470a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(Int *,last);  \
19459c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19469c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19479c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19489c7779b64eacf264ee427b97ae0df8596b1960ccbart
19499c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19509c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
19519c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19529c7779b64eacf264ee427b97ae0df8596b1960ccbart
19539c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19549c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Improve definedness checking of process environment  ---*/
19559c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19569c7779b64eacf264ee427b97ae0df8596b1960ccbart
19579c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19589c7779b64eacf264ee427b97ae0df8596b1960ccbart
19599c7779b64eacf264ee427b97ae0df8596b1960ccbart/* If these wind up getting generated via a macro, so that multiple
19609c7779b64eacf264ee427b97ae0df8596b1960ccbart   versions of each function exist (as above), use the _EZU variants
19619c7779b64eacf264ee427b97ae0df8596b1960ccbart   to assign equivalance class tags. */
19629c7779b64eacf264ee427b97ae0df8596b1960ccbart
19639c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- putenv ----------------------*/
19649c7779b64eacf264ee427b97ae0df8596b1960ccbart
19659c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
19669c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
19679c7779b64eacf264ee427b97ae0df8596b1960ccbart{
19689c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
19699c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
19709c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = string;
19719c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
19729c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
19739c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
19749c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
19759c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
19769c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
19779c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, string);
19789c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
19799c7779b64eacf264ee427b97ae0df8596b1960ccbart}
19809c7779b64eacf264ee427b97ae0df8596b1960ccbart
19819c7779b64eacf264ee427b97ae0df8596b1960ccbart
19829c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- unsetenv ----------------------*/
19839c7779b64eacf264ee427b97ae0df8596b1960ccbart
19849c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
19859c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
19869c7779b64eacf264ee427b97ae0df8596b1960ccbart{
19879c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
19889c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
19899c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = name;
19909c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
19919c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
19929c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
19939c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
19949c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
19959c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
19969c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, name);
19979c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
19989c7779b64eacf264ee427b97ae0df8596b1960ccbart}
19999c7779b64eacf264ee427b97ae0df8596b1960ccbart
20009c7779b64eacf264ee427b97ae0df8596b1960ccbart
20019c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- setenv ----------------------*/
20029c7779b64eacf264ee427b97ae0df8596b1960ccbart
20039c7779b64eacf264ee427b97ae0df8596b1960ccbart/* setenv */
20049c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20059c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite);
20069c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20079c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite)
20089c7779b64eacf264ee427b97ae0df8596b1960ccbart{
20099c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
20109c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
20119c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p;
20129c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
20139c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
20149c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
20159c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (name)
20169c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = name; *p; p++)
20179c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20189c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (value)
20199c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = value; *p; p++)
20209c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20219c7779b64eacf264ee427b97ae0df8596b1960ccbart    (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
20229c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_WWW(result, fn, name, value, overwrite);
20239c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20249c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20259c7779b64eacf264ee427b97ae0df8596b1960ccbart
20269c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif /* defined(VGO_linux) */
20279c7779b64eacf264ee427b97ae0df8596b1960ccbart
20289c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
20299c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- end                                                          ---*/
20309c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
2031