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