string/memory functions: avoid qemu bugs/performance issues.
Use V on real hardware, but GC on qemu.
Change-Id: I419546d94555540e14a14dcc52bd99413cbbcfa1
diff --git a/libc/Android.bp b/libc/Android.bp
index 174ecd9..6e5bddd 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -664,8 +664,9 @@
},
arm64: {
srcs: [
- "upstream-openbsd/lib/libc/string/stpncpy.c",
+ "upstream-openbsd/lib/libc/string/memrchr.c",
"upstream-openbsd/lib/libc/string/strcat.c",
+ "upstream-openbsd/lib/libc/string/stpncpy.c",
"upstream-openbsd/lib/libc/string/strlcat.c",
"upstream-openbsd/lib/libc/string/strlcpy.c",
"upstream-openbsd/lib/libc/string/strncat.c",
@@ -681,7 +682,9 @@
],
},
x86: {
- // This space intentionally left blank.
+ srcs: [
+ // x86 has custom implementations of all of these.
+ ],
},
x86_64: {
srcs: [
@@ -849,29 +852,6 @@
"arch-arm/bionic/syscall.S",
"arch-arm/bionic/vfork.S",
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.c",
- "bionic/strrchr.cpp",
-
- "arch-arm/generic/bionic/memcmp.S",
- "arch-arm/generic/bionic/memmove.S",
- "arch-arm/generic/bionic/memset.S",
- "arch-arm/generic/bionic/stpcpy.c",
- "arch-arm/generic/bionic/strcat.c",
- "arch-arm/generic/bionic/strcmp.S",
- "arch-arm/generic/bionic/strcpy.S",
- "arch-arm/generic/bionic/strlen.c",
-
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/memmove.S",
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/stpcpy.S",
- "arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- "arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/strlen.S",
-
"arch-arm/cortex-a7/bionic/memcpy.S",
"arch-arm/cortex-a7/bionic/memset.S",
@@ -882,14 +862,37 @@
"arch-arm/cortex-a9/bionic/strcpy.S",
"arch-arm/cortex-a9/bionic/strlen.S",
- "arch-arm/krait/bionic/memcpy.S",
- "arch-arm/krait/bionic/memset.S",
+ "arch-arm/cortex-a15/bionic/memcpy.S",
+ "arch-arm/cortex-a15/bionic/memmove.S",
+ "arch-arm/cortex-a15/bionic/memset.S",
+ "arch-arm/cortex-a15/bionic/stpcpy.S",
+ "arch-arm/cortex-a15/bionic/strcat.S",
+ "arch-arm/cortex-a15/bionic/strcmp.S",
+ "arch-arm/cortex-a15/bionic/strcpy.S",
+ "arch-arm/cortex-a15/bionic/strlen.S",
"arch-arm/cortex-a53/bionic/memcpy.S",
"arch-arm/cortex-a55/bionic/memcpy.S",
+ "arch-arm/generic/bionic/memcmp.S",
+ "arch-arm/generic/bionic/memmove.S",
+ "arch-arm/generic/bionic/memset.S",
+ "arch-arm/generic/bionic/stpcpy.c",
+ "arch-arm/generic/bionic/strcat.c",
+ "arch-arm/generic/bionic/strcmp.S",
+ "arch-arm/generic/bionic/strcpy.S",
+ "arch-arm/generic/bionic/strlen.c",
+
+ "arch-arm/krait/bionic/memcpy.S",
+ "arch-arm/krait/bionic/memset.S",
+
"arch-arm/kryo/bionic/memcpy.S",
+
+ "bionic/strchr.cpp",
+ "bionic/strchrnul.cpp",
+ "bionic/strnlen.cpp",
+ "bionic/strrchr.cpp",
],
},
arm64: {
@@ -910,27 +913,40 @@
"arch-riscv64/bionic/syscall.S",
"arch-riscv64/bionic/vfork.S",
- // TODO(b/306514350): Remove this and replace with the optimized
- // version once the bug is resolved.
- "upstream-freebsd/lib/libc/string/memcmp.c",
+ "arch-riscv64/string/memchr_v.S",
+ "arch-riscv64/string/memcmp_v.S",
+ "arch-riscv64/string/memcpy_v.S",
+ "arch-riscv64/string/memmove_v.S",
+ "arch-riscv64/string/memset_v.S",
+ "arch-riscv64/string/stpcpy_v.S",
+ "arch-riscv64/string/strcat_v.S",
+ "arch-riscv64/string/strchr_v.S",
+ "arch-riscv64/string/strcmp_v.S",
+ "arch-riscv64/string/strcpy_v.S",
+ "arch-riscv64/string/strlen_v.S",
+ "arch-riscv64/string/strncat_v.S",
+ "arch-riscv64/string/strncmp_v.S",
+ "arch-riscv64/string/strncpy_v.S",
+ "arch-riscv64/string/strnlen_v.S",
+
+ "arch-riscv64/string/memchr.c",
+ "arch-riscv64/string/memcmp.c",
+ "arch-riscv64/string/memcpy.c",
+ "arch-riscv64/string/memmove.c",
+ "arch-riscv64/string/memset.c",
+ "arch-riscv64/string/stpcpy.c",
+ "arch-riscv64/string/strcat.c",
+ "arch-riscv64/string/strchr.c",
+ "arch-riscv64/string/strcmp.c",
+ "arch-riscv64/string/strcpy.c",
+ "arch-riscv64/string/strlen.c",
+ "arch-riscv64/string/strncat.c",
+ "arch-riscv64/string/strncmp.c",
+ "arch-riscv64/string/strncpy.c",
+ "arch-riscv64/string/strnlen.c",
"bionic/strchrnul.cpp",
"bionic/strrchr.cpp",
-
- "arch-riscv64/string/memchr.S",
- "arch-riscv64/string/memcpy.S",
- "arch-riscv64/string/memmove.S",
- "arch-riscv64/string/memset.S",
- "arch-riscv64/string/stpcpy.S",
- "arch-riscv64/string/strcat.S",
- "arch-riscv64/string/strchr.S",
- "arch-riscv64/string/strcmp.S",
- "arch-riscv64/string/strcpy.S",
- "arch-riscv64/string/strlen.S",
- "arch-riscv64/string/strncat.S",
- "arch-riscv64/string/strncmp.S",
- "arch-riscv64/string/strncpy.S",
- "arch-riscv64/string/strnlen.S",
],
},
@@ -945,8 +961,6 @@
"arch-x86/bionic/vfork.S",
"arch-x86/bionic/__x86.get_pc_thunk.S",
- "bionic/strchrnul.cpp",
-
"arch-x86/generic/string/memcmp.S",
"arch-x86/generic/string/strcmp.S",
"arch-x86/generic/string/strncmp.S",
@@ -994,6 +1008,8 @@
"arch-x86/string/sse4-memcmp-slm.S",
"arch-x86/string/sse4-wmemcmp-slm.S",
+
+ "bionic/strchrnul.cpp",
],
},
x86_64: {
@@ -1005,11 +1021,6 @@
"arch-x86_64/bionic/syscall.S",
"arch-x86_64/bionic/vfork.S",
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.c",
- "bionic/strrchr.cpp",
-
"arch-x86_64/string/avx2-memset-kbl.S",
"arch-x86_64/string/sse2-memmove-slm.S",
"arch-x86_64/string/sse2-memset-slm.S",
@@ -1023,6 +1034,11 @@
"arch-x86_64/string/sse4-memcmp-slm.S",
"arch-x86_64/string/ssse3-strcmp-slm.S",
"arch-x86_64/string/ssse3-strncmp-slm.S",
+
+ "bionic/strchr.cpp",
+ "bionic/strchrnul.cpp",
+ "bionic/strnlen.cpp",
+ "bionic/strrchr.cpp",
],
},
},
@@ -1540,6 +1556,9 @@
arm64: {
srcs: ["arch-arm64/static_function_dispatch.S"],
},
+ riscv64: {
+ srcs: ["arch-riscv64/static_function_dispatch.S"]
+ },
},
}
@@ -1568,6 +1587,9 @@
arm64: {
srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
},
+ riscv64: {
+ srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"]
+ },
},
}
diff --git a/libc/NOTICE b/libc/NOTICE
index b345544..d464e1d 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -2077,6 +2077,38 @@
Copyright (c) 1990, 1993
The Regents of the University of California. All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Mike Hibler and Chris Torek.
+
+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.
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
(c) UNIX System Laboratories, Inc.
All or some portions of this file are derived from material licensed
to the University of California by American Telephone and Telegraph
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
new file mode 100644
index 0000000..24fafe7
--- /dev/null
+++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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.
+ */
+
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include <private/bionic_ifuncs.h>
+
+extern "C" {
+
+static __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
+ register long a0 __asm__("a0") = dir_fd;
+ register long a1 __asm__("a1") = reinterpret_cast<long>(path);
+ register long a2 __asm__("a2") = mode;
+ register long a7 __asm__("a7") = __NR_faccessat;
+ __asm__("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a7) : "memory");
+ return a0;
+}
+
+static bool have_fast_v() {
+ static bool result = []() {
+ // We don't want to do a full "bogomips" test, so just check for the
+ // presence of a file that would indicate that we're running in qemu.
+ return ifunc_faccessat(AT_FDCWD, "/dev/hvc0", F_OK) == 0;
+ }();
+ return result;
+}
+
+typedef void* memchr_func(const void*, int, size_t);
+DEFINE_IFUNC_FOR(memchr) {
+ if (have_fast_v()) RETURN_FUNC(memchr_func, memchr_v);
+ RETURN_FUNC(memchr_func, memchr_gc);
+}
+
+typedef int memcmp_func(const void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcmp) {
+ if (have_fast_v()) RETURN_FUNC(memcmp_func, memcmp_v);
+ RETURN_FUNC(memcmp_func, memcmp_gc);
+}
+
+typedef void* memcpy_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcpy) {
+ if (have_fast_v()) RETURN_FUNC(memcpy_func, memcpy_v);
+ RETURN_FUNC(memcpy_func, memcpy_gc);
+}
+
+typedef void* memmove_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memmove) {
+ if (have_fast_v()) RETURN_FUNC(memmove_func, memmove_v);
+ RETURN_FUNC(memmove_func, memmove_gc);
+}
+
+typedef void* memset_func(void*, int, size_t);
+DEFINE_IFUNC_FOR(memset) {
+ if (have_fast_v()) RETURN_FUNC(memset_func, memset_v);
+ RETURN_FUNC(memset_func, memset_gc);
+}
+
+typedef char* stpcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(stpcpy) {
+ if (have_fast_v()) RETURN_FUNC(stpcpy_func, stpcpy_v);
+ RETURN_FUNC(stpcpy_func, stpcpy_gc);
+}
+
+typedef char* strcat_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcat) {
+ if (have_fast_v()) RETURN_FUNC(strcat_func, strcat_v);
+ RETURN_FUNC(strcat_func, strcat_gc);
+}
+
+typedef char* strchr_func(const char*, int);
+DEFINE_IFUNC_FOR(strchr) {
+ if (have_fast_v()) RETURN_FUNC(strchr_func, strchr_v);
+ RETURN_FUNC(strchr_func, strchr_gc);
+}
+
+typedef int strcmp_func(const char*, const char*);
+DEFINE_IFUNC_FOR(strcmp) {
+ if (have_fast_v()) RETURN_FUNC(strcmp_func, strcmp_v);
+ RETURN_FUNC(strcmp_func, strcmp_gc);
+}
+
+typedef char* strcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcpy) {
+ if (have_fast_v()) RETURN_FUNC(strcpy_func, strcpy_v);
+ RETURN_FUNC(strcpy_func, strcpy_gc);
+}
+
+typedef size_t strlen_func(const char*);
+DEFINE_IFUNC_FOR(strlen) {
+ if (have_fast_v()) RETURN_FUNC(strlen_func, strlen_v);
+ RETURN_FUNC(strlen_func, strlen_gc);
+}
+
+typedef char* strncat_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncat) {
+ if (have_fast_v()) RETURN_FUNC(strncat_func, strncat_v);
+ RETURN_FUNC(strncat_func, strncat_gc);
+}
+
+typedef int strncmp_func(const char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncmp) {
+ if (have_fast_v()) RETURN_FUNC(strncmp_func, strncmp_v);
+ RETURN_FUNC(strncmp_func, strncmp_gc);
+}
+
+typedef char* strncpy_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncpy) {
+ if (have_fast_v()) RETURN_FUNC(strncpy_func, strncpy_v);
+ RETURN_FUNC(strncpy_func, strncpy_gc);
+}
+
+typedef size_t strnlen_func(const char*, size_t);
+DEFINE_IFUNC_FOR(strnlen) {
+ if (have_fast_v()) RETURN_FUNC(strnlen_func, strnlen_v);
+ RETURN_FUNC(strnlen_func, strnlen_gc);
+}
+
+} // extern "C"
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/static_function_dispatch.S
similarity index 62%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/static_function_dispatch.S
index 2c6f60a..accfec8 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/static_function_dispatch.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,27 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <private/bionic_asm.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+ j impl; \
+END(name)
+
+// TODO: switch to the V variants when qemu is fixed.
+FUNCTION_DELEGATE(memchr, memchr_gc)
+FUNCTION_DELEGATE(memcmp, memcmp_gc)
+FUNCTION_DELEGATE(memcpy, memcpy_gc)
+FUNCTION_DELEGATE(memmove, memmove_gc)
+FUNCTION_DELEGATE(memset, memset_gc)
+FUNCTION_DELEGATE(stpcpy, stpcpy_gc)
+FUNCTION_DELEGATE(strcat, strcat_gc)
+FUNCTION_DELEGATE(strchr, strchr_gc)
+FUNCTION_DELEGATE(strcmp, strcmp_gc)
+FUNCTION_DELEGATE(strcpy, strcpy_gc)
+FUNCTION_DELEGATE(strlen, strlen_gc)
+FUNCTION_DELEGATE(strncat, strncat_gc)
+FUNCTION_DELEGATE(strncmp, strncmp_gc)
+FUNCTION_DELEGATE(strncpy, strncpy_gc)
+FUNCTION_DELEGATE(strnlen, strnlen_gc)
diff --git a/libc/arch-riscv64/string/bcopy.c b/libc/arch-riscv64/string/bcopy.c
new file mode 100644
index 0000000..57adcf6
--- /dev/null
+++ b/libc/arch-riscv64/string/bcopy.c
@@ -0,0 +1,122 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+
+typedef intptr_t word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ */
+#include <string.h>
+
+void *
+#ifdef MEMCOPY
+memcpy_gc
+#else
+memmove_gc
+#endif
+(void *dst0, const void *src0, size_t length)
+{
+ char *dst = dst0;
+ const char *src = src0;
+ size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (uintptr_t)src; /* only need low bits */
+ if ((t | (uintptr_t)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (uintptr_t)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src;
+ src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (uintptr_t)src;
+ if ((t | (uintptr_t)dst) & wmask) {
+ if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize;
+ *(word *)(void *)dst = *(const word *)(const void *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ return (dst0);
+#else
+ return;
+#endif
+}
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/memchr.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/memchr.c
index 2c6f60a..34eb6d7 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/memchr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define memchr memchr_gc
+#include <upstream-openbsd/lib/libc/string/memchr.c>
diff --git a/libc/arch-riscv64/string/memchr.S b/libc/arch-riscv64/string/memchr_v.S
similarity index 98%
rename from libc/arch-riscv64/string/memchr.S
rename to libc/arch-riscv64/string/memchr_v.S
index 8833436..d4999c3 100644
--- a/libc/arch-riscv64/string/memchr.S
+++ b/libc/arch-riscv64/string/memchr_v.S
@@ -68,7 +68,7 @@
#define vData v0
#define vMask v8
-ENTRY(memchr)
+ENTRY(memchr_v)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -93,4 +93,4 @@
add iResult, pSrc, iTemp
ret
-END(memchr)
+END(memchr_v)
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/arch-riscv64/string/memcmp.c
similarity index 88%
rename from libc/upstream-freebsd/lib/libc/string/memcmp.c
rename to libc/arch-riscv64/string/memcmp.c
index 183b09c..2d7335a 100644
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ b/libc/arch-riscv64/string/memcmp.c
@@ -32,19 +32,13 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <string.h>
/*
* Compare memory regions.
*/
int
-memcmp(const void *s1, const void *s2, size_t n)
+memcmp_gc(const void *s1, const void *s2, size_t n)
{
if (n != 0) {
const unsigned char *p1 = s1, *p2 = s2;
@@ -56,4 +50,3 @@
}
return (0);
}
-
diff --git a/libc/arch-riscv64/string/memchr.S b/libc/arch-riscv64/string/memcmp_v.S
similarity index 85%
copy from libc/arch-riscv64/string/memchr.S
copy to libc/arch-riscv64/string/memcmp_v.S
index 8833436..55e08db 100644
--- a/libc/arch-riscv64/string/memchr.S
+++ b/libc/arch-riscv64/string/memcmp_v.S
@@ -57,32 +57,38 @@
#define iResult a0
-#define pSrc a0
-#define iValue a1
+#define pSrc1 a0
+#define pSrc2 a1
#define iNum a2
#define iVL a3
#define iTemp a4
+#define iTemp1 a5
+#define iTemp2 a6
#define ELEM_LMUL_SETTING m8
-#define vData v0
-#define vMask v8
+#define vData1 v0
+#define vData2 v8
+#define vMask v16
-ENTRY(memchr)
+ENTRY(memcmp_v)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
- vle8ff.v vData, (pSrc)
- vmseq.vx vMask, vData, iValue
+ vle8.v vData1, (pSrc1)
+ vle8.v vData2, (pSrc2)
+
+ vmsne.vv vMask, vData1, vData2
+ sub iNum, iNum, iVL
vfirst.m iTemp, vMask
- # skip the loop if we find the matched value.
+ /* skip the loop if we find the different
+ value between pSrc1 and pSrc2. */
bgez iTemp, L(found)
- csrr iVL, vl
- sub iNum, iNum, iVL
- add pSrc, pSrc, iVL
+ add pSrc1, pSrc1, iVL
+ add pSrc2, pSrc2, iVL
bnez iNum, L(loop)
@@ -90,7 +96,11 @@
ret
L(found):
- add iResult, pSrc, iTemp
+ add pSrc1, pSrc1, iTemp
+ add pSrc2, pSrc2, iTemp
+ lbu iTemp1, 0(pSrc1)
+ lbu iTemp2, 0(pSrc2)
+ sub iResult, iTemp1, iTemp2
ret
-END(memchr)
+END(memcmp_v)
diff --git a/libc/arch-riscv64/string/memcpy.c b/libc/arch-riscv64/string/memcpy.c
new file mode 100644
index 0000000..ee11504
--- /dev/null
+++ b/libc/arch-riscv64/string/memcpy.c
@@ -0,0 +1,2 @@
+#define MEMCOPY
+#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memcpy.S b/libc/arch-riscv64/string/memcpy_v.S
similarity index 98%
rename from libc/arch-riscv64/string/memcpy.S
rename to libc/arch-riscv64/string/memcpy_v.S
index def1d9b..93ec60f 100644
--- a/libc/arch-riscv64/string/memcpy.S
+++ b/libc/arch-riscv64/string/memcpy_v.S
@@ -65,7 +65,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memcpy)
+ENTRY(memcpy_v)
mv pDstPtr, pDst
@@ -82,4 +82,4 @@
ret
-END(memcpy)
+END(memcpy_v)
diff --git a/libc/arch-riscv64/string/memmove.c b/libc/arch-riscv64/string/memmove.c
new file mode 100644
index 0000000..e9bb2c2
--- /dev/null
+++ b/libc/arch-riscv64/string/memmove.c
@@ -0,0 +1,2 @@
+#define MEMMOVE
+#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memmove.S b/libc/arch-riscv64/string/memmove_v.S
similarity index 98%
rename from libc/arch-riscv64/string/memmove.S
rename to libc/arch-riscv64/string/memmove_v.S
index fa70f76..cad2b05 100644
--- a/libc/arch-riscv64/string/memmove.S
+++ b/libc/arch-riscv64/string/memmove_v.S
@@ -67,7 +67,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memmove)
+ENTRY(memmove_v)
mv pDstPtr, pDst
@@ -99,4 +99,4 @@
bnez iNum, L(backward_copy_loop)
ret
-END(memmove)
+END(memmove_v)
diff --git a/libc/arch-riscv64/string/memset.c b/libc/arch-riscv64/string/memset.c
new file mode 100644
index 0000000..d51cbf9
--- /dev/null
+++ b/libc/arch-riscv64/string/memset.c
@@ -0,0 +1,108 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Hibler and Chris Torek.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/types.h>
+
+#include <limits.h>
+
+#define wsize sizeof(u_long)
+#define wmask (wsize - 1)
+
+#include <string.h>
+
+#define RETURN return (dst0)
+#define VAL c0
+#define WIDEVAL c
+
+void *
+memset_gc(void *dst0, int c0, size_t length)
+{
+ size_t t;
+ u_long c;
+ u_char *dst;
+
+ dst = dst0;
+ /*
+ * If not enough words, just fill bytes. A length >= 2 words
+ * guarantees that at least one of them is `complete' after
+ * any necessary alignment. For instance:
+ *
+ * |-----------|-----------|-----------|
+ * |00|01|02|03|04|05|06|07|08|09|0A|00|
+ * ^---------------------^
+ * dst dst+length-1
+ *
+ * but we use a minimum of 3 here since the overhead of the code
+ * to do word writes is substantial.
+ *
+ * TODO: This threshold might not be sensible for 64-bit u_long.
+ * We should benchmark and revisit this decision.
+ */
+ if (length < 3 * wsize) {
+ while (length != 0) {
+ *dst++ = VAL;
+ --length;
+ }
+ RETURN;
+ }
+
+ if ((c = (u_char)c0) != 0) { /* Fill the word. */
+ c = (c << 8) | c; /* u_long is 16 bits. */
+ c = (c << 16) | c; /* u_long is 32 bits. */
+ c = (c << 32) | c; /* u_long is 64 bits. */
+ }
+ /* Align destination by filling in bytes. */
+ if ((t = (long)dst & wmask) != 0) {
+ t = wsize - t;
+ length -= t;
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ }
+
+ /* Fill words. Length was >= 2*words so we know t >= 1 here. */
+ t = length / wsize;
+ do {
+ *(u_long *)(void *)dst = WIDEVAL;
+ dst += wsize;
+ } while (--t != 0);
+
+ /* Mop up trailing bytes, if any. */
+ t = length & wmask;
+ if (t != 0)
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ RETURN;
+}
diff --git a/libc/arch-riscv64/string/memset.S b/libc/arch-riscv64/string/memset_v.S
similarity index 98%
rename from libc/arch-riscv64/string/memset.S
rename to libc/arch-riscv64/string/memset_v.S
index 5aa525e..06a2c6a 100644
--- a/libc/arch-riscv64/string/memset.S
+++ b/libc/arch-riscv64/string/memset_v.S
@@ -66,7 +66,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memset)
+ENTRY(memset_v)
mv pDstPtr, pDst
@@ -82,4 +82,4 @@
ret
-END(memset)
+END(memset_v)
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/stpcpy.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/stpcpy.c
index 2c6f60a..2afcf99 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/stpcpy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define stpcpy stpcpy_gc
+#include <upstream-openbsd/lib/libc/string/stpcpy.c>
diff --git a/libc/arch-riscv64/string/stpcpy.S b/libc/arch-riscv64/string/stpcpy_v.S
similarity index 98%
rename from libc/arch-riscv64/string/stpcpy.S
rename to libc/arch-riscv64/string/stpcpy_v.S
index c5d0945..6a853ec 100644
--- a/libc/arch-riscv64/string/stpcpy.S
+++ b/libc/arch-riscv64/string/stpcpy_v.S
@@ -68,7 +68,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(stpcpy)
+ENTRY(stpcpy_v)
L(stpcpy_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
vle8ff.v vStr1, (pSrc)
@@ -85,4 +85,4 @@
sub pDstPtr, pDstPtr, iCurrentVL
add pDstPtr, pDstPtr, iActiveElemPos
ret
-END(stpcpy)
+END(stpcpy_v)
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/strcat.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/strcat.c
index 2c6f60a..5fb1621 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/strcat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define strcat strcat_gc
+#include <upstream-openbsd/lib/libc/string/strcat.c>
diff --git a/libc/arch-riscv64/string/strcat.S b/libc/arch-riscv64/string/strcat_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strcat.S
rename to libc/arch-riscv64/string/strcat_v.S
index 5abf295..3d348e7 100644
--- a/libc/arch-riscv64/string/strcat.S
+++ b/libc/arch-riscv64/string/strcat_v.S
@@ -69,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcat)
+ENTRY(strcat_v)
mv pDstPtr, pDst
@@ -104,4 +104,4 @@
ret
-END(strcat)
+END(strcat_v)
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/arch-riscv64/string/strchr.c
similarity index 69%
copy from libc/upstream-freebsd/lib/libc/string/memcmp.c
copy to libc/arch-riscv64/string/strchr.c
index 183b09c..dc07766 100644
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ b/libc/arch-riscv64/string/strchr.c
@@ -1,11 +1,7 @@
+/* $OpenBSD: strchr.c,v 1.4 2018/10/01 06:37:37 martijn Exp $ */
/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,28 +28,16 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <string.h>
-/*
- * Compare memory regions.
- */
-int
-memcmp(const void *s1, const void *s2, size_t n)
+char *
+strchr_gc(const char *p, int ch)
{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
+ for (;; ++p) {
+ if (*p == (char) ch)
+ return((char *)p);
+ if (!*p)
+ return((char *)NULL);
}
- return (0);
+ /* NOTREACHED */
}
-
diff --git a/libc/arch-riscv64/string/strchr.S b/libc/arch-riscv64/string/strchr_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strchr.S
rename to libc/arch-riscv64/string/strchr_v.S
index ea13c5d..bc7b58a 100644
--- a/libc/arch-riscv64/string/strchr.S
+++ b/libc/arch-riscv64/string/strchr_v.S
@@ -69,7 +69,7 @@
#define vMaskEnd v8
#define vMaskCh v9
-ENTRY(strchr)
+ENTRY(strchr_v)
L(strchr_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
@@ -91,4 +91,4 @@
add pStr, pStr, iChOffset
ret
-END(strchr)
+END(strchr_v)
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/arch-riscv64/string/strcmp.c
similarity index 74%
copy from libc/upstream-freebsd/lib/libc/string/memcmp.c
copy to libc/arch-riscv64/string/strcmp.c
index 183b09c..7a1fefe 100644
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ b/libc/arch-riscv64/string/strcmp.c
@@ -1,8 +1,8 @@
+/* $OpenBSD: strcmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
+
/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
@@ -32,28 +32,16 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <string.h>
/*
- * Compare memory regions.
+ * Compare strings.
*/
int
-memcmp(const void *s1, const void *s2, size_t n)
+strcmp_gc(const char *s1, const char *s2)
{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
+ while (*s1 == *s2++)
+ if (*s1++ == 0)
+ return (0);
+ return (*(unsigned char *)s1 - *(unsigned char *)--s2);
}
-
diff --git a/libc/arch-riscv64/string/strcmp.S b/libc/arch-riscv64/string/strcmp_v.S
similarity index 99%
rename from libc/arch-riscv64/string/strcmp.S
rename to libc/arch-riscv64/string/strcmp_v.S
index 3332c83..01e72b1 100644
--- a/libc/arch-riscv64/string/strcmp.S
+++ b/libc/arch-riscv64/string/strcmp_v.S
@@ -74,7 +74,7 @@
#define vMask1 v16
#define vMask2 v17
-ENTRY(strcmp)
+ENTRY(strcmp_v)
# increase the lmul using the following sequences:
# 1/2, 1/2, 1, 2, 4, 4, 4, ...
@@ -166,4 +166,4 @@
sub iResult, iTemp1, iTemp2
ret
-END(strcmp)
+END(strcmp_v)
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/arch-riscv64/string/strcpy.c
similarity index 69%
copy from libc/upstream-freebsd/lib/libc/string/memcmp.c
copy to libc/arch-riscv64/string/strcpy.c
index 183b09c..a624541 100644
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ b/libc/arch-riscv64/string/strcpy.c
@@ -1,11 +1,8 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
+/* $OpenBSD: strcpy.c,v 1.10 2017/11/28 06:55:49 tb Exp $ */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,28 +29,13 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <string.h>
-/*
- * Compare memory regions.
- */
-int
-memcmp(const void *s1, const void *s2, size_t n)
+char *
+strcpy_gc(char *to, const char *from)
{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
+ char *save = to;
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
+ for (; (*to = *from) != '\0'; ++from, ++to);
+ return(save);
}
-
diff --git a/libc/arch-riscv64/string/strcpy.S b/libc/arch-riscv64/string/strcpy_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strcpy.S
rename to libc/arch-riscv64/string/strcpy_v.S
index b89b1a8..084b3a5 100644
--- a/libc/arch-riscv64/string/strcpy.S
+++ b/libc/arch-riscv64/string/strcpy_v.S
@@ -69,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcpy)
+ENTRY(strcpy_v)
mv pDstPtr, pDst
@@ -88,4 +88,4 @@
ret
-END(strcpy)
+END(strcpy_v)
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/arch-riscv64/string/strlen.c
similarity index 74%
copy from libc/upstream-freebsd/lib/libc/string/memcmp.c
copy to libc/arch-riscv64/string/strlen.c
index 183b09c..ac8d27f 100644
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ b/libc/arch-riscv64/string/strlen.c
@@ -1,12 +1,9 @@
+/* $OpenBSD: strlen.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
+
/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -32,28 +29,14 @@
* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <string.h>
-/*
- * Compare memory regions.
- */
-int
-memcmp(const void *s1, const void *s2, size_t n)
+size_t
+strlen_gc(const char *str)
{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
+ const char *s;
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
+ for (s = str; *s; ++s)
+ ;
+ return (s - str);
}
-
diff --git a/libc/arch-riscv64/string/strlen.S b/libc/arch-riscv64/string/strlen_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strlen.S
rename to libc/arch-riscv64/string/strlen_v.S
index 7f7d2dd..c284021 100644
--- a/libc/arch-riscv64/string/strlen.S
+++ b/libc/arch-riscv64/string/strlen_v.S
@@ -66,7 +66,7 @@
#define vStr v0
#define vMaskEnd v2
-ENTRY(strlen)
+ENTRY(strlen_v)
mv pCopyStr, pStr
L(loop):
@@ -84,4 +84,4 @@
ret
-END(strlen)
+END(strlen_v)
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/strncat.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/strncat.c
index 2c6f60a..8c26b95 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/strncat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define strncat strncat_gc
+#include <upstream-openbsd/lib/libc/string/strncat.c>
diff --git a/libc/arch-riscv64/string/strncat.S b/libc/arch-riscv64/string/strncat_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strncat.S
rename to libc/arch-riscv64/string/strncat_v.S
index 01cb14f..adc768d 100644
--- a/libc/arch-riscv64/string/strncat.S
+++ b/libc/arch-riscv64/string/strncat_v.S
@@ -70,7 +70,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncat)
+ENTRY(strncat_v)
mv pDstPtr, pDst
@@ -114,4 +114,4 @@
L(fill_zero_end):
ret
-END(strncat)
+END(strncat_v)
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/strncmp.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/strncmp.c
index 2c6f60a..ebc5357 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/strncmp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define strncmp strncmp_gc
+#include <upstream-openbsd/lib/libc/string/strncmp.c>
diff --git a/libc/arch-riscv64/string/strncmp.S b/libc/arch-riscv64/string/strncmp_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strncmp.S
rename to libc/arch-riscv64/string/strncmp_v.S
index b9e6ee2..1ce4817 100644
--- a/libc/arch-riscv64/string/strncmp.S
+++ b/libc/arch-riscv64/string/strncmp_v.S
@@ -71,7 +71,7 @@
#define vMask1 v8
#define vMask2 v9
-ENTRY(strncmp)
+ENTRY(strncmp_v)
beqz iLength, L(zero_length)
@@ -116,4 +116,4 @@
li iResult, 0
ret
-END(strncmp)
+END(strncmp_v)
diff --git a/libc/bionic/strnlen.c b/libc/arch-riscv64/string/strncpy.c
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/arch-riscv64/string/strncpy.c
index 2c6f60a..bbd1bd7 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/arch-riscv64/string/strncpy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,14 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
+#include <upstream-openbsd/android/include/openbsd-compat.h>
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#define strncpy strncpy_gc
+#include <upstream-openbsd/lib/libc/string/strncpy.c>
diff --git a/libc/arch-riscv64/string/strncpy.S b/libc/arch-riscv64/string/strncpy_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strncpy.S
rename to libc/arch-riscv64/string/strncpy_v.S
index 651a064..f133f28 100644
--- a/libc/arch-riscv64/string/strncpy.S
+++ b/libc/arch-riscv64/string/strncpy_v.S
@@ -71,7 +71,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncpy)
+ENTRY(strncpy_v)
mv pDstPtr, pDst
@@ -111,4 +111,4 @@
ret
-END(strncpy)
+END(strncpy_v)
diff --git a/libc/arch-riscv64/string/strnlen.c b/libc/arch-riscv64/string/strnlen.c
new file mode 100644
index 0000000..0e31c3b
--- /dev/null
+++ b/libc/arch-riscv64/string/strnlen.c
@@ -0,0 +1,32 @@
+/* $OpenBSD: strnlen.c,v 1.9 2019/01/25 00:19:25 millert Exp $ */
+
+/*
+ * Copyright (c) 2010 Todd C. Miller <millert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+
+size_t
+strnlen_gc(const char *str, size_t maxlen)
+{
+ const char *cp;
+
+ for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
+ ;
+
+ return (size_t)(cp - str);
+}
diff --git a/libc/arch-riscv64/string/strnlen.S b/libc/arch-riscv64/string/strnlen_v.S
similarity index 98%
rename from libc/arch-riscv64/string/strnlen.S
rename to libc/arch-riscv64/string/strnlen_v.S
index 66366f0..bd1bb9a 100644
--- a/libc/arch-riscv64/string/strnlen.S
+++ b/libc/arch-riscv64/string/strnlen_v.S
@@ -66,7 +66,7 @@
#define vStr v0
#define vMaskEnd v8
-ENTRY(strnlen)
+ENTRY(strnlen_v)
mv pCopyStr, pStr
mv iRetValue, iMaxlen
@@ -86,4 +86,4 @@
L(end_strnlen_loop):
ret
-END(strnlen)
+END(strnlen_v)
diff --git a/libc/bionic/strnlen.c b/libc/bionic/strnlen.cpp
similarity index 89%
rename from libc/bionic/strnlen.c
rename to libc/bionic/strnlen.cpp
index 2c6f60a..7101b21 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/bionic/strnlen.cpp
@@ -25,14 +25,10 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#include <string.h>
-size_t strnlen(const char* str, size_t maxlen)
-{
- char* p = memchr(str, 0, maxlen);
-
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
+size_t strnlen(const char* s, size_t n) {
+ const char* p = static_cast<const char*>(memchr(s, 0, n));
+ return p ? (p - s) : n;
}