Merge "Plumb scudo_stack_depot_size to debuggerd_process_info" into main
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 15a621b..1b4ba23 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -40,9 +40,10 @@
: nprops(nprops), valid(false), system_properties_(false) {
static const char prop_name_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
- valid = system_properties_.AreaInit(dir_.path, nullptr);
+ valid = system_properties_.AreaInit(dir_.path, nullptr, true);
if (!valid) {
- return;
+ printf("Failed to initialize properties, terminating...\n");
+ exit(1);
}
names = new char* [nprops];
@@ -100,6 +101,9 @@
}
system_properties_.contexts_->FreeAndUnmap();
+ if (system_properties_.appcompat_override_contexts_) {
+ system_properties_.appcompat_override_contexts_->FreeAndUnmap();
+ }
for (int i = 0; i < nprops; i++) {
delete names[i];
diff --git a/libc/Android.bp b/libc/Android.bp
index 174ecd9..6f36aad 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",
],
},
},
@@ -1036,8 +1052,8 @@
name: "generated_android_ids",
out: ["generated_android_ids.h"],
srcs: [":android_filesystem_config_header"],
- tool_files: ["fs_config_generator.py"],
- cmd: "$(location fs_config_generator.py) aidarray $(in) > $(out)",
+ tools: ["fs_config_generator"],
+ cmd: "$(location fs_config_generator) aidarray $(in) > $(out)",
}
// ========================================================
@@ -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"]
+ },
},
}
@@ -1736,7 +1758,12 @@
arm: {
// TODO: This is to work around b/24465209. Remove after root cause is fixed.
pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
+ ldflags: [
+ "-Wl,--hash-style=both",
+ // Since we are preserving the debug_frame, do not compress
+ // in this case to make unwinds as fast as possible.
+ "-Wl,--compress-debug-sections=none",
+ ],
version_script: ":libc.arm.map",
no_libcrt: true,
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..265ce3e
--- /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/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 451cb8c..07133b7 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -48,9 +48,7 @@
#include <android/set_abort_message.h>
#include <async_safe/log.h>
-#include "private/CachedProperty.h"
#include "private/ErrnoRestorer.h"
-#include "private/ScopedPthreadMutexLocker.h"
// Don't call libc's close or socket, since it might call back into us as a result of fdsan/fdtrack.
#pragma GCC poison close
diff --git a/libc/bionic/bionic_call_ifunc_resolver.cpp b/libc/bionic/bionic_call_ifunc_resolver.cpp
index 3cfb8b5..e44d998 100644
--- a/libc/bionic/bionic_call_ifunc_resolver.cpp
+++ b/libc/bionic/bionic_call_ifunc_resolver.cpp
@@ -28,6 +28,7 @@
#include "private/bionic_call_ifunc_resolver.h"
#include <sys/auxv.h>
+#include <sys/hwprobe.h>
#include <sys/ifunc.h>
#include "private/bionic_auxv.h"
@@ -50,20 +51,15 @@
return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(arg._hwcap | _IFUNC_ARG_HWCAP, &arg);
#elif defined(__arm__)
typedef ElfW(Addr) (*ifunc_resolver_t)(unsigned long);
- static unsigned long hwcap;
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- hwcap = getauxval(AT_HWCAP);
- }
+ static unsigned long hwcap = getauxval(AT_HWCAP);
return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(hwcap);
#elif defined(__riscv)
- // The pointer argument is currently unused, but reserved for future
+ // The third argument is currently unused, but reserved for future
// expansion. If we pass nullptr from the beginning, it'll be easier
// to recognize if/when we pass actual data (and matches glibc).
- typedef ElfW(Addr) (*ifunc_resolver_t)(uint64_t, void*);
+ typedef ElfW(Addr) (*ifunc_resolver_t)(uint64_t, __riscv_hwprobe_t, void*);
static uint64_t hwcap = getauxval(AT_HWCAP);
- return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(hwcap, nullptr);
+ return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(hwcap, __riscv_hwprobe, nullptr);
#else
typedef ElfW(Addr) (*ifunc_resolver_t)(void);
return reinterpret_cast<ifunc_resolver_t>(resolver_addr)();
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 8068fc2..f46d702 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -91,17 +91,6 @@
extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
static void call_ifunc_resolvers() {
- if (__rel_iplt_start == nullptr || __rel_iplt_end == nullptr) {
- // These symbols were not emitted by gold. Gold has code to do so, but for
- // whatever reason it is not being run. In these cases ifuncs cannot be
- // resolved, so we do not support using ifuncs in static executables linked
- // with gold.
- //
- // Since they are weak, they will be non-null when linked with bfd/lld and
- // null when linked with gold.
- return;
- }
-
for (ElfW(Rel)* r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
ElfW(Addr) resolver = *offset;
@@ -112,17 +101,6 @@
extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
static void call_ifunc_resolvers() {
- if (__rela_iplt_start == nullptr || __rela_iplt_end == nullptr) {
- // These symbols were not emitted by gold. Gold has code to do so, but for
- // whatever reason it is not being run. In these cases ifuncs cannot be
- // resolved, so we do not support using ifuncs in static executables linked
- // with gold.
- //
- // Since they are weak, they will be non-null when linked with bfd/lld and
- // null when linked with gold.
- return;
- }
-
for (ElfW(Rela)* r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
ElfW(Addr) resolver = r->r_addend;
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;
}
diff --git a/libc/fs_config_generator.py b/libc/fs_config_generator.py
deleted file mode 120000
index aafb7dc..0000000
--- a/libc/fs_config_generator.py
+++ /dev/null
@@ -1 +0,0 @@
-../../build/tools/fs_config/fs_config_generator.py
\ No newline at end of file
diff --git a/libc/include/bits/signal_types.h b/libc/include/bits/signal_types.h
index 699e257..d98901c 100644
--- a/libc/include/bits/signal_types.h
+++ b/libc/include/bits/signal_types.h
@@ -28,18 +28,11 @@
#pragma once
-#include <limits.h>
#include <sys/cdefs.h>
-#include <sys/types.h>
-/* For 64-bit, the kernel's struct sigaction doesn't match the POSIX one,
- * so we need to expose our own and translate behind the scenes.
- * For 32-bit, we're stuck with the definitions we already shipped,
- * even though they contain a sigset_t that's too small. See sigaction64.
- */
-#define sigaction __kernel_sigaction
+#include <limits.h>
#include <linux/signal.h>
-#undef sigaction
+#include <sys/types.h>
/* The arm and x86 kernel header files don't define _NSIG. */
#ifndef _KERNEL__NSIG
@@ -64,8 +57,13 @@
typedef struct { unsigned long __bits[_KERNEL__NSIG/(8*sizeof(long))]; } sigset64_t;
#endif
+/* The kernel's struct sigaction doesn't match the POSIX one. */
+
#if defined(__LP64__)
+/* For 64-bit, that's the only problem, and we only need two structs
+ * for source compatibility with 32-bit. */
+
#define __SIGACTION_BODY \
int sa_flags; \
union { \
@@ -82,6 +80,12 @@
#else
+/* For 32-bit, Android's ABIs used a too-small sigset_t that doesn't
+ * support RT signals, so we need two different structs.
+ */
+
+/* The arm32 kernel headers also pollute the namespace with these,
+ * but our header scrubber doesn't know how to remove #defines. */
#undef sa_handler
#undef sa_sigaction
@@ -95,7 +99,6 @@
void (*sa_restorer)(void);
};
-/* This matches the kernel's internal structure. */
struct sigaction64 {
union {
sighandler_t sa_handler;
diff --git a/libc/bionic/strnlen.c b/libc/include/bits/sockaddr_storage.h
similarity index 63%
copy from libc/bionic/strnlen.c
copy to libc/include/bits/sockaddr_storage.h
index 2c6f60a..effafab 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/include/bits/sockaddr_storage.h
@@ -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,33 @@
* 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);
+#pragma once
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+/**
+ * @file bits/sockaddr_storage.h
+ * @brief The `sockaddr_storage` struct.
+ */
+
+#include <sys/cdefs.h>
+
+#include <bits/sa_family_t.h>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
+/**
+ * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr.3type.html)
+ * is a structure large enough to contain any other `sockaddr_*` type, used to
+ * pass socket addresses without needing to know what kind of socket address
+ * you're passing.
+ */
+struct sockaddr_storage {
+ union {
+ struct {
+ sa_family_t ss_family;
+ char __data[128 - sizeof(sa_family_t)];
+ };
+ void* __align;
+ };
+};
+#pragma clang diagnostic pop
diff --git a/libc/bionic/strnlen.c b/libc/include/bits/tcphdr.h
similarity index 64%
copy from libc/bionic/strnlen.c
copy to libc/include/bits/tcphdr.h
index 2c6f60a..a9b6fe0 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/include/bits/tcphdr.h
@@ -25,14 +25,47 @@
* 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);
+#pragma once
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+#include <sys/cdefs.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+struct tcphdr {
+ __extension__ union {
+ struct {
+ uint16_t th_sport;
+ uint16_t th_dport;
+ uint32_t th_seq;
+ uint32_t th_ack;
+ uint8_t th_x2:4;
+ uint8_t th_off:4;
+ uint8_t th_flags;
+ uint16_t th_win;
+ uint16_t th_sum;
+ uint16_t th_urp;
+ };
+ struct {
+ uint16_t source;
+ uint16_t dest;
+ uint32_t seq;
+ uint32_t ack_seq;
+ uint16_t res1:4;
+ uint16_t doff:4;
+ uint16_t fin:1;
+ uint16_t syn:1;
+ uint16_t rst:1;
+ uint16_t psh:1;
+ uint16_t ack:1;
+ uint16_t urg:1;
+ uint16_t res2:2;
+ uint16_t window;
+ uint16_t check;
+ uint16_t urg_ptr;
+ };
+ };
+};
+
+__END_DECLS
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 04a73f7..81a50db 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -229,6 +229,8 @@
#undef SHT_NUM
#define SHT_NUM 20
+#define SHT_RISCV_ATTRIBUTES 0x70000003
+
/*
* Experimental support for SHT_RELR sections. For details, see proposal
* at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg.
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index b235e6e..163e614 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -33,20 +33,10 @@
#include <sys/cdefs.h>
#include <sys/socket.h>
-// Include linux/socket.h first to trigger the header guard without
-// the__kernel_sockaddr_storage define, so its definition uses the
-// kernel name.
-#include <linux/socket.h>
-
-// Redefine __kernel_sockaddr_storage to sockaddr_storage so that
-// the structs defined in linux/in.h use the sockaddr_storage defined
-// in sys/sockets.h.
-#define __kernel_sockaddr_storage sockaddr_storage
#include <linux/in.h>
-#undef __kernel_sockaddr_storage
-
#include <linux/in6.h>
#include <linux/ipv6.h>
+#include <linux/socket.h>
__BEGIN_DECLS
diff --git a/libc/include/netinet/tcp.h b/libc/include/netinet/tcp.h
index 147f6f7..d1c657b 100644
--- a/libc/include/netinet/tcp.h
+++ b/libc/include/netinet/tcp.h
@@ -32,47 +32,10 @@
#include <sys/cdefs.h>
#include <stdint.h>
-#define tcphdr __kernel_tcphdr
#include <linux/tcp.h>
-#undef tcphdr
__BEGIN_DECLS
-struct tcphdr {
- __extension__ union {
- struct {
- uint16_t th_sport;
- uint16_t th_dport;
- uint32_t th_seq;
- uint32_t th_ack;
- uint8_t th_x2:4;
- uint8_t th_off:4;
- uint8_t th_flags;
- uint16_t th_win;
- uint16_t th_sum;
- uint16_t th_urp;
- };
- struct {
- uint16_t source;
- uint16_t dest;
- uint32_t seq;
- uint32_t ack_seq;
- uint16_t res1:4;
- uint16_t doff:4;
- uint16_t fin:1;
- uint16_t syn:1;
- uint16_t rst:1;
- uint16_t psh:1;
- uint16_t ack:1;
- uint16_t urg:1;
- uint16_t res2:2;
- uint16_t window;
- uint16_t check;
- uint16_t urg_ptr;
- };
- };
-};
-
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 4feade5..871c62c 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -74,15 +74,10 @@
#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
#endif
-
#if defined(__LP64__)
-#if defined(PAGE_SIZE)
-#define PTHREAD_STACK_MIN (4 * PAGE_SIZE)
+#define PTHREAD_STACK_MIN 16384
#else
-#define PTHREAD_STACK_MIN 65536
-#endif
-#else
-#define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
+#define PTHREAD_STACK_MIN 8192
#endif
#define PTHREAD_CREATE_DETACHED 1
diff --git a/libc/include/string.h b/libc/include/string.h
index 89b2a45..47bdd72 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -37,7 +37,7 @@
__BEGIN_DECLS
-#if defined(__USE_BSD)
+#if defined(__USE_BSD) || defined(__USE_GNU)
#include <strings.h>
#endif
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 30dea89..079c825 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -139,7 +139,7 @@
* Returns 0 on success, -1 if the system properties failed to re-initialize (same conditions as
* __system properties_init)
*/
-int __system_properties_zygote_reload(void); __INTRODUCED_IN(__ANDROID_API_V__)
+int __system_properties_zygote_reload(void) __INTRODUCED_IN(__ANDROID_API_V__);
/* Deprecated: use __system_property_wait instead. */
uint32_t __system_property_wait_any(uint32_t __old_serial);
diff --git a/libc/include/sys/hwprobe.h b/libc/include/sys/hwprobe.h
index b1a8400..8e69e8a 100644
--- a/libc/include/sys/hwprobe.h
+++ b/libc/include/sys/hwprobe.h
@@ -53,6 +53,14 @@
*/
int __riscv_hwprobe(struct riscv_hwprobe* _Nonnull __pairs, size_t __pair_count, size_t __cpu_count, unsigned long* _Nullable __cpus, unsigned __flags);
+/**
+ * The type of the second argument passed to riscv64 ifunc resolvers.
+ * This argument allows riscv64 ifunc resolvers to call __riscv_hwprobe()
+ * without worrying about whether that relocation is resolved before
+ * the ifunc resolver is called.
+ */
+typedef int (*__riscv_hwprobe_t)(struct riscv_hwprobe* _Nonnull __pairs, size_t __pair_count, size_t __cpu_count, unsigned long* _Nullable __cpus, unsigned __flags);
+
__END_DECLS
#endif
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 22b88cb..9402e70 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -39,6 +39,7 @@
#include <linux/types.h>
#include <linux/compiler.h>
+#include <bits/sockaddr_storage.h>
#include <bits/sa_family_t.h>
__BEGIN_DECLS
@@ -72,15 +73,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullability-completeness"
-struct sockaddr_storage {
- union {
- struct {
- sa_family_t ss_family;
- char __data[128 - sizeof(sa_family_t)];
- };
- void* __align;
- };
-};
struct linger {
int l_onoff;
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index c0b379b..08b786a 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1202,7 +1202,7 @@
def removeStructs(self, structs):
"""Remove structs."""
- extra_includes = []
+ extra_includes = set()
block_num = 0
num_blocks = len(self.blocks)
while block_num < num_blocks:
@@ -1247,8 +1247,8 @@
# Add an include for the structure to be removed of the form:
# #include <bits/STRUCT_NAME.h>
struct_token = b.tokens[i + 1]
- if not structs[struct_token.id]:
- extra_includes.append("<bits/%s.h>" % struct_token.id)
+ if struct_token.id in structs and structs[struct_token.id]:
+ extra_includes.add("<%s>" % structs[struct_token.id])
# Search forward for the end of the structure.
# Very simple search, look for } and ; tokens.
@@ -1292,7 +1292,7 @@
continue
i += 1
- for extra_include in extra_includes:
+ for extra_include in sorted(extra_includes):
replacement = CppStringTokenizer(extra_include)
self.blocks.insert(2, Block(replacement.tokens, directive='include'))
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index ac12fc7..1d7b427 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -28,22 +28,23 @@
}
# This is the set of known kernel data structures we want to remove from
-# the final headers. If the map value is False, that means that in
-# addition to removing the structure, add an #include <bits/STRUCT.h>
-# to the file.
+# the final headers. If the map value is non-empty, that means that in
+# addition to removing the structure, add a #include to the file.
kernel_structs_to_remove = {
- # Remove the structures since they are still the same as
+ # Remove these structures since they are still the same as
# timeval, itimerval.
- "__kernel_old_timeval": True,
- "__kernel_old_itimerval": True,
+ "__kernel_old_timeval": None,
+ "__kernel_old_itimerval": None,
# Replace all of the below structures with #include <bits/STRUCT.h>
- "epoll_event": False,
- "flock": False,
- "flock64": False,
- "in_addr": False,
- "ip_mreq_source": False,
- "ip_msfilter": False,
- "timespec": False,
+ "__kernel_sockaddr_storage": "bits/sockaddr_storage.h",
+ "epoll_event": "bits/epoll_event.h",
+ "flock": "bits/flock.h",
+ "flock64": "bits/flock64.h",
+ "in_addr": "bits/in_addr.h",
+ "ip_mreq_source": "bits/ip_mreq_source.h",
+ "ip_msfilter": "bits/ip_msfilter.h",
+ "tcphdr": "bits/tcphdr.h",
+ "timespec": "bits/timespec.h",
}
# define to true if you want to remove all defined(CONFIG_FOO) tests
@@ -91,12 +92,17 @@
"__kernel_old_timeval": "timeval",
# Do the same for __kernel_old_itimerval as for timeval.
"__kernel_old_itimerval": "itimerval",
+ # Do the same for __kernel_sockaddr_storage.
+ "__kernel_sockaddr_storage": "sockaddr_storage",
# Replace __packed with __attribute__((__packed__)) to avoid depending
# on sys/cdefs.h
"__packed": "__attribute__((__packed__))",
# Remove unused macros (http://b/262917450).
"__force": "",
"__user": "",
+ # Rename the kernel's sigaction so we can expose our POSIX one publicly,
+ # but translate to the kernel's one internally.
+ "sigaction": "__kernel_sigaction",
}
diff --git a/libc/kernel/uapi/asm-arm/asm/signal.h b/libc/kernel/uapi/asm-arm/asm/signal.h
index 838bb13..fde3b9e 100644
--- a/libc/kernel/uapi/asm-arm/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm/asm/signal.h
@@ -52,7 +52,7 @@
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
#include <asm-generic/signal-defs.h>
-struct sigaction {
+struct __kernel_sigaction {
union {
__sighandler_t _sa_handler;
void(* _sa_sigaction) (int, struct siginfo *, void *);
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index bea99a7..21c7100 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -61,7 +61,7 @@
#ifdef SA_RESTORER
#define __ARCH_HAS_SA_RESTORER
#endif
-struct sigaction {
+struct __kernel_sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
#ifdef SA_RESTORER
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index 2e51445..96ac8fb 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -56,7 +56,7 @@
#include <asm-generic/signal-defs.h>
#ifndef __ASSEMBLY__
#ifdef __i386__
-struct sigaction {
+struct __kernel_sigaction {
union {
__sighandler_t _sa_handler;
void(* _sa_sigaction) (int, struct siginfo *, void *);
@@ -68,7 +68,7 @@
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#else
-struct sigaction {
+struct __kernel_sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
__sigrestore_t sa_restorer;
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index e784690..44efdd8 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -148,32 +148,32 @@
#define IP_MSFILTER_SIZE(numsrc) (sizeof(struct ip_msfilter) - sizeof(__u32) + (numsrc) * sizeof(__u32))
struct group_req {
__u32 gr_interface;
- struct __kernel_sockaddr_storage gr_group;
+ struct sockaddr_storage gr_group;
};
struct group_source_req {
__u32 gsr_interface;
- struct __kernel_sockaddr_storage gsr_group;
- struct __kernel_sockaddr_storage gsr_source;
+ struct sockaddr_storage gsr_group;
+ struct sockaddr_storage gsr_source;
};
struct group_filter {
union {
struct {
__u32 gf_interface_aux;
- struct __kernel_sockaddr_storage gf_group_aux;
+ struct sockaddr_storage gf_group_aux;
__u32 gf_fmode_aux;
__u32 gf_numsrc_aux;
- struct __kernel_sockaddr_storage gf_slist[1];
+ struct sockaddr_storage gf_slist[1];
};
struct {
__u32 gf_interface;
- struct __kernel_sockaddr_storage gf_group;
+ struct sockaddr_storage gf_group;
__u32 gf_fmode;
__u32 gf_numsrc;
- struct __kernel_sockaddr_storage gf_slist_flex[];
+ struct sockaddr_storage gf_slist_flex[];
};
};
};
-#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + (numsrc) * sizeof(struct sockaddr_storage))
#endif
#if __UAPI_DEF_IN_PKTINFO
struct in_pktinfo {
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index f00abae..d97f29b 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -163,13 +163,13 @@
struct sockaddr sa_local;
struct sockaddr_in sin_local;
struct sockaddr_in6 sin6_local;
- struct __kernel_sockaddr_storage ss_local;
+ struct sockaddr_storage ss_local;
};
union {
struct sockaddr sa_remote;
struct sockaddr_in sin_remote;
struct sockaddr_in6 sin6_remote;
- struct __kernel_sockaddr_storage ss_remote;
+ struct sockaddr_storage ss_remote;
};
};
struct mptcp_subflow_info {
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index bc41946..e2a7a38 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -205,7 +205,7 @@
__u64 flags;
};
struct rds_get_mr_for_dest_args {
- struct __kernel_sockaddr_storage dest_addr;
+ struct sockaddr_storage dest_addr;
struct rds_iovec vec;
__u64 cookie_addr;
__u64 flags;
diff --git a/libc/kernel/uapi/linux/socket.h b/libc/kernel/uapi/linux/socket.h
index 936f44a..27890a4 100644
--- a/libc/kernel/uapi/linux/socket.h
+++ b/libc/kernel/uapi/linux/socket.h
@@ -6,17 +6,9 @@
*/
#ifndef _UAPI_LINUX_SOCKET_H
#define _UAPI_LINUX_SOCKET_H
+#include <bits/sockaddr_storage.h>
#define _K_SS_MAXSIZE 128
typedef unsigned short __kernel_sa_family_t;
-struct __kernel_sockaddr_storage {
- union {
- struct {
- __kernel_sa_family_t ss_family;
- char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
- };
- void * __align;
- };
-};
#define SOCK_SNDBUF_LOCK 1
#define SOCK_RCVBUF_LOCK 2
#define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 843b6ef..65bab54 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -6,25 +6,10 @@
*/
#ifndef _UAPI_LINUX_TCP_H
#define _UAPI_LINUX_TCP_H
+#include <bits/tcphdr.h>
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/socket.h>
-struct tcphdr {
- __be16 source;
- __be16 dest;
- __be32 seq;
- __be32 ack_seq;
-#ifdef __LITTLE_ENDIAN_BITFIELD
- __u16 res1 : 4, doff : 4, fin : 1, syn : 1, rst : 1, psh : 1, ack : 1, urg : 1, ece : 1, cwr : 1;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u16 doff : 4, res1 : 4, cwr : 1, ece : 1, urg : 1, ack : 1, psh : 1, rst : 1, syn : 1, fin : 1;
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
- __be16 window;
- __sum16 check;
- __be16 urg_ptr;
-};
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
@@ -217,7 +202,7 @@
#define TCP_MD5SIG_FLAG_PREFIX 0x1
#define TCP_MD5SIG_FLAG_IFINDEX 0x2
struct tcp_md5sig {
- struct __kernel_sockaddr_storage tcpm_addr;
+ struct sockaddr_storage tcpm_addr;
__u8 tcpm_flags;
__u8 tcpm_prefixlen;
__u16 tcpm_keylen;
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index dbe79bc..5228e62 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -76,7 +76,7 @@
__u32 id;
__u16 addr_size;
__u16 reserved;
- struct __kernel_sockaddr_storage addr;
+ struct sockaddr_storage addr;
};
struct rdma_ucm_resolve_ip {
struct sockaddr_in6 src_addr;
@@ -90,8 +90,8 @@
__u16 src_size;
__u16 dst_size;
__u32 reserved;
- struct __kernel_sockaddr_storage src_addr;
- struct __kernel_sockaddr_storage dst_addr;
+ struct sockaddr_storage src_addr;
+ struct sockaddr_storage dst_addr;
};
struct rdma_ucm_resolve_route {
__u32 id;
@@ -125,8 +125,8 @@
__u16 pkey;
__u16 src_size;
__u16 dst_size;
- struct __kernel_sockaddr_storage src_addr;
- struct __kernel_sockaddr_storage dst_addr;
+ struct sockaddr_storage src_addr;
+ struct sockaddr_storage dst_addr;
__u32 ibdev_index;
__u32 reserved1;
};
@@ -213,7 +213,7 @@
__u32 id;
__u16 addr_size;
__u16 join_flags;
- struct __kernel_sockaddr_storage addr;
+ struct sockaddr_storage addr;
};
struct rdma_ucm_get_event {
__aligned_u64 response;
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 24bb18a..83e4aa8 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -61,6 +61,7 @@
"DebugData.cpp",
"debug_disable.cpp",
"GuardData.cpp",
+ "LogAllocatorStats.cpp",
"malloc_debug.cpp",
"PointerData.cpp",
"RecordData.cpp",
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 77d2f02..89a7ce7 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -204,6 +204,10 @@
"check_unreachable_on_signal",
{CHECK_UNREACHABLE_ON_SIGNAL, &Config::VerifyValueEmpty},
},
+ {
+ "log_allocator_stats_on_signal",
+ {LOG_ALLOCATOR_STATS_ON_SIGNAL, &Config::VerifyValueEmpty},
+ },
};
bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value,
@@ -467,6 +471,7 @@
backtrace_min_size_bytes_ = 0;
backtrace_max_size_bytes_ = SIZE_MAX;
check_unreachable_signal_ = SIGRTMAX - 16;
+ log_allocator_stats_signal_ = SIGRTMAX - 15;
// Process each option name we can find.
std::string option;
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index ef1d2a9..754970f 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -48,6 +48,7 @@
constexpr uint64_t VERBOSE = 0x1000;
constexpr uint64_t CHECK_UNREACHABLE_ON_SIGNAL = 0x2000;
constexpr uint64_t BACKTRACE_SPECIFIC_SIZES = 0x4000;
+constexpr uint64_t LOG_ALLOCATOR_STATS_ON_SIGNAL = 0x8000;
// In order to guarantee posix compliance, set the minimum alignment
// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.
@@ -100,6 +101,8 @@
int check_unreachable_signal() const { return check_unreachable_signal_; }
+ int log_allocator_stats_signal() const { return log_allocator_stats_signal_; }
+
private:
struct OptionInfo {
uint64_t option;
@@ -175,4 +178,5 @@
uint8_t rear_guard_value_;
int check_unreachable_signal_ = 0;
+ int log_allocator_stats_signal_ = 0;
};
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index 44c4a10..885cc95 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -31,6 +31,7 @@
#include "Config.h"
#include "DebugData.h"
#include "GuardData.h"
+#include "LogAllocatorStats.h"
#include "PointerData.h"
#include "debug_disable.h"
#include "malloc_debug.h"
@@ -75,6 +76,13 @@
if (config_.options() & EXPAND_ALLOC) {
extra_bytes_ += config_.expand_alloc_bytes();
}
+
+ if (config_.options() & LOG_ALLOCATOR_STATS_ON_SIGNAL) {
+ if (!LogAllocatorStats::Initialize(config_)) {
+ return false;
+ }
+ }
+
return true;
}
diff --git a/libc/malloc_debug/LogAllocatorStats.cpp b/libc/malloc_debug/LogAllocatorStats.cpp
new file mode 100644
index 0000000..6d1434e
--- /dev/null
+++ b/libc/malloc_debug/LogAllocatorStats.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 <errno.h>
+#include <malloc.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "Config.h"
+#include "LogAllocatorStats.h"
+#include "debug_log.h"
+
+namespace LogAllocatorStats {
+
+static std::atomic_bool g_call_mallopt = {};
+
+static void CallMalloptLogStats(int, struct siginfo*, void*) {
+ g_call_mallopt = true;
+}
+
+void CheckIfShouldLog() {
+ bool expected = true;
+ if (g_call_mallopt.compare_exchange_strong(expected, false)) {
+ info_log("Logging allocator stats...");
+ if (mallopt(M_LOG_STATS, 0) == 0) {
+ error_log("mallopt(M_LOG_STATS, 0) call failed.");
+ }
+ }
+}
+
+bool Initialize(const Config& config) {
+ struct sigaction64 log_stats_act = {};
+ log_stats_act.sa_sigaction = CallMalloptLogStats;
+ log_stats_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+ if (sigaction64(config.log_allocator_stats_signal(), &log_stats_act, nullptr) != 0) {
+ error_log("Unable to set up log allocator stats signal function: %s", strerror(errno));
+ return false;
+ }
+
+ if (config.options() & VERBOSE) {
+ info_log("%s: Run: 'kill -%d %d' to log allocator stats.", getprogname(),
+ config.log_allocator_stats_signal(), getpid());
+ }
+
+ return true;
+}
+
+} // namespace LogAllocatorStats
diff --git a/libc/bionic/strnlen.c b/libc/malloc_debug/LogAllocatorStats.h
similarity index 83%
copy from libc/bionic/strnlen.c
copy to libc/malloc_debug/LogAllocatorStats.h
index 2c6f60a..99e0738 100644
--- a/libc/bionic/strnlen.c
+++ b/libc/malloc_debug/LogAllocatorStats.h
@@ -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,16 @@
* 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);
+#pragma once
- if (p == NULL)
- return maxlen;
- else
- return (p - str);
-}
+// Forward declarations
+class ConfigData;
+
+namespace LogAllocatorStats {
+
+bool Initialize(const Config& config);
+
+void CheckIfShouldLog();
+
+} // namespace LogAllocatorStats
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index 37fafa7..4e39bed 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -340,6 +340,16 @@
04-15 12:35:33.305 7412 7412 E malloc_debug: #02 pc 000a9e38 /system/lib/libc++.so
04-15 12:35:33.305 7412 7412 E malloc_debug: #03 pc 000a28a8 /system/lib/libc++.so
+### log\_allocator\_stats\_on\_signal
+As of Android V, this option will trigger a call to:
+
+ mallopt(M_LOG_STATS, 0);
+
+When a process receives the signal SIGRTMAX - 15 (which is 49 on Android
+devices). The mallopt call is not async safe and is not called from the
+signal handler directly. Instead, the next time any allocation call occurs,
+the mallopt is called.
+
### record\_allocs[=TOTAL\_ENTRIES]
Keep track of every allocation/free made on every thread and dump them
to a file when the signal SIGRTMAX - 18 (which is 46 on Android devices)
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index b06ec9e..3731a5d 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -53,6 +53,7 @@
#include "Config.h"
#include "DebugData.h"
+#include "LogAllocatorStats.h"
#include "Unreachable.h"
#include "UnwindBacktrace.h"
#include "backtrace.h"
@@ -517,11 +518,15 @@
}
static TimedResult InternalMalloc(size_t size) {
- if ((g_debug->config().options() & BACKTRACE) && g_debug->pointer->ShouldDumpAndReset()) {
+ uint64_t options = g_debug->config().options();
+ if ((options & BACKTRACE) && g_debug->pointer->ShouldDumpAndReset()) {
debug_dump_heap(android::base::StringPrintf(
"%s.%d.txt", g_debug->config().backtrace_dump_prefix().c_str(), getpid())
.c_str());
}
+ if (options & LOG_ALLOCATOR_STATS_ON_SIGNAL) {
+ LogAllocatorStats::CheckIfShouldLog();
+ }
if (size == 0) {
size = 1;
@@ -593,11 +598,15 @@
}
static TimedResult InternalFree(void* pointer) {
- if ((g_debug->config().options() & BACKTRACE) && g_debug->pointer->ShouldDumpAndReset()) {
+ uint64_t options = g_debug->config().options();
+ if ((options & BACKTRACE) && g_debug->pointer->ShouldDumpAndReset()) {
debug_dump_heap(android::base::StringPrintf(
"%s.%d.txt", g_debug->config().backtrace_dump_prefix().c_str(), getpid())
.c_str());
}
+ if (options & LOG_ALLOCATOR_STATS_ON_SIGNAL) {
+ LogAllocatorStats::CheckIfShouldLog();
+ }
void* free_pointer = pointer;
size_t bytes;
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index a911e76..84c9145 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -824,6 +824,24 @@
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugConfigTest, log_allocator_stats_on_signal) {
+ ASSERT_TRUE(InitConfig("log_allocator_stats_on_signal")) << getFakeLogPrint();
+ ASSERT_EQ(LOG_ALLOCATOR_STATS_ON_SIGNAL, config->options());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, trigger_log_allocator_stats_on_signal_fail) {
+ ASSERT_FALSE(InitConfig("log_allocator_stats_on_signal=200")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg(
+ "6 malloc_debug malloc_testing: value set for option 'log_allocator_stats_on_signal' "
+ "which does not take a value\n");
+ ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugConfigTest, size) {
ASSERT_TRUE(InitConfig("backtrace_size=37")) << getFakeLogPrint();
ASSERT_EQ(BACKTRACE_SPECIFIC_SIZES, config->options());
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index bf3ed14..334dada 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -267,6 +267,9 @@
"4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
SIGRTMAX - 18, getpid());
expected_log += android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to log allocator stats.\n",
+ SIGRTMAX - 15, getpid());
+ expected_log += android::base::StringPrintf(
"4 malloc_debug malloc_testing: Run: 'kill -%d %d' to check for unreachable memory.\n",
SIGRTMAX - 16, getpid());
}
@@ -348,6 +351,16 @@
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, verbose_log_allocator_stats_on_signal) {
+ Init("verbose log_allocator_stats_on_signal");
+
+ std::string expected_log = android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to log allocator stats.\n", SIGRTMAX - 15,
+ getpid());
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, fill_on_free) {
Init("fill_on_free free_track free_track_backtrace_num_frames=0");
@@ -411,7 +424,8 @@
TEST_F(MallocDebugTest, all_options) {
Init(
"guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
- "record_allocs verify_pointers abort_on_error verbose check_unreachable_on_signal");
+ "record_allocs verify_pointers abort_on_error verbose check_unreachable_on_signal "
+ "log_allocator_stats_on_signal");
VerifyAllocCalls(true);
}
@@ -2781,6 +2795,27 @@
getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, log_allocator_stats_on_signal) {
+ Init("log_allocator_stats_on_signal");
+
+ ASSERT_TRUE(kill(getpid(), SIGRTMAX - 15) == 0);
+ sleep(1);
+
+ // The first unreachable check will pass.
+ void* pointer = debug_malloc(110);
+ ASSERT_TRUE(pointer != nullptr);
+ debug_free(pointer);
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ if (!running_with_hwasan()) {
+ // Do an exact match because the mallopt should not fail in normal operation.
+ ASSERT_STREQ("4 malloc_debug Logging allocator stats...\n", getFakeLogPrint().c_str());
+ } else {
+ // mallopt fails with hwasan, so just verify that the message is present.
+ ASSERT_MATCH(getFakeLogPrint(), "4 malloc_debug Logging allocator stats...\\n");
+ }
+}
+
TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_size) {
Init("leak_track backtrace backtrace_size=120");
diff --git a/libc/tools/generate_notice.py b/libc/tools/generate_notice.py
index 505708a..69d2d00 100755
--- a/libc/tools/generate_notice.py
+++ b/libc/tools/generate_notice.py
@@ -45,14 +45,6 @@
return True
-def is_auto_generated(content):
- if "Generated by gensyscalls.py" in content or "generated by genserv.py" in content:
- return True
- if "This header was automatically generated from a Linux kernel header" in content:
- return True
- return False
-
-
def is_copyright_end(line: str, first_line_was_hash: bool) -> bool:
endings = [
" $FreeBSD: ",
@@ -153,10 +145,6 @@
warn_verbose("ignoring short file %s" % path)
return
- if is_auto_generated(content):
- warn_verbose("ignoring auto-generated file %s" % path)
- return
-
if not "Copyright" in content:
if "public domain" in content.lower():
warn_verbose("ignoring public domain file %s" % path)
diff --git a/libdl/Android.bp b/libdl/Android.bp
index fde3dfc..3bda856 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -148,10 +148,6 @@
"//apex_available:platform",
"com.android.runtime",
],
-
- lto: {
- never: true,
- },
}
cc_library {
@@ -230,10 +226,6 @@
"//apex_available:platform",
"com.android.runtime",
],
-
- lto: {
- never: true,
- },
}
ndk_library {
diff --git a/linker/Android.bp b/linker/Android.bp
index 0ccd16d..2ca962a 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -498,10 +498,6 @@
"//apex_available:platform",
"com.android.runtime",
],
-
- lto: {
- never: true,
- },
}
cc_test {
diff --git a/linker/linker_utils_test.cpp b/linker/linker_utils_test.cpp
index 0b881d4..ac98416 100644
--- a/linker/linker_utils_test.cpp
+++ b/linker/linker_utils_test.cpp
@@ -105,15 +105,35 @@
}
TEST(linker_utils, page_start) {
- ASSERT_EQ(0x0001000U, page_start(0x0001000));
- ASSERT_EQ(0x3002000U, page_start(0x300222f));
- ASSERT_EQ(0x6001000U, page_start(0x6001fff));
+ const size_t kPageSize = page_size();
+
+ if (kPageSize == 4096) {
+ ASSERT_EQ(0x0001000U, page_start(0x0001000));
+ ASSERT_EQ(0x3002000U, page_start(0x300222f));
+ ASSERT_EQ(0x6001000U, page_start(0x6001fff));
+ } else if (kPageSize == 16384) {
+ ASSERT_EQ(0x0004000U, page_start(0x0004000));
+ ASSERT_EQ(0x3008000U, page_start(0x300822f));
+ ASSERT_EQ(0x6004000U, page_start(0x6004fff));
+ } else {
+ FAIL() << "Page size not supported " << kPageSize;
+ }
}
TEST(linker_utils, page_offset) {
- ASSERT_EQ(0x0U, page_offset(0x0001000));
- ASSERT_EQ(0x22fU, page_offset(0x300222f));
- ASSERT_EQ(0xfffU, page_offset(0x6001fff));
+ const size_t kPageSize = page_size();
+
+ if (kPageSize == 4096) {
+ ASSERT_EQ(0x0U, page_offset(0x0001000));
+ ASSERT_EQ(0x22fU, page_offset(0x30222f));
+ ASSERT_EQ(0xfffU, page_offset(0x6001fff));
+ } else if (kPageSize == 16384) {
+ ASSERT_EQ(0x0U, page_offset(0x0004000));
+ ASSERT_EQ(0x322fU, page_offset(0x30322f));
+ ASSERT_EQ(0x3fffU, page_offset(0x6003fff));
+ } else {
+ FAIL() << "Page size not supported " << kPageSize;
+ }
}
TEST(linker_utils, safe_add) {
diff --git a/tests/Android.bp b/tests/Android.bp
index 14b4e3e..a53418a 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -583,18 +583,6 @@
shared: {
enabled: false,
},
- cflags: [
- "-fno-emulated-tls",
- ],
- // With fuzzer builds, compiler instrumentation generates a reference to the
- // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer
- // library as an emutls symbol. The -fno-emulated-tls flag above configures
- // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack
- // symbol instead, which isn't defined. Disable the fuzzer for this test
- // until the platform is switched to ELF TLS.
- sanitize: {
- fuzzer: false,
- },
}
cc_test_library {
@@ -613,18 +601,6 @@
shared: {
enabled: false,
},
- cflags: [
- "-fno-emulated-tls",
- ],
- // With fuzzer builds, compiler instrumentation generates a reference to the
- // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer
- // library as an emutls symbol. The -fno-emulated-tls flag above configures
- // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack
- // symbol instead, which isn't defined. Disable the fuzzer for this test
- // until the platform is switched to ELF TLS.
- sanitize: {
- fuzzer: false,
- },
}
cc_test_library {
diff --git a/tests/ifunc_test.cpp b/tests/ifunc_test.cpp
index 1fdbf1a..09d987d 100644
--- a/tests/ifunc_test.cpp
+++ b/tests/ifunc_test.cpp
@@ -65,18 +65,18 @@
#include <sys/hwprobe.h>
static uint64_t g_hwcap;
+static __riscv_hwprobe_t g_hwprobe_ptr;
+static void* g_null;
static riscv_hwprobe g_hwprobes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0}};
-extern "C" fn_ptr_t hwcap_resolver(uint64_t hwcap, void* null) {
- // Check hwcap like arm32/arm64.
+extern "C" fn_ptr_t hwcap_resolver(uint64_t hwcap, __riscv_hwprobe_t hwprobe_ptr, void* null) {
g_hwcap = hwcap;
-
- // For now, the pointer argument is reserved for future expansion.
- if (null != NULL) abort();
+ g_hwprobe_ptr = hwprobe_ptr;
+ g_null = null;
// Ensure that __riscv_hwprobe() can be called from an ifunc.
- if (__riscv_hwprobe(g_hwprobes, 1, 0, nullptr, 0) != 0) return nullptr;
+ if ((*hwprobe_ptr)(g_hwprobes, 1, 0, nullptr, 0) != 0) return nullptr;
return ret42;
}
@@ -102,7 +102,11 @@
#elif defined(__arm__)
EXPECT_EQ(getauxval(AT_HWCAP), g_hwcap);
#elif defined(__riscv)
+ printf("hwcap=%lx hwprobe_ptr=%p (__riscv_hwprobe=%p) null=%p\n", g_hwcap, g_hwprobe_ptr,
+ __riscv_hwprobe, g_null);
+
EXPECT_EQ(getauxval(AT_HWCAP), g_hwcap);
+ EXPECT_EQ(nullptr, g_null);
riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0}};
ASSERT_EQ(0, __riscv_hwprobe(probes, 1, 0, nullptr, 0));
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 51f5ac6..0bef469 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -29,11 +29,11 @@
"-Wl,--rpath,${ORIGIN}",
"-Wl,--enable-new-dtags",
],
+ static_libs: ["libbase"],
relative_install_path: "bionic-loader-test-libs",
gtest: false,
sanitize: {
address: false,
- fuzzer: false,
},
stl: "libc++_static",
target: {
@@ -53,14 +53,12 @@
name: "libtest_elftls_shared_var",
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_shared_var.cpp"],
- cflags: ["-fno-emulated-tls"],
}
cc_test_library {
name: "libtest_elftls_shared_var_ie",
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_shared_var_ie.cpp"],
- cflags: ["-fno-emulated-tls"],
shared_libs: ["libtest_elftls_shared_var"],
}
@@ -68,7 +66,6 @@
name: "libtest_elftls_tprel",
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_tprel.cpp"],
- cflags: ["-fno-emulated-tls"],
}
cc_test {
@@ -82,7 +79,6 @@
name: "libtest_elftls_dynamic",
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_dynamic.cpp"],
- cflags: ["-fno-emulated-tls"],
shared_libs: ["libtest_elftls_shared_var"],
}
@@ -90,14 +86,12 @@
name: "thread_exit_cb_helper",
defaults: ["bionic_testlib_defaults"],
srcs: ["thread_exit_cb_helper.cpp"],
- cflags: ["-fno-emulated-tls"],
}
cc_test {
name: "tls_properties_helper",
defaults: ["bionic_testlib_defaults"],
srcs: ["tls_properties_helper.cpp"],
- cflags: ["-fno-emulated-tls"],
shared_libs: ["libtest_elftls_shared_var"],
}
@@ -107,7 +101,6 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_dynamic_filler.cpp"],
cflags: [
- "-fno-emulated-tls",
"-DTLS_FILLER=100",
],
}
@@ -117,7 +110,6 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_dynamic_filler.cpp"],
cflags: [
- "-fno-emulated-tls",
"-DTLS_FILLER=200",
],
}
@@ -127,7 +119,6 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["elftls_dynamic_filler.cpp"],
cflags: [
- "-fno-emulated-tls",
"-DTLS_FILLER=300",
],
}
@@ -645,7 +636,6 @@
],
sanitize: {
address: false,
- fuzzer: false,
},
stl: "libc++_static",
target: {
@@ -1739,10 +1729,6 @@
" $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
" $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
- bazel_module: {
- // Depends on soong_zip, which is not available yet.
- bp2build_available: false
- },
}
cc_genrule {
@@ -1781,9 +1767,4 @@
" touch $(genDir)/zipdir/empty_file.txt &&" +
" $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
" $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
-
- bazel_module: {
- // Depends on soong_zip, which is not available yet.
- bp2build_available: false
- },
}
diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp
index ed5601a..7aad392 100644
--- a/tests/libs/heap_tagging_helper.cpp
+++ b/tests/libs/heap_tagging_helper.cpp
@@ -16,12 +16,15 @@
#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/auxv.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
#include <unistd.h>
#include <memory>
+#include <android-base/stringprintf.h>
+
void action(int signo, siginfo_t* info __unused, void*) {
#ifdef __ANDROID__
if (signo == 11 && info->si_code == SEGV_MTEAERR) {
@@ -89,6 +92,13 @@
}
#endif // __aarch64__
+ // In fact, make sure that there are no tagged mappings at all.
+ auto cmd = android::base::StringPrintf("cat /proc/%d/smaps | grep -E 'VmFlags:.* mt'", getpid());
+ if (system(cmd.c_str()) == 0) {
+ fprintf(stderr, "unexpected PROT_MTE mappings found\n");
+ return 1;
+ }
+
fprintf(stderr, "normal exit\n");
return 0;
}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 73090e1..749d687 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
+#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
@@ -784,7 +785,7 @@
size_t guard_size;
ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
ASSERT_EQ(128U, guard_size);
- ASSERT_EQ(4096U, GetActualGuardSize(attributes));
+ ASSERT_EQ(static_cast<unsigned long>(getpagesize()), GetActualGuardSize(attributes));
}
TEST(pthread, pthread_attr_setguardsize_reasonable) {
@@ -808,7 +809,7 @@
size_t guard_size;
ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
ASSERT_EQ(32*1024U + 1, guard_size);
- ASSERT_EQ(36*1024U, GetActualGuardSize(attributes));
+ ASSERT_EQ(roundup(32 * 1024U + 1, getpagesize()), GetActualGuardSize(attributes));
}
TEST(pthread, pthread_attr_setguardsize_enormous) {
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index 5b061be..5558134 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -52,7 +52,7 @@
// Too large an initial value.
errno = 0;
- ASSERT_EQ(-1, sem_init(&s, 0, SEM_VALUE_MAX + 1));
+ ASSERT_EQ(-1, sem_init(&s, 0, static_cast<unsigned>(SEM_VALUE_MAX) + 1));
ASSERT_ERRNO(EINVAL);
ASSERT_EQ(0, sem_destroy(&s));
diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp
index 727af87..f5c6bb1 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -181,7 +181,8 @@
// And a rudimentary test of acquire-release memory ordering:
-static constexpr uint_least32_t BIG = 30'000'000ul; // Assumed even below.
+static constexpr uint_least32_t BIG = 30'000'000ul;
+static_assert((BIG % 2) == 0); // Assumed below.
struct three_atomics {
atomic_uint_least32_t x;
@@ -192,6 +193,8 @@
atomic_uint_least32_t z;
};
+atomic_bool read_enough(false);
+
// Very simple acquire/release memory ordering smoke test.
static void* writer(void* arg) {
three_atomics* a = reinterpret_cast<three_atomics*>(arg);
@@ -199,9 +202,18 @@
atomic_store_explicit(&a->x, i, memory_order_relaxed);
atomic_store_explicit(&a->z, i, memory_order_relaxed);
atomic_store_explicit(&a->y, i, memory_order_release);
+
+ // Force stores to be visible in spite of being overwritten below.
+ asm volatile("" ::: "memory");
+
atomic_store_explicit(&a->x, i+1, memory_order_relaxed);
atomic_store_explicit(&a->z, i+1, memory_order_relaxed);
atomic_store_explicit(&a->y, i+1, memory_order_release);
+ if (i >= BIG - 1000 && !atomic_load(&read_enough)) {
+ // Give reader a chance to catch up, at the expense of making the test
+ // less effective.
+ usleep(1000);
+ }
}
return nullptr;
}
@@ -229,7 +241,11 @@
<< xval << " < " << yval << ", " << zval << "\n";
return nullptr; // Only report once.
}
- if (repeat < repeat_limit) ++repeat;
+ if (repeat < repeat_limit) {
+ ++repeat;
+ } else if (!atomic_load_explicit(&read_enough, memory_order_relaxed)) {
+ atomic_store_explicit(&read_enough, true, memory_order_relaxed);
+ }
}
// The following assertion is not technically guaranteed to hold.
// But if it fails to hold, this test was useless, and we have a
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 6a94507..e9a3080 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1127,8 +1127,8 @@
TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
// Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
- // See prepare_arg_pages() in the kernel for the gory details:
- // https://elixir.bootlin.com/linux/v5.3.11/source/fs/exec.c#L451
+ // See setup_arg_pages() in the kernel for the gory details:
+ // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L749
// Get our current limit, and set things up so we restore the limit.
rlimit rl;
@@ -1145,19 +1145,24 @@
// _SC_ARG_MAX should be 1/4 the stack size.
EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
- // If you have a really small stack, the kernel still guarantees "32 pages" (see fs/exec.c).
+ // If you have a really small stack, the kernel still guarantees a stack
+ // expansion of 128KiB (see setup_arg_pages() in fs/exec.c).
rl.rlim_cur = 1024;
rl.rlim_max = RLIM_INFINITY;
ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
- EXPECT_EQ(static_cast<long>(32 * sysconf(_SC_PAGE_SIZE)), sysconf(_SC_ARG_MAX));
+ // The stack expansion number is defined in fs/exec.c.
+ // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L845
+ constexpr long kernel_stack_expansion = 131072;
+ EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
- // With a 128-page stack limit, we know exactly what _SC_ARG_MAX should be...
- rl.rlim_cur = 128 * sysconf(_SC_PAGE_SIZE);
+ // If you have a large stack, the kernel will keep the stack
+ // expansion to 128KiB (see setup_arg_pages() in fs/exec.c).
+ rl.rlim_cur = 524288;
rl.rlim_max = RLIM_INFINITY;
ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
- EXPECT_EQ(static_cast<long>((128 * sysconf(_SC_PAGE_SIZE)) / 4), sysconf(_SC_ARG_MAX));
+ EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
}
TEST(UNISTD_TEST, sysconf_unknown) {