This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Refactor debug routines.


Hi,

After I looked at generic and x86-64 code I found following problems.
a) Performance. Performance of checking memset_chk and memcpy_chk is 
comparable to nonchecking ones. A strcpy_chk on benchtests is much
slower than stupid variant. Other functions are also slow because debug
has often byte-by-byte implementation.
b) Extensibility. Adding overlap checks is easier to add in c than
assembly.

A solution is to write functions in style of bounds check followed by
jump to corresponding routine. 
This should produce identic assembly as assembly files in ideal case, 
unfortunately gcc (or our annotations) contains a bug and does not issue
tailcall. Code for memset is following

0000000000000000 <__memset_chk>:
   0:	48 83 ec 08          	sub    $0x8,%rsp
   4:	48 39 d1             	cmp    %rdx,%rcx
   7:	72 09                	jb     12 <__memset_chk+0x12>
   9:	48 83 c4 08          	add    $0x8,%rsp
   d:	e9 00 00 00 00       	jmpq   12 <__memset_chk+0x12>
  12:	e8 00 00 00 00       	callq  17 <__memset_chk+0x17>




	* debug/memcpy_chk.c: Refactor implementation.
	* debug/memmove_chk.c: Likewise.
	* debug/mempcpy_chk.c: Likewise.
	* debug/memset_chk.c: Likewise.
	* debug/stpcpy_chk.c: Likewise.
	* debug/stpncpy_chk.c: Likewise.
	* debug/strcat_chk.c: Likewise.
	* debug/strcpy_chk.c: Likewise.
	* debug/strncat_chk.c: Likewise.
	* debug/strncpy_chk.c: Likewise.
	* sysdeps/x86_64/memcpy_chk.S: Remove.
	* sysdeps/x86_64/mempcpy_chk.S: Likewise.
	* sysdeps/x86_64/memset_chk.S: Likewise.
	* sysdeps/x86_64/stpcpy_chk.S: Likewise.
	* sysdeps/x86_64/strcpy_chk.S: Likewise.
	* sysdeps/x86_64/multiarch/memcpy_chk.S: Likewise.
	* sysdeps/x86_64/multiarch/memmove_chk.c: Likewise.
	* sysdeps/x86_64/multiarch/mempcpy_chk.S: Likewise.
	* sysdeps/x86_64/memcpy.S: Remove *_chk function.
	* sysdeps/x86_64/mempcpy.S: Likewise.
	* sysdeps/x86_64/memset.S: Likewise.
	* sysdeps/x86_64/multiarch/memcpy.S: Likewise.
	* sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: Likewise.
	* sysdeps/x86_64/multiarch/memcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/multiarch/memmove-ssse3-back.S: Likewise.
	* sysdeps/x86_64/multiarch/memmove-ssse3.S: Likewise.
	* sysdeps/x86_64/multiarch/mempcpy.S: Likewise.
	* sysdeps/x86_64/multiarch/mempcpy-ssse3-back.S: Likewise.
	* sysdeps/x86_64/multiarch/mempcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/multiarch/ifunc-impl-list.c: Remove deleted ifuncs.


diff --git a/debug/memcpy_chk.c b/debug/memcpy_chk.c
index a53dd76..5bbc44f 100644
--- a/debug/memcpy_chk.c
+++ b/debug/memcpy_chk.c
@@ -32,34 +32,5 @@ __memcpy_chk (dstpp, srcpp, len, dstlen)
   if (__builtin_expect (dstlen < len, 0))
     __chk_fail ();
 
-  unsigned long int dstp = (long int) dstpp;
-  unsigned long int srcp = (long int) srcpp;
-
-  /* Copy from the beginning to the end.  */
-
-  /* If there not too few bytes to copy, use word copy.  */
-  if (len >= OP_T_THRES)
-    {
-      /* Copy just a few bytes to make DSTP aligned.  */
-      len -= (-dstp) % OPSIZ;
-      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
-
-      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
-	 as much as possible.  */
-
-      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
-
-      /* Copy from SRCP to DSTP taking advantage of the known alignment of
-	 DSTP.  Number of bytes remaining is put in the third argument,
-	 i.e. in LEN.  This number may vary from machine to machine.  */
-
-      WORD_COPY_FWD (dstp, srcp, len, len);
-
-      /* Fall out and copy the tail.  */
-    }
-
-  /* There are just a few bytes to copy.  Use byte memory operations.  */
-  BYTE_COPY_FWD (dstp, srcp, len);
-
-  return dstpp;
+  return memcpy (dstpp, srcpp, len);
 }
diff --git a/debug/memmove_chk.c b/debug/memmove_chk.c
index 3ea34c6..6337e76 100644
--- a/debug/memmove_chk.c
+++ b/debug/memmove_chk.c
@@ -36,66 +36,5 @@ MEMMOVE_CHK (dest, src, len, destlen)
   if (__builtin_expect (destlen < len, 0))
     __chk_fail ();
 
