mc_replace_strmem.c revision 98abfc7bb7798c4ac4580f7e0bc7171de94a0255
13e88418f808bf2840646504481d6a5be1df16541njn 23e88418f808bf2840646504481d6a5be1df16541njn/*--------------------------------------------------------------------*/ 33e88418f808bf2840646504481d6a5be1df16541njn/*--- Replacements for strcpy(), memcpy() et al, which run on the ---*/ 43e88418f808bf2840646504481d6a5be1df16541njn/*--- simulated CPU. ---*/ 566fe05a4cf9c53f09ffc6edc31497be506049831njn/*--- mac_replace_strmem.c ---*/ 63e88418f808bf2840646504481d6a5be1df16541njn/*--------------------------------------------------------------------*/ 73e88418f808bf2840646504481d6a5be1df16541njn 83e88418f808bf2840646504481d6a5be1df16541njn/* 9137bc55f216bc7d9528f159a78cdf9025e0b02ffnethercote This file is part of MemCheck, a heavyweight Valgrind tool for 100e1b514ab8e837f75a207a037ea53a6a721e9d28njn detecting memory errors. 113e88418f808bf2840646504481d6a5be1df16541njn 120e1b514ab8e837f75a207a037ea53a6a721e9d28njn Copyright (C) 2000-2003 Julian Seward 133e88418f808bf2840646504481d6a5be1df16541njn jseward@acm.org 143e88418f808bf2840646504481d6a5be1df16541njn 153e88418f808bf2840646504481d6a5be1df16541njn This program is free software; you can redistribute it and/or 163e88418f808bf2840646504481d6a5be1df16541njn modify it under the terms of the GNU General Public License as 173e88418f808bf2840646504481d6a5be1df16541njn published by the Free Software Foundation; either version 2 of the 183e88418f808bf2840646504481d6a5be1df16541njn License, or (at your option) any later version. 193e88418f808bf2840646504481d6a5be1df16541njn 203e88418f808bf2840646504481d6a5be1df16541njn This program is distributed in the hope that it will be useful, but 213e88418f808bf2840646504481d6a5be1df16541njn WITHOUT ANY WARRANTY; without even the implied warranty of 223e88418f808bf2840646504481d6a5be1df16541njn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 233e88418f808bf2840646504481d6a5be1df16541njn General Public License for more details. 243e88418f808bf2840646504481d6a5be1df16541njn 253e88418f808bf2840646504481d6a5be1df16541njn You should have received a copy of the GNU General Public License 263e88418f808bf2840646504481d6a5be1df16541njn along with this program; if not, write to the Free Software 273e88418f808bf2840646504481d6a5be1df16541njn Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 283e88418f808bf2840646504481d6a5be1df16541njn 02111-1307, USA. 293e88418f808bf2840646504481d6a5be1df16541njn 303e88418f808bf2840646504481d6a5be1df16541njn The GNU General Public License is contained in the file COPYING. 313e88418f808bf2840646504481d6a5be1df16541njn*/ 323e88418f808bf2840646504481d6a5be1df16541njn 3334419c1237100ca66b224e235bc6ded59c7ec2fenjn#include "mc_include.h" 3498abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge#include "memcheck.h" 353e88418f808bf2840646504481d6a5be1df16541njn#include "valgrind.h" 363e88418f808bf2840646504481d6a5be1df16541njn 3798abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardingestatic Addr record_overlap_error; 3898abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 3998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardingestatic int init_done; 4098abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 4198abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge/* Startup hook - called as init section */ 4298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardingestatic void init(void) __attribute__((constructor)); 4398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardingestatic void init(void) 4498abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge{ 4598abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge if (init_done) 4698abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge return; 4798abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 4898abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge VALGRIND_MAGIC_SEQUENCE(record_overlap_error, 0, 4998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP, 5098abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 0, 0, 0, 0); 5198abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge init_done = 1; 5298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge} 5398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 543e88418f808bf2840646504481d6a5be1df16541njn/* --------------------------------------------------------------------- 553e88418f808bf2840646504481d6a5be1df16541njn The normal versions of these functions are hyper-optimised, which fools 563e88418f808bf2840646504481d6a5be1df16541njn Memcheck and cause spurious value warnings. So we replace them with 573e88418f808bf2840646504481d6a5be1df16541njn simpler versions. THEY RUN ON SIMD CPU! 583e88418f808bf2840646504481d6a5be1df16541njn ------------------------------------------------------------------ */ 593e88418f808bf2840646504481d6a5be1df16541njn 60dda830a684b1444754beb101fa032cf19b71abd6sewardj/* Figure out if [dst .. dst+dstlen-1] overlaps with 61dda830a684b1444754beb101fa032cf19b71abd6sewardj [src .. src+srclen-1]. 62dda830a684b1444754beb101fa032cf19b71abd6sewardj We assume that the address ranges do not wrap around 63dda830a684b1444754beb101fa032cf19b71abd6sewardj (which is safe since on Linux addresses >= 0xC0000000 64dda830a684b1444754beb101fa032cf19b71abd6sewardj are not accessible and the program will segfault in this 65dda830a684b1444754beb101fa032cf19b71abd6sewardj circumstance, presumably). 66dda830a684b1444754beb101fa032cf19b71abd6sewardj*/ 673e88418f808bf2840646504481d6a5be1df16541njnstatic __inline__ 68dda830a684b1444754beb101fa032cf19b71abd6sewardjBool is_overlap ( void* dst, const void* src, UInt dstlen, UInt srclen ) 693e88418f808bf2840646504481d6a5be1df16541njn{ 70dda830a684b1444754beb101fa032cf19b71abd6sewardj Addr loS, hiS, loD, hiD; 71dda830a684b1444754beb101fa032cf19b71abd6sewardj 72dda830a684b1444754beb101fa032cf19b71abd6sewardj if (dstlen == 0 || srclen == 0) 73dda830a684b1444754beb101fa032cf19b71abd6sewardj return False; 74dda830a684b1444754beb101fa032cf19b71abd6sewardj 75dda830a684b1444754beb101fa032cf19b71abd6sewardj loS = (Addr)src; 76dda830a684b1444754beb101fa032cf19b71abd6sewardj loD = (Addr)dst; 77dda830a684b1444754beb101fa032cf19b71abd6sewardj hiS = loS + srclen - 1; 78dda830a684b1444754beb101fa032cf19b71abd6sewardj hiD = loD + dstlen - 1; 79dda830a684b1444754beb101fa032cf19b71abd6sewardj 80dda830a684b1444754beb101fa032cf19b71abd6sewardj /* So figure out if [loS .. hiS] overlaps with [loD .. hiD]. */ 81dda830a684b1444754beb101fa032cf19b71abd6sewardj if (loS < loD) { 82dda830a684b1444754beb101fa032cf19b71abd6sewardj return !(hiS < loD); 83dda830a684b1444754beb101fa032cf19b71abd6sewardj } 84dda830a684b1444754beb101fa032cf19b71abd6sewardj else if (loD < loS) { 85dda830a684b1444754beb101fa032cf19b71abd6sewardj return !(hiD < loS); 86dda830a684b1444754beb101fa032cf19b71abd6sewardj } 87dda830a684b1444754beb101fa032cf19b71abd6sewardj else { 88dda830a684b1444754beb101fa032cf19b71abd6sewardj /* They start at same place. Since we know neither of them has 89dda830a684b1444754beb101fa032cf19b71abd6sewardj zero length, they must overlap. */ 90dda830a684b1444754beb101fa032cf19b71abd6sewardj return True; 91dda830a684b1444754beb101fa032cf19b71abd6sewardj } 923e88418f808bf2840646504481d6a5be1df16541njn} 933e88418f808bf2840646504481d6a5be1df16541njn 94dda830a684b1444754beb101fa032cf19b71abd6sewardj 953e88418f808bf2840646504481d6a5be1df16541njnstatic __inline__ 963e88418f808bf2840646504481d6a5be1df16541njnvoid complain2 ( Char* s, char* dst, const char* src ) 973e88418f808bf2840646504481d6a5be1df16541njn{ 98b6cae9f8bd72046a92baec0936b85546815a7215njn OverlapExtra extra = { 99b6cae9f8bd72046a92baec0936b85546815a7215njn .src = (Addr)src, .dst = (Addr)dst, .len = -1, 100b6cae9f8bd72046a92baec0936b85546815a7215njn }; 10198abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge init(); 10298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge VALGRIND_NON_SIMD_CALL2( record_overlap_error, s, &extra ); 1033e88418f808bf2840646504481d6a5be1df16541njn} 1043e88418f808bf2840646504481d6a5be1df16541njn 1053e88418f808bf2840646504481d6a5be1df16541njnstatic __inline__ 1063e88418f808bf2840646504481d6a5be1df16541njnvoid complain3 ( Char* s, void* dst, const void* src, int n ) 1073e88418f808bf2840646504481d6a5be1df16541njn{ 108b6cae9f8bd72046a92baec0936b85546815a7215njn /* Must wrap it up here, because we cannot pass 4 args to core */ 109b6cae9f8bd72046a92baec0936b85546815a7215njn OverlapExtra extra = { 110b6cae9f8bd72046a92baec0936b85546815a7215njn .src = (Addr)src, .dst = (Addr)dst, .len = n, 111b6cae9f8bd72046a92baec0936b85546815a7215njn }; 11298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge init(); 11398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge VALGRIND_NON_SIMD_CALL2( record_overlap_error, s, &extra ); 1143e88418f808bf2840646504481d6a5be1df16541njn} 1153e88418f808bf2840646504481d6a5be1df16541njn 1163e88418f808bf2840646504481d6a5be1df16541njnchar* strrchr ( const char* s, int c ) 1173e88418f808bf2840646504481d6a5be1df16541njn{ 1183e88418f808bf2840646504481d6a5be1df16541njn UChar ch = (UChar)((UInt)c); 1193e88418f808bf2840646504481d6a5be1df16541njn UChar* p = (UChar*)s; 1203e88418f808bf2840646504481d6a5be1df16541njn UChar* last = NULL; 1213e88418f808bf2840646504481d6a5be1df16541njn while (True) { 1223e88418f808bf2840646504481d6a5be1df16541njn if (*p == ch) last = p; 1233e88418f808bf2840646504481d6a5be1df16541njn if (*p == 0) return last; 1243e88418f808bf2840646504481d6a5be1df16541njn p++; 1253e88418f808bf2840646504481d6a5be1df16541njn } 1263e88418f808bf2840646504481d6a5be1df16541njn} 1273e88418f808bf2840646504481d6a5be1df16541njn 1283e88418f808bf2840646504481d6a5be1df16541njnchar* strchr ( const char* s, int c ) 1293e88418f808bf2840646504481d6a5be1df16541njn{ 1303e88418f808bf2840646504481d6a5be1df16541njn UChar ch = (UChar)((UInt)c); 1313e88418f808bf2840646504481d6a5be1df16541njn UChar* p = (UChar*)s; 1323e88418f808bf2840646504481d6a5be1df16541njn while (True) { 1333e88418f808bf2840646504481d6a5be1df16541njn if (*p == ch) return p; 1343e88418f808bf2840646504481d6a5be1df16541njn if (*p == 0) return NULL; 1353e88418f808bf2840646504481d6a5be1df16541njn p++; 1363e88418f808bf2840646504481d6a5be1df16541njn } 1373e88418f808bf2840646504481d6a5be1df16541njn} 1383e88418f808bf2840646504481d6a5be1df16541njn 1393e88418f808bf2840646504481d6a5be1df16541njnchar* strcat ( char* dst, const char* src ) 1403e88418f808bf2840646504481d6a5be1df16541njn{ 14134419c1237100ca66b224e235bc6ded59c7ec2fenjn const Char* src_orig = src; 14234419c1237100ca66b224e235bc6ded59c7ec2fenjn Char* dst_orig = dst; 1433e88418f808bf2840646504481d6a5be1df16541njn while (*dst) dst++; 1443e88418f808bf2840646504481d6a5be1df16541njn while (*src) *dst++ = *src++; 1453e88418f808bf2840646504481d6a5be1df16541njn *dst = 0; 1463e88418f808bf2840646504481d6a5be1df16541njn 1473e88418f808bf2840646504481d6a5be1df16541njn /* This is a bit redundant, I think; any overlap and the strcat will 1483e88418f808bf2840646504481d6a5be1df16541njn go forever... or until a seg fault occurs. */ 149dda830a684b1444754beb101fa032cf19b71abd6sewardj if (is_overlap(dst_orig, 150dda830a684b1444754beb101fa032cf19b71abd6sewardj src_orig, 151dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)dst-(Addr)dst_orig+1, 152dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)src-(Addr)src_orig+1)) 15334419c1237100ca66b224e235bc6ded59c7ec2fenjn complain2("strcat", dst_orig, src_orig); 1543e88418f808bf2840646504481d6a5be1df16541njn 1553e88418f808bf2840646504481d6a5be1df16541njn return dst_orig; 1563e88418f808bf2840646504481d6a5be1df16541njn} 1573e88418f808bf2840646504481d6a5be1df16541njn 1583e88418f808bf2840646504481d6a5be1df16541njnchar* strncat ( char* dst, const char* src, int n ) 1593e88418f808bf2840646504481d6a5be1df16541njn{ 16034419c1237100ca66b224e235bc6ded59c7ec2fenjn const Char* src_orig = src; 16134419c1237100ca66b224e235bc6ded59c7ec2fenjn Char* dst_orig = dst; 1623e88418f808bf2840646504481d6a5be1df16541njn Int m = 0; 1633e88418f808bf2840646504481d6a5be1df16541njn 1643e88418f808bf2840646504481d6a5be1df16541njn while (*dst) dst++; 1659a90c7b27258c32a8912c7529add80b03c2f812enjn while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ 166b6483f853c3d646931bfa5f859d220ef9c7e3f3cnjn *dst = 0; /* always add null */ 1673e88418f808bf2840646504481d6a5be1df16541njn 1683e88418f808bf2840646504481d6a5be1df16541njn /* This checks for overlap after copying, unavoidable without 1693e88418f808bf2840646504481d6a5be1df16541njn pre-counting lengths... should be ok */ 170dda830a684b1444754beb101fa032cf19b71abd6sewardj if (is_overlap(dst_orig, 171dda830a684b1444754beb101fa032cf19b71abd6sewardj src_orig, 172dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)dst-(Addr)dst_orig+1, 173dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)src-(Addr)src_orig+1)) 17434419c1237100ca66b224e235bc6ded59c7ec2fenjn complain3("strncat", dst_orig, src_orig, n); 1753e88418f808bf2840646504481d6a5be1df16541njn 1763e88418f808bf2840646504481d6a5be1df16541njn return dst_orig; 1773e88418f808bf2840646504481d6a5be1df16541njn} 1783e88418f808bf2840646504481d6a5be1df16541njn 1793e88418f808bf2840646504481d6a5be1df16541njnunsigned int strlen ( const char* str ) 1803e88418f808bf2840646504481d6a5be1df16541njn{ 1813e88418f808bf2840646504481d6a5be1df16541njn UInt i = 0; 1823e88418f808bf2840646504481d6a5be1df16541njn while (str[i] != 0) i++; 1833e88418f808bf2840646504481d6a5be1df16541njn return i; 1843e88418f808bf2840646504481d6a5be1df16541njn} 1853e88418f808bf2840646504481d6a5be1df16541njn 1863e88418f808bf2840646504481d6a5be1df16541njnchar* strcpy ( char* dst, const char* src ) 1873e88418f808bf2840646504481d6a5be1df16541njn{ 18834419c1237100ca66b224e235bc6ded59c7ec2fenjn const Char* src_orig = src; 18934419c1237100ca66b224e235bc6ded59c7ec2fenjn Char* dst_orig = dst; 1903e88418f808bf2840646504481d6a5be1df16541njn 1913e88418f808bf2840646504481d6a5be1df16541njn while (*src) *dst++ = *src++; 1923e88418f808bf2840646504481d6a5be1df16541njn *dst = 0; 1933e88418f808bf2840646504481d6a5be1df16541njn 1943e88418f808bf2840646504481d6a5be1df16541njn /* This checks for overlap after copying, unavoidable without 1953e88418f808bf2840646504481d6a5be1df16541njn pre-counting length... should be ok */ 196dda830a684b1444754beb101fa032cf19b71abd6sewardj if (is_overlap(dst_orig, 197dda830a684b1444754beb101fa032cf19b71abd6sewardj src_orig, 198dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)dst-(Addr)dst_orig+1, 199dda830a684b1444754beb101fa032cf19b71abd6sewardj (Addr)src-(Addr)src_orig+1)) 20034419c1237100ca66b224e235bc6ded59c7ec2fenjn complain2("strcpy", dst_orig, src_orig); 2013e88418f808bf2840646504481d6a5be1df16541njn 2023e88418f808bf2840646504481d6a5be1df16541njn return dst_orig; 2033e88418f808bf2840646504481d6a5be1df16541njn} 2043e88418f808bf2840646504481d6a5be1df16541njn 2053e88418f808bf2840646504481d6a5be1df16541njnchar* strncpy ( char* dst, const char* src, int n ) 2063e88418f808bf2840646504481d6a5be1df16541njn{ 2071e6d765541116146edefc76cc15c2ea2730483c9nethercote const Char* src_orig = src; 2081e6d765541116146edefc76cc15c2ea2730483c9nethercote Char* dst_orig = dst; 2093e88418f808bf2840646504481d6a5be1df16541njn Int m = 0; 2103e88418f808bf2840646504481d6a5be1df16541njn 2119a90c7b27258c32a8912c7529add80b03c2f812enjn while (m < n && *src) { m++; *dst++ = *src++; } 2121e6d765541116146edefc76cc15c2ea2730483c9nethercote /* Check for overlap after copying; all n bytes of dst are relevant, 2131e6d765541116146edefc76cc15c2ea2730483c9nethercote but only m+1 bytes of src if terminator was found */ 2141e6d765541116146edefc76cc15c2ea2730483c9nethercote if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n)) 2151e6d765541116146edefc76cc15c2ea2730483c9nethercote complain3("strncpy", dst, src, n); 2163e88418f808bf2840646504481d6a5be1df16541njn while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ 2173e88418f808bf2840646504481d6a5be1df16541njn 2183e88418f808bf2840646504481d6a5be1df16541njn return dst_orig; 2193e88418f808bf2840646504481d6a5be1df16541njn} 2203e88418f808bf2840646504481d6a5be1df16541njn 2213e88418f808bf2840646504481d6a5be1df16541njnint strncmp ( const unsigned char* s1, const unsigned char* s2, 2223e88418f808bf2840646504481d6a5be1df16541njn unsigned int nmax ) 2233e88418f808bf2840646504481d6a5be1df16541njn{ 2243e88418f808bf2840646504481d6a5be1df16541njn unsigned int n = 0; 2253e88418f808bf2840646504481d6a5be1df16541njn while (True) { 2263e88418f808bf2840646504481d6a5be1df16541njn if (n >= nmax) return 0; 2273e88418f808bf2840646504481d6a5be1df16541njn if (*s1 == 0 && *s2 == 0) return 0; 2283e88418f808bf2840646504481d6a5be1df16541njn if (*s1 == 0) return -1; 2293e88418f808bf2840646504481d6a5be1df16541njn if (*s2 == 0) return 1; 2303e88418f808bf2840646504481d6a5be1df16541njn 2313e88418f808bf2840646504481d6a5be1df16541njn if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; 2323e88418f808bf2840646504481d6a5be1df16541njn if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; 2333e88418f808bf2840646504481d6a5be1df16541njn 2343e88418f808bf2840646504481d6a5be1df16541njn s1++; s2++; n++; 2353e88418f808bf2840646504481d6a5be1df16541njn } 2363e88418f808bf2840646504481d6a5be1df16541njn} 2373e88418f808bf2840646504481d6a5be1df16541njn 2383e88418f808bf2840646504481d6a5be1df16541njnint strcmp ( const char* s1, const char* s2 ) 2393e88418f808bf2840646504481d6a5be1df16541njn{ 2403e88418f808bf2840646504481d6a5be1df16541njn register unsigned char c1; 2413e88418f808bf2840646504481d6a5be1df16541njn register unsigned char c2; 2423e88418f808bf2840646504481d6a5be1df16541njn while (True) { 2433e88418f808bf2840646504481d6a5be1df16541njn c1 = *(unsigned char *)s1; 2443e88418f808bf2840646504481d6a5be1df16541njn c2 = *(unsigned char *)s2; 2453e88418f808bf2840646504481d6a5be1df16541njn if (c1 != c2) break; 2463e88418f808bf2840646504481d6a5be1df16541njn if (c1 == 0) break; 2473e88418f808bf2840646504481d6a5be1df16541njn s1++; s2++; 2483e88418f808bf2840646504481d6a5be1df16541njn } 2493e88418f808bf2840646504481d6a5be1df16541njn if ((unsigned char)c1 < (unsigned char)c2) return -1; 2503e88418f808bf2840646504481d6a5be1df16541njn if ((unsigned char)c1 > (unsigned char)c2) return 1; 2513e88418f808bf2840646504481d6a5be1df16541njn return 0; 2523e88418f808bf2840646504481d6a5be1df16541njn} 2533e88418f808bf2840646504481d6a5be1df16541njn 2543e88418f808bf2840646504481d6a5be1df16541njnvoid* memchr(const void *s, int c, unsigned int n) 2553e88418f808bf2840646504481d6a5be1df16541njn{ 2563e88418f808bf2840646504481d6a5be1df16541njn unsigned int i; 2573e88418f808bf2840646504481d6a5be1df16541njn UChar c0 = (UChar)c; 2583e88418f808bf2840646504481d6a5be1df16541njn UChar* p = (UChar*)s; 2593e88418f808bf2840646504481d6a5be1df16541njn for (i = 0; i < n; i++) 2603e88418f808bf2840646504481d6a5be1df16541njn if (p[i] == c0) return (void*)(&p[i]); 2613e88418f808bf2840646504481d6a5be1df16541njn return NULL; 2623e88418f808bf2840646504481d6a5be1df16541njn} 2633e88418f808bf2840646504481d6a5be1df16541njn 2643e88418f808bf2840646504481d6a5be1df16541njnvoid* memcpy( void *dst, const void *src, unsigned int len ) 2653e88418f808bf2840646504481d6a5be1df16541njn{ 2663e88418f808bf2840646504481d6a5be1df16541njn register char *d; 2673e88418f808bf2840646504481d6a5be1df16541njn register char *s; 2683e88418f808bf2840646504481d6a5be1df16541njn 269dda830a684b1444754beb101fa032cf19b71abd6sewardj if (is_overlap(dst, src, len, len)) 2703e88418f808bf2840646504481d6a5be1df16541njn complain3("memcpy", dst, src, len); 2713e88418f808bf2840646504481d6a5be1df16541njn 2723e88418f808bf2840646504481d6a5be1df16541njn if ( dst > src ) { 2733e88418f808bf2840646504481d6a5be1df16541njn d = (char *)dst + len - 1; 2743e88418f808bf2840646504481d6a5be1df16541njn s = (char *)src + len - 1; 2753e88418f808bf2840646504481d6a5be1df16541njn while ( len >= 4 ) { 2763e88418f808bf2840646504481d6a5be1df16541njn *d-- = *s--; 2773e88418f808bf2840646504481d6a5be1df16541njn *d-- = *s--; 2783e88418f808bf2840646504481d6a5be1df16541njn *d-- = *s--; 2793e88418f808bf2840646504481d6a5be1df16541njn *d-- = *s--; 2803e88418f808bf2840646504481d6a5be1df16541njn len -= 4; 2813e88418f808bf2840646504481d6a5be1df16541njn } 2823e88418f808bf2840646504481d6a5be1df16541njn while ( len-- ) { 2833e88418f808bf2840646504481d6a5be1df16541njn *d-- = *s--; 2843e88418f808bf2840646504481d6a5be1df16541njn } 2853e88418f808bf2840646504481d6a5be1df16541njn } else if ( dst < src ) { 2863e88418f808bf2840646504481d6a5be1df16541njn d = (char *)dst; 2873e88418f808bf2840646504481d6a5be1df16541njn s = (char *)src; 2883e88418f808bf2840646504481d6a5be1df16541njn while ( len >= 4 ) { 2893e88418f808bf2840646504481d6a5be1df16541njn *d++ = *s++; 2903e88418f808bf2840646504481d6a5be1df16541njn *d++ = *s++; 2913e88418f808bf2840646504481d6a5be1df16541njn *d++ = *s++; 2923e88418f808bf2840646504481d6a5be1df16541njn *d++ = *s++; 2933e88418f808bf2840646504481d6a5be1df16541njn len -= 4; 2943e88418f808bf2840646504481d6a5be1df16541njn } 2953e88418f808bf2840646504481d6a5be1df16541njn while ( len-- ) { 2963e88418f808bf2840646504481d6a5be1df16541njn *d++ = *s++; 2973e88418f808bf2840646504481d6a5be1df16541njn } 2983e88418f808bf2840646504481d6a5be1df16541njn } 2993e88418f808bf2840646504481d6a5be1df16541njn return dst; 3003e88418f808bf2840646504481d6a5be1df16541njn} 3013e88418f808bf2840646504481d6a5be1df16541njn 3023ceec2447bf0e57f3130beabff4a6d7a188765a1sewardjint memcmp ( const void *s1V, const void *s2V, unsigned int n ) 3033ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj{ 3043ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj int res; 3053ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj unsigned char a0; 3063ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj unsigned char b0; 3073ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj unsigned char* s1 = (unsigned char*)s1V; 3083ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj unsigned char* s2 = (unsigned char*)s2V; 3093ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj 3103ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj while (n != 0) { 3113ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj a0 = s1[0]; 3123ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj b0 = s2[0]; 3133ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj s1 += 1; 3143ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj s2 += 1; 3153ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj res = ((int)a0) - ((int)b0); 3163ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj if (res != 0) 3173ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj return res; 3183ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj n -= 1; 3193ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj } 3203ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj return 0; 3213ceec2447bf0e57f3130beabff4a6d7a188765a1sewardj} 3223e88418f808bf2840646504481d6a5be1df16541njn 3233e88418f808bf2840646504481d6a5be1df16541njn/*--------------------------------------------------------------------*/ 32466fe05a4cf9c53f09ffc6edc31497be506049831njn/*--- end mac_replace_strmem.c ---*/ 3253e88418f808bf2840646504481d6a5be1df16541njn/*--------------------------------------------------------------------*/ 326