This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Improve str(n)cat_chk performance.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org
- Date: Thu, 20 Aug 2015 09:35:17 +0200
- Subject: [PATCH] Improve str(n)cat_chk performance.
- Authentication-results: sourceware.org; auth=none
Here we sync implementation with strcat/strncat generic one. That makes
performance comparable with strcat instead of slow byte-by-byte loop.
Ok to commit this?
* debug/strcat_chk.c (__strcat_chk): Sync with generic implementation.
* debug/strncat_chk.c (__strncat_chk): Likewise.
diff --git a/debug/strcat_chk.c b/debug/strcat_chk.c
index 8d7359f..8f26012 100644
--- a/debug/strcat_chk.c
+++ b/debug/strcat_chk.c
@@ -16,8 +16,6 @@
<http://www.gnu.org/licenses/>. */
#include <string.h>
-#include <memcopy.h>
-
/* Append SRC on the end of DEST. */
char *
@@ -26,32 +24,12 @@ __strcat_chk (dest, src, destlen)
const char *src;
size_t destlen;
{
- char *s1 = dest;
- const char *s2 = src;
- char c;
-
- /* Find the end of the string. */
- do
- {
- if (__glibc_unlikely (destlen-- == 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 (__glibc_unlikely (destlen-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- }
- while (c != '\0');
+ size_t len = strlen (dest);
+ size_t srclen = strlen (src);
+ if (__glibc_unlikely (len + srclen + 1 > destlen))
+ __chk_fail ();
+
+ memcpy (dest + len, src, srclen + 1);
return dest;
}
diff --git a/debug/strncat_chk.c b/debug/strncat_chk.c
index 2951d05..c0a68c5 100644
--- a/debug/strncat_chk.c
+++ b/debug/strncat_chk.c
@@ -17,83 +17,16 @@
#include <string.h>
-#include <memcopy.h>
-
-
char *
-__strncat_chk (s1, s2, n, s1len)
- char *s1;
- const char *s2;
- size_t n;
- size_t s1len;
+__strncat_chk (char *dest, const char *src, size_t n, size_t destlen)
{
- char c;
- char *s = s1;
-
- /* Find the end of S1. */
- do
- {
- if (__glibc_unlikely (s1len-- == 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 (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- if (c == '\0')
- return s;
- if (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- if (c == '\0')
- return s;
- if (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- if (c == '\0')
- return s;
- if (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- if (c == '\0')
- return s;
- } while (--n4 > 0);
- n &= 3;
- }
-
- while (n > 0)
- {
- if (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- c = *s2++;
- *++s1 = c;
- if (c == '\0')
- return s;
- n--;
- }
+ size_t len = strlen (dest);
+ size_t srclen = __strnlen (src, n);
- if (c != '\0')
- {
- if (__glibc_unlikely (s1len-- == 0))
- __chk_fail ();
- *++s1 = '\0';
- }
+ if (__glibc_unlikely (len + srclen + 1 > destlen))
+ __chk_fail ();
- return s;
+ dest[len + srclen] = 0;
+ memcpy (dest + len, src, srclen);
+ return dest;
}