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