-  unsigned long int dstp = (long int) dest;
-  unsigned long int srcp = (long int) src;
-
-  /* This test makes the forward copying code be used whenever possible.
-     Reduces the working set.  */
-  if (dstp - srcp >= len)	/* *Unsigned* compare!  */
-    {
-      /* Copy from the beginning to the end.  */
-
-      /* If there not too few bytes to copy, use word copy.  */
-      if (len >= OP_T_THRES)
-	{
-	  /* Copy just a few bytes to make DSTP aligned.  */
-	  len -= (-dstp) % OPSIZ;
-	  BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
-
-	  /* Copy whole pages from SRCP to DSTP by virtual address
-	     manipulation, as much as possible.  */
-
-	  PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
-
-	  /* Copy from SRCP to DSTP taking advantage of the known
-	     alignment of DSTP.  Number of bytes remaining is put
-	     in the third argument, i.e. in LEN.  This number may
-	     vary from machine to machine.  */
-
-	  WORD_COPY_FWD (dstp, srcp, len, len);
-
-	  /* Fall out and copy the tail.  */
-	}
-
-      /* There are just a few bytes to copy.  Use byte memory operations.  */
-      BYTE_COPY_FWD (dstp, srcp, len);
-    }
-  else
-    {
-      /* Copy from the end to the beginning.  */
-      srcp += len;
-      dstp += len;
-
-      /* If there not too few bytes to copy, use word copy.  */
-      if (len >= OP_T_THRES)
-	{
-	  /* Copy just a few bytes to make DSTP aligned.  */
-	  len -= dstp % OPSIZ;
-	  BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
-
-	  /* Copy from SRCP to DSTP taking advantage of the known
-	     alignment of DSTP.  Number of bytes remaining is put
-	     in the third argument, i.e. in LEN.  This number may
-	     vary from machine to machine.  */
-
-	  WORD_COPY_BWD (dstp, srcp, len, len);
-
-	  /* Fall out and copy the tail.  */
-	}
-
-      /* There are just a few bytes to copy.  Use byte memory operations.  */
-      BYTE_COPY_BWD (dstp, srcp, len);
-    }
-
-  return dest;
+  return memmove (dest, src, len);
 }
diff --git a/debug/mempcpy_chk.c b/debug/mempcpy_chk.c
index 6895883..1573a29 100644
--- a/debug/mempcpy_chk.c
+++ b/debug/mempcpy_chk.c
@@ -33,34 +33,5 @@ __mempcpy_chk (dstpp, srcpp, len, dstlen)
   if (__builtin_expect (dstlen < len, 0))
     __chk_fail ();
 
-  unsigned long int dstp = (long int) dstpp;
-  unsigned long int srcp = (long int) srcpp;
-
-  /* Copy from the beginning to the end.  */
-
-  /* If there not too few bytes to copy, use word copy.  */
-  if (len >= OP_T_THRES)
-    {
-      /* Copy just a few bytes to make DSTP aligned.  */
-      len -= (-dstp) % OPSIZ;
-      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
-
-      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
-	 as much as possible.  */
-
-      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
-
-      /* Copy from SRCP to DSTP taking advantage of the known alignment of
-	 DSTP.  Number of bytes remaining is put in the third argument,
-	 i.e. in LEN.  This number may vary from machine to machine.  */
-
-      WORD_COPY_FWD (dstp, srcp, len, len);
-
-      /* Fall out and copy the tail.  */
-    }
-
-  /* There are just a few bytes to copy.  Use byte memory operations.  */
-  BYTE_COPY_FWD (dstp, srcp, len);
-
-  return (void *) dstp;
+  return __mempcpy (dstpp, srcpp, len);
 }
diff --git a/debug/memset_chk.c b/debug/memset_chk.c
index bfbc29d..ef1cadb 100644
--- a/debug/memset_chk.c
+++ b/debug/memset_chk.c
@@ -28,64 +28,5 @@ __memset_chk (dstpp, c, len, dstlen)
   if (__builtin_expect (dstlen < len, 0))
     __chk_fail ();
 
-  long int dstp = (long int) dstpp;
-
-  if (len >= 8)
-    {
-      size_t xlen;
-      op_t cccc;
-
-      cccc = (unsigned char) c;
-      cccc |= cccc << 8;
-      cccc |= cccc << 16;
-      if (OPSIZ > 4)
-	/* Do the shift in two steps to avoid warning if long has 32 bits.  */
-	cccc |= (cccc << 16) << 16;
-
-      /* There are at least some bytes to set.
-	 No need to test for LEN == 0 in this alignment loop.  */
-      while (dstp % OPSIZ != 0)
-	{
-	  ((byte *) dstp)[0] = c;
-	  dstp += 1;
-	  len -= 1;
-	}
-
-      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
-      xlen = len / (OPSIZ * 8);
-      while (xlen > 0)
-	{
-	  ((op_t *) dstp)[0] = cccc;
-	  ((op_t *) dstp)[1] = cccc;
-	  ((op_t *) dstp)[2] = cccc;
-	  ((op_t *) dstp)[3] = cccc;
-	  ((op_t *) dstp)[4] = cccc;
-	  ((op_t *) dstp)[5] = cccc;
-	  ((op_t *) dstp)[6] = cccc;
-	  ((op_t *) dstp)[7] = cccc;
-	  dstp += 8 * OPSIZ;
-	  xlen -= 1;
-	}
-      len %= OPSIZ * 8;
-
-      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
-      xlen = len / OPSIZ;
-      while (xlen > 0)
-	{
-	  ((op_t *) dstp)[0] = cccc;
-	  dstp += OPSIZ;
-	  xlen -= 1;
-	}
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  while (len > 0)
-    {
-      ((byte *) dstp)[0] = c;
-      dstp += 1;
-      len -= 1;
-    }
-
-  return dstpp;
+  return memset (dstpp, c, len);
 }
