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