From 45db99c7d03e497a3320907e722270fb7ee852f3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 3 Oct 2010 22:10:30 -0400 Subject: [PATCH] Fix handling of tail bytes of buffer in SSE2/SSSE3 x86-64 version strn{,case}cmp --- ChangeLog | 8 +++ string/stratcliff.c | 144 +++++++++++++++++++++++++++++----------- sysdeps/x86_64/strcmp.S | 32 ++++----- wcsmbs/wcsatcliff.c | 2 + 4 files changed, 133 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index a49e12a0eb..c0c1600af9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-10-03 Ulrich Drepper + + [BZ #12077] + * sysdeps/x86_64/strcmp.S: Fix handling of remaining bytes in buffer + for strncmp and strncasecmp. + * string/stratcliff.c: Add tests for strcmp and strncmp. + * wcsmbs/wcsatcliff.c: Adjust for stratcliff change. + 2010-09-28 Nobuhiro Iwamatsu * sysdeps/sh/sh4/fpu/fpu_control.h: Add 'extern "C"' protection to diff --git a/string/stratcliff.c b/string/stratcliff.c index 2bb59820f9..5165be2d13 100644 --- a/string/stratcliff.c +++ b/string/stratcliff.c @@ -1,5 +1,6 @@ /* Test for string function add boundaries of usable memory. - Copyright (C) 1996,1997,1999-2003,2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1996,1997,1999-2003,2007,2009,2010 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -47,6 +48,8 @@ # define MEMCPY memcpy # define MEMPCPY mempcpy # define MEMCHR memchr +# define STRCMP strcmp +# define STRNCMP strncmp #endif @@ -70,12 +73,12 @@ do_test (void) if (adr == MAP_FAILED || dest == MAP_FAILED) { if (errno == ENOSYS) - puts ("No test, mmap not available."); + puts ("No test, mmap not available."); else - { - printf ("mmap failed: %m"); - result = 1; - } + { + printf ("mmap failed: %m"); + result = 1; + } } else { @@ -93,8 +96,8 @@ do_test (void) /* strlen/wcslen test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { - for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) + { + for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) { adr[inner] = L('\0'); @@ -107,12 +110,12 @@ do_test (void) adr[inner] = L('T'); } - } + } /* strnlen/wcsnlen test */ for (outer = nchars; outer >= MAX (0, nchars - 128); --outer) - { - for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) + { + for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) { adr[inner] = L('\0'); @@ -126,9 +129,9 @@ do_test (void) adr[inner] = L('T'); } - } + } for (outer = nchars; outer >= MAX (0, nchars - 128); --outer) - { + { for (inner = MAX (outer, nchars - 64); inner <= nchars; ++inner) { if (STRNLEN (&adr[outer], inner - outer) @@ -139,11 +142,11 @@ do_test (void) result = 1; } } - } + } /* strchr/wcschr test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { + { for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) { for (inner = middle; inner < nchars; ++inner) @@ -167,7 +170,7 @@ do_test (void) adr[middle] = L('T'); } } - } + } /* Special test. */ adr[nchars - 1] = L('\0'); @@ -180,7 +183,7 @@ do_test (void) /* strrchr/wcsrchr test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { + { for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) { for (inner = middle; inner < nchars; ++inner) @@ -204,11 +207,11 @@ do_test (void) adr[middle] = L('T'); } } - } + } /* memchr test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { + { for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) { adr[middle] = L('V'); @@ -224,9 +227,9 @@ do_test (void) adr[middle] = L('T'); } - } + } for (outer = nchars; outer >= MAX (0, nchars - 128); --outer) - { + { CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer); if (cp != NULL) @@ -235,13 +238,13 @@ do_test (void) STRINGIFY (MEMCHR), outer); result = 1; } - } + } /* This function only exists for single-byte characters. */ #ifndef WCSTEST /* rawmemchr test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { + { for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) { adr[middle] = L('V'); @@ -257,13 +260,13 @@ do_test (void) adr[middle] = L('T'); } - } + } #endif /* strcpy/wcscpy test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { - for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) + { + for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) { adr[inner] = L('\0'); @@ -277,7 +280,74 @@ do_test (void) adr[inner] = L('T'); } - } + } + + /* strcmp/wcscmp tests */ + for (outer = 1; outer < 32; ++outer) + for (middle = 0; middle < 16; ++middle) + { + MEMSET (adr + middle, L('T'), 256); + adr[256] = L('\0'); + MEMSET (dest + nchars - outer, L('T'), outer - 1); + dest[nchars - 1] = L('\0'); + + if (STRCMP (adr + middle, dest + nchars - outer) <= 0) + { + printf ("%s 1 flunked for outer = %d, middle = %d\n", + STRINGIFY (STRCMP), outer, middle); + result = 1; + } + + if (STRCMP (dest + nchars - outer, adr + middle) >= 0) + { + printf ("%s 2 flunked for outer = %d, middle = %d\n", + STRINGIFY (STRCMP), outer, middle); + result = 1; + } + } + + /* strncmp/wcsncmp tests */ + for (outer = 1; outer < 32; ++outer) + for (middle = 0; middle < 16; ++middle) + { + MEMSET (adr + middle, L('T'), 256); + adr[256] = L('\0'); + MEMSET (dest + nchars - outer, L('T'), outer - 1); + dest[nchars - 1] = L('U'); + + for (inner = 0; inner < outer; ++inner) + { + if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0) + { + printf ("%s 1 flunked for outer = %d, middle = %d, " + "inner = %d\n", + STRINGIFY (STRNCMP), outer, middle, inner); + result = 1; + } + + if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0) + { + printf ("%s 2 flunked for outer = %d, middle = %d, " + "inner = %d\n", + STRINGIFY (STRNCMP), outer, middle, inner); + result = 1; + } + } + + if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0) + { + printf ("%s 1 flunked for outer = %d, middle = %d, full\n", + STRINGIFY (STRNCMP), outer, middle); + result = 1; + } + + if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0) + { + printf ("%s 2 flunked for outer = %d, middle = %d, full\n", + STRINGIFY (STRNCMP), outer, middle); + result = 1; + } + } /* strncpy/wcsncpy tests */ adr[nchars - 1] = L('T'); @@ -295,12 +365,12 @@ do_test (void) result = 1; } } - } + } adr[nchars - 1] = L('\0'); for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { - for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) + { + for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) { size_t len; @@ -334,12 +404,12 @@ do_test (void) adr[inner] = L('T'); } - } + } /* stpcpy/wcpcpy test */ for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { - for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) + { + for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner) { adr[inner] = L('\0'); @@ -352,7 +422,7 @@ do_test (void) adr[inner] = L('T'); } - } + } /* stpncpy/wcpncpy test */ adr[nchars - 1] = L('T'); @@ -374,8 +444,8 @@ do_test (void) adr[nchars - 1] = L('\0'); for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer) - { - for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) + { + for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle) { adr[middle] = L('\0'); @@ -393,7 +463,7 @@ do_test (void) adr[middle] = L('T'); } - } + } /* memcpy/wmemcpy test */ for (outer = nchars; outer >= MAX (0, nchars - 128); --outer) diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S index 2c77265e5b..165073e907 100644 --- a/sysdeps/x86_64/strcmp.S +++ b/sysdeps/x86_64/strcmp.S @@ -458,7 +458,7 @@ LABEL(nibble_ashr_1): jnz LABEL(ashr_1_exittail) /* find null char*/ # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $14, %r11 + cmp $15, %r11 jbe LABEL(ashr_1_exittail) # endif @@ -586,7 +586,7 @@ LABEL(nibble_ashr_2): jnz LABEL(ashr_2_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $13, %r11 + cmp $14, %r11 jbe LABEL(ashr_2_exittail) # endif @@ -711,7 +711,7 @@ LABEL(nibble_ashr_3): jnz LABEL(ashr_3_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $12, %r11 + cmp $13, %r11 jbe LABEL(ashr_3_exittail) # endif @@ -836,7 +836,7 @@ LABEL(nibble_ashr_4): jnz LABEL(ashr_4_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $11, %r11 + cmp $12, %r11 jbe LABEL(ashr_4_exittail) # endif @@ -961,7 +961,7 @@ LABEL(nibble_ashr_5): jnz LABEL(ashr_5_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $10, %r11 + cmp $11, %r11 jbe LABEL(ashr_5_exittail) # endif @@ -1086,7 +1086,7 @@ LABEL(nibble_ashr_6): jnz LABEL(ashr_6_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $9, %r11 + cmp $10, %r11 jbe LABEL(ashr_6_exittail) # endif @@ -1211,7 +1211,7 @@ LABEL(nibble_ashr_7): jnz LABEL(ashr_7_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $8, %r11 + cmp $9, %r11 jbe LABEL(ashr_7_exittail) # endif @@ -1336,7 +1336,7 @@ LABEL(nibble_ashr_8): jnz LABEL(ashr_8_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $7, %r11 + cmp $8, %r11 jbe LABEL(ashr_8_exittail) # endif @@ -1461,7 +1461,7 @@ LABEL(nibble_ashr_9): jnz LABEL(ashr_9_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $6, %r11 + cmp $7, %r11 jbe LABEL(ashr_9_exittail) # endif @@ -1586,7 +1586,7 @@ LABEL(nibble_ashr_10): jnz LABEL(ashr_10_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $5, %r11 + cmp $6, %r11 jbe LABEL(ashr_10_exittail) # endif @@ -1711,7 +1711,7 @@ LABEL(nibble_ashr_11): jnz LABEL(ashr_11_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $4, %r11 + cmp $5, %r11 jbe LABEL(ashr_11_exittail) # endif @@ -1836,7 +1836,7 @@ LABEL(nibble_ashr_12): jnz LABEL(ashr_12_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $3, %r11 + cmp $4, %r11 jbe LABEL(ashr_12_exittail) # endif @@ -1961,7 +1961,7 @@ LABEL(nibble_ashr_13): jnz LABEL(ashr_13_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $2, %r11 + cmp $3, %r11 jbe LABEL(ashr_13_exittail) # endif @@ -2086,7 +2086,7 @@ LABEL(nibble_ashr_14): jnz LABEL(ashr_14_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - cmp $1, %r11 + cmp $2, %r11 jbe LABEL(ashr_14_exittail) # endif @@ -2213,8 +2213,8 @@ LABEL(nibble_ashr_15): jnz LABEL(ashr_15_exittail) # if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L - test %r11, %r11 - je LABEL(ashr_15_exittail) + cmpq $1, %r11 + jbe LABEL(ashr_15_exittail) # endif pxor %xmm0, %xmm0 diff --git a/wcsmbs/wcsatcliff.c b/wcsmbs/wcsatcliff.c index b29571f294..95afff6098 100644 --- a/wcsmbs/wcsatcliff.c +++ b/wcsmbs/wcsatcliff.c @@ -16,6 +16,8 @@ #define MEMCPY wmemcpy #define MEMPCPY wmempcpy #define MEMCHR wmemchr +#define STRCMP wcscmp +#define STRNCMP wcsncmp #include "../string/stratcliff.c"