From 94aca5e740d6101f91002d027776252340f6abef Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Tue, 11 Jun 2013 20:51:55 +0530 Subject: Port remaining string benchmarks There were a few more string benchmarks (strcpy_chk and stpcpy_check) in the debug directory that needed to be ported over. --- ChangeLog | 12 ++ benchtests/Makefile | 3 +- benchtests/bench-stpcpy_chk-ifunc.c | 20 +++ benchtests/bench-stpcpy_chk.c | 45 +++++++ benchtests/bench-strcpy_chk-ifunc.c | 20 +++ benchtests/bench-strcpy_chk.c | 262 ++++++++++++++++++++++++++++++++++++ debug/test-strcpy_chk.c | 24 ---- 7 files changed, 361 insertions(+), 25 deletions(-) create mode 100644 benchtests/bench-stpcpy_chk-ifunc.c create mode 100644 benchtests/bench-stpcpy_chk.c create mode 100644 benchtests/bench-strcpy_chk-ifunc.c create mode 100644 benchtests/bench-strcpy_chk.c diff --git a/ChangeLog b/ChangeLog index f2f9f7da03..3a451b4efc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2013-06-11 Siddhesh Poyarekar + + * benchtests/Makefile (string-bench): Add strcpy_chk and + stpcpy_chk. + * benchtests/bench-stpcpy_chk-ifunc.c: New file. + * benchtests/bench-stpcpy_chk.c: New file. + * benchtests/bench-strcpy_chk-ifunc.c: New file. + * benchtests/bench-strcpy_chk.c: New file. + * debug/test-strcpy_chk.c (do_one_test): Remove HP_TIMING + code. + (do_test): Likewise. + 2013-06-11 Ryan S. Arnold * sysdeps/powerpc/dl-procinfo.c (_dl_powerpc_platforms): Add ppc405, diff --git a/benchtests/Makefile b/benchtests/Makefile index 5023c7c9c2..ba313d2cf8 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -27,7 +27,8 @@ bench := acos acosh asin asinh atan atanh cos cosh exp log modf pow rint sin \ string-bench := bcopy bzero memccpy memchr memcmp memmem memmove mempcpy \ memset rawmemchr stpcpy stpncpy strcasecmp strcasestr strcat \ strchr strchrnul strcmp strcpy strcspn strlen strncasecmp \ - strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr + strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr \ + strcpy_chk stpcpy_chk string-bench-ifunc := $(addsuffix -ifunc, $(string-bench)) string-bench-all := $(string-bench) $(string-bench-ifunc) diff --git a/benchtests/bench-stpcpy_chk-ifunc.c b/benchtests/bench-stpcpy_chk-ifunc.c new file mode 100644 index 0000000000..3449615bfe --- /dev/null +++ b/benchtests/bench-stpcpy_chk-ifunc.c @@ -0,0 +1,20 @@ +/* Measure IFUNC implementations of stpcpy checking function. + Copyright (C) 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 + . */ + +#define TEST_IFUNC 1 +#include "bench-stpcpy_chk.c" diff --git a/benchtests/bench-stpcpy_chk.c b/benchtests/bench-stpcpy_chk.c new file mode 100644 index 0000000000..964ca5e2ba --- /dev/null +++ b/benchtests/bench-stpcpy_chk.c @@ -0,0 +1,45 @@ +/* Measure stpcpy checking functions. + Copyright (C) 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 + . */ + +#define STRCPY_RESULT(dst, len) ((dst) + (len)) +#define TEST_MAIN +#define TEST_NAME "stpcpy_chk" +#include "bench-string.h" + +extern void __attribute__ ((noreturn)) __chk_fail (void); +char *simple_stpcpy_chk (char *, const char *, size_t); +extern char *normal_stpcpy (char *, const char *, size_t) + __asm ("stpcpy"); +extern char *__stpcpy_chk (char *, const char *, size_t); + +IMPL (simple_stpcpy_chk, 0) +IMPL (normal_stpcpy, 1) +IMPL (__stpcpy_chk, 2) + +char * +simple_stpcpy_chk (char *dst, const char *src, size_t len) +{ + if (! len) + __chk_fail (); + while ((*dst++ = *src++) != '\0') + if (--len == 0) + __chk_fail (); + return dst - 1; +} + +#include "bench-strcpy_chk.c" diff --git a/benchtests/bench-strcpy_chk-ifunc.c b/benchtests/bench-strcpy_chk-ifunc.c new file mode 100644 index 0000000000..2dd2aa318d --- /dev/null +++ b/benchtests/bench-strcpy_chk-ifunc.c @@ -0,0 +1,20 @@ +/* Measure IFUNC implementations of strcpy checking function. + Copyright (C) 2012-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 + . */ + +#define TEST_IFUNC 1 +#include "bench-strcpy_chk.c" diff --git a/benchtests/bench-strcpy_chk.c b/benchtests/bench-strcpy_chk.c new file mode 100644 index 0000000000..29e57285b0 --- /dev/null +++ b/benchtests/bench-strcpy_chk.c @@ -0,0 +1,262 @@ +/* Measure __strcpy_chk functions. + Copyright (C) 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 + . */ + +#ifndef STRCPY_RESULT +# define STRCPY_RESULT(dst, len) dst +# define TEST_MAIN +# define TEST_NAME "strcpy_chk" +# include "bench-string.h" + +/* This test case implicitly tests the availability of the __chk_fail + symbol, which is part of the public ABI and may be used + externally. */ +extern void __attribute__ ((noreturn)) __chk_fail (void); +char *simple_strcpy_chk (char *, const char *, size_t); +extern char *normal_strcpy (char *, const char *, size_t) + __asm ("strcpy"); +extern char *__strcpy_chk (char *, const char *, size_t); + +IMPL (simple_strcpy_chk, 0) +IMPL (normal_strcpy, 1) +IMPL (__strcpy_chk, 2) + +char * +simple_strcpy_chk (char *dst, const char *src, size_t len) +{ + char *ret = dst; + if (! len) + __chk_fail (); + while ((*dst++ = *src++) != '\0') + if (--len == 0) + __chk_fail (); + return ret; +} +#endif + +#include +#include +#include +#include + +volatile int chk_fail_ok; +jmp_buf chk_fail_buf; + +static void +handler (int sig) +{ + if (chk_fail_ok) + { + chk_fail_ok = 0; + longjmp (chk_fail_buf, 1); + } + else + _exit (127); +} + +typedef char *(*proto_t) (char *, const char *, size_t); + +static void +do_one_test (impl_t *impl, char *dst, const char *src, + size_t len, size_t dlen) +{ + char *res; + if (dlen <= len) + { + if (impl->test == 1) + return; + + chk_fail_ok = 1; + if (setjmp (chk_fail_buf) == 0) + { + res = CALL (impl, dst, src, dlen); + printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", + impl->name, len, dlen); + chk_fail_ok = 0; + ret = 1; + } + return; + } + else + res = CALL (impl, dst, src, dlen); + + if (res != STRCPY_RESULT (dst, len)) + { + printf ("Wrong result in function %s %p %p\n", impl->name, + res, STRCPY_RESULT (dst, len)); + ret = 1; + return; + } + + if (strcmp (dst, src) != 0) + { + printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", + impl->name, dst, src); + ret = 1; + return; + } + + if (HP_TIMING_AVAIL) + { + hp_timing_t start __attribute ((unused)); + hp_timing_t stop __attribute ((unused));; + hp_timing_t best_time = ~ (hp_timing_t) 0; + size_t i; + + for (i = 0; i < 32; ++i) + { + HP_TIMING_NOW (start); + CALL (impl, dst, src, dlen); + HP_TIMING_NOW (stop); + HP_TIMING_BEST (best_time, start, stop); + } + + printf ("\t%zd", (size_t) best_time); + } +} + +static void +do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char) +{ + size_t i; + char *s1, *s2; + + align1 &= 7; + if (align1 + len >= page_size) + return; + + align2 &= 7; + if (align2 + len >= page_size) + return; + + s1 = (char *) buf1 + align1; + s2 = (char *) buf2 + align2; + + for (i = 0; i < len; i++) + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; + + if (HP_TIMING_AVAIL && dlen > len) + printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); + + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len, dlen); + + if (HP_TIMING_AVAIL && dlen > len) + putchar ('\n'); +} + +int +test_main (void) +{ + size_t i; + + struct sigaction sa; + sa.sa_handler = handler; + sa.sa_flags = 0; + sigemptyset (&sa.sa_mask); + + sigaction (SIGABRT, &sa, NULL); + + /* Avoid all the buffer overflow messages on stderr. */ + int fd = open (_PATH_DEVNULL, O_WRONLY); + if (fd == -1) + close (STDERR_FILENO); + else + { + dup2 (fd, STDERR_FILENO); + close (fd); + } + setenv ("LIBC_FATAL_STDERR_", "1", 1); + + test_init (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) + printf ("\t%s", impl->name); + putchar ('\n'); + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i + 1, 127); + do_test (0, 0, i, i + 1, 255); + do_test (0, i, i, i + 1, 127); + do_test (i, 0, i, i + 1, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) + 1, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127); + do_test (2 * i, i, (8 << i), (8 << i) + 1, 255); + do_test (i, i, (8 << i), (8 << i) + 1, 127); + do_test (i, i, (8 << i), (8 << i) + 1, 255); + } + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i + 256, 127); + do_test (0, 0, i, i + 256, 255); + do_test (0, i, i, i + 256, 127); + do_test (i, 0, i, i + 256, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) + 256, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127); + do_test (2 * i, i, (8 << i), (8 << i) + 256, 255); + do_test (i, i, (8 << i), (8 << i) + 256, 127); + do_test (i, i, (8 << i), (8 << i) + 256, 255); + } + + for (i = 0; i < 16; ++i) + { + do_test (0, 0, i, i, 127); + do_test (0, 0, i, i + 2, 255); + do_test (0, i, i, i + 3, 127); + do_test (i, 0, i, i + 4, 255); + } + + for (i = 1; i < 8; ++i) + { + do_test (0, 0, 8 << i, (8 << i) - 15, 127); + do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127); + } + + for (i = 1; i < 8; ++i) + { + do_test (i, 2 * i, (8 << i), (8 << i) + i, 127); + do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255); + do_test (i, i, (8 << i), (8 << i) + i + 2, 127); + do_test (i, i, (8 << i), (8 << i) + i + 3, 255); + } + + return 0; +} + +#include "../test-skeleton.c" diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c index 1c64c60fb7..736ef3cd7a 100644 --- a/debug/test-strcpy_chk.c +++ b/debug/test-strcpy_chk.c @@ -110,24 +110,6 @@ do_one_test (impl_t *impl, char *dst, const char *src, ret = 1; return; } - - if (HP_TIMING_AVAIL) - { - hp_timing_t start __attribute ((unused)); - hp_timing_t stop __attribute ((unused));; - hp_timing_t best_time = ~ (hp_timing_t) 0; - size_t i; - - for (i = 0; i < 32; ++i) - { - HP_TIMING_NOW (start); - CALL (impl, dst, src, dlen); - HP_TIMING_NOW (stop); - HP_TIMING_BEST (best_time, start, stop); - } - - printf ("\t%zd", (size_t) best_time); - } } static void @@ -151,14 +133,8 @@ do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char) s1[i] = 32 + 23 * i % (max_char - 32); s1[len] = 0; - if (HP_TIMING_AVAIL && dlen > len) - printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); - FOR_EACH_IMPL (impl, 0) do_one_test (impl, s2, s1, len, dlen); - - if (HP_TIMING_AVAIL && dlen > len) - putchar ('\n'); } static void -- cgit 1.4.1