1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- simulated CPU. ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- mc_replace_strmem.c ---*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of MemCheck, a heavyweight Valgrind tool for 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown detecting memory errors. 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2000-2012 Julian Seward 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_basics.h" 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_tool_poolalloc.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_hashtable.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_redir.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_tooliface.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "valgrind.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "mc_include.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "memcheck.h" 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We have our own versions of these functions for two reasons: 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (a) it allows us to do overlap checking 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (b) some of the normal versions are hyper-optimised, which fools 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memcheck and cause spurious value warnings. Our versions are 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simpler. 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note that overenthusiastic use of PLT bypassing by the glibc people also 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown means that we need to patch multiple versions of some of the functions to 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown our own implementations. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown THEY RUN ON THE SIMD CPU! 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Assignment of behavioural equivalence class tags: 2NNNP is intended 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to be reserved for Memcheck. Current usage: 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20010 STRRCHR 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20020 STRCHR 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20030 STRCAT 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20040 STRNCAT 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20050 STRLCAT 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20060 STRNLEN 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20070 STRLEN 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20080 STRCPY 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20090 STRNCPY 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20100 STRLCPY 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20110 STRNCMP 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20120 STRCASECMP 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20130 STRNCASECMP 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20140 STRCASECMP_L 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20150 STRNCASECMP_L 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20160 STRCMP 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20170 MEMCHR 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20180 MEMCPY if there's a conflict between memcpy and 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20181 MEMMOVE memmove, prefer memmove 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20190 MEMCMP 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20200 STPCPY 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20210 MEMSET 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2022P unused (was previously MEMMOVE) 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20230 BCOPY 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20240 GLIBC25___MEMMOVE_CHK 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20250 GLIBC232_STRCHRNUL 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20260 GLIBC232_RAWMEMCHR 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20270 GLIBC25___STRCPY_CHK 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20280 GLIBC25___STPCPY_CHK 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20290 GLIBC25_MEMPCPY 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20300 GLIBC26___MEMCPY_CHK 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20310 STRSTR 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20320 STRPBRK 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20330 STRCSPN 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20340 STRSPN 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20350 STRCASESTR 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 20360 MEMRCHR 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 20370 WCSLEN 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Figure out if [dst .. dst+dstlen-1] overlaps with 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [src .. src+srclen-1]. 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We assume that the address ranges do not wrap around 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (which is safe since on Linux addresses >= 0xC0000000 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are not accessible and the program will segfault in this 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown circumstance, presumably). 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen ) 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr loS, hiS, loD, hiD; 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dstlen == 0 || srclen == 0) 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loS = (Addr)src; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loD = (Addr)dst; 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hiS = loS + srclen - 1; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hiD = loD + dstlen - 1; 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */ 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (loS < loD) { 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return !(hiS < loD); 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (loD < loS) { 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return !(hiD < loS); 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* They start at same place. Since we know neither of them has 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zero length, they must overlap. */ 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Call here to exit if we can't continue. On Android we can't call 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _exit for some reason, so we have to blunt-instrument it. */ 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__ ((__noreturn__)) 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline void my_exit ( int x ) 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(VGPV_arm_linux_android) 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__(".word 0xFFFFFFFF"); 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (1) {} 146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# elif defined(VGPV_x86_linux_android) 147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__("ud2"); 148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while (1) {} 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# else 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov extern __attribute__ ((__noreturn__)) void _exit(int status); 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _exit(x); 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This is a macro rather than a function because we don't want to have an 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// extra function in the stack trace. 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define RECORD_OVERLAP_ERROR(s, src, dst, len) \ 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VALGRIND_DO_CLIENT_REQUEST_STMT( \ 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR, \ 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s, src, dst, len, 0) 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strrchr ----------------------*/ 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRRCHR(soname, fnname) \ 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \ 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \ 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar ch = (UChar)((UInt)c); \ 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = (UChar*)s; \ 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* last = NULL; \ 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { \ 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*p == ch) last = p; \ 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*p == 0) return last; \ 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p++; \ 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Apparently rindex() is the same thing as strrchr() 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRRCHR(VG_Z_LIBC_SONAME, strrchr) 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRRCHR(VG_Z_LIBC_SONAME, rindex) 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr) 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRRCHR(VG_Z_LD_LINUX_SO_2, rindex) 186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */ 188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRRCHR(VG_Z_LIBC_SONAME, strrchr) 192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRRCHR(VG_Z_LIBC_SONAME, rindex) 193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRRCHR(VG_Z_DYLD, strrchr) 194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRRCHR(VG_Z_DYLD, rindex) 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRRCHR(VG_Z_LIBC_SONAME, strrchr) 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strchr ----------------------*/ 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRCHR(soname, fnname) \ 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ); \ 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20020,soname,fnname) ( const char* s, int c ) \ 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar ch = (UChar)((UInt)c); \ 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = (UChar*)s; \ 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { \ 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*p == ch) return p; \ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*p == 0) return NULL; \ 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p++; \ 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Apparently index() is the same thing as strchr() 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LIBC_SONAME, strchr) 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LIBC_SONAME, index) 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LIBC_SONAME, __GI_strchr) 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if !defined(VGP_x86_linux) 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LD_LINUX_SO_2, strchr) 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LD_LINUX_SO_2, index) 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr) 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index) 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRCHR(VG_Z_LIBC_SONAME, strchr) 229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCHR(VG_Z_LIBC_SONAME, index) 230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCHR(VG_Z_DYLD, strchr) 231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCHR(VG_Z_DYLD, index) 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCHR(VG_Z_LIBC_SONAME, strchr) 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcat ----------------------*/ 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRCAT(soname, fnname) \ 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \ 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ); \ 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20030,soname,fnname) \ 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ) \ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*dst) dst++; \ 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*src) *dst++ = *src++; \ 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *dst = 0; \ 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is a bit redundant, I think; any overlap and the strcat will */ \ 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* go forever... or until a seg fault occurs. */ \ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, \ 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src_orig, \ 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)dst-(Addr)dst_orig+1, \ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)src-(Addr)src_orig+1)) \ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \ 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst_orig; \ 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCAT(VG_Z_LIBC_SONAME, strcat) 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCAT(VG_Z_LIBC_SONAME, __GI_strcat) 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCAT(VG_Z_LIBC_SONAME, strcat) 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strncat ----------------------*/ 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRNCAT(soname, fnname) \ 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ); \ 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20040,soname,fnname) \ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ) \ 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT m = 0; \ 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*dst) dst++; \ 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \ 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *dst = 0; /* always add null */ \ 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This checks for overlap after copying, unavoidable without */ \ 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* pre-counting lengths... should be ok */ \ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, \ 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src_orig, \ 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Addr)dst-(Addr)dst_orig+1, \ 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)src-(Addr)src_orig+1)) \ 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \ 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst_orig; \ 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCAT(VG_Z_LIBC_SONAME, strncat) 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCAT(VG_Z_LIBC_SONAME, strncat) 304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCAT(VG_Z_DYLD, strncat) 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strlcat ----------------------*/ 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append src to dst. n is the size of dst's buffer. dst is guaranteed 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to be nul-terminated after the copy, unless n <= strlen(dst_orig). 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Returns min(n, strlen(dst_orig)) + strlen(src_orig). 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Truncation occurred if retval >= n. 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRLCAT(soname, fnname) \ 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \ 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ); \ 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20050,soname,fnname) \ 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ) \ 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT m = 0; \ 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m < n && *dst) { m++; dst++; } \ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (m < n) { \ 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Fill as far as dst_orig[n-2], then nul-terminate. */ \ 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m < n-1 && *src) { m++; *dst++ = *src++; } \ 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *dst = 0; \ 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { \ 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* No space to copy anything to dst. m == n */ \ 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Finish counting min(n, strlen(dst_orig)) + strlen(src_orig) */ \ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*src) { m++; src++; } \ 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This checks for overlap after copying, unavoidable without */ \ 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* pre-counting lengths... should be ok */ \ 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, \ 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src_orig, \ 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)dst-(Addr)dst_orig+1, \ 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)src-(Addr)src_orig+1)) \ 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strlcat", dst_orig, src_orig, n); \ 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return m; \ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRLCAT(VG_Z_LIBC_SONAME, strlcat) 351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRLCAT(VG_Z_DYLD, strlcat) 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLCAT(VG_Z_LIBC_SONAME, strlcat) 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strnlen ----------------------*/ 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRNLEN(soname, fnname) \ 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \ 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( const char* str, SizeT n ); \ 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20060,soname,fnname) \ 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( const char* str, SizeT n ) \ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT i = 0; \ 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (i < n && str[i] != 0) i++; \ 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return i; \ 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNLEN(VG_Z_LIBC_SONAME, strnlen) 372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen) 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNLEN(VG_Z_LIBC_SONAME, strnlen) 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strlen ----------------------*/ 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Note that this replacement often doesn't get used because gcc inlines 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// calls to strlen() with its own built-in version. This can be very 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// confusing if you aren't expecting it. Other small functions in 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// this file may also be inline by gcc. 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRLEN(soname, fnname) \ 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \ 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( const char* str ); \ 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20070,soname,fnname) \ 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( const char* str ) \ 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT i = 0; \ 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (str[i] != 0) i++; \ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return i; \ 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLEN(VG_Z_LIBC_SONAME, strlen) 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLEN(VG_Z_LIBC_SONAME, __GI_strlen) 401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */ 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRLEN(VG_Z_LIBC_SONAME, strlen) 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLEN(VG_Z_LIBC_SONAME, strlen) 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcpy ----------------------*/ 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRCPY(soname, fnname) \ 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \ 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ); \ 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20080,soname,fnname) \ 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ) \ 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*src) *dst++ = *src++; \ 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *dst = 0; \ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This checks for overlap after copying, unavoidable without */ \ 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* pre-counting length... should be ok */ \ 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, \ 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src_orig, \ 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Addr)dst-(Addr)dst_orig+1, \ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)src-(Addr)src_orig+1)) \ 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst_orig; \ 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCPY(VG_Z_LIBC_SONAME, strcpy) 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy) 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRCPY(VG_Z_LIBC_SONAME, strcpy) 443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCPY(VG_Z_DYLD, strcpy) 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCPY(VG_Z_LIBC_SONAME, strcpy) 445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strncpy ----------------------*/ 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRNCPY(soname, fnname) \ 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \ 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ); \ 454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ) \ 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT m = 0; \ 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m < n && *src) { m++; *dst++ = *src++; } \ 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Check for overlap after copying; all n bytes of dst are relevant, */ \ 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* but only m+1 bytes of src if terminator was found */ \ 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \ 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strncpy", dst, src, n); \ 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \ 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst_orig; \ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCPY(VG_Z_LIBC_SONAME, strncpy) 473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy) 474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRNCPY(VG_Z_LIBC_SONAME, strncpy) 477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCPY(VG_Z_DYLD, strncpy) 478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCPY(VG_Z_LIBC_SONAME, strncpy) 479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strlcpy ----------------------*/ 484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Copy up to n-1 bytes from src to dst. Then nul-terminate dst if n > 0. 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Returns strlen(src). Does not zero-fill the remainder of dst. */ 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRLCPY(soname, fnname) \ 488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \ 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ); \ 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20100,soname,fnname) \ 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( char* dst, const char* src, SizeT n ) \ 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const char* src_orig = src; \ 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char* dst_orig = dst; \ 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT m = 0; \ 496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (m < n-1 && *src) { m++; *dst++ = *src++; } \ 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* m non-nul bytes have now been copied, and m <= n-1. */ \ 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Check for overlap after copying; all n bytes of dst are relevant, */ \ 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* but only m+1 bytes of src if terminator was found */ \ 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) \ 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("strlcpy", dst, src, n); \ 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Nul-terminate dst. */ \ 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n > 0) *dst = 0; \ 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Finish counting strlen(src). */ \ 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*src) src++; \ 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return src - src_orig; \ 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STRLCPY(VG_Z_LIBC_SONAME, strlcpy); 514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRLCPY(VG_Z_LIBC_SONAME, strlcpy) 518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRLCPY(VG_Z_DYLD, strlcpy) 519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRLCPY(VG_Z_LIBC_SONAME, strlcpy) 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strncmp ----------------------*/ 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRNCMP(soname, fnname) \ 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \ 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( const char* s1, const char* s2, SizeT nmax ); \ 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \ 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( const char* s1, const char* s2, SizeT nmax ) \ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT n = 0; \ 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { \ 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n >= nmax) return 0; \ 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*s1 == 0 && *s2 == 0) return 0; \ 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*s1 == 0) return -1; \ 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*s2 == 0) return 1; \ 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \ 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \ 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s1++; s2++; n++; \ 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCMP(VG_Z_LIBC_SONAME, strncmp) 548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp) 549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRNCMP(VG_Z_LIBC_SONAME, strncmp) 552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCMP(VG_Z_DYLD, strncmp) 553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCMP(VG_Z_LIBC_SONAME, strncmp) 554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcasecmp ----------------------*/ 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 560f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#define STRCASECMP(soname, fnname) \ 561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \ 562f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2 ); \ 563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20120,soname,fnname) \ 564f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2 ) \ 565f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root { \ 566f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root extern int tolower(int); \ 567f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root register unsigned char c1; \ 568f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root register unsigned char c2; \ 569f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while (True) { \ 570f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root c1 = tolower(*(unsigned char *)s1); \ 571f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root c2 = tolower(*(unsigned char *)s2); \ 572f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (c1 != c2) break; \ 573f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (c1 == 0) break; \ 574f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root s1++; s2++; \ 575f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } \ 576f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 577f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 578f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return 0; \ 579f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 580f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 581f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#if defined(VGO_linux) 582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) 583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp) 584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp) 585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp) 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 590f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#endif 591f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 592f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strncasecmp ----------------------*/ 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 595f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#define STRNCASECMP(soname, fnname) \ 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \ 597f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, SizeT nmax ); \ 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20130,soname,fnname) \ 599f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, SizeT nmax ) \ 600f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root { \ 601f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root extern int tolower(int); \ 602f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root SizeT n = 0; \ 603f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while (True) { \ 604f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (n >= nmax) return 0; \ 605f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s1 == 0 && *s2 == 0) return 0; \ 606f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s1 == 0) return -1; \ 607f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s2 == 0) return 1; \ 608f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root \ 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (tolower(*(unsigned char*)s1) \ 610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov < tolower(*(unsigned char*)s2)) return -1; \ 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (tolower(*(unsigned char*)s1) \ 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov > tolower(*(unsigned char*)s2)) return 1; \ 613f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root \ 614f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root s1++; s2++; n++; \ 615f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } \ 616f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 617f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 618f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#if defined(VGO_linux) 619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp) 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp) 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 624f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#elif defined(VGO_darwin) 625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp) 626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCASECMP(VG_Z_DYLD, strncasecmp) 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 628f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#endif 629f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 630f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcasecmp_l ----------------------*/ 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 633f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#define STRCASECMP_L(soname, fnname) \ 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \ 635f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, void* locale ); \ 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20140,soname,fnname) \ 637f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, void* locale ) \ 638f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root { \ 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov extern int tolower_l(int, void*) __attribute__((weak)); \ 640f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root register unsigned char c1; \ 641f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root register unsigned char c2; \ 642f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while (True) { \ 643f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root c1 = tolower_l(*(unsigned char *)s1, locale); \ 644f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root c2 = tolower_l(*(unsigned char *)s2, locale); \ 645f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (c1 != c2) break; \ 646f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (c1 == 0) break; \ 647f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root s1++; s2++; \ 648f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } \ 649f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 650f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 651f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return 0; \ 652f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 653f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 654f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#if defined(VGO_linux) 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l) 656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCASECMP_L(VG_Z_LIBC_SONAME, __GI_strcasecmp_l) 657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l) 658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l) 661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 662f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#endif 663f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 664f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strncasecmp_l ----------------------*/ 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 667f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#define STRNCASECMP_L(soname, fnname) \ 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \ 669f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, SizeT nmax, void* locale ); \ 670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20150,soname,fnname) \ 671f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ( const char* s1, const char* s2, SizeT nmax, void* locale ) \ 672f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root { \ 673f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root extern int tolower_l(int, void*) __attribute__((weak)); \ 674f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root SizeT n = 0; \ 675f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while (True) { \ 676f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (n >= nmax) return 0; \ 677f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s1 == 0 && *s2 == 0) return 0; \ 678f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s1 == 0) return -1; \ 679f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (*s2 == 0) return 1; \ 680f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root \ 681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (tolower_l(*(unsigned char*)s1, locale) \ 682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov < tolower_l(*(unsigned char*)s2, locale)) return -1; \ 683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (tolower_l(*(unsigned char*)s1, locale) \ 684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov > tolower_l(*(unsigned char*)s2, locale)) return 1; \ 685f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root \ 686f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root s1++; s2++; n++; \ 687f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } \ 688f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 689f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 690f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#if defined(VGO_linux) 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l) 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l) 693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI___strncasecmp_l) 694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 695f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#elif defined(VGO_darwin) 696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l) 697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l) 698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 699f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#endif 700f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 701f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcmp ----------------------*/ 703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRCMP(soname, fnname) \ 705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \ 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( const char* s1, const char* s2 ); \ 707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20160,soname,fnname) \ 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( const char* s1, const char* s2 ) \ 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register unsigned char c1; \ 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register unsigned char c2; \ 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { \ 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c1 = *(unsigned char *)s1; \ 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c2 = *(unsigned char *)s2; \ 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (c1 != c2) break; \ 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (c1 == 0) break; \ 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s1++; s2++; \ 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((unsigned char)c1 < (unsigned char)c2) return -1; \ 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((unsigned char)c1 > (unsigned char)c2) return 1; \ 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; \ 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(VG_Z_LIBC_SONAME, strcmp) 726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp) 727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp) 728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(VG_Z_LD64_SO_1, strcmp) 729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) 730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */ 731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //STRCMP(VG_Z_LIBC_SONAME, strcmp) 735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCMP(VG_Z_LIBC_SONAME, strcmp) 736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- memchr ----------------------*/ 741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MEMCHR(soname, fnname) \ 743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \ 744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const void *s, int c, SizeT n); \ 745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \ 746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const void *s, int c, SizeT n) \ 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT i; \ 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar c0 = (UChar)c; \ 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = (UChar*)s; \ 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) \ 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (p[i] == c0) return (void*)(&p[i]); \ 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCHR(VG_Z_LIBC_SONAME, memchr) 758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCHR(VG_Z_LIBC_SONAME, memchr) 761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCHR(VG_Z_DYLD, memchr) 762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------- memrchr ----------------------*/ 767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define MEMRCHR(soname, fnname) \ 769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \ 770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (const void *s, int c, SizeT n); \ 771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \ 772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (const void *s, int c, SizeT n) \ 773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { \ 774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SizeT i; \ 775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar c0 = (UChar)c; \ 776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar* p = (UChar*)s; \ 777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) \ 778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (p[n-1-i] == c0) return (void*)(&p[n-1-i]); \ 779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return NULL; \ 780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGO_linux) 783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMRCHR(VG_Z_LIBC_SONAME, memrchr) 784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGO_darwin) 786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMRCHR(VG_Z_LIBC_SONAME, memrchr) 787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMRCHR(VG_Z_DYLD, memrchr) 788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- memcpy ----------------------*/ 793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define MEMMOVE_OR_MEMCPY(becTag, soname, fnname, do_ol_check) \ 795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \ 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( void *dst, const void *src, SizeT len ); \ 797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZZ(becTag,soname,fnname) \ 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( void *dst, const void *src, SizeT len ) \ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (do_ol_check && is_overlap(dst, src, len, len)) \ 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \ 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr WS = sizeof(UWord); /* 8 or 4 */ \ 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr WM = WS - 1; /* 7 or 3 */ \ 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (len > 0) { \ 807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (dst < src) { \ 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copying backwards. */ \ 810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT n = len; \ 811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr d = (Addr)dst; \ 812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr s = (Addr)src; \ 813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (((s^d) & WM) == 0) { \ 815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* s and d have same UWord alignment. */ \ 816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Pull up to a UWord boundary. */ \ 817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((s & WM) != 0 && n >= 1) \ 818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \ 819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copy UWords. */ \ 820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= WS) \ 821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \ 822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (n == 0) \ 823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return dst; \ 824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (((s|d) & 1) == 0) { \ 826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Both are 16-aligned; copy what we can thusly. */ \ 827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= 2) \ 828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \ 829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copy leftovers, or everything if misaligned. */ \ 831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= 1) \ 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \ 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else if (dst > src) { \ 835b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 836b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT n = len; \ 837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr d = ((Addr)dst) + n; \ 838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr s = ((Addr)src) + n; \ 839b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copying forwards. */ \ 841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (((s^d) & WM) == 0) { \ 842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* s and d have same UWord alignment. */ \ 843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Back down to a UWord boundary. */ \ 844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while ((s & WM) != 0 && n >= 1) \ 845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \ 846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copy UWords. */ \ 847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= WS) \ 848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \ 849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (n == 0) \ 850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return dst; \ 851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (((s|d) & 1) == 0) { \ 853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Both are 16-aligned; copy what we can thusly. */ \ 854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= 2) \ 855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \ 856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Copy leftovers, or everything if misaligned. */ \ 858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n >= 1) \ 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \ 860b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define MEMMOVE(soname, fnname) \ 868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE_OR_MEMCPY(20181, soname, fnname, 0) 869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define MEMCPY(soname, fnname) \ 871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE_OR_MEMCPY(20180, soname, fnname, 1) 872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* For older memcpy we have to use memmove-like semantics and skip 875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the overlap check; sigh; see #275284. */ 876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */ 877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */ 878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LIBC_SONAME, memcpy) /* fallback case */ 879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */ 880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */ 881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* icc9 blats these around all over the place. Not only in the main 882b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov executable but various .so's. They are highly tuned and read 883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov memory beyond the source boundary (although work correctly and 884b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov never go across page boundaries), so give errors when run 885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov natively, at least for misaligned source arg. Just intercepting 886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov in the exe only until we understand more about the problem. See 887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov http://bugs.kde.org/show_bug.cgi?id=139776 888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(NONE, ZuintelZufastZumemcpy) 890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if DARWIN_VERS <= DARWIN_10_6 893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMCPY(VG_Z_LIBC_SONAME, memcpy) 894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# endif 895b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */ 896b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */ 897b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- memcmp ----------------------*/ 902b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MEMCMP(soname, fnname) \ 904b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \ 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( const void *s1V, const void *s2V, SizeT n ); \ 906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \ 907b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( const void *s1V, const void *s2V, SizeT n ) \ 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int res; \ 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char a0; \ 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char b0; \ 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char* s1 = (unsigned char*)s1V; \ 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char* s2 = (unsigned char*)s2V; \ 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (n != 0) { \ 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a0 = s1[0]; \ 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b0 = s2[0]; \ 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s1 += 1; \ 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2 += 1; \ 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = ((int)a0) - ((int)b0); \ 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (res != 0) \ 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; \ 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n -= 1; \ 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; \ 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCMP(VG_Z_LIBC_SONAME, memcmp) 930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCMP(VG_Z_LIBC_SONAME, bcmp) 931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMCMP(VG_Z_LD_SO_1, bcmp) 932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCMP(VG_Z_LIBC_SONAME, memcmp) 935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCMP(VG_Z_LIBC_SONAME, bcmp) 936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCMP(VG_Z_DYLD, memcmp) 937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMCMP(VG_Z_DYLD, bcmp) 938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- stpcpy ----------------------*/ 943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Copy SRC to DEST, returning the address of the terminating '\0' in 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DEST. (minor variant of strcpy) */ 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STPCPY(soname, fnname) \ 947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \ 948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ); \ 949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \ 950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( char* dst, const char* src ) \ 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* src_orig = src; \ 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst_orig = dst; \ 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*src) *dst++ = *src++; \ 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *dst = 0; \ 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This checks for overlap after copying, unavoidable without */ \ 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* pre-counting length... should be ok */ \ 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst_orig, \ 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src_orig, \ 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)dst-(Addr)dst_orig+1, \ 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)src-(Addr)src_orig+1)) \ 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \ 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STPCPY(VG_Z_LIBC_SONAME, stpcpy) 971b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy) 972b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy) 973b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy) 974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STPCPY(VG_Z_LIBC_SONAME, stpcpy) 977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //STPCPY(VG_Z_DYLD, stpcpy) 978b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 982b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- memset ----------------------*/ 983b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Why are we bothering to intercept this? It seems entirely 985b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pointless. */ 986b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MEMSET(soname, fnname) \ 988b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \ 989b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void *s, Int c, SizeT n); \ 990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \ 991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void *s, Int c, SizeT n) \ 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr a = (Addr)s; \ 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt c4 = (c & 0xFF); \ 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c4 = (c4 << 8) | c4; \ 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c4 = (c4 << 16) | c4; \ 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ((a & 3) != 0 && n >= 1) \ 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \ 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (n >= 4) \ 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { *(UInt*)a = c4; a += 4; n -= 4; } \ 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (n >= 1) \ 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { *(UChar*)a = (UChar)c; a += 1; n -= 1; } \ 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return s; \ 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1006b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1007b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMSET(VG_Z_LIBC_SONAME, memset) 1008b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //MEMSET(VG_Z_LIBC_SONAME, memset) 1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //MEMSET(VG_Z_DYLD, memset) 1012b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMSET(VG_Z_LIBC_SONAME, memset) 1013b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1017b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- memmove ----------------------*/ 1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* memmove -- use the MEMMOVE defn above. */ 1020b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE(VG_Z_LIBC_SONAME, memmove) 1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMMOVE(VG_Z_LIBC_SONAME, __GI_memmove) 1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if DARWIN_VERS <= DARWIN_10_6 1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MEMMOVE(VG_Z_LIBC_SONAME, memmove) 1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# endif 1029b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */ 1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */ 1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- bcopy ----------------------*/ 1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BCOPY(soname, fnname) \ 1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \ 1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const void *srcV, void *dstV, SizeT n); \ 1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void VG_REPLACE_FUNCTION_EZU(20230,soname,fnname) \ 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const void *srcV, void *dstV, SizeT n) \ 1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT i; \ 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst = (Char*)dstV; \ 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* src = (Char*)srcV; \ 1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dst < src) { \ 1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) \ 1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dst[i] = src[i]; \ 1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else \ 1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dst > src) { \ 1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) \ 1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dst[n-i-1] = src[n-i-1]; \ 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1059b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //BCOPY(VG_Z_LIBC_SONAME, bcopy) 1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //BCOPY(VG_Z_DYLD, bcopy) 1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*-------------------- memmove_chk --------------------*/ 1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* glibc 2.5 variant of memmove which checks the dest is big enough. 1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown There is no specific part of glibc that this is copied from. */ 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC25___MEMMOVE_CHK(soname, fnname) \ 1071b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \ 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *dstV, const void *srcV, SizeT n, SizeT destlen); \ 1073b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20240,soname,fnname) \ 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *dstV, const void *srcV, SizeT n, SizeT destlen) \ 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT i; \ 1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dst = (Char*)dstV; \ 1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* src = (Char*)srcV; \ 1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destlen < n) \ 1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto badness; \ 1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dst < src) { \ 1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) \ 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dst[i] = src[i]; \ 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else \ 1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dst > src) { \ 1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) \ 1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dst[n-i-1] = src[n-i-1]; \ 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown badness: \ 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_PRINTF_BACKTRACE( \ 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "*** memmove_chk: buffer overflow detected ***: " \ 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "program terminated\n"); \ 1095b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my_exit(127); \ 1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ \ 1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC25___MEMMOVE_CHK(VG_Z_LIBC_SONAME, __memmove_chk) 1102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*-------------------- strchrnul --------------------*/ 1109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find the first occurrence of C in S or the final NUL byte. */ 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC232_STRCHRNUL(soname, fnname) \ 1112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \ 1113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const char* s, int c_in); \ 1114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20250,soname,fnname) \ 1115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const char* s, int c_in) \ 1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char c = (unsigned char) c_in; \ 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char* char_ptr = (unsigned char *)s; \ 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { \ 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*char_ptr == 0) return char_ptr; \ 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*char_ptr == c) return char_ptr; \ 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char_ptr++; \ 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul) 1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- rawmemchr ----------------------*/ 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find the first occurrence of C in S. */ 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC232_RAWMEMCHR(soname, fnname) \ 1138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \ 1139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const char* s, int c_in); \ 1140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20260,soname,fnname) \ 1141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (const char* s, int c_in) \ 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char c = (unsigned char) c_in; \ 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char* char_ptr = (unsigned char *)s; \ 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { \ 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*char_ptr == c) return char_ptr; \ 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char_ptr++; \ 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined (VGO_linux) 1152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr) 1153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr) 1154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcpy_chk ----------------------*/ 1161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* glibc variant of strcpy that checks the dest is big enough. 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Copied from glibc-2.5/debug/test-strcpy_chk.c. */ 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC25___STRCPY_CHK(soname,fnname) \ 1165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \ 1166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (char* dst, const char* src, SizeT len); \ 1167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20270,soname,fnname) \ 1168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (char* dst, const char* src, SizeT len) \ 1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char* ret = dst; \ 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (! len) \ 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto badness; \ 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ((*dst++ = *src++) != '\0') \ 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (--len == 0) \ 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto badness; \ 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ret; \ 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown badness: \ 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_PRINTF_BACKTRACE( \ 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "*** strcpy_chk: buffer overflow detected ***: " \ 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "program terminated\n"); \ 1181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my_exit(127); \ 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ \ 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC25___STRCPY_CHK(VG_Z_LIBC_SONAME, __strcpy_chk) 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- stpcpy_chk ----------------------*/ 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* glibc variant of stpcpy that checks the dest is big enough. 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Copied from glibc-2.5/debug/test-stpcpy_chk.c. */ 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC25___STPCPY_CHK(soname,fnname) \ 1199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \ 1200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (char* dst, const char* src, SizeT len); \ 1201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char* VG_REPLACE_FUNCTION_EZU(20280,soname,fnname) \ 1202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (char* dst, const char* src, SizeT len) \ 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (! len) \ 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto badness; \ 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ((*dst++ = *src++) != '\0') \ 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (--len == 0) \ 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto badness; \ 1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst - 1; \ 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown badness: \ 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_PRINTF_BACKTRACE( \ 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "*** stpcpy_chk: buffer overflow detected ***: " \ 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "program terminated\n"); \ 1214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my_exit(127); \ 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ \ 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC25___STPCPY_CHK(VG_Z_LIBC_SONAME, __stpcpy_chk) 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- mempcpy ----------------------*/ 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* mempcpy */ 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC25_MEMPCPY(soname, fnname) \ 1231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \ 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( void *dst, const void *src, SizeT len ); \ 1233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20290,soname,fnname) \ 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( void *dst, const void *src, SizeT len ) \ 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register char *d; \ 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register char *s; \ 1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT len_saved = len; \ 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (len == 0) \ 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst, src, len, len)) \ 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("mempcpy", dst, src, len); \ 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( dst > src ) { \ 1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = (char *)dst + len - 1; \ 1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = (char *)src + len - 1; \ 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( len-- ) { \ 1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d-- = *s--; \ 1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else if ( dst < src ) { \ 1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = (char *)dst; \ 1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = (char *)src; \ 1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( len-- ) { \ 1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d++ = *s++; \ 1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (void*)( ((char*)dst) + len_saved ); \ 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 1263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy) 1264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */ 1265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy) 1268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*-------------------- memcpy_chk --------------------*/ 1273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define GLIBC26___MEMCPY_CHK(soname, fnname) \ 1275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \ 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* dst, const void* src, SizeT len, SizeT dstlen ); \ 1277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20300,soname,fnname) \ 1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* dst, const void* src, SizeT len, SizeT dstlen ) \ 1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register char *d; \ 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown register char *s; \ 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dstlen < len) goto badness; \ 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (len == 0) \ 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_overlap(dst, src, len, len)) \ 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \ 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( dst > src ) { \ 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = (char *)dst + len - 1; \ 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = (char *)src + len - 1; \ 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( len-- ) { \ 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d-- = *s--; \ 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else if ( dst < src ) { \ 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = (char *)dst; \ 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = (char *)src; \ 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( len-- ) { \ 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d++ = *s++; \ 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dst; \ 1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown badness: \ 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_PRINTF_BACKTRACE( \ 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "*** memcpy_chk: buffer overflow detected ***: " \ 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "program terminated\n"); \ 1309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov my_exit(127); \ 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ \ 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk) 1316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strstr ----------------------*/ 1323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRSTR(soname, fnname) \ 1325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \ 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* haystack, void* needle); \ 1327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \ 1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* haystack, void* needle) \ 1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* h = (UChar*)haystack; \ 1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* n = (UChar*)needle; \ 1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* find the length of n, not including terminating zero */ \ 1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord nlen = 0; \ 1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (n[nlen]) nlen++; \ 1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if n is the empty string, match immediately. */ \ 1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (nlen == 0) return h; \ 1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* assert(nlen >= 1); */ \ 1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar n0 = n[0]; \ 1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { \ 1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar hh = *h; \ 1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (hh == 0) return NULL; \ 1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (hh != n0) { h++; continue; } \ 1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord i; \ 1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < nlen; i++) { \ 1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n[i] != h[i]) \ 1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; \ 1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* assert(i >= 0 && i <= nlen); */ \ 1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (i == nlen) \ 1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return h; \ 1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h++; \ 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 1362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRSTR(VG_Z_LIBC_SONAME, strstr) 1363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strpbrk ----------------------*/ 1370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRPBRK(soname, fnname) \ 1372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \ 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* sV, void* acceptV); \ 1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20320,soname,fnname) \ 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* sV, void* acceptV) \ 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* s = (UChar*)sV; \ 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* accept = (UChar*)acceptV; \ 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* find the length of 'accept', not including terminating zero */ \ 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord nacc = 0; \ 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (accept[nacc]) nacc++; \ 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if n is the empty string, fail immediately. */ \ 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (nacc == 0) return NULL; \ 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* assert(nacc >= 1); */ \ 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { \ 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord i; \ 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar sc = *s; \ 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sc == 0) \ 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; \ 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < nacc; i++) { \ 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sc == accept[i]) \ 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return s; \ 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s++; \ 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; \ 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 1404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRPBRK(VG_Z_LIBC_SONAME, strpbrk) 1405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcspn ----------------------*/ 1412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define STRCSPN(soname, fnname) \ 1414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \ 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* sV, void* rejectV); \ 1416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20330,soname,fnname) \ 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void* sV, void* rejectV) \ 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* s = (UChar*)sV; \ 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* reject = (UChar*)rejectV; \ 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* find the length of 'reject', not including terminating zero */ \ 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord nrej = 0; \ 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (reject[nrej]) nrej++; \ 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord len = 0; \ 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { \ 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord i; \ 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar sc = *s; \ 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sc == 0) \ 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; \ 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < nrej; i++) { \ 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sc == reject[i]) \ 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; \ 1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* assert(i >= 0 && i <= nrej); */ \ 1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (i < nrej) \ 1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; \ 1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s++; \ 1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len++; \ 1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return len; \ 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 1447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRCSPN(VG_Z_LIBC_SONAME, strcspn) 1448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strspn ----------------------*/ 1455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define STRSPN(soname, fnname) \ 1457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \ 1458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void* sV, void* acceptV); \ 1459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov SizeT VG_REPLACE_FUNCTION_EZU(20340,soname,fnname) \ 1460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void* sV, void* acceptV) \ 1461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { \ 1462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* s = (UChar*)sV; \ 1463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* accept = (UChar*)acceptV; \ 1464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* find the length of 'accept', not including terminating zero */ \ 1466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord nacc = 0; \ 1467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (accept[nacc]) nacc++; \ 1468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nacc == 0) return 0; \ 1469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord len = 0; \ 1471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (1) { \ 1472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord i; \ 1473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar sc = *s; \ 1474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sc == 0) \ 1475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; \ 1476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < nacc; i++) { \ 1477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (sc == accept[i]) \ 1478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; \ 1479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 1480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* assert(i >= 0 && i <= nacc); */ \ 1481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i == nacc) \ 1482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; \ 1483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s++; \ 1484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len++; \ 1485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 1486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return len; \ 1488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov STRSPN(VG_Z_LIBC_SONAME, strspn) 1492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- strcasestr ----------------------*/ 1499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define STRCASESTR(soname, fnname) \ 1501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \ 1502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void* haystack, void* needle); \ 1503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* VG_REPLACE_FUNCTION_EZU(20350,soname,fnname) \ 1504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (void* haystack, void* needle) \ 1505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { \ 1506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov extern int tolower(int); \ 1507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* h = (UChar*)haystack; \ 1508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* n = (UChar*)needle; \ 1509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* find the length of n, not including terminating zero */ \ 1511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord nlen = 0; \ 1512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (n[nlen]) nlen++; \ 1513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* if n is the empty string, match immediately. */ \ 1515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (nlen == 0) return h; \ 1516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* assert(nlen >= 1); */ \ 1518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar n0 = tolower(n[0]); \ 1519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (1) { \ 1521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar hh = tolower(*h); \ 1522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hh == 0) return NULL; \ 1523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (hh != n0) { h++; continue; } \ 1524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UWord i; \ 1526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < nlen; i++) { \ 1527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (tolower(n[i]) != tolower(h[i])) \ 1528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; \ 1529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 1530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* assert(i >= 0 && i <= nlen); */ \ 1531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i == nlen) \ 1532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return h; \ 1533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov \ 1534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov h++; \ 1535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 1536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) 1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng STRCASESTR(VG_Z_LIBC_SONAME, strcasestr) 1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# endif 1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGO_darwin) 1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 1546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*---------------------- wcslen ----------------------*/ 1549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// This is a wchar_t equivalent to strlen. Unfortunately 1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// we don't have wchar_t available here, but it looks like 1552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// a 32 bit int on Linux. I don't know if that is also 1553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// valid on MacOSX. 1554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define WCSLEN(soname, fnname) \ 1556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \ 1557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ( const UInt* str ); \ 1558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SizeT VG_REPLACE_FUNCTION_EZU(20370,soname,fnname) \ 1559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ( const UInt* str ) \ 1560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng { \ 1561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SizeT i = 0; \ 1562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while (str[i] != 0) i++; \ 1563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return i; \ 1564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGO_linux) 1567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng WCSLEN(VG_Z_LIBC_SONAME, wcslen) 1568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin) 1570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Improve definedness checking of process environment ---*/ 1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* If these wind up getting generated via a macro, so that multiple 1581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov versions of each function exist (as above), use the _EZU variants 1582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to assign equivalance class tags. */ 1583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- putenv ----------------------*/ 1585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string); 1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, putenv) (char* string) 1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn fn; 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word result; 1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const char* p = string; 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_GET_ORIG_FN(fn); 1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now by walking over the string we magically produce 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown traces when hitting undefined memory. */ 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (p) 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*p++) 1597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__("" ::: "memory"); 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_W(result, fn, string); 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- unsetenv ----------------------*/ 1604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name); 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, unsetenv) (const char* name) 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn fn; 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word result; 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const char* p = name; 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_GET_ORIG_FN(fn); 1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now by walking over the string we magically produce 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown traces when hitting undefined memory. */ 1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (p) 1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*p++) 1616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__("" ::: "memory"); 1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_W(result, fn, name); 1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---------------------- setenv ----------------------*/ 1623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* setenv */ 1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv) 1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const char* name, const char* value, int overwrite); 1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, setenv) 1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const char* name, const char* value, int overwrite) 1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OrigFn fn; 1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word result; 1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const char* p; 1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_GET_ORIG_FN(fn); 1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now by walking over the string we magically produce 1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown traces when hitting undefined memory. */ 1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (name) 1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (p = name; *p; p++) 1638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__("" ::: "memory"); 1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (value) 1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (p = value; *p; p++) 1641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __asm__ __volatile__("" ::: "memory"); 1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VALGRIND_CHECK_VALUE_IS_DEFINED (overwrite); 1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CALL_FN_W_WWW(result, fn, name, value, overwrite); 1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* defined(VGO_linux) */ 1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1652