diff --git a/debug/stpcpy_chk.c b/debug/stpcpy_chk.c
index b16b83d..9984350 100644
--- a/debug/stpcpy_chk.c
+++ b/debug/stpcpy_chk.c
@@ -29,16 +29,7 @@ __stpcpy_chk (dest, src, destlen)
      const char *src;
      size_t destlen;
 {
-  char *d = dest;
-  const char *s = src;
-
-  do
-    {
-      if (__builtin_expect (destlen-- == 0, 0))
-	__chk_fail ();
-      *d++ = *s;
-    }
-  while (*s++ != '\0');
-
-  return d - 1;
+  size_t len = strlen (src) + 1;
+  __memcpy_chk (dest, src, len, destlen);
+  return dest + len - 1;
 }
diff --git a/debug/stpncpy_chk.c b/debug/stpncpy_chk.c
index 35a2c23..f9fa66c 100644
--- a/debug/stpncpy_chk.c
+++ b/debug/stpncpy_chk.c
@@ -31,54 +31,5 @@ __stpncpy_chk (char *dest, const char *src, size_t n, size_t destlen)
   if (__builtin_expect (destlen < n, 0))
     __chk_fail ();
 
-  if (n >= 4)
-    {
-      size_t n4 = n >> 2;
-
-      for (;;)
-	{
-	  c = *src++;
-	  *dest++ = c;
-	  if (c == '\0')
-	    break;
-	  c = *src++;
-	  *dest++ = c;
-	  if (c == '\0')
-	    break;
-	  c = *src++;
-	  *dest++ = c;
-	  if (c == '\0')
-	    break;
-	  c = *src++;
-	  *dest++ = c;
-	  if (c == '\0')
-	    break;
-	  if (--n4 == 0)
-	    goto last_chars;
-	}
-      n -= dest - s;
-      goto zero_fill;
-    }
-
- last_chars:
-  n &= 3;
-  if (n == 0)
-    return dest;
-
-  for (;;)
-    {
-      c = *src++;
-      --n;
-      *dest++ = c;
-      if (c == '\0')
-	break;
-      if (n == 0)
-	return dest;
-    }
-
- zero_fill:
-  while (n-- > 0)
-    dest[n] = '\0';
-
-  return dest - 1;
+  return __stpncpy (dest, src, n);
 }
diff --git a/debug/strcat_chk.c b/debug/strcat_chk.c
index 20623d4..dca6c26 100644
--- a/debug/strcat_chk.c
+++ b/debug/strcat_chk.c
@@ -21,37 +21,16 @@
 
 /* Append SRC on the end of DEST.  */
 char *
-__strcat_chk (dest, src, destlen)
+__strcat_chk (dest, src, totallen)
      char *dest;
      const char *src;
-     size_t destlen;
+     size_t totallen;
 {
-  char *s1 = dest;
-  const char *s2 = src;
-  char c;
-
-  /* Find the end of the string.  */
-  do
-    {
-      if (__builtin_expect (destlen-- == 0, 0))
-	__chk_fail ();
-      c = *s1++;
-    }
-  while (c != '\0');
-
-  /* Make S1 point before the next character, so we can increment
-     it while memory is read (wins on pipelined cpus).  */
-  ++destlen;
-  s1 -= 2;
-
-  do
-    {
-      if (__builtin_expect (destlen-- == 0, 0))
-	__chk_fail ();
-      c = *s2++;
-      *++s1 = c;
-    }
-  while (c != '\0');
+  size_t destlen = strlen (dest);
+  size_t srclen = strlen (src) + 1;
+  if (__builtin_expect (totallen < destlen + srclen, 0))
+	  __chk_fail ();
 
+  memcpy (dest + destlen, src, srclen); 
   return dest;
 }
diff --git a/debug/strcpy_chk.c b/debug/strcpy_chk.c
index 81bf46f..ae37225 100644
--- a/debug/strcpy_chk.c
+++ b/debug/strcpy_chk.c
@@ -28,40 +28,6 @@ __strcpy_chk (dest, src, destlen)
      const char *src;
      size_t destlen;
 {
-  char c;
-  char *s = (char *) src;
-  const ptrdiff_t off = dest - s;
-
-  while (__builtin_expect (destlen >= 4, 0))
-    {
-      c = s[0];
-      s[off] = c;
-      if (c == '\0')
-        return dest;
-      c = s[1];
-      s[off + 1] = c;
-      if (c == '\0')
-        return dest;
-      c = s[2];
-      s[off + 2] = c;
-      if (c == '\0')
-        return dest;
-      c = s[3];
-      s[off + 3] = c;
-      if (c == '\0')
-        return dest;
-      destlen -= 4;
-      s += 4;
-    }
-
-  do
-    {
-      if (__builtin_expect (destlen-- == 0, 0))
-        __chk_fail ();
-      c = *s;
-      *(s++ + off) = c;
-    }
-  while (c != '\0');
-
-  return dest;
+  size_t len = strlen (src) + 1;
+  return __memcpy_chk (dest, src, len, destlen);
 }
