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
11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2000-2017 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)
250a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# if !defined(VGP_x86_linux) && !defined(VGP_amd64_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
257ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#if defined(VGPV_mips32_linux_android)
258ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes  STRCHR(NONE,        __dl_strchr)
259ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes#endif
260ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes
2619c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
2629c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCHR(VG_Z_LIBC_SONAME, strchr)
263c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# if DARWIN_VERS == DARWIN_10_9
264c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCHR(libsystemZuplatformZddylib, _platform_strchr)
265c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
2669090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_10
2679951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  /* _platform_strchr$VARIANT$Generic */
2689951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Generic)
269e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  /* _platform_strchr$VARIANT$Haswell */
270366cefb68a2b15558ed1ddcda74c675d3ac39948rhyskidd  STRCHR(libsystemZuplatformZddylib, _platform_strchr$VARIANT$Haswell)
2719951323b382138ba9ffbb33901af85bc0ad5dc3frhyskidd# endif
2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
2748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          strchr)
2758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LIBC_SONAME,          index)
2768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCHR(VG_Z_LD_SO_1,              strchr)
2778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2789c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
2799c7779b64eacf264ee427b97ae0df8596b1960ccbart
2809c7779b64eacf264ee427b97ae0df8596b1960ccbart
2819c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcat ----------------------*/
2829c7779b64eacf264ee427b97ae0df8596b1960ccbart
2839c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCAT(soname, fnname) \
2849c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2859c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
2869c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \
2879c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
2889c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
2899c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
2909c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
2919c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
2929c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
2939c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
2949c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
2959c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This is a bit redundant, I think;  any overlap and the strcat will */ \
2969c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* go forever... or until a seg fault occurs. */ \
2979c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
2989c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
2999c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
3009c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3019c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \
3029c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3039c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3049c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3059c7779b64eacf264ee427b97ae0df8596b1960ccbart
3069c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3079c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, strcat)
3089c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
3099c7779b64eacf264ee427b97ae0df8596b1960ccbart
3109c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3119c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCAT(VG_Z_LIBC_SONAME, strcat)
3129c7779b64eacf264ee427b97ae0df8596b1960ccbart
3138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LIBC_SONAME, strcat)
3158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCAT(VG_Z_LD_SO_1,     strcat)
3168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3179c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3189c7779b64eacf264ee427b97ae0df8596b1960ccbart
3199c7779b64eacf264ee427b97ae0df8596b1960ccbart
3209c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncat ----------------------*/
3219c7779b64eacf264ee427b97ae0df8596b1960ccbart
3229c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCAT(soname, fnname) \
3239c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3249c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
3259c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \
3269c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
3279c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3289c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3299c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
3309c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3329c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*dst) dst++; \
3339c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \
3349c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0;                                       /* always add null   */ \
3359c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3369c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3379c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3389c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3399c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3409c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
3419c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3429c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \
3439c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3449c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
3459c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3469c7779b64eacf264ee427b97ae0df8596b1960ccbart
3479c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCAT(VG_Z_LIBC_SONAME, strncat)
3499c7779b64eacf264ee427b97ae0df8596b1960ccbart
3509c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
3519c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_LIBC_SONAME, strncat)
3529c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCAT(VG_Z_DYLD,        strncat)
3539c7779b64eacf264ee427b97ae0df8596b1960ccbart
3548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
3558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCAT(VG_Z_LIBC_SONAME, strncat)
3568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
3579c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
3589c7779b64eacf264ee427b97ae0df8596b1960ccbart
3599c7779b64eacf264ee427b97ae0df8596b1960ccbart
3609c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcat ----------------------*/
3619c7779b64eacf264ee427b97ae0df8596b1960ccbart
3629c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Append src to dst. n is the size of dst's buffer. dst is guaranteed
3639c7779b64eacf264ee427b97ae0df8596b1960ccbart   to be nul-terminated after the copy, unless n <= strlen(dst_orig).
3649c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns min(n, strlen(dst_orig)) + strlen(src_orig).
3659c7779b64eacf264ee427b97ae0df8596b1960ccbart   Truncation occurred if retval >= n.
3669c7779b64eacf264ee427b97ae0df8596b1960ccbart*/
3679c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCAT(soname, fnname) \
3689c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3699c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ); \
3709c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \
3719c7779b64eacf264ee427b97ae0df8596b1960ccbart        ( char* dst, const char* src, SizeT n ) \
3729c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
3739c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
3749c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
3759c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
3769c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3779c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n && *dst) { m++; dst++; } \
3789c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (m < n) { \
3799c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* Fill as far as dst_orig[n-2], then nul-terminate. */ \
3809c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (m < n-1 && *src) { m++; *dst++ = *src++; } \
3819c7779b64eacf264ee427b97ae0df8596b1960ccbart         *dst = 0; \
3829c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
3839c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* No space to copy anything to dst. m == n */ \
3849c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
3859c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \
3869c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) { m++; src++; } \
3879c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
3889c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting lengths... should be ok */ \
3899c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
3909c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
3919c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
3929c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
3939c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \
3949c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
3959c7779b64eacf264ee427b97ae0df8596b1960ccbart      return m; \
3969c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
3979c7779b64eacf264ee427b97ae0df8596b1960ccbart
3989c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
3999c7779b64eacf264ee427b97ae0df8596b1960ccbart
4009c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4019c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4029c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCAT(VG_Z_DYLD,        strlcat)
4039c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4049c7779b64eacf264ee427b97ae0df8596b1960ccbart
4058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCAT(VG_Z_LIBC_SONAME, strlcat)
4078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4089c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4099c7779b64eacf264ee427b97ae0df8596b1960ccbart
4109c7779b64eacf264ee427b97ae0df8596b1960ccbart
4119c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strnlen ----------------------*/
4129c7779b64eacf264ee427b97ae0df8596b1960ccbart
4139c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNLEN(soname, fnname) \
4149c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4159c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ); \
4169c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \
4179c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( const char* str, SizeT n ) \
4189c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4199c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4209c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (i < n && str[i] != 0) i++; \
4219c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4229c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4239c7779b64eacf264ee427b97ae0df8596b1960ccbart
4249c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4259c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4269c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
4279c7779b64eacf264ee427b97ae0df8596b1960ccbart
4289c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
429aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
430aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNLEN(libsystemZucZddylib, strnlen)
431aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
4329c7779b64eacf264ee427b97ae0df8596b1960ccbart
4338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNLEN(VG_Z_LIBC_SONAME, strnlen)
4358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4369c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4379c7779b64eacf264ee427b97ae0df8596b1960ccbart
4389c7779b64eacf264ee427b97ae0df8596b1960ccbart
4399c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlen ----------------------*/
4409c7779b64eacf264ee427b97ae0df8596b1960ccbart
4419c7779b64eacf264ee427b97ae0df8596b1960ccbart// Note that this replacement often doesn't get used because gcc inlines
4429c7779b64eacf264ee427b97ae0df8596b1960ccbart// calls to strlen() with its own built-in version.  This can be very
4439c7779b64eacf264ee427b97ae0df8596b1960ccbart// confusing if you aren't expecting it.  Other small functions in
4449c7779b64eacf264ee427b97ae0df8596b1960ccbart// this file may also be inline by gcc.
4459c7779b64eacf264ee427b97ae0df8596b1960ccbart
4469c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLEN(soname, fnname) \
4479c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4489c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str ); \
4499c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \
4509c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const char* str )  \
4519c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4529c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
4539c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
4549c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
4559c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
4569c7779b64eacf264ee427b97ae0df8596b1960ccbart
4579c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
4589c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          strlen)
4599c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
4609c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2)
4619c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse2_no_bsf)
4629c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse42)
4639c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
4649c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
46526ed419d60369d0545510eba0832566e24452e1esewardj# if defined(VGPV_arm_linux_android) \
46626ed419d60369d0545510eba0832566e24452e1esewardj     || defined(VGPV_x86_linux_android) \
4679c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
4689c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
4699c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
4709c7779b64eacf264ee427b97ae0df8596b1960ccbart
4719c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
4729c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLEN(VG_Z_LIBC_SONAME, strlen)
4739090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
474c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRLEN(libsystemZucZddylib, strlen)
475c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
4768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
4788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LIBC_SONAME,          strlen)
4798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLEN(VG_Z_LD_SO_1,              strlen)
4808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4819c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
4829c7779b64eacf264ee427b97ae0df8596b1960ccbart
4839c7779b64eacf264ee427b97ae0df8596b1960ccbart
4849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy ----------------------*/
4859c7779b64eacf264ee427b97ae0df8596b1960ccbart
4869c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCPY(soname, fnname) \
4879c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4889c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ); \
4899c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \
4909c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( char* dst, const char* src ) \
4919c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
4929c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
4939c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
4949c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4959c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
4969c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
4979c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
4989c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
4999c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
5009c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
5019c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
5029c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
5039c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
5049c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \
5059c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5069c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5079c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5089c7779b64eacf264ee427b97ae0df8596b1960ccbart
5099c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5109c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
5119c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
5129c7779b64eacf264ee427b97ae0df8596b1960ccbart
5139c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5149c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCPY(VG_Z_LIBC_SONAME, strcpy)
515aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
516aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRCPY(libsystemZucZddylib, strcpy)
517aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5189c7779b64eacf264ee427b97ae0df8596b1960ccbart
5198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LIBC_SONAME, strcpy)
5218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCPY(VG_Z_LD_SO_1,     strcpy)
5228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5239c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5249c7779b64eacf264ee427b97ae0df8596b1960ccbart
5259c7779b64eacf264ee427b97ae0df8596b1960ccbart
5269c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncpy ----------------------*/
5279c7779b64eacf264ee427b97ae0df8596b1960ccbart
5289c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCPY(soname, fnname) \
5299c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5309c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
5319c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
5329c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
5339c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5349c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5359c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
5369c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5379c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5389c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
5399c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5409c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5419c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5429c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \
5439c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
5449c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5459c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
5469c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5479c7779b64eacf264ee427b97ae0df8596b1960ccbart
5489c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5499c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5509c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
5519c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
5529c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
5539c7779b64eacf264ee427b97ae0df8596b1960ccbart
5549c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
5559c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5569090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
557aec49a463fd7c90ef190ff72318e50224e463e90sewardj  STRNCPY(libsystemZucZddylib, strncpy)
558aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
5599c7779b64eacf264ee427b97ae0df8596b1960ccbart
5608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
5618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LIBC_SONAME, strncpy)
5628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCPY(VG_Z_LD_SO_1,     strncpy)
5638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
5649c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
5659c7779b64eacf264ee427b97ae0df8596b1960ccbart
5669c7779b64eacf264ee427b97ae0df8596b1960ccbart
5679c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strlcpy ----------------------*/
5689c7779b64eacf264ee427b97ae0df8596b1960ccbart
5699c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0.
5709c7779b64eacf264ee427b97ae0df8596b1960ccbart   Returns strlen(src). Does not zero-fill the remainder of dst. */
5719c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRLCPY(soname, fnname) \
5729c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5739c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ); \
5749c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \
5759c7779b64eacf264ee427b97ae0df8596b1960ccbart       ( char* dst, const char* src, SizeT n ) \
5769c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
5779c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
5789c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst_orig = dst; \
5799c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
5809c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
5818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
5828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      \
5839c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m < n-1 && *src) { m++; *dst++ = *src++; } \
5849c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* m non-nul bytes have now been copied, and m <= n-1. */ \
5859c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
5869c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
5879c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \
5889c7779b64eacf264ee427b97ae0df8596b1960ccbart          RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \
5899c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Nul-terminate dst. */ \
5909c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (n > 0) *dst = 0; \
5919c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Finish counting strlen(src). */ \
5929c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) src++; \
5939c7779b64eacf264ee427b97ae0df8596b1960ccbart      return src - src_orig; \
5949c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
5959c7779b64eacf264ee427b97ae0df8596b1960ccbart
5969c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
5979c7779b64eacf264ee427b97ae0df8596b1960ccbart
5989c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
5999c6b05db45362b1afb981aa8298ab12ab4027b1adejanj    || defined(VGPV_mips32_linux_android)
6008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
6019c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
6029c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6039c7779b64eacf264ee427b97ae0df8596b1960ccbart
6049c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO
6069c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6079c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRLCPY(VG_Z_DYLD,        strlcpy)
6089c7779b64eacf264ee427b97ae0df8596b1960ccbart STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6099c7779b64eacf264ee427b97ae0df8596b1960ccbart
6108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* special case for n == 0 which is undocumented but heavily used */
6128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO \
6138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    if (n == 0) { \
6148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       while (*src) src++; \
6158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj       return src - src_orig; \
6168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    }
6178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
6198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6209c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6219c7779b64eacf264ee427b97ae0df8596b1960ccbart
6229c7779b64eacf264ee427b97ae0df8596b1960ccbart
6239c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncmp ----------------------*/
6249c7779b64eacf264ee427b97ae0df8596b1960ccbart
6259c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCMP(soname, fnname) \
6269c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6279c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
6289c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
6299c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
6309c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6319c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
6329c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6339c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
6349c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
6359c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
6369c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
6379c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6389c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
6399c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
6409c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
6419c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
6429c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6439c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6449c7779b64eacf264ee427b97ae0df8596b1960ccbart
6459c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
6469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
6489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
6499c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
6509c7779b64eacf264ee427b97ae0df8596b1960ccbart
6519c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6529c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCMP(VG_Z_LIBC_SONAME,        strncmp)
6539090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
654798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  STRNCMP(libsystemZuplatformZddylib, _platform_strncmp)
655798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj# endif
6569c7779b64eacf264ee427b97ae0df8596b1960ccbart
6578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCMP(VG_Z_LIBC_SONAME, strncmp)
6598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
6609c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
6619c7779b64eacf264ee427b97ae0df8596b1960ccbart
6629c7779b64eacf264ee427b97ae0df8596b1960ccbart
6639c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp ----------------------*/
6649c7779b64eacf264ee427b97ae0df8596b1960ccbart
6659c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP(soname, fnname) \
6669c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6679c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
6689c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \
6699c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
6709c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
6719c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
6729c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
6739c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
6749c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
6759c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower(*(const UChar *)s1); \
6769c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower(*(const UChar *)s2); \
6779c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
6789c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
6799c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
6809c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
6819c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
6829c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
6839c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
6849c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
6859c7779b64eacf264ee427b97ae0df8596b1960ccbart
6869c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
68726ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
68826ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
68926ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
69026ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
6919c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6929c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
6939c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
6949c7779b64eacf264ee427b97ae0df8596b1960ccbart
6959c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
6969c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
6979c7779b64eacf264ee427b97ae0df8596b1960ccbart
6988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
6998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
7008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7019c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7029c7779b64eacf264ee427b97ae0df8596b1960ccbart
7039c7779b64eacf264ee427b97ae0df8596b1960ccbart
7049c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp ----------------------*/
7059c7779b64eacf264ee427b97ae0df8596b1960ccbart
7069c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP(soname, fnname) \
7079c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7089c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ); \
7099c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \
7109c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax ) \
7119c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7129c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
7139c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7149c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7159c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7169c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7179c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7189c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7199c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7209c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7219c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower(*(const UChar*)s2)) return -1; \
7229c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower(*(const UChar *)s1) \
7239c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower(*(const UChar *)s2)) return 1; \
7249c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
7259c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
7269c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7279c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7289c7779b64eacf264ee427b97ae0df8596b1960ccbart
7299c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
73026ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
73126ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
73226ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
73326ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
7349c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7359c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
7369c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
7379c7779b64eacf264ee427b97ae0df8596b1960ccbart
7389c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7399c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7409c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP(VG_Z_DYLD,        strncasecmp)
7419c7779b64eacf264ee427b97ae0df8596b1960ccbart
7428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
7448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7459c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7469c7779b64eacf264ee427b97ae0df8596b1960ccbart
7479c7779b64eacf264ee427b97ae0df8596b1960ccbart
7489c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasecmp_l ----------------------*/
7499c7779b64eacf264ee427b97ae0df8596b1960ccbart
7509c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASECMP_L(soname, fnname) \
7519c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7529c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ); \
7539c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \
7549c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, void* locale ) \
7559c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7569c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak)); \
7579c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
7589c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
7599c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7609c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = tolower_l(*(const UChar *)s1, locale); \
7619c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = tolower_l(*(const UChar *)s2, locale); \
7629c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
7639c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
7649c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
7659c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
7669c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
7679c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
7689c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
7699c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
7709c7779b64eacf264ee427b97ae0df8596b1960ccbart
7719c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
7729c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7739c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l)
7749c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
7759c7779b64eacf264ee427b97ae0df8596b1960ccbart
7769c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
7779c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
7789c7779b64eacf264ee427b97ae0df8596b1960ccbart
7798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
7808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
7819c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
7829c7779b64eacf264ee427b97ae0df8596b1960ccbart
7839c7779b64eacf264ee427b97ae0df8596b1960ccbart
7849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strncasecmp_l ----------------------*/
7859c7779b64eacf264ee427b97ae0df8596b1960ccbart
7869c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRNCASECMP_L(soname, fnname) \
7879c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7889c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ); \
7899c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \
7909c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2, SizeT nmax, void* locale ) \
7919c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
7929c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower_l(int, void*) __attribute__((weak));    \
7939c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT n = 0; \
7949c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
7959c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (n >= nmax) return 0; \
7969c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0 && *s2 == 0) return 0; \
7979c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s1 == 0) return -1; \
7989c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*s2 == 0) return 1; \
7999c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8009c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
8019c7779b64eacf264ee427b97ae0df8596b1960ccbart             < tolower_l(*(const UChar *)s2, locale)) return -1; \
8029c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (tolower_l(*(const UChar *)s1, locale) \
8039c7779b64eacf264ee427b97ae0df8596b1960ccbart             > tolower_l(*(const UChar *)s2, locale)) return 1; \
8049c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
8059c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; n++; \
8069c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8079c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8089c7779b64eacf264ee427b97ae0df8596b1960ccbart
8099c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8109c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8119c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
8129c7779b64eacf264ee427b97ae0df8596b1960ccbart STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l)
8139c7779b64eacf264ee427b97ae0df8596b1960ccbart
8149c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8159c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
8169c7779b64eacf264ee427b97ae0df8596b1960ccbart //STRNCASECMP_L(VG_Z_DYLD,        strncasecmp_l)
8179c7779b64eacf264ee427b97ae0df8596b1960ccbart
8188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8209c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8219c7779b64eacf264ee427b97ae0df8596b1960ccbart
8229c7779b64eacf264ee427b97ae0df8596b1960ccbart
8239c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcmp ----------------------*/
8249c7779b64eacf264ee427b97ae0df8596b1960ccbart
8259c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCMP(soname, fnname) \
8269c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8279c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ); \
8289c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \
8299c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const char* s1, const char* s2 ) \
8309c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8319c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c1; \
8329c7779b64eacf264ee427b97ae0df8596b1960ccbart      register UChar c2; \
8339c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
8349c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *(const UChar *)s1; \
8359c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *(const UChar *)s2; \
8369c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
8379c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
8389c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
8399c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
8409c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 < (UChar)c2) return -1; \
8419c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ((UChar)c1 > (UChar)c2) return 1; \
8429c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
8439c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8449c7779b64eacf264ee427b97ae0df8596b1960ccbart
8459c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8469c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8479c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
8489c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse2)
8499c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME,          __strcmp_sse42)
8509c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
8519c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LD64_SO_1,            strcmp)
8529c6b05db45362b1afb981aa8298ab12ab4027b1adejanj# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8539c6b05db45362b1afb981aa8298ab12ab4027b1adejanj     || defined(VGPV_mips32_linux_android)
8549c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
8559c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
8569c7779b64eacf264ee427b97ae0df8596b1960ccbart
8579c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
8589c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCMP(VG_Z_LIBC_SONAME, strcmp)
8599090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
860c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj  STRCMP(libsystemZuplatformZddylib, _platform_strcmp)
861c3e09f66fa315ff9b207db6925a80bc5693ce838sewardj# endif
8629c7779b64eacf264ee427b97ae0df8596b1960ccbart
8638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
8648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LIBC_SONAME,          strcmp)
8658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCMP(VG_Z_LD_SO_1,              strcmp)
8668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
8679c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
8689c7779b64eacf264ee427b97ae0df8596b1960ccbart
8699c7779b64eacf264ee427b97ae0df8596b1960ccbart
8709c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memchr ----------------------*/
8719c7779b64eacf264ee427b97ae0df8596b1960ccbart
8729c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCHR(soname, fnname) \
8739c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8749c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
8759c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
8769c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
8779c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
8789c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
8799c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
88070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
8819c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
88270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[i] == c0) return CONST_CAST(void *,&p[i]); \
8839c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
8849c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
8859c7779b64eacf264ee427b97ae0df8596b1960ccbart
8869c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
8879c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, memchr)
8889c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
8899c7779b64eacf264ee427b97ae0df8596b1960ccbart
8909c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
891aec49a463fd7c90ef190ff72318e50224e463e90sewardj# if DARWIN_VERS == DARWIN_10_9
892798e95b2ac2f772cc4b347650d37fa4ac2de1320sewardj  MEMCHR(VG_Z_DYLD,                   memchr)
893aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr)
894aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
8959090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_10
896a95abead5600e5b0e7a430d4d373aad7e267e35csewardj  MEMCHR(VG_Z_DYLD,                   memchr)
897312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memchr$VARIANT$Generic */
898312bcb109bfb6899086dda47b02a5436f26516d4sewardj  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Generic)
899e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  /* _platform_memchr$VARIANT$Haswell */
900e4fcda3d77cb2304a0feb9f5658c1f316fc3369frhyskidd  MEMCHR(libsystemZuplatformZddylib, _platform_memchr$VARIANT$Haswell)
901312bcb109bfb6899086dda47b02a5436f26516d4sewardj# endif
9029c7779b64eacf264ee427b97ae0df8596b1960ccbart
9038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
9048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCHR(VG_Z_LIBC_SONAME, memchr)
9058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
9069c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9079c7779b64eacf264ee427b97ae0df8596b1960ccbart
9089c7779b64eacf264ee427b97ae0df8596b1960ccbart
9099c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memrchr ----------------------*/
9109c7779b64eacf264ee427b97ae0df8596b1960ccbart
9119c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMRCHR(soname, fnname) \
9129c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9139c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n); \
9149c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
9159c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *s, int c, SizeT n) \
9169c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9179c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
9189c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar c0 = (UChar)c; \
91970a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const UChar* p = s; \
9209c7779b64eacf264ee427b97ae0df8596b1960ccbart      for (i = 0; i < n; i++) \
92170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (p[n-1-i] == c0) return CONST_CAST(void *,&p[n-1-i]); \
9229c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
9239c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
9249c7779b64eacf264ee427b97ae0df8596b1960ccbart
9259c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
9269c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9279c7779b64eacf264ee427b97ae0df8596b1960ccbart
9289c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
9299c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
9309c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMRCHR(VG_Z_DYLD,        memrchr)
9319c7779b64eacf264ee427b97ae0df8596b1960ccbart
9328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
9338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
9349c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
9359c7779b64eacf264ee427b97ae0df8596b1960ccbart
9369c7779b64eacf264ee427b97ae0df8596b1960ccbart
9379c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcpy ----------------------*/
9389c7779b64eacf264ee427b97ae0df8596b1960ccbart
9399c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check)  \
9409c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9419c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
9429c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \
9439c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
9449c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
9459c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (do_ol_check && is_overlap(dst, src, len, len)) \
9469c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
9479c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9489c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WS = sizeof(UWord); /* 8 or 4 */ \
9499c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Addr WM = WS - 1;        /* 7 or 3 */ \
9509c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
9519c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len > 0) { \
9529c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (dst < src || !is_overlap(dst, src, len, len)) { \
9539c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9549c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying backwards. */ \
9559c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9569c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = (Addr)dst; \
9579c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = (Addr)src; \
9589c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9599c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9609c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9619c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Pull up to a UWord boundary. */ \
9629c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9639c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9649c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9659c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9669c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
9679c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9689c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9699c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9709c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9719c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9729c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
9739c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
9749c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9759c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
9769c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
9779c7779b64eacf264ee427b97ae0df8596b1960ccbart               { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
9789c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9799c7779b64eacf264ee427b97ae0df8596b1960ccbart         } else if (dst > src) { \
9809c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
9819c7779b64eacf264ee427b97ae0df8596b1960ccbart            SizeT n = len; \
9829c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  d = ((Addr)dst) + n; \
9839c7779b64eacf264ee427b97ae0df8596b1960ccbart            Addr  s = ((Addr)src) + n; \
9849c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
9859c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copying forwards. */ \
9869c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s^d) & WM) == 0) { \
9879c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* s and d have same UWord alignment. */ \
9889c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Back down to a UWord boundary. */ \
9899c7779b64eacf264ee427b97ae0df8596b1960ccbart               while ((s & WM) != 0 && n >= 1) \
9909c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
9919c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Copy UWords. */ \
9929c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= WS) \
9939c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
9949c7779b64eacf264ee427b97ae0df8596b1960ccbart               if (n == 0) \
9959c7779b64eacf264ee427b97ae0df8596b1960ccbart                  return dst; \
9969c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
9979c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (((s|d) & 1) == 0) { \
9989c7779b64eacf264ee427b97ae0df8596b1960ccbart               /* Both are 16-aligned; copy what we can thusly. */ \
9999c7779b64eacf264ee427b97ae0df8596b1960ccbart               while (n >= 2) \
10009c7779b64eacf264ee427b97ae0df8596b1960ccbart                  { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
10019c7779b64eacf264ee427b97ae0df8596b1960ccbart            } \
10029c7779b64eacf264ee427b97ae0df8596b1960ccbart            /* Copy leftovers, or everything if misaligned. */ \
10039c7779b64eacf264ee427b97ae0df8596b1960ccbart            while (n >= 1) \
10049c7779b64eacf264ee427b97ae0df8596b1960ccbart               { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
10059c7779b64eacf264ee427b97ae0df8596b1960ccbart            \
10069c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
10079c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10089c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10099c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
10109c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10119c7779b64eacf264ee427b97ae0df8596b1960ccbart
10129c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMMOVE(soname, fnname)  \
10139c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0)
10149c7779b64eacf264ee427b97ae0df8596b1960ccbart
10159c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCPY(soname, fnname) \
10169c7779b64eacf264ee427b97ae0df8596b1960ccbart   MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1)
10179c7779b64eacf264ee427b97ae0df8596b1960ccbart
10189c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10199c7779b64eacf264ee427b97ae0df8596b1960ccbart /* For older memcpy we have to use memmove-like semantics and skip
10209c7779b64eacf264ee427b97ae0df8596b1960ccbart    the overlap check; sigh; see #275284. */
10219c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
10229c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
10239c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpy) /* fallback case */
10249c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __GI_memcpy)
10259c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,    __memcpy_sse2)
10269c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD_SO_1,      memcpy) /* ld.so.1 */
10279c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LD64_SO_1,    memcpy) /* ld64.so.1 */
10289c7779b64eacf264ee427b97ae0df8596b1960ccbart /* icc9 blats these around all over the place.  Not only in the main
10299c7779b64eacf264ee427b97ae0df8596b1960ccbart    executable but various .so's.  They are highly tuned and read
10309c7779b64eacf264ee427b97ae0df8596b1960ccbart    memory beyond the source boundary (although work correctly and
10319c7779b64eacf264ee427b97ae0df8596b1960ccbart    never go across page boundaries), so give errors when run
10329c7779b64eacf264ee427b97ae0df8596b1960ccbart    natively, at least for misaligned source arg.  Just intercepting
10339c7779b64eacf264ee427b97ae0df8596b1960ccbart    in the exe only until we understand more about the problem.  See
10349c7779b64eacf264ee427b97ae0df8596b1960ccbart    http://bugs.kde.org/show_bug.cgi?id=139776
10359c7779b64eacf264ee427b97ae0df8596b1960ccbart */
10369c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(NONE, ZuintelZufastZumemcpy)
10379c7779b64eacf264ee427b97ae0df8596b1960ccbart
10389c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
10399c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
10409c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
10419c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
10429c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
10439c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCPY(VG_Z_LIBC_SONAME,  memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
10449c7779b64eacf264ee427b97ae0df8596b1960ccbart
10458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
10468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LIBC_SONAME,  memcpy)
1047ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes MEMCPY(VG_Z_LIBC_SONAME,  memcpyZPZa)
10488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCPY(VG_Z_LD_SO_1,      memcpy)
10498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
10509c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
10519c7779b64eacf264ee427b97ae0df8596b1960ccbart
10529c7779b64eacf264ee427b97ae0df8596b1960ccbart
10539c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memcmp ----------------------*/
10549c7779b64eacf264ee427b97ae0df8596b1960ccbart
10559c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMCMP(soname, fnname) \
10569c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10579c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n ); \
10589c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname)       \
10599c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const void *s1V, const void *s2V, SizeT n )  \
10609c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
1061094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WS = sizeof(UWord); /* 8 or 4 */ \
1062094b991ef067868dcaa5076d12d851e24eb33bbasewardj      const SizeT WM = WS - 1;        /* 7 or 3 */ \
106311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s1A = (Addr)s1V; \
106411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      Addr s2A = (Addr)s2V; \
106511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
106611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      if (((s1A | s2A) & WM) == 0) { \
106711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* Both areas are word aligned.  Skip over the */ \
106811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         /* equal prefix as fast as possible. */ \
106911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         while (n >= WS) { \
107011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w1 = *(UWord*)s1A; \
107111e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            UWord w2 = *(UWord*)s2A; \
107211e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            if (w1 != w2) break; \
107311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s1A += WS; \
107411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            s2A += WS; \
107511e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj            n -= WS; \
107611e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         } \
107711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      } \
107811e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      \
107911e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s1 = (const UChar*) s1A; \
108011e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj      const UChar* s2 = (const UChar*) s2A; \
10819c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
10829c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n != 0) { \
108311e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar a0 = s1[0]; \
108411e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         UChar b0 = s2[0]; \
10859c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1 += 1; \
10869c7779b64eacf264ee427b97ae0df8596b1960ccbart         s2 += 1; \
108711e20f70b6da76415ca57b8fc75a4ac8d6411e53sewardj         int res = ((int)a0) - ((int)b0); \
10889c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (res != 0) \
10899c7779b64eacf264ee427b97ae0df8596b1960ccbart            return res; \
10909c7779b64eacf264ee427b97ae0df8596b1960ccbart         n -= 1; \
10919c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
10929c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
10939c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
10949c7779b64eacf264ee427b97ae0df8596b1960ccbart
10959c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
10969c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, memcmp)
10979c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
10989c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
10999c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
11009c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LIBC_SONAME, bcmp)
11019c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMCMP(VG_Z_LD_SO_1,     bcmp)
11029c7779b64eacf264ee427b97ae0df8596b1960ccbart
11039c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11049090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1105aec49a463fd7c90ef190ff72318e50224e463e90sewardj  MEMCMP(libsystemZuplatformZddylib, _platform_memcmp)
1106aec49a463fd7c90ef190ff72318e50224e463e90sewardj# endif
11079c7779b64eacf264ee427b97ae0df8596b1960ccbart
11088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, memcmp)
11108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LIBC_SONAME, bcmp)
11118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMCMP(VG_Z_LD_SO_1,     memcmp)
11128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11139c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11149c7779b64eacf264ee427b97ae0df8596b1960ccbart
11159c7779b64eacf264ee427b97ae0df8596b1960ccbart
11169c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy ----------------------*/
11179c7779b64eacf264ee427b97ae0df8596b1960ccbart
11189c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Copy SRC to DEST, returning the address of the terminating '\0' in
11199c7779b64eacf264ee427b97ae0df8596b1960ccbart   DEST. (minor variant of strcpy) */
11209c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPCPY(soname, fnname) \
11219c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11229c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ); \
11239c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
11249c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src ) \
11259c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11269c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11279c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_orig = dst; \
11289c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11299c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
11309c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
11319c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11329c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
11339c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
11349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
11359c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
11369c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1,  \
11379c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
11389c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \
11399c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11409c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
11419c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11429c7779b64eacf264ee427b97ae0df8596b1960ccbart
11439c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11449c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11459c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __GI_stpcpy)
11469c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2)
11479c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LIBC_SONAME,          __stpcpy_sse2_unaligned)
11489c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_SO_2,        stpcpy)
11499c7779b64eacf264ee427b97ae0df8596b1960ccbart STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
11509c7779b64eacf264ee427b97ae0df8596b1960ccbart
11519c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
11529c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11539c7779b64eacf264ee427b97ae0df8596b1960ccbart //STPCPY(VG_Z_DYLD,                 stpcpy)
11549c7779b64eacf264ee427b97ae0df8596b1960ccbart
11558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
11568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STPCPY(VG_Z_LIBC_SONAME,          stpcpy)
11578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11589c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11599c7779b64eacf264ee427b97ae0df8596b1960ccbart
11609c7779b64eacf264ee427b97ae0df8596b1960ccbart
11619c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpncpy ----------------------*/
11629c7779b64eacf264ee427b97ae0df8596b1960ccbart
11639c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STPNCPY(soname, fnname) \
11649c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11659c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ); \
11669c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
11679c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( char* dst, const char* src, SizeT n ) \
11689c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
11699c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src_orig = src; \
11709c7779b64eacf264ee427b97ae0df8596b1960ccbart            HChar* dst_str  = dst; \
11719c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT m = 0; \
11729c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11739c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m   < n && *src) { m++; *dst++ = *src++; } \
11749c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
11759c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* but only m+1 bytes of src if terminator was found */ \
11769c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
11779c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
11789c7779b64eacf264ee427b97ae0df8596b1960ccbart      dst_str = dst; \
11799c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
11809c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
11819c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_str; \
11829c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
11839c7779b64eacf264ee427b97ae0df8596b1960ccbart
11849c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
11859c7779b64eacf264ee427b97ae0df8596b1960ccbart STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
11869c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
11879c7779b64eacf264ee427b97ae0df8596b1960ccbart
11889c7779b64eacf264ee427b97ae0df8596b1960ccbart
11899c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memset ----------------------*/
11909c7779b64eacf264ee427b97ae0df8596b1960ccbart
11919c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Why are we bothering to intercept this?  It seems entirely
11929c7779b64eacf264ee427b97ae0df8596b1960ccbart   pointless. */
11939c7779b64eacf264ee427b97ae0df8596b1960ccbart
11949c7779b64eacf264ee427b97ae0df8596b1960ccbart#define MEMSET(soname, fnname) \
1195ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
11969c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n); \
1197ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   void* VG_REPLACE_FUNCTION_EZZ(20210,soname,fnname) \
11989c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *s, Int c, SizeT n) \
11999c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12009c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (sizeof(void*) == 8) { \
12019c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr  a  = (Addr)s;   \
12029c7779b64eacf264ee427b97ae0df8596b1960ccbart         ULong c8 = (c & 0xFF); \
12039c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 8) | c8; \
12049c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 16) | c8; \
12059c7779b64eacf264ee427b97ae0df8596b1960ccbart         c8 = (c8 << 32) | c8; \
12069c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 7) != 0 && n >= 1) \
12079c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1208a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes         while (n >= 32) \
1209a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes            { *(ULong*)a = c8; a += 8; n -= 8;   \
1210a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(ULong*)a = c8; a += 8; n -= 8;   \
1211a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(ULong*)a = c8; a += 8; n -= 8;   \
1212a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(ULong*)a = c8; a += 8; n -= 8; } \
12139c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 8) \
12149c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(ULong*)a = c8; a += 8; n -= 8; } \
12159c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12169c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12179c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12189c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else { \
12199c7779b64eacf264ee427b97ae0df8596b1960ccbart         Addr a  = (Addr)s;   \
12209c7779b64eacf264ee427b97ae0df8596b1960ccbart         UInt c4 = (c & 0xFF); \
12219c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 8) | c4; \
12229c7779b64eacf264ee427b97ae0df8596b1960ccbart         c4 = (c4 << 16) | c4; \
12239c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ((a & 3) != 0 && n >= 1) \
12249c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
1225a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes         while (n >= 16) \
1226a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes            { *(UInt*)a = c4; a += 4; n -= 4;   \
1227a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(UInt*)a = c4; a += 4; n -= 4;   \
1228a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(UInt*)a = c4; a += 4; n -= 4;   \
1229a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes              *(UInt*)a = c4; a += 4; n -= 4; } \
12309c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 4) \
12319c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UInt*)a = c4; a += 4; n -= 4; } \
12329c7779b64eacf264ee427b97ae0df8596b1960ccbart         while (n >= 1) \
12339c7779b64eacf264ee427b97ae0df8596b1960ccbart            { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \
12349c7779b64eacf264ee427b97ae0df8596b1960ccbart         return s; \
12359c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12369c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
12379c7779b64eacf264ee427b97ae0df8596b1960ccbart
12389c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12399c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12409c7779b64eacf264ee427b97ae0df8596b1960ccbart
12419c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12429c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_LIBC_SONAME, memset)
12439c7779b64eacf264ee427b97ae0df8596b1960ccbart //MEMSET(VG_Z_DYLD,        memset)
12449c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMSET(VG_Z_LIBC_SONAME, memset)
12459c7779b64eacf264ee427b97ae0df8596b1960ccbart
12468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMSET(VG_Z_LIBC_SONAME, memset)
1248ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes MEMSET(VG_Z_LIBC_SONAME, memsetZPZa)
12498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12509c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12519c7779b64eacf264ee427b97ae0df8596b1960ccbart
12529c7779b64eacf264ee427b97ae0df8596b1960ccbart
12539c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- memmove ----------------------*/
12549c7779b64eacf264ee427b97ae0df8596b1960ccbart
12559c7779b64eacf264ee427b97ae0df8596b1960ccbart/* memmove -- use the MEMMOVE defn above. */
12569c7779b64eacf264ee427b97ae0df8596b1960ccbart
12579c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
12589c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12599c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove)
1260b97cf8e9a718e61a540e63001d4c9346773c630emjw /* See bug #349828 Override for ld64.so.1 like memcpy, because for some
1261b97cf8e9a718e61a540e63001d4c9346773c630emjw    arches MEMCPY_OK_FOR_FORWARD_MEMMOVE is set, which might cause memmove
1262b97cf8e9a718e61a540e63001d4c9346773c630emjw    to call memcpy.  */
1263b97cf8e9a718e61a540e63001d4c9346773c630emjw MEMMOVE(VG_Z_LD64_SO_1, memmove)
12649c7779b64eacf264ee427b97ae0df8596b1960ccbart
12659c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
12669c7779b64eacf264ee427b97ae0df8596b1960ccbart# if DARWIN_VERS <= DARWIN_10_6
12679c7779b64eacf264ee427b97ae0df8596b1960ccbart  MEMMOVE(VG_Z_LIBC_SONAME, memmove)
12689c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
12699c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
12709c7779b64eacf264ee427b97ae0df8596b1960ccbart MEMMOVE(VG_Z_LIBC_SONAME,  memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
12719090d2f691fd59c3a67c55e74f3c66c9c5671b01rhyskidd# if DARWIN_VERS >= DARWIN_10_9
1272312bcb109bfb6899086dda47b02a5436f26516d4sewardj  /* _platform_memmove$VARIANT$Ivybridge */
1273eb86ddab35602995b31767f72a2babb6a692c3f3sewardj  MEMMOVE(libsystemZuplatformZddylib, ZuplatformZumemmoveZDVARIANTZDIvybridge)
1274eb86ddab35602995b31767f72a2babb6a692c3f3sewardj# endif
12758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
12778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LIBC_SONAME, memmove)
1278ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes MEMMOVE(VG_Z_LIBC_SONAME, memmoveZPZa)
12798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MEMMOVE(VG_Z_LD_SO_1,     memmove)
12808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
12819c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
12829c7779b64eacf264ee427b97ae0df8596b1960ccbart
12839c7779b64eacf264ee427b97ae0df8596b1960ccbart
12849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- bcopy ----------------------*/
12859c7779b64eacf264ee427b97ae0df8596b1960ccbart
12869c7779b64eacf264ee427b97ae0df8596b1960ccbart#define BCOPY(soname, fnname) \
12879c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12889c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n); \
12899c7779b64eacf264ee427b97ae0df8596b1960ccbart   void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \
12909c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const void *srcV, void *dstV, SizeT n) \
12919c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
12929c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
12939c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV; \
12949c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
12959c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
12969c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
12979c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
12989c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
12999c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
13009c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
13019c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13029c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
13039c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13049c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13059c7779b64eacf264ee427b97ae0df8596b1960ccbart
13069c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13079c7779b64eacf264ee427b97ae0df8596b1960ccbart BCOPY(VG_Z_LIBC_SONAME, bcopy)
13089c7779b64eacf264ee427b97ae0df8596b1960ccbart
13099c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13109c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_LIBC_SONAME, bcopy)
13119c7779b64eacf264ee427b97ae0df8596b1960ccbart //BCOPY(VG_Z_DYLD,        bcopy)
13129c7779b64eacf264ee427b97ae0df8596b1960ccbart
13138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_darwin)
13148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj BCOPY(VG_Z_LIBC_SONAME, bcopy)
13158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13169c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13179c7779b64eacf264ee427b97ae0df8596b1960ccbart
13189c7779b64eacf264ee427b97ae0df8596b1960ccbart
13199c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memmove_chk --------------------*/
13209c7779b64eacf264ee427b97ae0df8596b1960ccbart
13219c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc 2.5 variant of memmove which checks the dest is big enough.
13229c7779b64eacf264ee427b97ae0df8596b1960ccbart   There is no specific part of glibc that this is copied from. */
13239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___MEMMOVE_CHK(soname, fnname) \
13249c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13259c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen); \
13269c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \
13279c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
13289c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
13299c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i; \
13309c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* dst = dstV;        \
13319c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* src = srcV; \
13329c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (destlen < n) \
13339c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
13349c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst < src) { \
13359c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13369c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[i] = src[i]; \
13379c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13389c7779b64eacf264ee427b97ae0df8596b1960ccbart      else  \
13399c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dst > src) { \
13409c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < n; i++) \
13419c7779b64eacf264ee427b97ae0df8596b1960ccbart            dst[n-i-1] = src[n-i-1]; \
13429c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13439c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
13449c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
13459c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
13469c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memmove_chk: buffer overflow detected ***: " \
13479c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
134877ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
13499c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
13509c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
13519c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13529c7779b64eacf264ee427b97ae0df8596b1960ccbart
13539c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13549c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk)
13559c7779b64eacf264ee427b97ae0df8596b1960ccbart
13569c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13579c7779b64eacf264ee427b97ae0df8596b1960ccbart
13588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13609c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13619c7779b64eacf264ee427b97ae0df8596b1960ccbart
13629c7779b64eacf264ee427b97ae0df8596b1960ccbart
13639c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- strchrnul --------------------*/
13649c7779b64eacf264ee427b97ae0df8596b1960ccbart
13659c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S or the final NUL byte.  */
13669c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_STRCHRNUL(soname, fnname) \
13679c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13689c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in); \
13699c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \
13709c7779b64eacf264ee427b97ae0df8596b1960ccbart            (const char* s, int c_in) \
13719c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
137270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      HChar c = (HChar) c_in; \
137370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const HChar* char_ptr = s; \
13749c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
137570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == 0) return CONST_CAST(HChar *,char_ptr);  \
137670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(HChar *,char_ptr);  \
13779c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
13789c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
13799c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
13809c7779b64eacf264ee427b97ae0df8596b1960ccbart
13819c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
13829c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul)
13839c7779b64eacf264ee427b97ae0df8596b1960ccbart
13849c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
13859c7779b64eacf264ee427b97ae0df8596b1960ccbart
13868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
13878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
13889c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
13899c7779b64eacf264ee427b97ae0df8596b1960ccbart
13909c7779b64eacf264ee427b97ae0df8596b1960ccbart
13919c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- rawmemchr ----------------------*/
13929c7779b64eacf264ee427b97ae0df8596b1960ccbart
13939c7779b64eacf264ee427b97ae0df8596b1960ccbart/* Find the first occurrence of C in S.  */
13949c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC232_RAWMEMCHR(soname, fnname) \
13951ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13961ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in); \
13971ef205bfce335a8d54b6b188e83254b92c52d7adflorian   void* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \
13981ef205bfce335a8d54b6b188e83254b92c52d7adflorian            (const void* s, int c_in) \
13999c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14001ef205bfce335a8d54b6b188e83254b92c52d7adflorian      UChar c = (UChar) c_in; \
14011ef205bfce335a8d54b6b188e83254b92c52d7adflorian      const UChar* char_ptr = s; \
14029c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
140370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*char_ptr == c) return CONST_CAST(void *,char_ptr); \
14049c7779b64eacf264ee427b97ae0df8596b1960ccbart         char_ptr++; \
14059c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
14069c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14079c7779b64eacf264ee427b97ae0df8596b1960ccbart
14089c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined (VGO_linux)
14099c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
14109c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
14119c7779b64eacf264ee427b97ae0df8596b1960ccbart
14129c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14139c7779b64eacf264ee427b97ae0df8596b1960ccbart
14148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14169c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14179c7779b64eacf264ee427b97ae0df8596b1960ccbart
14189c7779b64eacf264ee427b97ae0df8596b1960ccbart
14199c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcpy_chk ----------------------*/
14209c7779b64eacf264ee427b97ae0df8596b1960ccbart
14219c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of strcpy that checks the dest is big enough.
14229c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-strcpy_chk.c. */
14239c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STRCPY_CHK(soname,fnname) \
14249c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14259c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14269c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \
14279c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14289c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14299c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar* ret = dst; \
14309c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14319c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14329c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14339c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14349c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14359c7779b64eacf264ee427b97ae0df8596b1960ccbart      return ret; \
14369c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14379c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14389c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** strcpy_chk: buffer overflow detected ***: " \
14399c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
144077ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
14419c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14429c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14439c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14449c7779b64eacf264ee427b97ae0df8596b1960ccbart
14459c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14469c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk)
14479c7779b64eacf264ee427b97ae0df8596b1960ccbart
14489c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14499c7779b64eacf264ee427b97ae0df8596b1960ccbart
14508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14529c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14539c7779b64eacf264ee427b97ae0df8596b1960ccbart
14549c7779b64eacf264ee427b97ae0df8596b1960ccbart
14559c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- stpcpy_chk ----------------------*/
14569c7779b64eacf264ee427b97ae0df8596b1960ccbart
14579c7779b64eacf264ee427b97ae0df8596b1960ccbart/* glibc variant of stpcpy that checks the dest is big enough.
14589c7779b64eacf264ee427b97ae0df8596b1960ccbart   Copied from glibc-2.5/debug/test-stpcpy_chk.c. */
14599c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25___STPCPY_CHK(soname,fnname) \
14609c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14619c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len); \
14629c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \
14639c7779b64eacf264ee427b97ae0df8596b1960ccbart            (char* dst, const char* src, SizeT len) \
14649c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14659c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (! len) \
14669c7779b64eacf264ee427b97ae0df8596b1960ccbart         goto badness; \
14679c7779b64eacf264ee427b97ae0df8596b1960ccbart      while ((*dst++ = *src++) != '\0') \
14689c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (--len == 0) \
14699c7779b64eacf264ee427b97ae0df8596b1960ccbart            goto badness; \
14709c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst - 1; \
14719c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
14729c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
14739c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** stpcpy_chk: buffer overflow detected ***: " \
14749c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
147577ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
14769c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
14779c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
14789c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
14799c7779b64eacf264ee427b97ae0df8596b1960ccbart
14809c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
14819c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk)
14829c7779b64eacf264ee427b97ae0df8596b1960ccbart
14839c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
14849c7779b64eacf264ee427b97ae0df8596b1960ccbart
14858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
14868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14879c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
14889c7779b64eacf264ee427b97ae0df8596b1960ccbart
14899c7779b64eacf264ee427b97ae0df8596b1960ccbart
14909c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- mempcpy ----------------------*/
14919c7779b64eacf264ee427b97ae0df8596b1960ccbart
14929c7779b64eacf264ee427b97ae0df8596b1960ccbart/* mempcpy */
14939c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC25_MEMPCPY(soname, fnname) \
14949c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14959c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ); \
14969c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \
14979c7779b64eacf264ee427b97ae0df8596b1960ccbart            ( void *dst, const void *src, SizeT len ) \
14989c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
14999c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT len_saved = len; \
15009c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15019c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
15029c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
15039c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15049c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
15059c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \
15069c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15079c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
150809041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = (char *)dst + len - 1; \
150909041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = (const char *)src + len - 1; \
15109c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15119c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
15129c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15139c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
151409041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register HChar *d = dst; \
151509041e493017aee3d5c52fb2e1dc6db064518e5cflorian         register const HChar *s = src; \
15169c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15179c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
15189c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15199c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15209c7779b64eacf264ee427b97ae0df8596b1960ccbart      return (void*)( ((char*)dst) + len_saved ); \
15219c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15229c7779b64eacf264ee427b97ae0df8596b1960ccbart
15239c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15249c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
1525a9176d9640606a083a6e9b97515b15f631de5059mjw GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, __GI_mempcpy)
15269c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC25_MEMPCPY(VG_Z_LD_SO_1,     mempcpy) /* ld.so.1 */
1527f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_SO_3, mempcpy) /* ld-linux.so.3 */
1528f2d866396dd99ebc9247221282916be9efd4fb4abart GLIBC25_MEMPCPY(VG_Z_LD_LINUX_X86_64_SO_2, mempcpy) /* ld-linux-x86-64.so.2 */
15299c7779b64eacf264ee427b97ae0df8596b1960ccbart
15309c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15319c7779b64eacf264ee427b97ae0df8596b1960ccbart //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
15329c7779b64eacf264ee427b97ae0df8596b1960ccbart
15338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15359c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15369c7779b64eacf264ee427b97ae0df8596b1960ccbart
15379c7779b64eacf264ee427b97ae0df8596b1960ccbart
15389c7779b64eacf264ee427b97ae0df8596b1960ccbart/*-------------------- memcpy_chk --------------------*/
15399c7779b64eacf264ee427b97ae0df8596b1960ccbart
15409c7779b64eacf264ee427b97ae0df8596b1960ccbart#define GLIBC26___MEMCPY_CHK(soname, fnname) \
15419c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15429c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ); \
15439c7779b64eacf264ee427b97ae0df8596b1960ccbart   void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \
15449c7779b64eacf264ee427b97ae0df8596b1960ccbart            (void* dst, const void* src, SizeT len, SizeT dstlen ) \
15459c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15469c7779b64eacf264ee427b97ae0df8596b1960ccbart      register HChar *d; \
15479c7779b64eacf264ee427b97ae0df8596b1960ccbart      register const HChar *s; \
15489c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15499c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (dstlen < len) goto badness; \
15509c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15519c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (len == 0) \
15529c7779b64eacf264ee427b97ae0df8596b1960ccbart         return dst; \
15539c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15549c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst, src, len, len)) \
15559c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \
15569c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
15579c7779b64eacf264ee427b97ae0df8596b1960ccbart      if ( dst > src ) { \
15589c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst + len - 1; \
15599c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src + len - 1; \
15609c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15619c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d-- = *s--; \
15629c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15639c7779b64eacf264ee427b97ae0df8596b1960ccbart      } else if ( dst < src ) { \
15649c7779b64eacf264ee427b97ae0df8596b1960ccbart         d = (HChar *)dst; \
15659c7779b64eacf264ee427b97ae0df8596b1960ccbart         s = (const HChar *)src; \
15669c7779b64eacf264ee427b97ae0df8596b1960ccbart         while ( len-- ) { \
15679c7779b64eacf264ee427b97ae0df8596b1960ccbart            *d++ = *s++; \
15689c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
15699c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
15709c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst; \
15719c7779b64eacf264ee427b97ae0df8596b1960ccbart     badness: \
15729c7779b64eacf264ee427b97ae0df8596b1960ccbart      VALGRIND_PRINTF_BACKTRACE( \
15739c7779b64eacf264ee427b97ae0df8596b1960ccbart         "*** memcpy_chk: buffer overflow detected ***: " \
15749c7779b64eacf264ee427b97ae0df8596b1960ccbart         "program terminated\n"); \
157577ae9992c9acc09fdab63e1bc951bea61e719b1eflorian     my_exit(1); \
15769c7779b64eacf264ee427b97ae0df8596b1960ccbart     /*NOTREACHED*/ \
15779c7779b64eacf264ee427b97ae0df8596b1960ccbart     return NULL; \
15789c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
15799c7779b64eacf264ee427b97ae0df8596b1960ccbart
15809c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
15819c7779b64eacf264ee427b97ae0df8596b1960ccbart GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
15829c7779b64eacf264ee427b97ae0df8596b1960ccbart
15839c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
15849c7779b64eacf264ee427b97ae0df8596b1960ccbart
15858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
15868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
15879c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
15889c7779b64eacf264ee427b97ae0df8596b1960ccbart
15899c7779b64eacf264ee427b97ae0df8596b1960ccbart
15909c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strstr ----------------------*/
15919c7779b64eacf264ee427b97ae0df8596b1960ccbart
15929c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSTR(soname, fnname) \
15939c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15949c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
15959c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
15969c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
15979c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
15989c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
15999c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle; \
16009c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16019c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
16029c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
16039c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
16049c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16059c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
160670a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);         \
16079c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16089c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
16099c7779b64eacf264ee427b97ae0df8596b1960ccbart      HChar n0 = n[0]; \
16109c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16119c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16129c7779b64eacf264ee427b97ae0df8596b1960ccbart         const HChar hh = *h; \
16139c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
16149c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
16159c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16169c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16179c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
16189c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (n[i] != h[i]) \
16199c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
16209c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16219c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
16229c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
162370a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);          \
16249c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
16259c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
16269c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16279c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16289c7779b64eacf264ee427b97ae0df8596b1960ccbart
16299c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16309c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          strstr)
16319c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse2)
16329c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSTR(VG_Z_LIBC_SONAME,          __strstr_sse42)
16339c7779b64eacf264ee427b97ae0df8596b1960ccbart
16349c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16359c7779b64eacf264ee427b97ae0df8596b1960ccbart
16368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSTR(VG_Z_LIBC_SONAME,          strstr)
16388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16399c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16409c7779b64eacf264ee427b97ae0df8596b1960ccbart
16419c7779b64eacf264ee427b97ae0df8596b1960ccbart
16429c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strpbrk ----------------------*/
16439c7779b64eacf264ee427b97ae0df8596b1960ccbart
16449c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRPBRK(soname, fnname) \
16459c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16469c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
16479c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \
16489c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
16499c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16509c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16519c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* accept = acceptV; \
16529c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16539c7779b64eacf264ee427b97ae0df8596b1960ccbart      /*  find the length of 'accept', not including terminating zero */ \
16549c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
16559c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
16569c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16579c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, fail immediately. */ \
16589c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return NULL; \
16599c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16609c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nacc >= 1); */ \
16619c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
16629c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
16639c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
16649c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
16659c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
16669c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
16679c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
166870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian              return CONST_CAST(HChar *,s);       \
16699c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
16709c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
16719c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
16729c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16739c7779b64eacf264ee427b97ae0df8596b1960ccbart      return NULL; \
16749c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
16759c7779b64eacf264ee427b97ae0df8596b1960ccbart
16769c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
16779c7779b64eacf264ee427b97ae0df8596b1960ccbart STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16789c7779b64eacf264ee427b97ae0df8596b1960ccbart
16799c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
16809c7779b64eacf264ee427b97ae0df8596b1960ccbart
16818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
16828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRPBRK(VG_Z_LIBC_SONAME,          strpbrk)
16838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
16849c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
16859c7779b64eacf264ee427b97ae0df8596b1960ccbart
16869c7779b64eacf264ee427b97ae0df8596b1960ccbart
16879c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcspn ----------------------*/
16889c7779b64eacf264ee427b97ae0df8596b1960ccbart
16899c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCSPN(soname, fnname) \
16909c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16919c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV); \
16929c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \
16939c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* rejectV) \
16949c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
16959c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* s = sV; \
16969c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* reject = rejectV; \
16979c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
16989c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'reject', not including terminating zero */ \
16999c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nrej = 0; \
17009c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (reject[nrej]) nrej++; \
17019c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17029c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
17039c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17049c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17059c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
17069c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
17079c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17089c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nrej; i++) { \
17099c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == reject[i]) \
17109c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17119c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17129c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nrej); */ \
17139c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i < nrej) \
17149c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17159c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
17169c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
17179c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17189c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17199c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17209c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17219c7779b64eacf264ee427b97ae0df8596b1960ccbart
17229c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17239c7779b64eacf264ee427b97ae0df8596b1960ccbart STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
1724ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes STRCSPN(VG_Z_LIBC_SONAME,          __GI_strcspn)
17259c7779b64eacf264ee427b97ae0df8596b1960ccbart
17269c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17279c7779b64eacf264ee427b97ae0df8596b1960ccbart
17288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRCSPN(VG_Z_LIBC_SONAME,          strcspn)
17308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17319c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17329c7779b64eacf264ee427b97ae0df8596b1960ccbart
17339c7779b64eacf264ee427b97ae0df8596b1960ccbart
17349c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strspn ----------------------*/
17359c7779b64eacf264ee427b97ae0df8596b1960ccbart
17369c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRSPN(soname, fnname) \
17379c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17389c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV); \
17399c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \
17409c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* sV, const char* acceptV) \
17419c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17429c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* s = (const UChar *)sV;        \
17439c7779b64eacf264ee427b97ae0df8596b1960ccbart      const UChar* accept = (const UChar *)acceptV;     \
17449c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17459c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of 'accept', not including terminating zero */ \
17469c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nacc = 0; \
17479c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (accept[nacc]) nacc++; \
17489c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (nacc == 0) return 0; \
17499c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17509c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord len = 0; \
17519c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
17529c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
17539c7779b64eacf264ee427b97ae0df8596b1960ccbart         HChar sc = *s; \
17549c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (sc == 0) \
17559c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17569c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nacc; i++) { \
17579c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (sc == accept[i]) \
17589c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
17599c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
17609c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nacc); */ \
17619c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nacc) \
17629c7779b64eacf264ee427b97ae0df8596b1960ccbart            break; \
17639c7779b64eacf264ee427b97ae0df8596b1960ccbart         s++; \
17649c7779b64eacf264ee427b97ae0df8596b1960ccbart         len++; \
17659c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
17669c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17679c7779b64eacf264ee427b97ae0df8596b1960ccbart      return len; \
17689c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
17699c7779b64eacf264ee427b97ae0df8596b1960ccbart
17709c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
17719c7779b64eacf264ee427b97ae0df8596b1960ccbart STRSPN(VG_Z_LIBC_SONAME,          strspn)
17729c7779b64eacf264ee427b97ae0df8596b1960ccbart
17739c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
17749c7779b64eacf264ee427b97ae0df8596b1960ccbart
17758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
17768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj STRSPN(VG_Z_LIBC_SONAME,          strspn)
17778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
17789c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
17799c7779b64eacf264ee427b97ae0df8596b1960ccbart
17809c7779b64eacf264ee427b97ae0df8596b1960ccbart
17819c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- strcasestr ----------------------*/
17829c7779b64eacf264ee427b97ae0df8596b1960ccbart
17839c7779b64eacf264ee427b97ae0df8596b1960ccbart#define STRCASESTR(soname, fnname) \
17849c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17859c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle); \
17869c7779b64eacf264ee427b97ae0df8596b1960ccbart   char* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \
17879c7779b64eacf264ee427b97ae0df8596b1960ccbart         (const char* haystack, const char* needle) \
17889c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
17899c7779b64eacf264ee427b97ae0df8596b1960ccbart      extern int tolower(int); \
17909c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* h = haystack; \
17919c7779b64eacf264ee427b97ae0df8596b1960ccbart      const HChar* n = needle;   \
17929c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17939c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* find the length of n, not including terminating zero */ \
17949c7779b64eacf264ee427b97ae0df8596b1960ccbart      UWord nlen = 0; \
17959c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (n[nlen]) nlen++; \
17969c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
17979c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* if n is the empty string, match immediately. */ \
179870a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      if (nlen == 0) return CONST_CAST(HChar *,h);       \
17999c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18009c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* assert(nlen >= 1); */ \
18019c7779b64eacf264ee427b97ae0df8596b1960ccbart      UChar n0 = tolower(n[0]);                 \
18029c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
18039c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (1) { \
18049c7779b64eacf264ee427b97ae0df8596b1960ccbart         UChar hh = tolower(*h);    \
18059c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh == 0) return NULL; \
18069c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (hh != n0) { h++; continue; } \
18079c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
18089c7779b64eacf264ee427b97ae0df8596b1960ccbart         UWord i; \
18099c7779b64eacf264ee427b97ae0df8596b1960ccbart         for (i = 0; i < nlen; i++) { \
18109c7779b64eacf264ee427b97ae0df8596b1960ccbart            if (tolower(n[i]) != tolower(h[i]))  \
18119c7779b64eacf264ee427b97ae0df8596b1960ccbart               break; \
18129c7779b64eacf264ee427b97ae0df8596b1960ccbart         } \
18139c7779b64eacf264ee427b97ae0df8596b1960ccbart         /* assert(i >= 0 && i <= nlen); */ \
18149c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (i == nlen) \
181570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian           return CONST_CAST(HChar *,h);    \
18169c7779b64eacf264ee427b97ae0df8596b1960ccbart         \
18179c7779b64eacf264ee427b97ae0df8596b1960ccbart         h++; \
18189c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18199c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18209c7779b64eacf264ee427b97ae0df8596b1960ccbart
18219c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
182226ed419d60369d0545510eba0832566e24452e1esewardj# if !defined(VGPV_arm_linux_android) \
182326ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_x86_linux_android) \
182426ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_mips32_linux_android) \
182526ed419d60369d0545510eba0832566e24452e1esewardj     && !defined(VGPV_arm64_linux_android)
18269c7779b64eacf264ee427b97ae0df8596b1960ccbart  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18279c7779b64eacf264ee427b97ae0df8596b1960ccbart# endif
18289c7779b64eacf264ee427b97ae0df8596b1960ccbart
18299c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18309c7779b64eacf264ee427b97ae0df8596b1960ccbart
18318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj  STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
18338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18349c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18359c7779b64eacf264ee427b97ae0df8596b1960ccbart
18369c7779b64eacf264ee427b97ae0df8596b1960ccbart
18379c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcslen ----------------------*/
18389c7779b64eacf264ee427b97ae0df8596b1960ccbart
18399c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strlen.  Unfortunately
18409c7779b64eacf264ee427b97ae0df8596b1960ccbart// we don't have wchar_t available here, but it looks like
18419c7779b64eacf264ee427b97ae0df8596b1960ccbart// a 32 bit int on Linux.  I don't know if that is also
18429c7779b64eacf264ee427b97ae0df8596b1960ccbart// valid on MacOSX.
18439c7779b64eacf264ee427b97ae0df8596b1960ccbart
18449c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSLEN(soname, fnname) \
18459c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18469c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str ); \
18479c7779b64eacf264ee427b97ae0df8596b1960ccbart   SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \
18489c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( const UInt* str )  \
18499c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18509c7779b64eacf264ee427b97ae0df8596b1960ccbart      SizeT i = 0; \
18519c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (str[i] != 0) i++; \
18529c7779b64eacf264ee427b97ae0df8596b1960ccbart      return i; \
18539c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18549c7779b64eacf264ee427b97ae0df8596b1960ccbart
18559c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18569c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18579c7779b64eacf264ee427b97ae0df8596b1960ccbart
18589c7779b64eacf264ee427b97ae0df8596b1960ccbart#elif defined(VGO_darwin)
18599c7779b64eacf264ee427b97ae0df8596b1960ccbart
18608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGO_solaris)
18618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj WCSLEN(VG_Z_LIBC_SONAME,          wcslen)
18628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
18639c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18649c7779b64eacf264ee427b97ae0df8596b1960ccbart
18659c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscmp ----------------------*/
18669c7779b64eacf264ee427b97ae0df8596b1960ccbart
18679c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcmp.  We don't
18689c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
18699c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide and wcscmp uses signed
18709c7779b64eacf264ee427b97ae0df8596b1960ccbart// comparison, not unsigned as in strcmp function.
18719c7779b64eacf264ee427b97ae0df8596b1960ccbart
18729c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCMP(soname, fnname) \
18739c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18749c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ); \
18759c7779b64eacf264ee427b97ae0df8596b1960ccbart   int VG_REPLACE_FUNCTION_EZU(20380,soname,fnname) \
18769c7779b64eacf264ee427b97ae0df8596b1960ccbart          ( const Int* s1, const Int* s2 ) \
18779c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
18789c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c1; \
18799c7779b64eacf264ee427b97ae0df8596b1960ccbart      register Int c2; \
18809c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
18819c7779b64eacf264ee427b97ae0df8596b1960ccbart         c1 = *s1; \
18829c7779b64eacf264ee427b97ae0df8596b1960ccbart         c2 = *s2; \
18839c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 != c2) break; \
18849c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (c1 == 0) break; \
18859c7779b64eacf264ee427b97ae0df8596b1960ccbart         s1++; s2++; \
18869c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
18879c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 < c2) return -1; \
18889c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (c1 > c2) return 1; \
18899c7779b64eacf264ee427b97ae0df8596b1960ccbart      return 0; \
18909c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
18919c7779b64eacf264ee427b97ae0df8596b1960ccbart
18929c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
18939c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCMP(VG_Z_LIBC_SONAME,          wcscmp)
18949c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
18959c7779b64eacf264ee427b97ae0df8596b1960ccbart
18969c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcscpy ----------------------*/
18979c7779b64eacf264ee427b97ae0df8596b1960ccbart
18989c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strcpy.  We don't
18999c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19009c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19019c7779b64eacf264ee427b97ae0df8596b1960ccbart
19029c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSCPY(soname, fnname) \
19039c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
19049c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ); \
19059c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20390,soname,fnname) \
19069c7779b64eacf264ee427b97ae0df8596b1960ccbart      ( Int* dst, const Int* src ) \
19079c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
19089c7779b64eacf264ee427b97ae0df8596b1960ccbart      const Int* src_orig = src; \
19099c7779b64eacf264ee427b97ae0df8596b1960ccbart            Int* dst_orig = dst; \
19109c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
19119c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (*src) *dst++ = *src++; \
19129c7779b64eacf264ee427b97ae0df8596b1960ccbart      *dst = 0; \
19139c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
19149c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* This checks for overlap after copying, unavoidable without */ \
19159c7779b64eacf264ee427b97ae0df8596b1960ccbart      /* pre-counting length... should be ok */ \
19169c7779b64eacf264ee427b97ae0df8596b1960ccbart      if (is_overlap(dst_orig,  \
19179c7779b64eacf264ee427b97ae0df8596b1960ccbart                     src_orig,  \
19189c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)dst-(Addr)dst_orig+1, \
19199c7779b64eacf264ee427b97ae0df8596b1960ccbart                     (Addr)src-(Addr)src_orig+1)) \
19209c7779b64eacf264ee427b97ae0df8596b1960ccbart         RECORD_OVERLAP_ERROR("wcscpy", dst_orig, src_orig, 0); \
19219c7779b64eacf264ee427b97ae0df8596b1960ccbart      \
19229c7779b64eacf264ee427b97ae0df8596b1960ccbart      return dst_orig; \
19239c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19249c7779b64eacf264ee427b97ae0df8596b1960ccbart
19259c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19269c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCPY(VG_Z_LIBC_SONAME, wcscpy)
19279c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19289c7779b64eacf264ee427b97ae0df8596b1960ccbart
19299c7779b64eacf264ee427b97ae0df8596b1960ccbart
19309c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcschr ----------------------*/
19319c7779b64eacf264ee427b97ae0df8596b1960ccbart
19329c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strchr.  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 WCSCHR(soname, fnname) \
19379c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ); \
19389c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20400,soname,fnname) ( const Int* s, Int c ) \
19399c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
194070a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
19419c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
194270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == c) return CONST_CAST(Int *,p);  \
19439c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == 0) return NULL; \
19449c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19459c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19469c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19479c7779b64eacf264ee427b97ae0df8596b1960ccbart
19489c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19499c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSCHR(VG_Z_LIBC_SONAME,          wcschr)
19509c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19519c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- wcsrchr ----------------------*/
19529c7779b64eacf264ee427b97ae0df8596b1960ccbart
19539c7779b64eacf264ee427b97ae0df8596b1960ccbart// This is a wchar_t equivalent to strrchr.  We don't
19549c7779b64eacf264ee427b97ae0df8596b1960ccbart// have wchar_t available here, but in the GNU C Library
19559c7779b64eacf264ee427b97ae0df8596b1960ccbart// wchar_t is always 32 bits wide.
19569c7779b64eacf264ee427b97ae0df8596b1960ccbart
19579c7779b64eacf264ee427b97ae0df8596b1960ccbart#define WCSRCHR(soname, fnname) \
19589c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ); \
19599c7779b64eacf264ee427b97ae0df8596b1960ccbart   Int* VG_REPLACE_FUNCTION_EZU(20410,soname,fnname)( const Int* s, Int c ) \
19609c7779b64eacf264ee427b97ae0df8596b1960ccbart   { \
196170a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* p = s; \
196270a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian      const Int* last = NULL; \
19639c7779b64eacf264ee427b97ae0df8596b1960ccbart      while (True) { \
19649c7779b64eacf264ee427b97ae0df8596b1960ccbart         if (*p == c) last = p; \
196570a5de1d6c1a5c74b91b564b0ead8ae8a460173cflorian         if (*p == 0) return CONST_CAST(Int *,last);  \
19669c7779b64eacf264ee427b97ae0df8596b1960ccbart         p++; \
19679c7779b64eacf264ee427b97ae0df8596b1960ccbart      } \
19689c7779b64eacf264ee427b97ae0df8596b1960ccbart   }
19699c7779b64eacf264ee427b97ae0df8596b1960ccbart
19709c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19719c7779b64eacf264ee427b97ae0df8596b1960ccbart WCSRCHR(VG_Z_LIBC_SONAME, wcsrchr)
19729c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif
19739c7779b64eacf264ee427b97ae0df8596b1960ccbart
19749c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19759c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- Improve definedness checking of process environment  ---*/
19769c7779b64eacf264ee427b97ae0df8596b1960ccbart/*------------------------------------------------------------*/
19779c7779b64eacf264ee427b97ae0df8596b1960ccbart
19789c7779b64eacf264ee427b97ae0df8596b1960ccbart#if defined(VGO_linux)
19799c7779b64eacf264ee427b97ae0df8596b1960ccbart
19809c7779b64eacf264ee427b97ae0df8596b1960ccbart/* If these wind up getting generated via a macro, so that multiple
19819c7779b64eacf264ee427b97ae0df8596b1960ccbart   versions of each function exist (as above), use the _EZU variants
19829c7779b64eacf264ee427b97ae0df8596b1960ccbart   to assign equivalance class tags. */
19839c7779b64eacf264ee427b97ae0df8596b1960ccbart
19849c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- putenv ----------------------*/
19859c7779b64eacf264ee427b97ae0df8596b1960ccbart
19869c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string);
19879c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string)
19889c7779b64eacf264ee427b97ae0df8596b1960ccbart{
19899c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
19909c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
19919c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = string;
19929c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
19939c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
19949c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
19959c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
19969c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
19979c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
19989c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, string);
19999c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20009c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20019c7779b64eacf264ee427b97ae0df8596b1960ccbart
20029c7779b64eacf264ee427b97ae0df8596b1960ccbart
20039c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- unsetenv ----------------------*/
20049c7779b64eacf264ee427b97ae0df8596b1960ccbart
20059c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name);
20069c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name)
20079c7779b64eacf264ee427b97ae0df8596b1960ccbart{
20089c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
20099c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
20109c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p = name;
20119c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
20129c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
20139c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
20149c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (p)
20159c7779b64eacf264ee427b97ae0df8596b1960ccbart        while (*p++)
20169c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20179c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_W(result, fn, name);
20189c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20199c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20209c7779b64eacf264ee427b97ae0df8596b1960ccbart
20219c7779b64eacf264ee427b97ae0df8596b1960ccbart
20229c7779b64eacf264ee427b97ae0df8596b1960ccbart/*---------------------- setenv ----------------------*/
20239c7779b64eacf264ee427b97ae0df8596b1960ccbart
20249c7779b64eacf264ee427b97ae0df8596b1960ccbart/* setenv */
20259c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20269c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite);
20279c7779b64eacf264ee427b97ae0df8596b1960ccbartint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv)
20289c7779b64eacf264ee427b97ae0df8596b1960ccbart    (const char* name, const char* value, int overwrite)
20299c7779b64eacf264ee427b97ae0df8596b1960ccbart{
20309c7779b64eacf264ee427b97ae0df8596b1960ccbart    OrigFn fn;
20319c7779b64eacf264ee427b97ae0df8596b1960ccbart    Word result;
20329c7779b64eacf264ee427b97ae0df8596b1960ccbart    const HChar* p;
20339c7779b64eacf264ee427b97ae0df8596b1960ccbart    VALGRIND_GET_ORIG_FN(fn);
20349c7779b64eacf264ee427b97ae0df8596b1960ccbart    /* Now by walking over the string we magically produce
20359c7779b64eacf264ee427b97ae0df8596b1960ccbart       traces when hitting undefined memory. */
20369c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (name)
20379c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = name; *p; p++)
20389c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20399c7779b64eacf264ee427b97ae0df8596b1960ccbart    if (value)
20409c7779b64eacf264ee427b97ae0df8596b1960ccbart        for (p = value; *p; p++)
20419c7779b64eacf264ee427b97ae0df8596b1960ccbart            __asm__ __volatile__("" ::: "memory");
20429c7779b64eacf264ee427b97ae0df8596b1960ccbart    (void) VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite);
20439c7779b64eacf264ee427b97ae0df8596b1960ccbart    CALL_FN_W_WWW(result, fn, name, value, overwrite);
20449c7779b64eacf264ee427b97ae0df8596b1960ccbart    return result;
20459c7779b64eacf264ee427b97ae0df8596b1960ccbart}
20469c7779b64eacf264ee427b97ae0df8596b1960ccbart
20479c7779b64eacf264ee427b97ae0df8596b1960ccbart#endif /* defined(VGO_linux) */
20489c7779b64eacf264ee427b97ae0df8596b1960ccbart
20499c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
20509c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--- end                                                          ---*/
20519c7779b64eacf264ee427b97ae0df8596b1960ccbart/*--------------------------------------------------------------------*/
2052