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