diff --git a/debug/strncat_chk.c b/debug/strncat_chk.c
index 5e14aff..394540f 100644
--- a/debug/strncat_chk.c
+++ b/debug/strncat_chk.c
@@ -27,73 +27,13 @@ __strncat_chk (s1, s2, n, s1len)
      size_t n;
      size_t s1len;
 {
-  char c;
-  char *s = s1;
-
-  /* Find the end of S1.  */
-  do
-    {
-      if (__builtin_expect (s1len-- == 0, 0))
-	__chk_fail ();
-      c = *s1++;
-    }
-  while (c != '\0');
-
-  /* Make S1 point before next character, so we can increment
-     it while memory is read (wins on pipelined cpus).  */
-  ++s1len;
-  s1 -= 2;
-
-  if (n >= 4)
-    {
-      size_t n4 = n >> 2;
-      do
-	{
-	  if (__builtin_expect (s1len-- == 0, 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__builtin_expect (s1len-- == 0, 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__builtin_expect (s1len-- == 0, 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	  if (__builtin_expect (s1len-- == 0, 0))
-	    __chk_fail ();
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    return s;
-	} while (--n4 > 0);
-      n &= 3;
-    }
-
-  while (n > 0)
-    {
-      if (__builtin_expect (s1len-- == 0, 0))
-	__chk_fail ();
-      c = *s2++;
-      *++s1 = c;
-      if (c == '\0')
-	return s;
-      n--;
-    }
-
-  if (c != '\0')
-    {
-      if (__builtin_expect (s1len-- == 0, 0))
-	__chk_fail ();
-      *++s1 = '\0';
-    }
-
-  return s;
+  size_t destlen = strlen (s1);
+  size_t srclen = strnlen (s2, n);
+
+  if (s1len < destlen + srclen + 1)
+    __chk_fail (); 
+ 
+  memcpy (s1 + destlen, s2, srclen);
+  s1[destlen + srclen] = '\0';
+  return s1;
 }
diff --git a/debug/strncpy_chk.c b/debug/strncpy_chk.c
index d067bd9..2e078b1 100644
--- a/debug/strncpy_chk.c
+++ b/debug/strncpy_chk.c
@@ -26,63 +26,8 @@ __strncpy_chk (s1, s2, n, s1len)
      size_t n;
      size_t s1len;
 {
-  char c;
-  char *s = s1;
-
   if (__builtin_expect (s1len < n, 0))
     __chk_fail ();
 
-  --s1;
-
-  if (n >= 4)
-    {
-      size_t n4 = n >> 2;
-
-      for (;;)
-	{
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    break;
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    break;
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    break;
-	  c = *s2++;
-	  *++s1 = c;
-	  if (c == '\0')
-	    break;
-	  if (--n4 == 0)
-	    goto last_chars;
-	}
-      n = n - (s1 - s) - 1;
-      if (n == 0)
-	return s;
-      goto zero_fill;
-    }
-
- last_chars:
-  n &= 3;
-  if (n == 0)
-    return s;
-
-  do
-    {
-      c = *s2++;
-      *++s1 = c;
-      if (--n == 0)
-	return s;
-    }
-  while (c != '\0');
-
- zero_fill:
-  do
-    *++s1 = '\0';
-  while (--n > 0);
-
-  return s;
+  return strncpy (s1, s2, n);
 }
diff --git a/sysdeps/x86_64/memcpy.S b/sysdeps/x86_64/memcpy.S
index d6cd553..55c3eae 100644
--- a/sysdeps/x86_64/memcpy.S
+++ b/sysdeps/x86_64/memcpy.S
@@ -44,14 +44,7 @@
 
         .text
 
-#if defined PIC && !defined NOT_IN_libc
-ENTRY_CHK (__memcpy_chk)
 
-	cmpq	%rdx, %rcx
-	jb	HIDDEN_JUMPTARGET (__chk_fail)
-
-END_CHK (__memcpy_chk)
-#endif
 
 ENTRY(memcpy)				/* (void *, const void*, size_t) */
 
diff --git a/sysdeps/x86_64/memcpy_chk.S b/sysdeps/x86_64/memcpy_chk.S
deleted file mode 100644
index c6453c8..0000000
--- a/sysdeps/x86_64/memcpy_chk.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Checking memcpy for x86-64.
-   Copyright (C) 2004-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include "asm-syntax.h"
-
-#ifndef PIC
-	/* For libc.so this is defined in memcpy.S.
-	   For libc.a, this is a separate source to avoid
-	   memcpy bringing in __chk_fail and all routines
-	   it calls.  */
-        .text
-ENTRY (__memcpy_chk)
-	cmpq	%rdx, %rcx
-	jb	__chk_fail
-	jmp	memcpy
-END (__memcpy_chk)
-#endif
diff --git a/sysdeps/x86_64/mempcpy.S b/sysdeps/x86_64/mempcpy.S
index acee5e5..2cbaea5 100644
--- a/sysdeps/x86_64/mempcpy.S
+++ b/sysdeps/x86_64/mempcpy.S
@@ -1,6 +1,5 @@
 #define USE_AS_MEMPCPY
 #define memcpy __mempcpy
-#define __memcpy_chk __mempcpy_chk
 #include <sysdeps/x86_64/memcpy.S>
 
 libc_hidden_def (__mempcpy)
diff --git a/sysdeps/x86_64/mempcpy_chk.S b/sysdeps/x86_64/mempcpy_chk.S
deleted file mode 100644
index 484e584..0000000
--- a/sysdeps/x86_64/mempcpy_chk.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Checking mempcpy for x86-64.
-   Copyright (C) 2004-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include "asm-syntax.h"
-
-#ifndef PIC
-	/* For libc.so this is defined in memcpy.S.
-	   For libc.a, this is a separate source to avoid
-	   mempcpy bringing in __chk_fail and all routines
-	   it calls.  */
-        .text
-ENTRY (__mempcpy_chk)
-	cmpq	%rdx, %rcx
-	jb	__chk_fail
-	jmp	mempcpy
-END (__mempcpy_chk)
-#endif
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
index 9b1de89..65b5ced 100644
--- a/sysdeps/x86_64/memset.S
+++ b/sysdeps/x86_64/memset.S
@@ -42,12 +42,7 @@ ENTRY(__memset_tail)
 END(__memset_tail)
 #endif
 
-#if defined PIC && !defined NOT_IN_libc
-ENTRY_CHK (__memset_chk)
-	cmpq	%rdx, %rcx
-	jb	HIDDEN_JUMPTARGET (__chk_fail)
-END_CHK (__memset_chk)
-#endif
+
 
 ENTRY (memset)
 	movd	%esi, %xmm8
diff --git a/sysdeps/x86_64/memset_chk.S b/sysdeps/x86_64/memset_chk.S
deleted file mode 100644
index c17f22a..0000000
--- a/sysdeps/x86_64/memset_chk.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Checking memset for x86-64.
-   Copyright (C) 2004-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include "asm-syntax.h"
-
-#ifndef SHARED
-	/* For libc.so this is defined in memset.S.
-	   For libc.a, this is a separate source to avoid
-	   memset bringing in __chk_fail and all routines
-	   it calls.  */
-        .text
-ENTRY (__memset_chk)
-	cmpq	%rdx, %rcx
-	jb	__chk_fail
-	jmp	memset
-END (__memset_chk)
-#endif
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index 71beab8..fa3389c 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -44,15 +44,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_SSSE3, __memcmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_sse2))
 
-  /* Support sysdeps/x86_64/multiarch/memmove_chk.S.  */
-  IFUNC_IMPL (i, name, __memmove_chk,
-	      IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3,
-			      __memmove_chk_ssse3_back)
-	      IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3,
-			      __memmove_chk_ssse3)
-	      IFUNC_IMPL_ADD (array, i, __memmove_chk, 1,
-			      __memmove_chk_sse2))
-
   /* Support sysdeps/x86_64/multiarch/memmove.S.  */
   IFUNC_IMPL (i, name, memmove,
 	      IFUNC_IMPL_ADD (array, i, memmove, HAS_SSSE3,
@@ -201,15 +192,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_sse2))
 
 #ifdef SHARED
