From 7f72497ef756ff7d03d5560c2d1c1f92f73fcb52 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 1 Mar 2021 20:57:36 -0500 Subject: [PATCH] libc: Use musl's optimized strchr and strchrnul Parentheses added to HASZERO macro to avoid a GCC warning, and formatted with clang-format as we have adopted these and don't consider them 'contrib' code. Obtained from: musl (snapshot at commit 4d0a82170a25) Reviewed by: kib (libc integration), mjg (both earlier) MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17630 --- lib/libc/string/strchr.c | 67 +++++++++------------- lib/libc/string/strchrnul.c | 75 ++++++++++++++----------- libexec/rtld-elf/rtld-libc/Makefile.inc | 4 +- stand/libsa/Makefile | 2 +- 4 files changed, 71 insertions(+), 77 deletions(-) diff --git a/lib/libc/string/strchr.c b/lib/libc/string/strchr.c index 61244da4519c..4a20ea658252 100644 --- a/lib/libc/string/strchr.c +++ b/lib/libc/string/strchr.c @@ -1,56 +1,39 @@ /*- - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: MIT * - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2005-2014 Rich Felker, et al. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)index.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); -#include #include -char * -strchr(const char *p, int ch) -{ - char c; +char *__strchrnul(const char *, int); - c = ch; - for (;; ++p) { - if (*p == c) - return ((char *)p); - if (*p == '\0') - return (NULL); - } - /* NOTREACHED */ +char * +strchr(const char *s, int c) +{ + char *r = __strchrnul(s, c); + return *(unsigned char *)r == (unsigned char)c ? r : NULL; } __weak_reference(strchr, index); diff --git a/lib/libc/string/strchrnul.c b/lib/libc/string/strchrnul.c index 1c777be1854f..e1fb83886042 100644 --- a/lib/libc/string/strchrnul.c +++ b/lib/libc/string/strchrnul.c @@ -1,51 +1,62 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: MIT * - * Copyright (c) 2013 Niclas Zeising + * Copyright (c) 2005-2014 Rich Felker, et al. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include __FBSDID("$FreeBSD$"); -#include +#include +#include #include -__weak_reference(__strchrnul, strchrnul); +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1 / UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX / 2 + 1)) +#define HASZERO(x) (((x)-ONES) & ~(x)&HIGHS) char *__strchrnul(const char *, int); char * -__strchrnul(const char *p, int ch) +__strchrnul(const char *s, int c) { - char c; + c = (unsigned char)c; + if (!c) + return (char *)s + strlen(s); - c = ch; - for (;; ++p) { - if (*p == c || *p == '\0') - return ((char *)p); - } - /* NOTREACHED */ +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + const word *w; + for (; (uintptr_t)s % ALIGN; s++) + if (!*s || *(unsigned char *)s == c) + return (char *)s; + size_t k = ONES * c; + for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w ^ k); w++) + ; + s = (void *)w; +#endif + for (; *s && *(unsigned char *)s != c; s++) + ; + return (char *)s; } +__weak_reference(__strchrnul, strchrnul); diff --git a/libexec/rtld-elf/rtld-libc/Makefile.inc b/libexec/rtld-elf/rtld-libc/Makefile.inc index d682472c3cca..d5f5993e3f16 100644 --- a/libexec/rtld-elf/rtld-libc/Makefile.inc +++ b/libexec/rtld-elf/rtld-libc/Makefile.inc @@ -41,8 +41,8 @@ CFLAGS.errlst.c+=-I${LIBC_SRCTOP}/include # Use the string and memory .o files from libc instead of rebuilding them (they # might be using optimized assembly and duplicating that logic here is awkward). _libc_string_objects= bcmp bcopy bzero memset memchr memcmp memcpy memmove \ - stpncpy strcat strchr strcmp stpcpy strcpy strcspn strdup strlcat strlcpy \ - strlen strncmp strncpy strrchr strsep strspn strstr strtok + stpncpy strcat strchr strchrnul strcmp stpcpy strcpy strcspn strdup \ + strlcat strlcpy strlen strncmp strncpy strrchr strsep strspn strstr strtok # Also use all the syscall .o files from libc_nossp_pic: _libc_other_objects= sigsetjmp lstat stat fstat fstatat fstatfs syscall \ cerror geteuid getegid sigfastblock munmap mprotect \ diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 6fe916405fe4..838fefb260a8 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -29,7 +29,7 @@ SRCS+= ntoh.c .PATH: ${LIBCSRC}/string SRCS+= bcmp.c bcopy.c bzero.c ffs.c fls.c \ memccpy.c memchr.c memcmp.c memcpy.c memmove.c memset.c \ - strcat.c strchr.c strcmp.c strcpy.c stpcpy.c stpncpy.c \ + strcat.c strchr.c strchrnul.c strcmp.c strcpy.c stpcpy.c stpncpy.c \ strcspn.c strlcat.c strlcpy.c strlen.c strncat.c strncmp.c strncpy.c \ strnlen.c strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c