-  /* Support sysdeps/x86_64/multiarch/memcpy_chk.S.  */
-  IFUNC_IMPL (i, name, __memcpy_chk,
-	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3,
-			      __memcpy_chk_ssse3_back)
-	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3,
-			      __memcpy_chk_ssse3)
-	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
-			      __memcpy_chk_sse2))
-
   /* Support sysdeps/x86_64/multiarch/memcpy.S.  */
   IFUNC_IMPL (i, name, memcpy,
 	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_SSSE3,
@@ -218,15 +200,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_sse2_unaligned)
 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_sse2))
 
-  /* Support sysdeps/x86_64/multiarch/mempcpy_chk.S.  */
-  IFUNC_IMPL (i, name, __mempcpy_chk,
-	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3,
-			      __mempcpy_chk_ssse3_back)
-	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3,
-			      __mempcpy_chk_ssse3)
-	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
-			      __mempcpy_chk_sse2))
-
   /* Support sysdeps/x86_64/multiarch/mempcpy.S.  */
   IFUNC_IMPL (i, name, mempcpy,
 	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_SSSE3,
diff --git a/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S b/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
index 0eb7d9b..ab4d4d9 100644
--- a/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
+++ b/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
@@ -28,7 +28,6 @@
 
 #ifndef MEMCPY
 # define MEMCPY		__memcpy_ssse3_back
-# define MEMCPY_CHK	__memcpy_chk_ssse3_back
 #endif
 
 #define JMPTBL(I, B)	I - B
@@ -44,12 +43,7 @@
   ud2
 
 	.section .text.ssse3,"ax",@progbits
-#if !defined USE_AS_BCOPY
-ENTRY (MEMCPY_CHK)
-	cmpq	%rdx, %rcx
-	jb	HIDDEN_JUMPTARGET (__chk_fail)
-END (MEMCPY_CHK)
-#endif
+
 
 ENTRY (MEMCPY)
 	mov	%rdi, %rax
diff --git a/sysdeps/x86_64/multiarch/memcpy-ssse3.S b/sysdeps/x86_64/multiarch/memcpy-ssse3.S
index 0cedab2..691f7d9 100644
--- a/sysdeps/x86_64/multiarch/memcpy-ssse3.S
+++ b/sysdeps/x86_64/multiarch/memcpy-ssse3.S
@@ -28,7 +28,6 @@
 
 #ifndef MEMCPY
 # define MEMCPY		__memcpy_ssse3
-# define MEMCPY_CHK	__memcpy_chk_ssse3
 #endif
 
 #define JMPTBL(I, B)	I - B
@@ -44,12 +43,6 @@
   ud2
 
 	.section .text.ssse3,"ax",@progbits
-#if !defined USE_AS_BCOPY
-ENTRY (MEMCPY_CHK)
-	cmpq	%rdx, %rcx
-	jb	HIDDEN_JUMPTARGET (__chk_fail)
-END (MEMCPY_CHK)
-#endif
 
 ENTRY (MEMCPY)
 	mov	%rdi, %rax
diff --git a/sysdeps/x86_64/multiarch/memcpy.S b/sysdeps/x86_64/multiarch/memcpy.S
index a1e5031..373397c 100644
--- a/sysdeps/x86_64/multiarch/memcpy.S
+++ b/sysdeps/x86_64/multiarch/memcpy.S
@@ -55,17 +55,6 @@ END(__new_memcpy)
 # define END(name) \
 	cfi_endproc; .size __memcpy_sse2, .-__memcpy_sse2
 
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memcpy_chk_sse2, @function; \
-	.globl __memcpy_chk_sse2; \
-	.p2align 4; \
-	__memcpy_chk_sse2: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memcpy_chk_sse2, .-__memcpy_chk_sse2
-
 # undef libc_hidden_builtin_def
 /* It doesn't make sense to send libc-internal memcpy calls through a PLT.
    The speedup we get from using SSSE3 instruction is likely eaten away
diff --git a/sysdeps/x86_64/multiarch/memcpy_chk.S b/sysdeps/x86_64/multiarch/memcpy_chk.S
deleted file mode 100644
index ad01d8c..0000000
--- a/sysdeps/x86_64/multiarch/memcpy_chk.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Multiple versions of __memcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2013 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch memcpy functions for static binaries.
- */
-#ifndef NOT_IN_libc
-# ifdef SHARED
-	.text
-ENTRY(__memcpy_chk)
-	.type	__memcpy_chk, @gnu_indirect_function
-	cmpl	$0, KIND_OFFSET+__cpu_features(%rip)
-	jne	1f
-	call	__init_cpu_features
-1:	leaq	__memcpy_chk_sse2(%rip), %rax
-	testl	$bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
-	jz	2f
-	leaq	__memcpy_chk_ssse3(%rip), %rax
-	testl	$bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip)
-	jz	2f
-	leaq	__memcpy_chk_ssse3_back(%rip), %rax
-2:	ret
-END(__memcpy_chk)
-# else
-#  include "../memcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/x86_64/multiarch/memmove-ssse3-back.S b/sysdeps/x86_64/multiarch/memmove-ssse3-back.S
index f9a4e9a..084ad3d 100644
--- a/sysdeps/x86_64/multiarch/memmove-ssse3-back.S
+++ b/sysdeps/x86_64/multiarch/memmove-ssse3-back.S
@@ -1,4 +1,3 @@
 #define USE_AS_MEMMOVE
 #define MEMCPY		__memmove_ssse3_back
-#define MEMCPY_CHK	__memmove_chk_ssse3_back
 #include "memcpy-ssse3-back.S"
diff --git a/sysdeps/x86_64/multiarch/memmove-ssse3.S b/sysdeps/x86_64/multiarch/memmove-ssse3.S
index 295430b..d861ec5 100644
--- a/sysdeps/x86_64/multiarch/memmove-ssse3.S
+++ b/sysdeps/x86_64/multiarch/memmove-ssse3.S
@@ -1,4 +1,3 @@
 #define USE_AS_MEMMOVE
 #define MEMCPY		__memmove_ssse3
-#define MEMCPY_CHK	__memmove_chk_ssse3
 #include "memcpy-ssse3.S"
diff --git a/sysdeps/x86_64/multiarch/memmove_chk.c b/sysdeps/x86_64/multiarch/memmove_chk.c
deleted file mode 100644
index 17ed460..0000000
--- a/sysdeps/x86_64/multiarch/memmove_chk.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Multiple versions of __memmove_chk.
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <string.h>
-#include "init-arch.h"
-
-#define MEMMOVE_CHK __memmove_chk_sse2
-
-extern __typeof (__memmove_chk) __memmove_chk_sse2 attribute_hidden;
-extern __typeof (__memmove_chk) __memmove_chk_ssse3 attribute_hidden;
-extern __typeof (__memmove_chk) __memmove_chk_ssse3_back attribute_hidden;
-
-#include "debug/memmove_chk.c"
-
-libc_ifunc (__memmove_chk,
-	    HAS_SSSE3
-	    ? (HAS_FAST_COPY_BACKWARD
-	       ? __memmove_chk_ssse3_back : __memmove_chk_ssse3)
-	    : __memmove_chk_sse2);
diff --git a/sysdeps/x86_64/multiarch/mempcpy-ssse3-back.S b/sysdeps/x86_64/multiarch/mempcpy-ssse3-back.S
index 82ffacb..21d443e 100644
--- a/sysdeps/x86_64/multiarch/mempcpy-ssse3-back.S
+++ b/sysdeps/x86_64/multiarch/mempcpy-ssse3-back.S
@@ -1,4 +1,3 @@
 #define USE_AS_MEMPCPY
 #define MEMCPY		__mempcpy_ssse3_back
-#define MEMCPY_CHK	__mempcpy_chk_ssse3_back
 #include "memcpy-ssse3-back.S"
diff --git a/sysdeps/x86_64/multiarch/mempcpy-ssse3.S b/sysdeps/x86_64/multiarch/mempcpy-ssse3.S
index 822d98e..dd8f23a 100644
--- a/sysdeps/x86_64/multiarch/mempcpy-ssse3.S
+++ b/sysdeps/x86_64/multiarch/mempcpy-ssse3.S
@@ -1,4 +1,3 @@
 #define USE_AS_MEMPCPY
 #define MEMCPY		__mempcpy_ssse3
-#define MEMCPY_CHK	__mempcpy_chk_ssse3
 #include "memcpy-ssse3.S"
diff --git a/sysdeps/x86_64/multiarch/mempcpy.S b/sysdeps/x86_64/multiarch/mempcpy.S
index b8b7fcd..16da84f 100644
--- a/sysdeps/x86_64/multiarch/mempcpy.S
+++ b/sysdeps/x86_64/multiarch/mempcpy.S
@@ -52,16 +52,6 @@ END(__mempcpy)
 # define END(name) \
 	cfi_endproc; .size __mempcpy_sse2, .-__mempcpy_sse2
 
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __mempcpy_chk_sse2, @function; \
-	.globl __mempcpy_chk_sse2; \
-	.p2align 4; \
-	__mempcpy_chk_sse2: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __mempcpy_chk_sse2, .-__mempcpy_chk_sse2
 
 # undef libc_hidden_def
 # undef libc_hidden_builtin_def
diff --git a/sysdeps/x86_64/multiarch/mempcpy_chk.S b/sysdeps/x86_64/multiarch/mempcpy_chk.S
deleted file mode 100644
index 3801db3..0000000
--- a/sysdeps/x86_64/multiarch/mempcpy_chk.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Multiple versions of __mempcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2013 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch mempcpy functions for static binaries.
- */
-#ifndef NOT_IN_libc
-# ifdef SHARED
-	.text
-ENTRY(__mempcpy_chk)
-	.type	__mempcpy_chk, @gnu_indirect_function
-	cmpl	$0, KIND_OFFSET+__cpu_features(%rip)
-	jne	1f
-	call	__init_cpu_features
-1:	leaq	__mempcpy_chk_sse2(%rip), %rax
-	testl	$bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip)
-	jz	2f
-	leaq	__mempcpy_chk_ssse3(%rip), %rax
-	testl	$bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip)
-	jz	2f
-	leaq	__mempcpy_chk_ssse3_back(%rip), %rax
-2:	ret
-END(__mempcpy_chk)
-# else
-#  include "../mempcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/x86_64/stpcpy_chk.S b/sysdeps/x86_64/stpcpy_chk.S
deleted file mode 100644
index 905e8d7..0000000
--- a/sysdeps/x86_64/stpcpy_chk.S
+++ /dev/null
@@ -1,3 +0,0 @@
-#define USE_AS_STPCPY_CHK
-#define STRCPY_CHK __stpcpy_chk
-#include <sysdeps/x86_64/strcpy_chk.S>
diff --git a/sysdeps/x86_64/strcpy_chk.S b/sysdeps/x86_64/strcpy_chk.S
deleted file mode 100644
index 7e171de..0000000
--- a/sysdeps/x86_64/strcpy_chk.S
+++ /dev/null
@@ -1,208 +0,0 @@
-/* strcpy/stpcpy checking implementation for x86-64.
-   Copyright (C) 2002-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Andreas Jaeger <aj@suse.de>, 2002.
-   Adopted into checking version by Jakub Jelinek <jakub@redhat.com>.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include "asm-syntax.h"
-
-#ifndef USE_AS_STPCPY_CHK
-# define STRCPY_CHK __strcpy_chk
-#endif
-
-	.text
-ENTRY (STRCPY_CHK)
-	movq	%rsi, %rcx	/* Source register. */
-	andl	$7, %ecx	/* mask alignment bits */
-#ifndef USE_AS_STPCPY_CHK
-	movq	%rdi, %r10	/* Duplicate destination pointer.  */
-#endif
-	jz 5f			/* aligned => start loop */
-
-	cmpq	$8, %rdx	/* Check if only few bytes left in
-				   destination.  */
-	jb	50f
-
-	subq	$8, %rcx	/* We need to align to 8 bytes.  */
-	addq	%rcx, %rdx	/* Subtract count of stored bytes
-				   in the cycle below from destlen.  */
-
-	/* Search the first bytes directly.  */
-0:
-	movb	(%rsi), %al	/* Fetch a byte */
-	testb	%al, %al	/* Is it NUL? */
-	movb	%al, (%rdi)	/* Store it */
-	jz	4f		/* If it was NUL, done! */
-	incq	%rsi
-	incq	%rdi
-	incl	%ecx
-	jnz	0b
-
-5:
-	movq $0xfefefefefefefeff,%r8
-	cmpq	$32, %rdx	/* Are there enough bytes in destination
-				   for the next unrolled round?  */
-	jb	60f		/* If not, avoid the unrolled loop.  */
-
-	/* Now the sources is aligned.  Unfortunatly we cannot force
-	   to have both source and destination aligned, so ignore the
-	   alignment of the destination.  */
-	.p2align 4
-1:
-	/* 1st unroll.  */
-	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
-	addq	$8, %rsi	/* Adjust pointer for next word.  */
-	movq	%rax, %r9	/* Save a copy for NUL finding.  */
-	addq	%r8, %r9	/* add the magic value to the word.  We get
-				   carry bits reported for each byte which
-				   is *not* 0 */
-	jnc	3f		/* highest byte is NUL => return pointer */
-	xorq	%rax, %r9	/* (word+magic)^word */
-	orq	%r8, %r9	/* set all non-carry bits */
-	incq	%r9		/* add 1: if one carry bit was *not* set
-				   the addition will not result in 0.  */
-
-	jnz	3f		/* found NUL => return pointer */
-
-	movq	%rax, (%rdi)	/* Write value to destination.  */
-	addq	$8, %rdi	/* Adjust pointer.  */
-
-	/* 2nd unroll.  */
-	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
-	addq	$8, %rsi	/* Adjust pointer for next word.  */
-	movq	%rax, %r9	/* Save a copy for NUL finding.  */
-	addq	%r8, %r9	/* add the magic value to the word.  We get
-				   carry bits reported for each byte which
-				   is *not* 0 */
-	jnc	3f		/* highest byte is NUL => return pointer */
-	xorq	%rax, %r9	/* (word+magic)^word */
-	orq	%r8, %r9	/* set all non-carry bits */
-	incq	%r9		/* add 1: if one carry bit was *not* set
-				   the addition will not result in 0.  */
-
-	jnz	3f		/* found NUL => return pointer */
-
-	movq	%rax, (%rdi)	/* Write value to destination.  */
-	addq	$8, %rdi	/* Adjust pointer.  */
-
-	/* 3rd unroll.  */
-	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
-	addq	$8, %rsi	/* Adjust pointer for next word.  */
-	movq	%rax, %r9	/* Save a copy for NUL finding.  */
-	addq	%r8, %r9	/* add the magic value to the word.  We get
-				   carry bits reported for each byte which
-				   is *not* 0 */
-	jnc	3f		/* highest byte is NUL => return pointer */
-	xorq	%rax, %r9	/* (word+magic)^word */
-	orq	%r8, %r9	/* set all non-carry bits */
-	incq	%r9		/* add 1: if one carry bit was *not* set
-				   the addition will not result in 0.  */
-
-	jnz	3f		/* found NUL => return pointer */
-
-	movq	%rax, (%rdi)	/* Write value to destination.  */
-	addq	$8, %rdi	/* Adjust pointer.  */
-
-	/* 4th unroll.  */
-	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
-	addq	$8, %rsi	/* Adjust pointer for next word.  */
-	movq	%rax, %r9	/* Save a copy for NUL finding.  */
-	addq	%r8, %r9	/* add the magic value to the word.  We get
-				   carry bits reported for each byte which
-				   is *not* 0 */
-	jnc	3f		/* highest byte is NUL => return pointer */
-	xorq	%rax, %r9	/* (word+magic)^word */
-	orq	%r8, %r9	/* set all non-carry bits */
-	incq	%r9		/* add 1: if one carry bit was *not* set
-				   the addition will not result in 0.  */
-
-	jnz	3f		/* found NUL => return pointer */
-
-	subq	$32, %rdx	/* Adjust destlen.  */
-	movq	%rax, (%rdi)	/* Write value to destination.  */
-	addq	$8, %rdi	/* Adjust pointer.  */
-	cmpq	$32, %rdx	/* Are there enough bytes in destination
-				   for the next unrolled round?  */
-	jae	1b		/* Next iteration.  */
-
-60:
-	cmpq	$8, %rdx	/* Are there enough bytes in destination
-				   for the next unrolled round?  */
-	jb	50f		/* Now, copy and check byte by byte.  */
-
-	movq	(%rsi), %rax	/* Read double word (8 bytes).  */
-	addq	$8, %rsi	/* Adjust pointer for next word.  */
-	movq	%rax, %r9	/* Save a copy for NUL finding.  */
-	addq	%r8, %r9	/* add the magic value to the word.  We get
-				   carry bits reported for each byte which
-				   is *not* 0 */
-	jnc	3f		/* highest byte is NUL => return pointer */
-	xorq	%rax, %r9	/* (word+magic)^word */
-	orq	%r8, %r9	/* set all non-carry bits */
-	incq	%r9		/* add 1: if one carry bit was *not* set
-				   the addition will not result in 0.  */
-
-	jnz	3f		/* found NUL => return pointer */
-
-	subq	$8, %rdx	/* Adjust destlen.  */
-	movq	%rax, (%rdi)	/* Write value to destination.  */
-	addq	$8, %rdi	/* Adjust pointer.  */
-	jmp	60b		/* Next iteration.  */
-
-	/* Do the last few bytes. %rax contains the value to write.
-	   The loop is unrolled twice.  */
-	.p2align 4
-3:
-	/* Note that stpcpy needs to return with the value of the NUL
-	   byte.  */
-	movb	%al, (%rdi)	/* 1st byte.  */
-	testb	%al, %al	/* Is it NUL.  */
-	jz	4f		/* yes, finish.  */
-	incq	%rdi		/* Increment destination.  */
-	movb	%ah, (%rdi)	/* 2nd byte.  */
-	testb	%ah, %ah	/* Is it NUL?.  */
-	jz	4f		/* yes, finish.  */
-	incq	%rdi		/* Increment destination.  */
-	shrq	$16, %rax	/* Shift...  */
-	jmp	3b		/* and look at next two bytes in %rax.  */
-
-51:
-	/* Search the bytes directly, checking for overflows.  */
-	incq	%rsi
-	incq	%rdi
-	decq	%rdx
-	jz	HIDDEN_JUMPTARGET (__chk_fail)
-52:
-	movb	(%rsi), %al	/* Fetch a byte */
-	testb	%al, %al	/* Is it NUL? */
-	movb	%al, (%rdi)	/* Store it */
-	jnz	51b		/* If it was NUL, done! */
-4:
-#ifdef USE_AS_STPCPY_CHK
-	movq	%rdi, %rax	/* Destination is return value.  */
-#else
-	movq	%r10, %rax	/* Source is return value.  */
-#endif
-	retq
-
-50:
-	testq	%rdx, %rdx
-	jnz	52b
-	jmp	HIDDEN_JUMPTARGET (__chk_fail)
-
-END (STRCPY_CHK)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]