aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-06-14 19:30:29 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-06-14 19:30:29 +0000
commit730a9963fa65360c323634ca02cf353b35946e5a (patch)
treef12ffa955f8105409bb0ab2b022f9c289f561c97
parent41ea538b401b10c9e2102a582289c29be718ab51 (diff)
parent04cf93f337c20b9e4ba6a3abb77bc2328e7df4ad (diff)
downloadbionic-ndk-r26-release.tar.gz
Merge "Snap for 10321980 from 6045af29318e0fef2075d7484988041439128ea2 to ndk-r26-release" into ndk-r26-releasendk-r26dndk-r26cndk-r26bndk-r26-rc1ndk-r26-beta1ndk-r26ndk-r26-release
-rw-r--r--libc/Android.bp21
-rw-r--r--libc/NOTICE28
-rw-r--r--libc/arch-riscv64/dynamic_function_dispatch.cpp107
-rw-r--r--libc/arch-riscv64/static_function_dispatch.S55
-rw-r--r--libc/arch-riscv64/string/memchr_vext.S100
-rw-r--r--libc/arch-riscv64/string/memcmp_vext.S110
-rw-r--r--libc/arch-riscv64/string/memcpy_vext.S88
-rw-r--r--libc/arch-riscv64/string/memmove_vext.S106
-rw-r--r--libc/arch-riscv64/string/memset_vext.S89
-rw-r--r--libc/arch-riscv64/string/strcat_vext.S111
-rw-r--r--libc/arch-riscv64/string/strchr_vext.S98
-rw-r--r--libc/arch-riscv64/string/strcmp_vext.S173
-rw-r--r--libc/arch-riscv64/string/strcpy_vext.S95
-rw-r--r--libc/arch-riscv64/string/strlen_vext.S91
-rw-r--r--libc/arch-riscv64/string/strncat_vext.S121
-rw-r--r--libc/arch-riscv64/string/strncmp_vext.S123
-rw-r--r--libc/arch-riscv64/string/strncpy_vext.S118
-rw-r--r--libc/arch-riscv64/string/strnlen_vext.S93
-rw-r--r--libc/arch-riscv64/string/sys/asm.h76
-rw-r--r--libc/bionic/atexit.cpp6
-rw-r--r--libc/bionic/bionic_allocator.cpp26
-rw-r--r--libc/bionic/bionic_elf_tls.cpp5
-rw-r--r--libc/bionic/fdsan.cpp3
-rw-r--r--libc/bionic/getpagesize.cpp3
-rw-r--r--libc/bionic/libc_init_static.cpp10
-rw-r--r--libc/bionic/mmap.cpp3
-rw-r--r--libc/bionic/mremap.cpp3
-rw-r--r--libc/bionic/pthread_attr.cpp7
-rw-r--r--libc/bionic/pthread_create.cpp14
-rw-r--r--libc/bionic/strtold.cpp2
-rw-r--r--libc/bionic/sysconf.cpp1
-rw-r--r--libc/bionic/sysinfo.cpp7
-rw-r--r--libc/bionic/wcstod.cpp2
-rw-r--r--libc/include/android/versioning.h22
-rw-r--r--libc/include/bits/fortify/fcntl.h32
-rw-r--r--libc/include/bits/fortify/poll.h12
-rw-r--r--libc/include/bits/fortify/socket.h14
-rw-r--r--libc/include/bits/fortify/stdio.h22
-rw-r--r--libc/include/bits/fortify/stdlib.h2
-rw-r--r--libc/include/bits/fortify/string.h54
-rw-r--r--libc/include/bits/fortify/strings.h4
-rw-r--r--libc/include/bits/fortify/unistd.h44
-rw-r--r--libc/include/bits/stdatomic.h8
-rw-r--r--libc/include/bits/termios_inlines.h18
-rw-r--r--libc/include/bits/threads_inlines.h59
-rw-r--r--libc/include/complex.h44
-rw-r--r--libc/include/fenv.h145
-rw-r--r--libc/include/ftw.h4
-rw-r--r--libc/include/iconv.h2
-rw-r--r--libc/include/math.h121
-rw-r--r--libc/include/sched.h2
-rw-r--r--libc/include/stdlib.h2
-rw-r--r--libc/include/sys/cdefs.h33
-rw-r--r--libc/include/sys/stat.h8
-rw-r--r--libc/include/sys/thread_properties.h22
-rw-r--r--libc/include/wchar.h2
-rw-r--r--libc/platform/bionic/page.h32
-rw-r--r--libc/stdio/scanf_common.h115
-rw-r--r--libc/stdio/vfscanf.cpp61
-rw-r--r--libc/stdio/vfwscanf.cpp70
-rw-r--r--libm/Android.bp1
-rw-r--r--linker/linker.cpp4
-rw-r--r--linker/linker_cfi.cpp6
-rw-r--r--linker/linker_main.cpp4
-rw-r--r--linker/linker_mapped_file_fragment.cpp1
-rw-r--r--linker/linker_phdr.cpp60
-rw-r--r--linker/linker_utils.cpp10
-rw-r--r--linker/linker_utils.h2
-rw-r--r--linker/linker_utils_test.cpp7
-rw-r--r--tests/Android.bp2
-rw-r--r--tests/complex_force_long_double_test.cpp2
-rw-r--r--tests/complex_test.cpp141
-rw-r--r--tests/math_force_long_double_test.cpp2
-rw-r--r--tests/math_test.cpp671
-rw-r--r--tests/stdio_test.cpp138
-rw-r--r--tools/versioner/src/versioner.cpp4
-rw-r--r--tools/versioner/tests/preprocessor/expected/foo.h19
-rw-r--r--tools/versioner/tests/preprocessor/headers/foo.h7
78 files changed, 2978 insertions, 952 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index ecabb06b7..1e2458a29 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -932,6 +932,21 @@ cc_library_static {
"arch-riscv64/bionic/setjmp.S",
"arch-riscv64/bionic/syscall.S",
"arch-riscv64/bionic/vfork.S",
+
+ "arch-riscv64/string/memchr_vext.S",
+ "arch-riscv64/string/memcmp_vext.S",
+ "arch-riscv64/string/memcpy_vext.S",
+ "arch-riscv64/string/memmove_vext.S",
+ "arch-riscv64/string/memset_vext.S",
+ "arch-riscv64/string/strcat_vext.S",
+ "arch-riscv64/string/strchr_vext.S",
+ "arch-riscv64/string/strcmp_vext.S",
+ "arch-riscv64/string/strcpy_vext.S",
+ "arch-riscv64/string/strlen_vext.S",
+ "arch-riscv64/string/strncat_vext.S",
+ "arch-riscv64/string/strncmp_vext.S",
+ "arch-riscv64/string/strncpy_vext.S",
+ "arch-riscv64/string/strnlen_vext.S",
],
},
@@ -1541,6 +1556,9 @@ cc_library_static {
arm64: {
srcs: ["arch-arm64/static_function_dispatch.S"],
},
+ riscv64: {
+ srcs: ["arch-riscv64/static_function_dispatch.S"]
+ },
},
}
@@ -1569,6 +1587,9 @@ cc_library_static {
arm64: {
srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
},
+ riscv64: {
+ srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"]
+ },
},
}
diff --git a/libc/NOTICE b/libc/NOTICE
index 4d3a10861..441e79c03 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -4540,6 +4540,34 @@ SUCH DAMAGE.
-------------------------------------------------------------------
+Copyright (c) 2023 SiFive, Inc.
+All rights reserved.
+
+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. The name of the company may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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)1999 Citrus Project,
All rights reserved.
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
new file mode 100644
index 000000000..0925c5f6d
--- /dev/null
+++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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 <private/bionic_ifuncs.h>
+#include <stddef.h>
+#include <sys/auxv.h>
+
+#if defined(__riscv_v)
+extern "C" {
+
+typedef void* memchr_func(const void*, int, size_t);
+DEFINE_IFUNC_FOR(memchr) {
+ RETURN_FUNC(memchr_func, memchr_vext);
+}
+
+typedef int memcmp_func(const void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcmp) {
+ RETURN_FUNC(memcmp_func, memcmp_vext);
+}
+
+typedef void* memcpy_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memcpy) {
+ RETURN_FUNC(memcpy_func, memcpy_vext);
+}
+
+typedef void* memmove_func(void*, const void*, size_t);
+DEFINE_IFUNC_FOR(memmove) {
+ RETURN_FUNC(memmove_func, memmove_vext);
+}
+
+typedef void* memset_func(void*, int, size_t);
+DEFINE_IFUNC_FOR(memset) {
+ RETURN_FUNC(memset_func, memset_vext);
+}
+
+typedef char* strcat_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcat) {
+ RETURN_FUNC(strcat_func, strcat_vext);
+}
+
+typedef char* strchr_func(const char*, int);
+DEFINE_IFUNC_FOR(strchr) {
+ RETURN_FUNC(strchr_func, strchr_vext);
+}
+
+typedef int strcmp_func(const char*, const char*);
+DEFINE_IFUNC_FOR(strcmp) {
+ RETURN_FUNC(strcmp_func, strcmp_vext);
+}
+
+typedef char* strcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcpy) {
+ RETURN_FUNC(strcpy_func, strcpy_vext);
+}
+
+typedef size_t strlen_func(const char*);
+DEFINE_IFUNC_FOR(strlen) {
+ RETURN_FUNC(strlen_func, strlen_vext);
+}
+
+typedef char* strncat_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncat) {
+ RETURN_FUNC(strncat_func, strncat_vext);
+}
+
+typedef int strncmp_func(const char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncmp) {
+ RETURN_FUNC(strncmp_func, strncmp_vext);
+}
+
+typedef char* strncpy_func(char*, const char*, size_t);
+DEFINE_IFUNC_FOR(strncpy) {
+ RETURN_FUNC(strncpy_func, strncpy_vext);
+}
+
+typedef size_t strnlen_func(const char*, size_t);
+DEFINE_IFUNC_FOR(strnlen) {
+ RETURN_FUNC(strnlen_func, strnlen_vext);
+}
+
+} // extern "C"
+#endif
diff --git a/libc/arch-riscv64/static_function_dispatch.S b/libc/arch-riscv64/static_function_dispatch.S
new file mode 100644
index 000000000..3bf02754d
--- /dev/null
+++ b/libc/arch-riscv64/static_function_dispatch.S
@@ -0,0 +1,55 @@
+/*
+ * 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 <private/bionic_asm.h>
+
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+ j impl; \
+END(name)
+
+#if defined(__riscv_v)
+
+FUNCTION_DELEGATE(memchr, memchr_vext)
+FUNCTION_DELEGATE(memcmp, memcmp_vext)
+FUNCTION_DELEGATE(memcpy, memcpy_vext)
+FUNCTION_DELEGATE(memmove, memmove_vext)
+FUNCTION_DELEGATE(memset, memset_vext)
+FUNCTION_DELEGATE(strcat, strcat_vext)
+FUNCTION_DELEGATE(strchr, strchr_vext)
+FUNCTION_DELEGATE(strcmp, strcmp_vext)
+FUNCTION_DELEGATE(strcpy, strcpy_vext)
+FUNCTION_DELEGATE(strlen, strlen_vext)
+FUNCTION_DELEGATE(strncat, strncat_vext)
+FUNCTION_DELEGATE(strncmp, strncmp_vext)
+FUNCTION_DELEGATE(strncpy, strncpy_vext)
+FUNCTION_DELEGATE(strnlen, strnlen_vext)
+
+#endif
+
+NOTE_GNU_PROPERTY()
diff --git a/libc/arch-riscv64/string/memchr_vext.S b/libc/arch-riscv64/string/memchr_vext.S
new file mode 100644
index 000000000..376126588
--- /dev/null
+++ b/libc/arch-riscv64/string/memchr_vext.S
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pSrc a0
+#define iValue a1
+#define iNum a2
+
+#define iVL a3
+#define iTemp a4
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+#define vMask v8
+
+ENTRY(memchr_vext)
+
+L(loop):
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vData, (pSrc)
+ vmseq.vx vMask, vData, iValue
+ vfirst.m iTemp, vMask
+
+ # skip the loop if we find the matched value.
+ bgez iTemp, L(found)
+
+ csrr iVL, vl
+ sub iNum, iNum, iVL
+ add pSrc, pSrc, iVL
+
+ bnez iNum, L(loop)
+
+ li iResult, 0
+ ret
+
+L(found):
+ add iResult, pSrc, iTemp
+ ret
+
+END(memchr_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memcmp_vext.S b/libc/arch-riscv64/string/memcmp_vext.S
new file mode 100644
index 000000000..d8e7a0692
--- /dev/null
+++ b/libc/arch-riscv64/string/memcmp_vext.S
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#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 vData1 v0
+#define vData2 v8
+#define vMask v16
+
+ENTRY(memcmp_vext)
+
+L(loop):
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+ 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 different
+ value between pSrc1 and pSrc2. */
+ bgez iTemp, L(found)
+
+ add pSrc1, pSrc1, iVL
+ add pSrc2, pSrc2, iVL
+
+ bnez iNum, L(loop)
+
+ li iResult, 0
+ ret
+
+L(found):
+ add pSrc1, pSrc1, iTemp
+ add pSrc2, pSrc2, iTemp
+ lbu iTemp1, 0(pSrc1)
+ lbu iTemp2, 0(pSrc2)
+ sub iResult, iTemp1, iTemp2
+ ret
+
+END(memcmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memcpy_vext.S b/libc/arch-riscv64/string/memcpy_vext.S
new file mode 100644
index 000000000..100f538c0
--- /dev/null
+++ b/libc/arch-riscv64/string/memcpy_vext.S
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iNum a2
+
+#define iVL a3
+#define pDstPtr a4
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memcpy_vext)
+
+ mv pDstPtr, pDst
+
+L(loop):
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8.v vData, (pSrc)
+ sub iNum, iNum, iVL
+ add pSrc, pSrc, iVL
+ vse8.v vData, (pDstPtr)
+ add pDstPtr, pDstPtr, iVL
+
+ bnez iNum, L(loop)
+
+ ret
+
+END(memcpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memmove_vext.S b/libc/arch-riscv64/string/memmove_vext.S
new file mode 100644
index 000000000..722ffd118
--- /dev/null
+++ b/libc/arch-riscv64/string/memmove_vext.S
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iNum a2
+
+#define iVL a3
+#define pDstPtr a4
+#define pSrcBackwardPtr a5
+#define pDstBackwardPtr a6
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memmove_vext)
+
+ mv pDstPtr, pDst
+
+ bgeu pSrc, pDst, L(forward_copy_loop)
+ add pSrcBackwardPtr, pSrc, iNum
+ add pDstBackwardPtr, pDst, iNum
+ bltu pDst, pSrcBackwardPtr, L(backward_copy_loop)
+
+L(forward_copy_loop):
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8.v vData, (pSrc)
+ sub iNum, iNum, iVL
+ add pSrc, pSrc, iVL
+ vse8.v vData, (pDstPtr)
+ add pDstPtr, pDstPtr, iVL
+
+ bnez iNum, L(forward_copy_loop)
+ ret
+
+L(backward_copy_loop):
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+
+ sub pSrcBackwardPtr, pSrcBackwardPtr, iVL
+ vle8.v vData, (pSrcBackwardPtr)
+ sub iNum, iNum, iVL
+ sub pDstBackwardPtr, pDstBackwardPtr, iVL
+ vse8.v vData, (pDstBackwardPtr)
+ bnez iNum, L(backward_copy_loop)
+ ret
+
+END(memmove_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/memset_vext.S b/libc/arch-riscv64/string/memset_vext.S
new file mode 100644
index 000000000..ef8387dbd
--- /dev/null
+++ b/libc/arch-riscv64/string/memset_vext.S
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define iValue a1
+#define iNum a2
+
+#define iVL a3
+#define iTemp a4
+#define pDstPtr a5
+
+#define ELEM_LMUL_SETTING m8
+#define vData v0
+
+ENTRY(memset_vext)
+
+ mv pDstPtr, pDst
+
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+ vmv.v.x vData, iValue
+
+L(loop):
+ vse8.v vData, (pDstPtr)
+ sub iNum, iNum, iVL
+ add pDstPtr, pDstPtr, iVL
+ vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
+ bnez iNum, L(loop)
+
+ ret
+
+END(memset_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcat_vext.S b/libc/arch-riscv64/string/strcat_vext.S
new file mode 100644
index 000000000..790c07ab2
--- /dev/null
+++ b/libc/arch-riscv64/string/strcat_vext.S
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define pDstPtr a2
+
+#define iVL a3
+#define iCurrentVL a4
+#define iActiveElemPos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strcat_vext)
+
+ mv pDstPtr, pDst
+
+ // the strlen of dst
+L(strlen_loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vStr1, (pDstPtr)
+ // find the '\0'
+ vmseq.vx vMask1, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask1
+ add pDstPtr, pDstPtr, iCurrentVL
+ bltz iActiveElemPos, L(strlen_loop)
+
+ sub pDstPtr, pDstPtr, iCurrentVL
+ add pDstPtr, pDstPtr, iActiveElemPos
+
+ // copy pSrc to pDstPtr
+L(strcpy_loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vStr1, (pSrc)
+ vmseq.vx vMask2, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask2
+ vmsif.m vMask1, vMask2
+ add pSrc, pSrc, iCurrentVL
+ vse8.v vStr1, (pDstPtr), vMask1.t
+ add pDstPtr, pDstPtr, iCurrentVL
+ bltz iActiveElemPos, L(strcpy_loop)
+
+ ret
+
+END(strcat_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strchr_vext.S b/libc/arch-riscv64/string/strchr_vext.S
new file mode 100644
index 000000000..89828eafa
--- /dev/null
+++ b/libc/arch-riscv64/string/strchr_vext.S
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pStr a0
+#define iCh a1
+#define iEndOffset a2
+#define iChOffset a3
+#define iTemp1 a4
+#define iTemp2 a5
+#define iCurrentVL a6
+#define iVL t0
+
+#define ELEM_LMUL_SETTING m1
+#define vStr v0
+#define vMaskEnd v8
+#define vMaskCh v9
+
+ENTRY(strchr_vext)
+
+L(strchr_loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vStr, (pStr)
+ vmseq.vi vMaskEnd, vStr, 0
+ vmseq.vx vMaskCh, vStr, iCh
+ vfirst.m iEndOffset, vMaskEnd /* first occurrence of \0 */
+ vfirst.m iChOffset, vMaskCh /* first occurrence of ch */
+ sltz iTemp1, iChOffset
+ sltu iTemp2, iEndOffset, iChOffset
+ or iTemp1, iTemp1, iTemp2
+ beqz iTemp1, L(found_ch) /* Found ch, not preceded by \0? */
+ csrr iCurrentVL, vl
+ add pStr, pStr, iCurrentVL
+ bltz iEndOffset, L(strchr_loop) /* Didn't find \0? */
+ li pStr, 0
+ ret
+L(found_ch):
+ add pStr, pStr, iChOffset
+ ret
+
+END(strchr_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcmp_vext.S b/libc/arch-riscv64/string/strcmp_vext.S
new file mode 100644
index 000000000..d6ad96e4d
--- /dev/null
+++ b/libc/arch-riscv64/string/strcmp_vext.S
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pStr1 a0
+#define pStr2 a1
+
+#define iVL a2
+#define iTemp1 a3
+#define iTemp2 a4
+#define iLMUL1 a5
+#define iLMUL2 a6
+#define iLMUL4 a7
+
+#define iLMUL t0
+
+#define vStr1 v0
+#define vStr2 v8
+#define vMask1 v16
+#define vMask2 v17
+
+ENTRY(strcmp_vext)
+
+ # increase the lmul using the following sequences:
+ # 1/2, 1/2, 1, 2, 4, 4, 4, ...
+
+ # lmul=1/2
+ vsetvli iVL, zero, e8, mf2, ta, ma
+
+ vle8ff.v vStr1, (pStr1)
+ # check if vStr1[i] == 0
+ vmseq.vx vMask1, vStr1, zero
+
+ vle8ff.v vStr2, (pStr2)
+ # check if vStr1[i] != vStr2[i]
+ vmsne.vv vMask2, vStr1, vStr2
+
+ # find the index x for vStr1[x]==0
+ vfirst.m iTemp1, vMask1
+ # find the index x for vStr1[x]!=vStr2[x]
+ vfirst.m iTemp2, vMask2
+
+ bgez iTemp1, L(check1)
+ bgez iTemp2, L(check2)
+
+ # get the current vl updated by vle8ff.
+ csrr iVL, vl
+ add pStr1, pStr1, iVL
+ add pStr2, pStr2, iVL
+
+ vsetvli iVL, zero, e8, mf2, ta, ma
+ addi iLMUL1, zero, 1
+ addi iLMUL, zero, 1
+ j L(loop)
+L(m1):
+ vsetvli iVL, zero, e8, m1, ta, ma
+ addi iLMUL2, zero, 2
+ addi iLMUL, zero, 2
+ j L(loop)
+L(m2):
+ vsetvli iVL, zero, e8, m2, ta, ma
+ addi iLMUL4, zero, 4
+ addi iLMUL, zero, 4
+ j L(loop)
+L(m4):
+ vsetvli iVL, zero, e8, m4, ta, ma
+
+L(loop):
+ vle8ff.v vStr1, (pStr1)
+ vmseq.vx vMask1, vStr1, zero
+
+ vle8ff.v vStr2, (pStr2)
+ vmsne.vv vMask2, vStr1, vStr2
+
+ vfirst.m iTemp1, vMask1
+ vfirst.m iTemp2, vMask2
+
+ bgez iTemp1, L(check1)
+ bgez iTemp2, L(check2)
+
+ csrr iVL, vl
+ add pStr1, pStr1, iVL
+ add pStr2, pStr2, iVL
+
+ beq iLMUL, iLMUL1, L(m1)
+ beq iLMUL, iLMUL2, L(m2)
+ beq iLMUL, iLMUL4, L(m4)
+ j L(loop)
+
+ // iTemp1>=0
+L(check1):
+ bltz iTemp2, 1f
+ blt iTemp2, iTemp1, L(check2)
+1:
+ // iTemp2<0
+ // iTemp2>=0 && iTemp1<iTemp2
+ add pStr1, pStr1, iTemp1
+ add pStr2, pStr2, iTemp1
+ lbu iTemp1, 0(pStr1)
+ lbu iTemp2, 0(pStr2)
+ sub iResult, iTemp1, iTemp2
+ ret
+
+ // iTemp1<0
+ // iTemp2>=0
+L(check2):
+ add pStr1, pStr1, iTemp2
+ add pStr2, pStr2, iTemp2
+ lbu iTemp1, 0(pStr1)
+ lbu iTemp2, 0(pStr2)
+ sub iResult, iTemp1, iTemp2
+ ret
+
+END(strcmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strcpy_vext.S b/libc/arch-riscv64/string/strcpy_vext.S
new file mode 100644
index 000000000..9c11f7df4
--- /dev/null
+++ b/libc/arch-riscv64/string/strcpy_vext.S
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define pDstPtr a2
+
+#define iVL a3
+#define iCurrentVL a4
+#define iActiveElemPos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strcpy_vext)
+
+ mv pDstPtr, pDst
+
+ // copy pSrc to pDstPtr
+L(strcpy_loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vStr1, (pSrc)
+ vmseq.vx vMask2, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask2
+ vmsif.m vMask1, vMask2
+ add pSrc, pSrc, iCurrentVL
+ vse8.v vStr1, (pDstPtr), vMask1.t
+ add pDstPtr, pDstPtr, iCurrentVL
+ bltz iActiveElemPos, L(strcpy_loop)
+
+ ret
+
+END(strcpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strlen_vext.S b/libc/arch-riscv64/string/strlen_vext.S
new file mode 100644
index 000000000..393af58b6
--- /dev/null
+++ b/libc/arch-riscv64/string/strlen_vext.S
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+#define pStr a0
+#define pCopyStr a1
+#define iVL a2
+#define iCurrentVL a2
+#define iEndOffset a3
+
+#define ELEM_LMUL_SETTING m2
+#define vStr v0
+#define vMaskEnd v2
+
+ENTRY(strlen_vext)
+
+ mv pCopyStr, pStr
+L(loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vStr, (pCopyStr)
+ csrr iCurrentVL, vl
+ vmseq.vi vMaskEnd, vStr, 0
+ vfirst.m iEndOffset, vMaskEnd
+ add pCopyStr, pCopyStr, iCurrentVL
+ bltz iEndOffset, L(loop)
+
+ add pStr, pStr, iCurrentVL
+ add pCopyStr, pCopyStr, iEndOffset
+ sub iResult, pCopyStr, iResult
+
+ ret
+
+END(strlen)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncat_vext.S b/libc/arch-riscv64/string/strncat_vext.S
new file mode 100644
index 000000000..e9da434f1
--- /dev/null
+++ b/libc/arch-riscv64/string/strncat_vext.S
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iLength a2
+#define pDstPtr a3
+
+#define iVL a4
+#define iCurrentVL a5
+#define iActiveElemPos a6
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strncat_vext)
+
+ mv pDstPtr, pDst
+
+ // the strlen of dst
+L(strlen_loop):
+ vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vStr1, (pDstPtr)
+ // find the '\0'
+ vmseq.vx vMask1, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask1
+ add pDstPtr, pDstPtr, iCurrentVL
+ bltz iActiveElemPos, L(strlen_loop)
+
+ sub pDstPtr, pDstPtr, iCurrentVL
+ add pDstPtr, pDstPtr, iActiveElemPos
+
+ // copy pSrc to pDstPtr
+L(strcpy_loop):
+ vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vStr1, (pSrc)
+ vmseq.vx vMask2, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask2
+ vmsif.m vMask1, vMask2
+ add pSrc, pSrc, iCurrentVL
+ sub iLength, iLength, iCurrentVL
+ vse8.v vStr1, (pDstPtr), vMask1.t
+ add pDstPtr, pDstPtr, iCurrentVL
+ beqz iLength, L(fill_zero)
+ bltz iActiveElemPos, L(strcpy_loop)
+
+ ret
+
+L(fill_zero):
+ bgez iActiveElemPos, L(fill_zero_end)
+ sb zero, (pDstPtr)
+
+L(fill_zero_end):
+ ret
+
+END(strncat_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncmp_vext.S b/libc/arch-riscv64/string/strncmp_vext.S
new file mode 100644
index 000000000..88f0f3e9c
--- /dev/null
+++ b/libc/arch-riscv64/string/strncmp_vext.S
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define iResult a0
+
+#define pStr1 a0
+#define pStr2 a1
+#define iLength a2
+
+#define iVL a3
+#define iTemp1 a4
+#define iTemp2 a5
+
+#define ELEM_LMUL_SETTING m1
+#define vStr1 v0
+#define vStr2 v4
+#define vMask1 v8
+#define vMask2 v9
+
+ENTRY(strncmp_vext)
+
+ beqz iLength, L(zero_length)
+
+L(loop):
+ vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vStr1, (pStr1)
+ # vStr1[i] == 0
+ vmseq.vx vMask1, vStr1, zero
+
+ vle8ff.v vStr2, (pStr2)
+ # vStr1[i] != vStr2[i]
+ vmsne.vv vMask2, vStr1, vStr2
+
+ csrr iVL, vl
+
+ # r = mask1 | mask2
+ # We could use vfirst.m to get the first zero char or the
+ # first different char between str1 and str2.
+ vmor.mm vMask1, vMask1, vMask2
+
+ sub iLength, iLength, iVL
+
+ vfirst.m iTemp1, vMask1
+
+ bgez iTemp1, L(end_loop)
+
+ add pStr1, pStr1, iVL
+ add pStr2, pStr2, iVL
+ bnez iLength, L(loop)
+L(end_loop):
+
+ add pStr1, pStr1, iTemp1
+ add pStr2, pStr2, iTemp1
+ lbu iTemp1, 0(pStr1)
+ lbu iTemp2, 0(pStr2)
+
+ sub iResult, iTemp1, iTemp2
+ ret
+
+L(zero_length):
+ li iResult, 0
+ ret
+
+END(strncmp_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strncpy_vext.S b/libc/arch-riscv64/string/strncpy_vext.S
new file mode 100644
index 000000000..1aedaf9cd
--- /dev/null
+++ b/libc/arch-riscv64/string/strncpy_vext.S
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pDst a0
+#define pSrc a1
+#define iLength a2
+#define pDstPtr a3
+
+#define iVL a4
+#define iCurrentVL a5
+#define iActiveElemPos a6
+
+#define ELEM_LMUL_SETTING m1
+#define vMask1 v0
+#define vMask2 v1
+#define ZERO_FILL_ELEM_LMUL_SETTING m8
+#define vStr1 v8
+#define vStr2 v16
+
+ENTRY(strncpy_vext)
+
+ mv pDstPtr, pDst
+
+ // copy pSrc to pDstPtr
+L(strcpy_loop):
+ vsetvli iVL, iLength, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vStr1, (pSrc)
+ vmseq.vx vMask2, vStr1, zero
+ csrr iCurrentVL, vl
+ vfirst.m iActiveElemPos, vMask2
+ vmsif.m vMask1, vMask2
+ add pSrc, pSrc, iCurrentVL
+ sub iLength, iLength, iCurrentVL
+ vse8.v vStr1, (pDstPtr), vMask1.t
+ add pDstPtr, pDstPtr, iCurrentVL
+ bgez iActiveElemPos, L(fill_zero)
+ bnez iLength, L(strcpy_loop)
+ ret
+
+ # fill the tail zero.
+L(fill_zero):
+ sub iVL, iCurrentVL, iActiveElemPos
+ add iLength, iLength, iVL
+ bnez iLength, 1f
+ ret
+1:
+ sub pDstPtr, pDstPtr, iVL
+ vsetvli zero, iLength, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+ vmv.v.x vStr2, zero
+
+L(fill_zero_loop):
+ vsetvli iVL, iLength, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+ vse8.v vStr2, (pDstPtr)
+ sub iLength, iLength, iVL
+ add pDstPtr, pDstPtr, iVL
+ bnez iLength, L(fill_zero_loop)
+
+ ret
+
+END(strncpy_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/strnlen_vext.S b/libc/arch-riscv64/string/strnlen_vext.S
new file mode 100644
index 000000000..f546689bb
--- /dev/null
+++ b/libc/arch-riscv64/string/strnlen_vext.S
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#if defined(__riscv_v)
+
+#include "sys/asm.h"
+
+#define pStr a0
+#define pCopyStr a2
+#define iRetValue a0
+#define iMaxlen a1
+#define iCurrentVL a3
+#define iEndOffset a4
+
+#define ELEM_LMUL_SETTING m1
+#define vStr v0
+#define vMaskEnd v8
+
+ENTRY(strnlen_vext)
+
+ mv pCopyStr, pStr
+ mv iRetValue, iMaxlen
+L(strnlen_loop):
+ beqz iMaxlen, L(end_strnlen_loop)
+ vsetvli zero, iMaxlen, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vStr, (pCopyStr)
+ vmseq.vi vMaskEnd, vStr, 0
+ vfirst.m iEndOffset, vMaskEnd /* first occurrence of \0 */
+ csrr iCurrentVL, vl
+ add pCopyStr, pCopyStr, iCurrentVL
+ sub iMaxlen, iMaxlen, iCurrentVL
+ bltz iEndOffset, L(strnlen_loop)
+ add iMaxlen, iMaxlen, iCurrentVL
+ sub iRetValue, iRetValue, iMaxlen
+ add iRetValue, iRetValue, iEndOffset
+L(end_strnlen_loop):
+ ret
+
+END(strnlen_vext)
+
+#endif
diff --git a/libc/arch-riscv64/string/sys/asm.h b/libc/arch-riscv64/string/sys/asm.h
new file mode 100644
index 000000000..cc76dc515
--- /dev/null
+++ b/libc/arch-riscv64/string/sys/asm.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (c) 2023 SiFive, Inc.
+ * All rights reserved.
+ *
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC 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.
+ */
+
+#ifndef _SYS_ASM_H
+#define _SYS_ASM_H
+
+#undef LEAF
+#define LEAF(symbol) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, @function; \
+ symbol: \
+ .cfi_startproc;
+
+#undef END
+#define END(function) \
+ .cfi_endproc; \
+ .size function, .- function
+
+#define ENTRY(name) LEAF(name)
+
+#define L(label) .L##label
+
+#endif /* _SYS_ASM_H */
diff --git a/libc/bionic/atexit.cpp b/libc/bionic/atexit.cpp
index 5dbf322e3..dae15e0d8 100644
--- a/libc/bionic/atexit.cpp
+++ b/libc/bionic/atexit.cpp
@@ -73,8 +73,8 @@ class AtexitArray {
// restart concurrent __cxa_finalize passes.
uint64_t total_appends_;
- static size_t page_start_of_index(size_t idx) { return PAGE_START(idx * sizeof(AtexitEntry)); }
- static size_t page_end_of_index(size_t idx) { return PAGE_END(idx * sizeof(AtexitEntry)); }
+ static size_t page_start_of_index(size_t idx) { return page_start(idx * sizeof(AtexitEntry)); }
+ static size_t page_end_of_index(size_t idx) { return page_end(idx * sizeof(AtexitEntry)); }
// Recompact the array if it will save at least one page of memory at the end.
bool needs_recompaction() const {
@@ -167,7 +167,7 @@ void AtexitArray::set_writable(bool writable, size_t start_idx, size_t num_entri
// than one.
bool AtexitArray::next_capacity(size_t capacity, size_t* result) {
if (capacity == 0) {
- *result = PAGE_END(sizeof(AtexitEntry)) / sizeof(AtexitEntry);
+ *result = page_end(sizeof(AtexitEntry)) / sizeof(AtexitEntry);
return true;
}
size_t num_bytes;
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 98183d415..53f944f84 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -95,12 +95,10 @@ static inline uint16_t log2(size_t number) {
return result;
}
-BionicSmallObjectAllocator::BionicSmallObjectAllocator(uint32_t type,
- size_t block_size)
+BionicSmallObjectAllocator::BionicSmallObjectAllocator(uint32_t type, size_t block_size)
: type_(type),
block_size_(block_size),
- blocks_per_page_((PAGE_SIZE - sizeof(small_object_page_info)) /
- block_size),
+ blocks_per_page_((page_size() - sizeof(small_object_page_info)) / block_size),
free_pages_cnt_(0),
page_list_(nullptr) {}
@@ -157,14 +155,13 @@ void BionicSmallObjectAllocator::free_page(small_object_page_info* page) {
if (page_list_ == page) {
page_list_ = page->next_page;
}
- munmap(page, PAGE_SIZE);
+ munmap(page, page_size());
free_pages_cnt_--;
}
void BionicSmallObjectAllocator::free(void* ptr) {
small_object_page_info* const page =
- reinterpret_cast<small_object_page_info*>(
- PAGE_START(reinterpret_cast<uintptr_t>(ptr)));
+ reinterpret_cast<small_object_page_info*>(page_start(reinterpret_cast<uintptr_t>(ptr)));
if (reinterpret_cast<uintptr_t>(ptr) % block_size_ != 0) {
async_safe_fatal("invalid pointer: %p (block_size=%zd)", ptr, block_size_);
@@ -192,14 +189,13 @@ void BionicSmallObjectAllocator::free(void* ptr) {
}
void BionicSmallObjectAllocator::alloc_page() {
- void* const map_ptr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* const map_ptr =
+ mmap(nullptr, page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_ptr == MAP_FAILED) {
async_safe_fatal("mmap failed: %s", strerror(errno));
}
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE,
- "bionic_alloc_small_objects");
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, page_size(), "bionic_alloc_small_objects");
small_object_page_info* const page =
reinterpret_cast<small_object_page_info*>(map_ptr);
@@ -269,10 +265,10 @@ void* BionicAllocator::alloc_mmap(size_t align, size_t size) {
size_t header_size = __BIONIC_ALIGN(kPageInfoSize, align);
size_t allocated_size;
if (__builtin_add_overflow(header_size, size, &allocated_size) ||
- PAGE_END(allocated_size) < allocated_size) {
+ page_end(allocated_size) < allocated_size) {
async_safe_fatal("overflow trying to alloc %zu bytes", size);
}
- allocated_size = PAGE_END(allocated_size);
+ allocated_size = page_end(allocated_size);
void* map_ptr = mmap(nullptr, allocated_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
@@ -317,7 +313,7 @@ void* BionicAllocator::alloc(size_t size) {
void* BionicAllocator::memalign(size_t align, size_t size) {
// The Bionic allocator only supports alignment up to one page, which is good
// enough for ELF TLS.
- align = MIN(align, PAGE_SIZE);
+ align = MIN(align, page_size());
align = MAX(align, 16);
if (!powerof2(align)) {
align = BIONIC_ROUND_UP_POWER_OF_2(align);
@@ -327,7 +323,7 @@ void* BionicAllocator::memalign(size_t align, size_t size) {
}
inline page_info* BionicAllocator::get_page_info_unchecked(void* ptr) {
- uintptr_t header_page = PAGE_START(reinterpret_cast<size_t>(ptr) - kPageInfoSize);
+ uintptr_t header_page = page_start(reinterpret_cast<size_t>(ptr) - kPageInfoSize);
return reinterpret_cast<page_info*>(header_page);
}
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index 79893e32f..077f31085 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -34,10 +34,11 @@
#include <sys/param.h>
#include <unistd.h>
+#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
#include "private/ScopedRWLock.h"
#include "private/ScopedSignalBlocker.h"
#include "private/bionic_globals.h"
-#include "platform/bionic/macros.h"
#include "private/bionic_tls.h"
#include "pthread_internal.h"
@@ -81,7 +82,7 @@ bool __bionic_check_tls_alignment(size_t* alignment) {
return false;
}
// Bionic only respects TLS alignment up to one page.
- *alignment = MIN(*alignment, PAGE_SIZE);
+ *alignment = MIN(*alignment, page_size());
return true;
}
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 6433b597d..3eb8c198b 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -40,6 +40,7 @@
#include <unistd.h>
#include <async_safe/log.h>
+#include <platform/bionic/page.h>
#include <platform/bionic/reserved_signals.h>
#include <sys/system_properties.h>
@@ -80,7 +81,7 @@ FdEntry* FdTableImpl<inline_fds>::at(size_t idx) {
size_t required_count = max - inline_fds;
size_t required_size = sizeof(FdTableOverflow) + required_count * sizeof(FdEntry);
- size_t aligned_size = __BIONIC_ALIGN(required_size, PAGE_SIZE);
+ size_t aligned_size = __BIONIC_ALIGN(required_size, page_size());
size_t aligned_count = (aligned_size - sizeof(FdTableOverflow)) / sizeof(FdEntry);
void* allocation =
diff --git a/libc/bionic/getpagesize.cpp b/libc/bionic/getpagesize.cpp
index 3a5990025..da97633ca 100644
--- a/libc/bionic/getpagesize.cpp
+++ b/libc/bionic/getpagesize.cpp
@@ -27,9 +27,10 @@
*/
#include <unistd.h>
+#include "platform/bionic/page.h"
// Portable code should use sysconf(_SC_PAGE_SIZE) directly instead.
int getpagesize() {
// We dont use sysconf(3) here because that drags in stdio, which makes static binaries fat.
- return PAGE_SIZE;
+ return page_size();
}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index d64d402ab..3b0ab821b 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -129,8 +129,8 @@ static void apply_gnu_relro() {
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr);
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz);
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr);
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz);
// Check return value here? What do we do if we fail?
mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_end - seg_page_start, PROT_READ);
@@ -354,9 +354,9 @@ __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const v
__libc_shared_globals()->initial_memtag_stack = memtag_stack;
if (memtag_stack) {
- void* page_start =
- reinterpret_cast<void*>(PAGE_START(reinterpret_cast<uintptr_t>(stack_top)));
- if (mprotect(page_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
+ void* pg_start =
+ reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
+ if (mprotect(pg_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %s\n",
strerror(errno));
}
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index ed6b9c68f..f05dcb8ce 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -32,6 +32,7 @@
#include <unistd.h>
#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
@@ -46,7 +47,7 @@ void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offse
}
// Prevent allocations large enough for `end - start` to overflow.
- size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
+ size_t rounded = __BIONIC_ALIGN(size, page_size());
if (rounded < size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index d7c9353e0..88ec829de 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -33,12 +33,13 @@
#include <unistd.h>
#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
extern "C" void* __mremap(void*, size_t, size_t, int, void*);
void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
// prevent allocations large enough for `end - start` to overflow
- size_t rounded = __BIONIC_ALIGN(new_size, PAGE_SIZE);
+ size_t rounded = __BIONIC_ALIGN(new_size, page_size());
if (rounded < new_size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index 89aa28966..cdae72cef 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -36,8 +36,9 @@
#include <async_safe/log.h>
-#include "private/bionic_defs.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
+#include "private/bionic_defs.h"
#include "pthread_internal.h"
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
@@ -143,10 +144,10 @@ int pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* stack_size) {
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_size) {
- if ((stack_size & (PAGE_SIZE - 1) || stack_size < PTHREAD_STACK_MIN)) {
+ if ((stack_size & (page_size() - 1) || stack_size < PTHREAD_STACK_MIN)) {
return EINVAL;
}
- if (reinterpret_cast<uintptr_t>(stack_base) & (PAGE_SIZE - 1)) {
+ if (reinterpret_cast<uintptr_t>(stack_base) & (page_size() - 1)) {
return EINVAL;
}
attr->stack_base = stack_base;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 844f9d8f3..b46c6cfed 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -42,6 +42,7 @@
#include "platform/bionic/macros.h"
#include "platform/bionic/mte.h"
+#include "platform/bionic/page.h"
#include "private/ErrnoRestorer.h"
#include "private/ScopedRWLock.h"
#include "private/bionic_constants.h"
@@ -71,7 +72,7 @@ void __init_bionic_tls_ptrs(bionic_tcb* tcb, bionic_tls* tls) {
// Allocate a temporary bionic_tls that the dynamic linker's main thread can
// use while it's loading the initial set of ELF modules.
bionic_tls* __allocate_temp_bionic_tls() {
- size_t allocation_size = __BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE);
+ size_t allocation_size = __BIONIC_ALIGN(sizeof(bionic_tls), page_size());
void* allocation = mmap(nullptr, allocation_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
@@ -84,7 +85,7 @@ bionic_tls* __allocate_temp_bionic_tls() {
}
void __free_temp_bionic_tls(bionic_tls* tls) {
- munmap(tls, __BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE));
+ munmap(tls, __BIONIC_ALIGN(sizeof(bionic_tls), page_size()));
}
static void __init_alternate_signal_stack(pthread_internal_t* thread) {
@@ -203,12 +204,11 @@ int __init_thread(pthread_internal_t* thread) {
return 0;
}
-
// Allocate a thread's primary mapping. This mapping includes static TLS and
// optionally a stack. Static TLS includes ELF TLS segments and the bionic_tls
// struct.
//
-// The stack_guard_size must be a multiple of the PAGE_SIZE.
+// The stack_guard_size must be a multiple of the page_size().
ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) {
const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
@@ -220,7 +220,7 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si
// Align the result to a page size.
const size_t unaligned_size = mmap_size;
- mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
+ mmap_size = __BIONIC_ALIGN(mmap_size, page_size());
if (mmap_size < unaligned_size) return {};
// Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a
@@ -271,9 +271,9 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi
if (attr->stack_base == nullptr) {
// The caller didn't provide a stack, so allocate one.
- // Make sure the guard size is a multiple of PAGE_SIZE.
+ // Make sure the guard size is a multiple of page_size().
const size_t unaligned_guard_size = attr->guard_size;
- attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+ attr->guard_size = __BIONIC_ALIGN(attr->guard_size, page_size());
if (attr->guard_size < unaligned_guard_size) return EAGAIN;
mapping = __allocate_thread_mapping(attr->stack_size, attr->guard_size);
diff --git a/libc/bionic/strtold.cpp b/libc/bionic/strtold.cpp
index 6b673e6e0..c55dd61c0 100644
--- a/libc/bionic/strtold.cpp
+++ b/libc/bionic/strtold.cpp
@@ -26,8 +26,6 @@
* SUCH DAMAGE.
*/
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-
#include <float.h>
#include <stdlib.h>
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 1c06c9efc..3906e2ef3 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -38,6 +38,7 @@
#include <time.h>
#include <unistd.h>
+#include "platform/bionic/page.h"
#include "private/bionic_tls.h"
static long __sysconf_rlimit(int resource) {
diff --git a/libc/bionic/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 1e4a0e855..79fd55e01 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -33,8 +33,9 @@
#include <string.h>
#include <unistd.h>
-#include "private/get_cpu_count_from_string.h"
+#include "platform/bionic/page.h"
#include "private/ScopedReaddir.h"
+#include "private/get_cpu_count_from_string.h"
int __get_cpu_count(const char* sys_file) {
int cpu_count = 1;
@@ -64,11 +65,11 @@ int get_nprocs() {
long get_phys_pages() {
struct sysinfo si;
sysinfo(&si);
- return (static_cast<int64_t>(si.totalram) * si.mem_unit) / PAGE_SIZE;
+ return (static_cast<int64_t>(si.totalram) * si.mem_unit) / page_size();
}
long get_avphys_pages() {
struct sysinfo si;
sysinfo(&si);
- return ((static_cast<int64_t>(si.freeram) + si.bufferram) * si.mem_unit) / PAGE_SIZE;
+ return ((static_cast<int64_t>(si.freeram) + si.bufferram) * si.mem_unit) / page_size();
}
diff --git a/libc/bionic/wcstod.cpp b/libc/bionic/wcstod.cpp
index 75a59f554..c82d7882e 100644
--- a/libc/bionic/wcstod.cpp
+++ b/libc/bionic/wcstod.cpp
@@ -26,8 +26,6 @@
* SUCH DAMAGE.
*/
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-
#include <wchar.h>
#include <stdlib.h>
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index efe4354cb..08fe45dfd 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -26,9 +26,6 @@
#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
-#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" #api_level)))
-#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" #api_level)))
-#define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __attribute__((annotate("introduced_in_x86=" #api_level))) __VERSIONER_NO_GUARD
#define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
#define __VERSIONER_FORTIFY_INLINE __attribute__((annotate("versioner_fortify_inline")))
@@ -52,11 +49,9 @@
#if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
#define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,__what)))
#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN(api_level)
-#define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
#else
#define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,strict,__what)))
#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level)
-#define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level)
#endif
#define __INTRODUCED_IN(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
@@ -69,12 +64,6 @@
//
// void foo() __INTRODUCED_IN_32(30) __INTRODUCED_IN_64(31);
//
-// This also takes the advantage of the fact that we never use bitness-specific macro with
-// arch-specific macro. In other words,
-//
-// void foo() __INTRODUCED_IN_ARM(30) __INTRODUCED_IN_64(31);
-//
-// hasn't been supported and won't be.
#if !defined(__LP64__)
#define __INTRODUCED_IN_32(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
#define __INTRODUCED_IN_64(api_level)
@@ -83,17 +72,6 @@
#define __INTRODUCED_IN_64(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
#endif
-#if defined(__arm__) || defined(__aarch64__)
-#define __INTRODUCED_IN_ARM(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
-#define __INTRODUCED_IN_X86(api_level)
-#elif defined(__i386__) || defined(__x86_64__)
-#define __INTRODUCED_IN_ARM(api_level)
-#define __INTRODUCED_IN_X86(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
-#else
-#define __INTRODUCED_IN_ARM(api_level)
-#define __INTRODUCED_IN_X86(api_level)
-#endif
-
#define __VERSIONER_NO_GUARD
#define __VERSIONER_FORTIFY_INLINE
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 1f6ebad71..ce600ff58 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -30,13 +30,13 @@
#error "Never include this file directly; instead, include <fcntl.h>"
#endif
-int __open_2(const char*, int) __INTRODUCED_IN(17);
-int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
+int __open_2(const char* _Nonnull, int) __INTRODUCED_IN(17);
+int __openat_2(int, const char* _Nonnull, int) __INTRODUCED_IN(17);
/*
* These are the easiest way to call the real open even in clang FORTIFY.
*/
-int __open_real(const char*, int, ...) __RENAME(open);
-int __openat_real(int, const char*, int, ...) __RENAME(openat);
+int __open_real(const char* _Nonnull, int, ...) __RENAME(open);
+int __openat_real(int, const char* _Nonnull, int, ...) __RENAME(openat);
#if defined(__BIONIC_FORTIFY)
#define __open_too_many_args_error "too many arguments"
@@ -46,7 +46,7 @@ int __openat_real(int, const char*, int, ...) __RENAME(openat);
#define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+int open(const char* _Nonnull pathname, int flags, mode_t modes, ...) __overloadable
__errorattr(__open_too_many_args_error);
/*
@@ -56,7 +56,7 @@ int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
* open(const char *, int, ...).
*/
__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags)
+int open(const char* _Nonnull const __pass_object_size pathname, int flags)
__overloadable
__clang_error_if(__open_modes_useful(flags), "'open' " __open_too_few_args_error) {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -67,7 +67,7 @@ int open(const char* const __pass_object_size pathname, int flags)
}
__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
+int open(const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
__overloadable
__clang_warning_if(!__open_modes_useful(flags) && modes,
"'open' " __open_useless_modes_warning) {
@@ -75,12 +75,12 @@ int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
}
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+int openat(int dirfd, const char* _Nonnull pathname, int flags, mode_t modes, ...)
__overloadable
__errorattr(__open_too_many_args_error);
__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags)
+int openat(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags)
__overloadable
__clang_error_if(__open_modes_useful(flags), "'openat' " __open_too_few_args_error) {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -91,7 +91,7 @@ int openat(int dirfd, const char* const __pass_object_size pathname, int flags)
}
__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes)
+int openat(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
__overloadable
__clang_warning_if(!__open_modes_useful(flags) && modes,
"'openat' " __open_useless_modes_warning) {
@@ -101,18 +101,18 @@ int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
/* Note that open == open64, so we reuse those bits in the open64 variants below. */
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open64(const char* pathname, int flags, mode_t modes, ...) __overloadable
+int open64(const char* _Nonnull pathname, int flags, mode_t modes, ...) __overloadable
__errorattr(__open_too_many_args_error);
__BIONIC_FORTIFY_INLINE
-int open64(const char* const __pass_object_size pathname, int flags)
+int open64(const char* _Nonnull const __pass_object_size pathname, int flags)
__overloadable
__clang_error_if(__open_modes_useful(flags), "'open64' " __open_too_few_args_error) {
return open(pathname, flags);
}
__BIONIC_FORTIFY_INLINE
-int open64(const char* const __pass_object_size pathname, int flags, mode_t modes)
+int open64(const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
__overloadable
__clang_warning_if(!__open_modes_useful(flags) && modes,
"'open64' " __open_useless_modes_warning) {
@@ -120,19 +120,19 @@ int open64(const char* const __pass_object_size pathname, int flags, mode_t mode
}
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat64(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+int openat64(int dirfd, const char* _Nonnull pathname, int flags, mode_t modes, ...)
__overloadable
__errorattr(__open_too_many_args_error);
__BIONIC_FORTIFY_INLINE
-int openat64(int dirfd, const char* const __pass_object_size pathname, int flags)
+int openat64(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags)
__overloadable
__clang_error_if(__open_modes_useful(flags), "'openat64' " __open_too_few_args_error) {
return openat(dirfd, pathname, flags);
}
__BIONIC_FORTIFY_INLINE
-int openat64(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes)
+int openat64(int dirfd, const char* _Nonnull const __pass_object_size pathname, int flags, mode_t modes)
__overloadable
__clang_warning_if(!__open_modes_useful(flags) && modes,
"'openat64' " __open_useless_modes_warning) {
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
index 0b5cd4bc7..f2e27d796 100644
--- a/libc/include/bits/fortify/poll.h
+++ b/libc/include/bits/fortify/poll.h
@@ -30,9 +30,9 @@
#error "Never include this file directly; instead, include <poll.h>"
#endif
-int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t) __INTRODUCED_IN(23);
-int __ppoll64_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset64_t*, size_t) __INTRODUCED_IN(28);
+int __poll_chk(struct pollfd* _Nullable, nfds_t, int, size_t) __INTRODUCED_IN(23);
+int __ppoll_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset_t* _Nullable, size_t) __INTRODUCED_IN(23);
+int __ppoll64_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset64_t* _Nullable, size_t) __INTRODUCED_IN(28);
#if defined(__BIONIC_FORTIFY)
#define __bos_fd_count_trivially_safe(bos_val, fds, fd_count) \
@@ -40,7 +40,7 @@ int __ppoll64_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset64
(fd_count) <= __BIONIC_CAST(static_cast, nfds_t, -1) / sizeof(*fds))
__BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout)
+int poll(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, int timeout)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
"in call to 'poll', fd_count is larger than the given buffer") {
@@ -55,7 +55,7 @@ int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeo
}
__BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask)
+int ppoll(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, const struct timespec* _Nullable timeout, const sigset_t* _Nullable mask)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
"in call to 'ppoll', fd_count is larger than the given buffer") {
@@ -71,7 +71,7 @@ int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const st
#if __ANDROID_API__ >= 28
__BIONIC_FORTIFY_INLINE
-int ppoll64(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset64_t* mask)
+int ppoll64(struct pollfd* _Nullable const fds __pass_object_size, nfds_t fd_count, const struct timespec* _Nullable timeout, const sigset64_t* _Nullable mask)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
"in call to 'ppoll64', fd_count is larger than the given buffer") {
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
index 9e7df6dd3..8297580f0 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -30,15 +30,15 @@
#error "Never include this file directly; instead, include <sys/socket.h>"
#endif
-extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+extern ssize_t __sendto_chk(int, const void* _Nonnull, size_t, size_t, int, const struct sockaddr* _Nullable,
socklen_t) __INTRODUCED_IN(26);
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
- socklen_t*) __INTRODUCED_IN(21);
+ssize_t __recvfrom_chk(int, void* _Nullable, size_t, size_t, int, struct sockaddr* _Nullable,
+ socklen_t* _Nullable) __INTRODUCED_IN(21);
#if defined(__BIONIC_FORTIFY)
__BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+ssize_t recvfrom(int fd, void* _Nullable const buf __pass_object_size0, size_t len, int flags, struct sockaddr* _Nullable src_addr, socklen_t* _Nullable addr_len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'recvfrom' called with size bigger than buffer") {
@@ -53,7 +53,7 @@ ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len, int fl
}
__BIONIC_FORTIFY_INLINE
-ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
+ssize_t sendto(int fd, const void* _Nonnull const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* _Nullable dest_addr, socklen_t addr_len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'sendto' called with size bigger than buffer") {
@@ -68,7 +68,7 @@ ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len, in
}
__BIONIC_FORTIFY_INLINE
-ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int flags)
+ssize_t recv(int socket, void* _Nullable const buf __pass_object_size0, size_t len, int flags)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'recv' called with size bigger than buffer") {
@@ -76,7 +76,7 @@ ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int fl
}
__BIONIC_FORTIFY_INLINE
-ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
+ssize_t send(int socket, const void* _Nonnull const buf __pass_object_size0, size_t len, int flags)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
"'send' called with size bigger than buffer") {
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 95db0178e..578d04c4d 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -30,29 +30,29 @@
#error "Never include this file directly; instead, include <stdio.h>"
#endif
-char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
-size_t __fread_chk(void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(24);
-size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(24);
+char* _Nullable __fgets_chk(char* _Nonnull, int, FILE* _Nonnull, size_t) __INTRODUCED_IN(17);
+size_t __fread_chk(void* _Nonnull, size_t, size_t, FILE* _Nonnull, size_t) __INTRODUCED_IN(24);
+size_t __fwrite_chk(const void* _Nonnull, size_t, size_t, FILE* _Nonnull, size_t) __INTRODUCED_IN(24);
#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE __printflike(3, 0)
-int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+int vsnprintf(char* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size dest, size_t size, const char* _Nonnull format, va_list ap)
__diagnose_as_builtin(__builtin_vsnprintf, 1, 2, 3, 4)
__overloadable {
return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
}
__BIONIC_FORTIFY_INLINE __printflike(2, 0)
-int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap) __overloadable {
+int vsprintf(char* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size dest, const char* _Nonnull format, va_list ap) __overloadable {
return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
}
#endif
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char* dest, const char* format)
+int sprintf(char* __BIONIC_COMPLICATED_NULLNESS dest, const char* _Nonnull format)
__overloadable
__enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
"format string will always overflow destination buffer")
@@ -60,7 +60,7 @@ int sprintf(char* dest, const char* format)
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
-int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
+int sprintf(char* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size dest, const char* _Nonnull format, ...) __overloadable {
va_list va;
va_start(va, format);
int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
@@ -70,7 +70,7 @@ int sprintf(char* const __pass_object_size dest, const char* format, ...) __over
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
-int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+int snprintf(char* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size dest, size_t size, const char* _Nonnull format, ...)
__diagnose_as_builtin(__builtin_snprintf, 1, 2, 3)
__overloadable {
va_list va;
@@ -86,7 +86,7 @@ int snprintf(char* const __pass_object_size dest, size_t size, const char* forma
!__unsafe_check_mul_overflow(size, count))
__BIONIC_FORTIFY_INLINE
-size_t fread(void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+size_t fread(void* const _Nonnull __pass_object_size0 buf, size_t size, size_t count, FILE* _Nonnull stream)
__overloadable
__clang_error_if(__unsafe_check_mul_overflow(size, count),
"in call to 'fread', size * count overflows")
@@ -103,7 +103,7 @@ size_t fread(void* const __pass_object_size0 buf, size_t size, size_t count, FIL
}
__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+size_t fwrite(const void* const _Nonnull __pass_object_size0 buf, size_t size, size_t count, FILE* _Nonnull stream)
__overloadable
__clang_error_if(__unsafe_check_mul_overflow(size, count),
"in call to 'fwrite', size * count overflows")
@@ -121,7 +121,7 @@ size_t fwrite(const void* const __pass_object_size0 buf, size_t size, size_t cou
#undef __bos_trivially_ge_mul
__BIONIC_FORTIFY_INLINE
-char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
+char* _Nullable fgets(char* const _Nonnull __pass_object_size dest, int size, FILE* _Nonnull stream)
__overloadable
__clang_error_if(size < 0, "in call to 'fgets', size should not be negative")
__clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index 623be583b..b84dae474 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -35,7 +35,7 @@
/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
#define __PATH_MAX 4096
-char* realpath(const char* path, char* resolved)
+char* _Nullable realpath(const char* _Nonnull path, char* _Nullable resolved)
__clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?")
__clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX),
"'realpath' output parameter must be NULL or a pointer to a buffer "
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index f668b9f71..3dc1ccaf7 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -30,20 +30,20 @@
#error "Never include this file directly; instead, include <string.h>"
#endif
-void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
-void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
-char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
-char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
-size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
-size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+void* _Nullable __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+void* _Nullable __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+char* _Nonnull __stpncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) __INTRODUCED_IN(21);
+char* _Nonnull __strncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) __INTRODUCED_IN(21);
+size_t __strlcpy_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17);
+size_t __strlcat_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17);
#if defined(__BIONIC_FORTIFY)
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+extern void* _Nullable __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+void* _Nonnull memcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
__diagnose_as_builtin(__builtin_memcpy, 1, 2, 3)
__overloadable {
return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
@@ -51,7 +51,7 @@ void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_a
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+void* _Nonnull memmove(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t len)
__diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
__overloadable {
return __builtin___memmove_chk(dst, src, len, __bos0(dst));
@@ -61,7 +61,7 @@ void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
#if defined(__USE_GNU)
#if __ANDROID_API__ >= 30
__BIONIC_FORTIFY_INLINE
-void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+void* _Nonnull mempcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
__diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
@@ -78,7 +78,7 @@ void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_
#endif /* __USE_GNU */
__BIONIC_FORTIFY_INLINE
-char* stpcpy(char* const dst __pass_object_size, const char* src)
+char* _Nonnull stpcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'stpcpy' called with string bigger than buffer") {
@@ -90,7 +90,7 @@ char* stpcpy(char* const dst __pass_object_size, const char* src)
}
__BIONIC_FORTIFY_INLINE
-char* strcpy(char* const dst __pass_object_size, const char* src)
+char* _Nonnull strcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__diagnose_as_builtin(__builtin_strcpy, 1, 2)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
@@ -103,7 +103,7 @@ char* strcpy(char* const dst __pass_object_size, const char* src)
}
__BIONIC_FORTIFY_INLINE
-char* strcat(char* const dst __pass_object_size, const char* src)
+char* _Nonnull strcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
__overloadable
__clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
"'strcat' called with string bigger than buffer") {
@@ -117,7 +117,7 @@ char* strcat(char* const dst __pass_object_size, const char* src)
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
+char* _Nonnull strncat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t n)
__diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
__overloadable {
return __builtin___strncat_chk(dst, src, n, __bos(dst));
@@ -126,7 +126,7 @@ char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
+void* _Nonnull memset(void* _Nonnull const s __pass_object_size0, int c, size_t n) __overloadable
__diagnose_as_builtin(__builtin_memset, 1, 2, 3)
/* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
__clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
@@ -139,7 +139,7 @@ void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
#if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_INLINE
-void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+void* _Nullable memchr(const void* _Nonnull const s __pass_object_size, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (__bos_trivially_ge(bos, n)) {
@@ -150,7 +150,7 @@ void* memchr(const void* const s __pass_object_size, int c, size_t n) __overload
}
__BIONIC_FORTIFY_INLINE
-void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+void* _Nullable __memrchr_fortify(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (__bos_trivially_ge(bos, n)) {
@@ -164,7 +164,7 @@ void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n)
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+char* _Nonnull stpncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
__diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
__overloadable {
size_t bos_dst = __bos(dst);
@@ -180,7 +180,7 @@ char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_o
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_INLINE
-char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+char* _Nonnull strncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
__diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
__overloadable {
size_t bos_dst = __bos(dst);
@@ -196,7 +196,7 @@ char* strncpy(char* const dst __pass_object_size, const char* const src __pass_o
#endif
__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
+size_t strlcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
"'strlcpy' called with size bigger than buffer") {
@@ -208,7 +208,7 @@ size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
}
__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
+size_t strlcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
"'strlcat' called with size bigger than buffer") {
@@ -221,13 +221,13 @@ size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const s __pass_object_size0) __overloadable {
+size_t strlen(const char* _Nonnull const s __pass_object_size0) __overloadable {
return __strlen_chk(s, __bos0(s));
}
#endif
__BIONIC_FORTIFY_INLINE
-char* strchr(const char* const s __pass_object_size, int c) __overloadable {
+char* _Nullable strchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
size_t bos = __bos(s);
@@ -239,7 +239,7 @@ char* strchr(const char* const s __pass_object_size, int c) __overloadable {
}
__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
+char* _Nullable strrchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
size_t bos = __bos(s);
@@ -254,18 +254,18 @@ char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
#if defined(__cplusplus)
extern "C++" {
__BIONIC_FORTIFY_INLINE
-void* memrchr(void* const __pass_object_size s, int c, size_t n) {
+void* _Nullable memrchr(void* _Nonnull const __pass_object_size s, int c, size_t n) {
return __memrchr_fortify(s, c, n);
}
__BIONIC_FORTIFY_INLINE
-const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
+const void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) {
return __memrchr_fortify(s, c, n);
}
}
#else
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
return __memrchr_fortify(s, c, n);
}
#endif
diff --git a/libc/include/bits/fortify/strings.h b/libc/include/bits/fortify/strings.h
index 5515ef9bb..a36f02c63 100644
--- a/libc/include/bits/fortify/strings.h
+++ b/libc/include/bits/fortify/strings.h
@@ -29,7 +29,7 @@
#if defined(__BIONIC_FORTIFY)
__BIONIC_FORTIFY_INLINE
-void __bionic_bcopy(const void *src, void* const dst __pass_object_size0, size_t len)
+void __bionic_bcopy(const void * _Nonnull src, void* _Nonnull const dst __pass_object_size0, size_t len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
"'bcopy' called with size bigger than buffer") {
@@ -44,7 +44,7 @@ void __bionic_bcopy(const void *src, void* const dst __pass_object_size0, size_t
}
__BIONIC_FORTIFY_INLINE
-void __bionic_bzero(void* const b __pass_object_size0, size_t len)
+void __bionic_bzero(void* _Nonnull const b __pass_object_size0, size_t len)
__overloadable
__clang_error_if(__bos_unevaluated_lt(__bos0(b), len),
"'bzero' called with size bigger than buffer") {
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
index 335d0b534..bbc228d69 100644
--- a/libc/include/bits/fortify/unistd.h
+++ b/libc/include/bits/fortify/unistd.h
@@ -29,24 +29,24 @@
#error "Never include this file directly; instead, include <unistd.h>"
#endif
-char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
+char* _Nullable __getcwd_chk(char* _Nullable, size_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
+ssize_t __pread_chk(int, void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread_real(int, void* _Nonnull, size_t, off_t) __RENAME(pread);
-ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64);
+ssize_t __pread64_chk(int, void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread64_real(int, void* _Nonnull, size_t, off64_t) __RENAME(pread64);
-ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
+ssize_t __pwrite_chk(int, const void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite_real(int, const void* _Nonnull, size_t, off_t) __RENAME(pwrite);
-ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64);
+ssize_t __pwrite64_chk(int, const void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite64_real(int, const void* _Nonnull, size_t, off64_t) __RENAME(pwrite64);
-ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
-ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
-ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+ssize_t __read_chk(int, void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t) __INTRODUCED_IN(21);
+ssize_t __write_chk(int, const void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t) __INTRODUCED_IN(24);
+ssize_t __readlink_chk(const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
+ssize_t __readlinkat_chk(int dirfd, const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
#if defined(__BIONIC_FORTIFY)
@@ -70,7 +70,7 @@ ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTROD
__builtin_constant_p(index) && (index) <= SSIZE_MAX))
__BIONIC_FORTIFY_INLINE
-char* getcwd(char* const __pass_object_size buf, size_t size)
+char* _Nullable getcwd(char* const _Nullable __pass_object_size buf, size_t size)
__overloadable
__error_if_overflows_objectsize(size, __bos(buf), getcwd) {
#if __ANDROID_API__ >= 24 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -85,7 +85,7 @@ char* getcwd(char* const __pass_object_size buf, size_t size)
#if !defined(__USE_FILE_OFFSET64)
__BIONIC_FORTIFY_INLINE
-ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count, off_t offset)
+ssize_t pread(int fd, void* const _Nonnull __pass_object_size0 buf, size_t count, off_t offset)
__overloadable
__error_if_overflows_ssizet(count, pread)
__error_if_overflows_objectsize(count, __bos0(buf), pread) {
@@ -101,7 +101,7 @@ ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count, off_t o
#endif /* !defined(__USE_FILE_OFFSET64) */
__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count, off64_t offset)
+ssize_t pread64(int fd, void* const _Nonnull __pass_object_size0 buf, size_t count, off64_t offset)
__overloadable
__error_if_overflows_ssizet(count, pread64)
__error_if_overflows_objectsize(count, __bos0(buf), pread64) {
@@ -117,7 +117,7 @@ ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count, off64
#if !defined(__USE_FILE_OFFSET64)
__BIONIC_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count, off_t offset)
+ssize_t pwrite(int fd, const void* const _Nonnull __pass_object_size0 buf, size_t count, off_t offset)
__overloadable
__error_if_overflows_ssizet(count, pwrite)
__error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
@@ -133,7 +133,7 @@ ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
#endif /* !defined(__USE_FILE_OFFSET64) */
__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf, size_t count, off64_t offset)
+ssize_t pwrite64(int fd, const void* const _Nonnull __pass_object_size0 buf, size_t count, off64_t offset)
__overloadable
__error_if_overflows_ssizet(count, pwrite64)
__error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
@@ -148,7 +148,7 @@ ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf, size_t count
}
__BIONIC_FORTIFY_INLINE
-ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
+ssize_t read(int fd, void* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf, size_t count)
__overloadable
__error_if_overflows_ssizet(count, read)
__error_if_overflows_objectsize(count, __bos0(buf), read) {
@@ -163,7 +163,7 @@ ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
}
__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
+ssize_t write(int fd, const void* const __BIONIC_COMPLICATED_NULLNESS __pass_object_size0 buf, size_t count)
__overloadable
__error_if_overflows_ssizet(count, write)
__error_if_overflows_objectsize(count, __bos0(buf), write) {
@@ -178,7 +178,7 @@ ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
}
__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* const __pass_object_size buf, size_t size)
+ssize_t readlink(const char* _Nonnull path, char* _Nonnull const __pass_object_size buf, size_t size)
__overloadable
__error_if_overflows_ssizet(size, readlink)
__error_if_overflows_objectsize(size, __bos(buf), readlink) {
@@ -193,7 +193,7 @@ ssize_t readlink(const char* path, char* const __pass_object_size buf, size_t si
}
__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path, char* const __pass_object_size buf, size_t size)
+ssize_t readlinkat(int dirfd, const char* _Nonnull path, char* const _Nonnull __pass_object_size buf, size_t size)
__overloadable
__error_if_overflows_ssizet(size, readlinkat)
__error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h
index 2ce6ee655..fe3d68d09 100644
--- a/libc/include/bits/stdatomic.h
+++ b/libc/include/bits/stdatomic.h
@@ -269,18 +269,18 @@ typedef struct {
#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) }
-static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) {
+static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) {
return (atomic_exchange_explicit(&__object->__flag, 1, __order));
}
-static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) {
+static __inline void atomic_flag_clear_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) {
atomic_store_explicit(&__object->__flag, 0, __order);
}
-static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) {
+static __inline bool atomic_flag_test_and_set(volatile atomic_flag * _Nonnull __object) {
return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst));
}
-static __inline void atomic_flag_clear(volatile atomic_flag *__object) {
+static __inline void atomic_flag_clear(volatile atomic_flag * _Nonnull __object) {
atomic_flag_clear_explicit(__object, memory_order_seq_cst);
}
diff --git a/libc/include/bits/termios_inlines.h b/libc/include/bits/termios_inlines.h
index 5f7cc424c..a884b595f 100644
--- a/libc/include/bits/termios_inlines.h
+++ b/libc/include/bits/termios_inlines.h
@@ -45,19 +45,19 @@ __BEGIN_DECLS
// Supporting separate input and output speeds would require an ABI
// change for `struct termios`.
-static __inline speed_t cfgetspeed(const struct termios* s) {
+static __inline speed_t cfgetspeed(const struct termios* _Nonnull s) {
return __BIONIC_CAST(static_cast, speed_t, s->c_cflag & CBAUD);
}
-__BIONIC_TERMIOS_INLINE speed_t cfgetispeed(const struct termios* s) {
+__BIONIC_TERMIOS_INLINE speed_t cfgetispeed(const struct termios* _Nonnull s) {
return cfgetspeed(s);
}
-__BIONIC_TERMIOS_INLINE speed_t cfgetospeed(const struct termios* s) {
+__BIONIC_TERMIOS_INLINE speed_t cfgetospeed(const struct termios* _Nonnull s) {
return cfgetspeed(s);
}
-__BIONIC_TERMIOS_INLINE void cfmakeraw(struct termios* s) {
+__BIONIC_TERMIOS_INLINE void cfmakeraw(struct termios* _Nonnull s) {
s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
s->c_oflag &= ~OPOST;
s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
@@ -67,7 +67,7 @@ __BIONIC_TERMIOS_INLINE void cfmakeraw(struct termios* s) {
s->c_cc[VTIME] = 0;
}
-__BIONIC_TERMIOS_INLINE int cfsetspeed(struct termios* s, speed_t speed) {
+__BIONIC_TERMIOS_INLINE int cfsetspeed(struct termios* _Nonnull s, speed_t speed) {
// CBAUD is 0x100f, and every matching bit pattern has a Bxxx constant.
if ((speed & ~CBAUD) != 0) {
errno = EINVAL;
@@ -77,11 +77,11 @@ __BIONIC_TERMIOS_INLINE int cfsetspeed(struct termios* s, speed_t speed) {
return 0;
}
-__BIONIC_TERMIOS_INLINE int cfsetispeed(struct termios* s, speed_t speed) {
+__BIONIC_TERMIOS_INLINE int cfsetispeed(struct termios* _Nonnull s, speed_t speed) {
return cfsetspeed(s, speed);
}
-__BIONIC_TERMIOS_INLINE int cfsetospeed(struct termios* s, speed_t speed) {
+__BIONIC_TERMIOS_INLINE int cfsetospeed(struct termios* _Nonnull s, speed_t speed) {
return cfsetspeed(s, speed);
}
@@ -99,7 +99,7 @@ __BIONIC_TERMIOS_INLINE int tcflush(int fd, int queue) {
return ioctl(fd, TCFLSH, __BIONIC_CAST(static_cast, unsigned long, queue));
}
-__BIONIC_TERMIOS_INLINE int tcgetattr(int fd, struct termios* s) {
+__BIONIC_TERMIOS_INLINE int tcgetattr(int fd, struct termios* _Nonnull s) {
return ioctl(fd, TCGETS, s);
}
@@ -112,7 +112,7 @@ __BIONIC_TERMIOS_INLINE int tcsendbreak(int fd, int duration) {
return ioctl(fd, TCSBRKP, __BIONIC_CAST(static_cast, unsigned long, duration));
}
-__BIONIC_TERMIOS_INLINE int tcsetattr(int fd, int optional_actions, const struct termios* s) {
+__BIONIC_TERMIOS_INLINE int tcsetattr(int fd, int optional_actions, const struct termios* _Nonnull s) {
int cmd;
switch (optional_actions) {
case TCSANOW: cmd = TCSETS; break;
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 17de4a11a..5878e0acc 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -48,46 +48,46 @@ static __inline int __bionic_thrd_error(int __pthread_code) {
}
}
-__BIONIC_THREADS_INLINE void call_once(once_flag* __flag,
- void (*__function)(void)) {
+__BIONIC_THREADS_INLINE void call_once(once_flag* _Nonnull __flag,
+ void (* _Nonnull __function)(void)) {
pthread_once(__flag, __function);
}
-__BIONIC_THREADS_INLINE int cnd_broadcast(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_broadcast(cnd_t* _Nonnull __cnd) {
return __bionic_thrd_error(pthread_cond_broadcast(__cnd));
}
-__BIONIC_THREADS_INLINE void cnd_destroy(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE void cnd_destroy(cnd_t* _Nonnull __cnd) {
pthread_cond_destroy(__cnd);
}
-__BIONIC_THREADS_INLINE int cnd_init(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_init(cnd_t* _Nonnull __cnd) {
return __bionic_thrd_error(pthread_cond_init(__cnd, NULL));
}
-__BIONIC_THREADS_INLINE int cnd_signal(cnd_t* __cnd) {
+__BIONIC_THREADS_INLINE int cnd_signal(cnd_t* _Nonnull __cnd) {
return __bionic_thrd_error(pthread_cond_signal(__cnd));
}
-__BIONIC_THREADS_INLINE int cnd_timedwait(cnd_t* __cnd,
- mtx_t* __mtx,
- const struct timespec* __timeout) {
+__BIONIC_THREADS_INLINE int cnd_timedwait(cnd_t* _Nonnull __cnd,
+ mtx_t* _Nonnull __mtx,
+ const struct timespec* _Nullable __timeout) {
return __bionic_thrd_error(pthread_cond_timedwait(__cnd, __mtx, __timeout));
}
-__BIONIC_THREADS_INLINE int cnd_wait(cnd_t* __cnd, mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int cnd_wait(cnd_t* _Nonnull __cnd, mtx_t* _Nonnull __mtx) {
return __bionic_thrd_error(pthread_cond_wait(__cnd, __mtx));
}
-__BIONIC_THREADS_INLINE void mtx_destroy(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE void mtx_destroy(mtx_t* _Nonnull __mtx) {
pthread_mutex_destroy(__mtx);
}
-__BIONIC_THREADS_INLINE int mtx_init(mtx_t* __mtx, int __type) {
+__BIONIC_THREADS_INLINE int mtx_init(mtx_t* _Nonnull __mtx, int __type) {
int __pthread_type = (__type & mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE
: PTHREAD_MUTEX_NORMAL;
__type &= ~mtx_recursive;
@@ -99,31 +99,32 @@ __BIONIC_THREADS_INLINE int mtx_init(mtx_t* __mtx, int __type) {
return __bionic_thrd_error(pthread_mutex_init(__mtx, &__attr));
}
-__BIONIC_THREADS_INLINE int mtx_lock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_lock(mtx_t* _Nonnull __mtx) {
return __bionic_thrd_error(pthread_mutex_lock(__mtx));
}
-__BIONIC_THREADS_INLINE int mtx_timedlock(mtx_t* __mtx,
- const struct timespec* __timeout) {
+__BIONIC_THREADS_INLINE int mtx_timedlock(mtx_t* _Nonnull __mtx,
+ const struct timespec* _Nullable __timeout) {
return __bionic_thrd_error(pthread_mutex_timedlock(__mtx, __timeout));
}
-__BIONIC_THREADS_INLINE int mtx_trylock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_trylock(mtx_t* _Nonnull __mtx) {
return __bionic_thrd_error(pthread_mutex_trylock(__mtx));
}
-__BIONIC_THREADS_INLINE int mtx_unlock(mtx_t* __mtx) {
+__BIONIC_THREADS_INLINE int mtx_unlock(mtx_t* _Nonnull __mtx) {
return __bionic_thrd_error(pthread_mutex_unlock(__mtx));
}
-
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
struct __bionic_thrd_data {
thrd_start_t __func;
void* __arg;
};
+#pragma clang diagnostic pop
-static inline void* __bionic_thrd_trampoline(void* __arg) {
+static inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
struct __bionic_thrd_data __data =
*__BIONIC_CAST(static_cast, struct __bionic_thrd_data*, __arg);
free(__arg);
@@ -132,9 +133,9 @@ static inline void* __bionic_thrd_trampoline(void* __arg) {
__BIONIC_CAST(static_cast, uintptr_t, __result));
}
-__BIONIC_THREADS_INLINE int thrd_create(thrd_t* __thrd,
- thrd_start_t __func,
- void* __arg) {
+__BIONIC_THREADS_INLINE int thrd_create(thrd_t* _Nonnull __thrd,
+ thrd_start_t _Nonnull __func,
+ void* _Nullable __arg) {
struct __bionic_thrd_data* __pthread_arg =
__BIONIC_CAST(static_cast, struct __bionic_thrd_data*,
malloc(sizeof(struct __bionic_thrd_data)));
@@ -164,7 +165,7 @@ __BIONIC_THREADS_INLINE void thrd_exit(int __result) {
__BIONIC_CAST(static_cast, uintptr_t, __result)));
}
-__BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* __result) {
+__BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* _Nullable __result) {
void* __pthread_result;
if (pthread_join(__thrd, &__pthread_result) != 0) return thrd_error;
if (__result) {
@@ -173,8 +174,8 @@ __BIONIC_THREADS_INLINE int thrd_join(thrd_t __thrd, int* __result) {
return thrd_success;
}
-__BIONIC_THREADS_INLINE int thrd_sleep(const struct timespec* __duration,
- struct timespec* __remaining) {
+__BIONIC_THREADS_INLINE int thrd_sleep(const struct timespec* _Nonnull __duration,
+ struct timespec* _Nullable __remaining) {
int __rc = nanosleep(__duration, __remaining);
if (__rc == 0) return 0;
return (errno == EINTR) ? -1 : -2;
@@ -186,7 +187,7 @@ __BIONIC_THREADS_INLINE void thrd_yield(void) {
-__BIONIC_THREADS_INLINE int tss_create(tss_t* __key, tss_dtor_t __dtor) {
+__BIONIC_THREADS_INLINE int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) {
return __bionic_thrd_error(pthread_key_create(__key, __dtor));
}
@@ -194,11 +195,11 @@ __BIONIC_THREADS_INLINE void tss_delete(tss_t __key) {
pthread_key_delete(__key);
}
-__BIONIC_THREADS_INLINE void* tss_get(tss_t __key) {
+__BIONIC_THREADS_INLINE void* _Nullable tss_get(tss_t __key) {
return pthread_getspecific(__key);
}
-__BIONIC_THREADS_INLINE int tss_set(tss_t __key, void* __value) {
+__BIONIC_THREADS_INLINE int tss_set(tss_t __key, void* _Nonnull __value) {
return __bionic_thrd_error(pthread_setspecific(__key, __value));
}
diff --git a/libc/include/complex.h b/libc/include/complex.h
index 50da3306d..f205abdba 100644
--- a/libc/include/complex.h
+++ b/libc/include/complex.h
@@ -55,99 +55,99 @@ __BEGIN_DECLS
/* 7.3.5.1 The cacos functions */
double complex cacos(double complex __z) __INTRODUCED_IN(23);
float complex cacosf(float complex __z) __INTRODUCED_IN(23);
-long double complex cacosl(long double complex __z) __RENAME_LDBL(cacos, 23, 26);
+long double complex cacosl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.2 The casin functions */
double complex casin(double complex __z) __INTRODUCED_IN(23);
float complex casinf(float complex __z) __INTRODUCED_IN(23);
-long double complex casinl(long double complex __z) __RENAME_LDBL(casin, 23, 26);
+long double complex casinl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The catan functions */
double complex catan(double complex __z) __INTRODUCED_IN(23);
float complex catanf(float complex __z) __INTRODUCED_IN(23);
-long double complex catanl(long double complex __z) __RENAME_LDBL(catan, 23, 26);
+long double complex catanl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The ccos functions */
double complex ccos(double complex __z) __INTRODUCED_IN(23);
float complex ccosf(float complex __z) __INTRODUCED_IN(23);
-long double complex ccosl(long double complex __z) __RENAME_LDBL(ccos, 23, 26);
+long double complex ccosl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The csin functions */
double complex csin(double complex __z) __INTRODUCED_IN(23);
float complex csinf(float complex __z) __INTRODUCED_IN(23);
-long double complex csinl(long double complex __z) __RENAME_LDBL(csin, 23, 26);
+long double complex csinl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The ctan functions */
double complex ctan(double complex __z) __INTRODUCED_IN(23);
float complex ctanf(float complex __z) __INTRODUCED_IN(23);
-long double complex ctanl(long double complex __z) __RENAME_LDBL(ctan, 23, 26);
+long double complex ctanl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6 Hyperbolic functions */
/* 7.3.6.1 The cacosh functions */
double complex cacosh(double complex __z) __INTRODUCED_IN(23);
float complex cacoshf(float complex __z) __INTRODUCED_IN(23);
-long double complex cacoshl(long double complex __z) __RENAME_LDBL(cacosh, 23, 26);
+long double complex cacoshl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.2 The casinh functions */
double complex casinh(double complex __z) __INTRODUCED_IN(23);
float complex casinhf(float complex __z) __INTRODUCED_IN(23);
-long double complex casinhl(long double complex __z) __RENAME_LDBL(casinh, 23, 26);
+long double complex casinhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.3 The catanh functions */
double complex catanh(double complex __z) __INTRODUCED_IN(23);
float complex catanhf(float complex __z) __INTRODUCED_IN(23);
-long double complex catanhl(long double complex __z) __RENAME_LDBL(catanh, 23, 26);
+long double complex catanhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.4 The ccosh functions */
double complex ccosh(double complex __z) __INTRODUCED_IN(23);
float complex ccoshf(float complex __z) __INTRODUCED_IN(23);
-long double complex ccoshl(long double complex __z) __RENAME_LDBL(ccosh, 23, 26);
+long double complex ccoshl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.5 The csinh functions */
double complex csinh(double complex __z) __INTRODUCED_IN(23);
float complex csinhf(float complex __z) __INTRODUCED_IN(23);
-long double complex csinhl(long double complex __z) __RENAME_LDBL(csinh, 23, 26);
+long double complex csinhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.6 The ctanh functions */
double complex ctanh(double complex __z) __INTRODUCED_IN(23);
float complex ctanhf(float complex __z) __INTRODUCED_IN(23);
-long double complex ctanhl(long double complex __z) __RENAME_LDBL(ctanh, 23, 26);
+long double complex ctanhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.7 Exponential and logarithmic functions */
/* 7.3.7.1 The cexp functions */
double complex cexp(double complex __z) __INTRODUCED_IN(23);
float complex cexpf(float complex __z) __INTRODUCED_IN(23);
-long double complex cexpl(long double complex __z) __RENAME_LDBL(cexp, 23, 26);
+long double complex cexpl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.7.2 The clog functions */
double complex clog(double complex __z) __INTRODUCED_IN(26);
float complex clogf(float complex __z) __INTRODUCED_IN(26);
-long double complex clogl(long double complex __z) __RENAME_LDBL(clog, 26, 26);
+long double complex clogl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.8 Power and absolute-value functions */
/* 7.3.8.1 The cabs functions */
double cabs(double complex __z) __INTRODUCED_IN(23);
float cabsf(float complex __z) __INTRODUCED_IN(23);
-long double cabsl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(cabs)*/;
+long double cabsl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.8.2 The cpow functions */
double complex cpow(double complex __x, double complex __z) __INTRODUCED_IN(26);
float complex cpowf(float complex __x, float complex __z) __INTRODUCED_IN(26);
-long double complex cpowl(long double complex __x, long double complex __z) __RENAME_LDBL(cpow, 26, 26);
+long double complex cpowl(long double complex __x, long double complex __z) __INTRODUCED_IN(26);
/* 7.3.8.3 The csqrt functions */
double complex csqrt(double complex __z) __INTRODUCED_IN(23);
float complex csqrtf(float complex __z) __INTRODUCED_IN(23);
-long double complex csqrtl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(csqrt)*/;
+long double complex csqrtl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9 Manipulation functions */
/* 7.3.9.1 The carg functions */
double carg(double complex __z) __INTRODUCED_IN(23);
float cargf(float complex __z) __INTRODUCED_IN(23);
-long double cargl(long double complex __z) __RENAME_LDBL(carg, 23, 23);
+long double cargl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.2 The cimag functions */
double cimag(double complex __z) __INTRODUCED_IN(23);
float cimagf(float complex __z) __INTRODUCED_IN(23);
-long double cimagl(long double complex __z) __RENAME_LDBL(cimag, 23, 23);
+long double cimagl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.3 The conj functions */
double complex conj(double complex __z) __INTRODUCED_IN(23);
float complex conjf(float complex __z) __INTRODUCED_IN(23);
-long double complex conjl(long double complex __z) __RENAME_LDBL(conj, 23, 23);
+long double complex conjl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.4 The cproj functions */
double complex cproj(double complex __z) __INTRODUCED_IN(23);
float complex cprojf(float complex __z) __INTRODUCED_IN(23);
-long double complex cprojl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23) /*__RENAME_LDBL(cproj)*/;
+long double complex cprojl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.5 The creal functions */
double creal(double complex __z) __INTRODUCED_IN(23);
float crealf(float complex __z) __INTRODUCED_IN(23);
-long double creall(long double complex __z) __RENAME_LDBL(creal, 23, 23);
+long double creall(long double complex __z) __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/fenv.h b/libc/include/fenv.h
index 6e8ea57c4..f7dcc8e4f 100644
--- a/libc/include/fenv.h
+++ b/libc/include/fenv.h
@@ -29,6 +29,11 @@
#pragma once
+/**
+ * @file fenv.h
+ * @brief Floating-point environment.
+ */
+
#include <sys/cdefs.h>
#if defined(__aarch64__) || defined(__arm__)
@@ -43,33 +48,135 @@
__BEGIN_DECLS
-int feclearexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fegetexceptflag(fexcept_t* _Nonnull __flag_ptr, int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int feraiseexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fesetexceptflag(const fexcept_t* _Nonnull __flag_ptr, int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fetestexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
+/**
+ * [feclearexcept(3)](http://man7.org/linux/man-pages/man3/feclearexcept.3.html)
+ * clears the given `exceptions` in hardware.
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int feclearexcept(int __exceptions);
-int fegetround(void) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fesetround(int __rounding_mode) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
+/**
+ * [fegetexceptflag(3)](http://man7.org/linux/man-pages/man3/fegetexceptflag.3.html)
+ * copies the state of the given `exceptions` from hardware into `*flag_ptr`.
+ * See fesetexceptflag().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int fegetexceptflag(fexcept_t* _Nonnull __flag_ptr, int __exceptions);
-int fegetenv(fenv_t* _Nonnull __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int feholdexcept(fenv_t* _Nonnull __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fesetenv(const fenv_t* _Nonnull __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int feupdateenv(const fenv_t* _Nonnull __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
+/**
+ * [feraiseexcept(3)](http://man7.org/linux/man-pages/man3/feraiseexcept.3.html)
+ * raises the given `exceptions` in hardware.
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int feraiseexcept(int __exceptions);
-int feenableexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fedisableexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
-int fegetexcept(void) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_X86(9);
+/**
+ * [fesetexceptflag(3)](http://man7.org/linux/man-pages/man3/fesetexceptflag.3.html)
+ * copies the state of the given `exceptions` from `*flag_ptr` into hardware.
+ * See fesetexceptflag().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int fesetexceptflag(const fexcept_t* _Nonnull __flag_ptr, int __exceptions);
-/*
- * The following constant represents the default floating-point environment
- * (that is, the one installed at program startup) and has type pointer to
- * const-qualified fenv_t.
+/**
+ * [fetestexcept(3)](http://man7.org/linux/man-pages/man3/fetestexcept.3.html)
+ * tests whether the given `exceptions` are set in hardware.
+ *
+ * Returns the currently-set subset of `exceptions`.
+ */
+int fetestexcept(int __exceptions);
+
+/**
+ * [fegetround(3)](http://man7.org/linux/man-pages/man3/fegetround.3.html)
+ * returns the current rounding mode.
+ *
+ * Returns the rounding mode on success, and returns a negative value on failure.
+ */
+int fegetround(void);
+
+/**
+ * [fesetround(3)](http://man7.org/linux/man-pages/man3/fesetround.3.html)
+ * sets the current rounding mode.
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int fesetround(int __rounding_mode);
+
+/**
+ * [fegetenv(3)](http://man7.org/linux/man-pages/man3/fegetenv.3.html)
+ * gets the current floating-point environment. See fesetenv().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int fegetenv(fenv_t* _Nonnull __env);
+
+/**
+ * [feholdexcept(3)](http://man7.org/linux/man-pages/man3/feholdexcept.3.html)
+ * gets the current floating-point environment, clears the status flags, and
+ * ignores floating point exceptions. See fesetenv()/feupdateenv().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int feholdexcept(fenv_t* _Nonnull __env);
+
+/**
+ * [fesetenv(3)](http://man7.org/linux/man-pages/man3/fesetenv.3.html)
+ * sets the current floating-point environment. See fegetenv().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int fesetenv(const fenv_t* _Nonnull __env);
+
+/**
+ * [feupdateenv(3)](http://man7.org/linux/man-pages/man3/feupdateenv.3.html)
+ * sets the current floating-point environment to `*env` but with currently-raised
+ * exceptions still raised. See fesetenv().
+ *
+ * Returns 0 on success, and returns non-zero on failure.
+ */
+int feupdateenv(const fenv_t* _Nonnull __env);
+
+/**
+ * [feenableexcept(3)](http://man7.org/linux/man-pages/man3/feenableexcept.3.html)
+ * sets the given `exceptions` to trap, if the hardware supports it. This is not
+ * generally useful on Android, because only x86/x86-64 can trap.
+ *
+ * Returns the previous set of enabled exceptions on success, and returns -1 on failure.
+ */
+int feenableexcept(int __exceptions);
+
+/**
+ * [fedisableexcept(3)](http://man7.org/linux/man-pages/man3/fedisableexcept.3.html)
+ * sets the given `exceptions` to not trap, if the hardware supports it. This is not
+ * generally useful on Android, because only x86/x86-64 can trap.
+ *
+ * Returns the previous set of enabled exceptions on success, and returns -1 on failure.
+ */
+int fedisableexcept(int __exceptions);
+
+/**
+ * [fegetexcept(3)](http://man7.org/linux/man-pages/man3/fegetexcept.3.html)
+ * returns the exceptions that currently trap. This is not generally useful on
+ * Android, because only x86/x86-64 can trap.
+ *
+ * Returns the exceptions that currently trap.
+ */
+int fegetexcept(void);
+
+/** See FE_DFL_ENV. */
+extern const fenv_t __fe_dfl_env;
+
+/**
+ * Constant representing the default floating-point environment
+ * (that is, the one installed at program startup).
*
* It can be used as an argument to the functions that manage the floating-point
* environment, namely fesetenv() and feupdateenv().
*/
-extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env)
__END_DECLS
diff --git a/libc/include/ftw.h b/libc/include/ftw.h
index c5fa4de1d..ee154f0bb 100644
--- a/libc/include/ftw.h
+++ b/libc/include/ftw.h
@@ -57,8 +57,8 @@ struct FTW {
__BEGIN_DECLS
int ftw(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat* _Nonnull, int), int __max_fd_count) __INTRODUCED_IN(17);
int nftw(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __INTRODUCED_IN(17);
-int ftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int), int __max_fd_count) __RENAME_STAT64(ftw, 17, 21);
-int nftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __RENAME_STAT64(nftw, 17, 21);
+int ftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int), int __max_fd_count) __INTRODUCED_IN(21);
+int nftw64(const char* _Nonnull __dir_path, int (* _Nonnull __callback)(const char* _Nonnull, const struct stat64* _Nonnull, int, struct FTW* _Nonnull), int __max_fd_count, int __flags) __INTRODUCED_IN(21);
__END_DECLS
#endif
diff --git a/libc/include/iconv.h b/libc/include/iconv.h
index 7cf36dcf2..794a2922b 100644
--- a/libc/include/iconv.h
+++ b/libc/include/iconv.h
@@ -54,7 +54,7 @@ typedef struct __iconv_t* iconv_t;
*
* Available since API level 28.
*/
-iconv_t _Nonnull iconv_open(const char* _Nonnull __src_encoding, const char* _Nonnull __dst_encoding) __INTRODUCED_IN(28);
+iconv_t _Nonnull iconv_open(const char* _Nonnull __dst_encoding, const char* _Nonnull __src_encoding) __INTRODUCED_IN(28);
/**
* [iconv(3)](http://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one
diff --git a/libc/include/math.h b/libc/include/math.h
index a5fa7c3f3..0572238c1 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -75,232 +75,231 @@ typedef __float_t float_t;
double acos(double __x);
float acosf(float __x);
-long double acosl(long double __x) __RENAME_LDBL(acos, 3, 21);
+long double acosl(long double __x);
double asin(double __x);
float asinf(float __x);
-long double asinl(long double __x) __RENAME_LDBL(asin, 3, 21);
+long double asinl(long double __x);
double atan(double __x);
float atanf(float __x);
-long double atanl(long double __x) __RENAME_LDBL(atan, 3, 21);
+long double atanl(long double __x);
double atan2(double __y, double __x);
float atan2f(float __y, float __x);
-long double atan2l(long double __y, long double __x) __RENAME_LDBL(atan2, 3, 21);
+long double atan2l(long double __y, long double __x);
double cos(double __x);
float cosf(float __x);
-long double cosl(long double __x) __RENAME_LDBL(cos, 3, 21);
+long double cosl(long double __x);
double sin(double __x);
float sinf(float __x);
-long double sinl(long double __x) __RENAME_LDBL(sin, 3, 21);
+long double sinl(long double __x);
double tan(double __x);
float tanf(float __x);
-long double tanl(long double __x) __RENAME_LDBL(tan, 3, 21);
+long double tanl(long double __x);
double acosh(double __x);
float acoshf(float __x);
-long double acoshl(long double __x) __RENAME_LDBL(acosh, 3, 21);
+long double acoshl(long double __x);
double asinh(double __x);
float asinhf(float __x);
-long double asinhl(long double __x) __RENAME_LDBL(asinh, 3, 21);
+long double asinhl(long double __x);
double atanh(double __x);
float atanhf(float __x);
-long double atanhl(long double __x) __RENAME_LDBL(atanh, 3, 21);
+long double atanhl(long double __x);
double cosh(double __x);
float coshf(float __x);
-long double coshl(long double __x) __RENAME_LDBL(cosh, 3, 21);
+long double coshl(long double __x);
double sinh(double __x);
float sinhf(float __x);
-long double sinhl(long double __x) __RENAME_LDBL(sinh, 3, 21);
+long double sinhl(long double __x);
double tanh(double __x);
float tanhf(float __x);
-long double tanhl(long double __x) __RENAME_LDBL(tanh, 3, 21);
+long double tanhl(long double __x);
double exp(double __x);
float expf(float __x);
-long double expl(long double __x) __RENAME_LDBL(exp, 3, 21);
+long double expl(long double __x);
double exp2(double __x);
float exp2f(float __x);
-long double exp2l(long double __x) __RENAME_LDBL(exp2, 3, 21);
+long double exp2l(long double __x);
double expm1(double __x);
float expm1f(float __x);
-long double expm1l(long double __x) __RENAME_LDBL(expm1, 3, 21);
+long double expm1l(long double __x);
double frexp(double __x, int* _Nonnull __exponent);
float frexpf(float __x, int* _Nonnull __exponent);
-long double frexpl(long double __x, int* _Nonnull __exponent) __RENAME_LDBL(frexp, 3, 21);
+long double frexpl(long double __x, int* _Nonnull __exponent);
int ilogb(double __x) __attribute_const__;
int ilogbf(float __x) __attribute_const__;
-int ilogbl(long double __x) __RENAME_LDBL(ilogb, 3, 3) __attribute_const__;
+int ilogbl(long double __x) __attribute_const__;
double ldexp(double __x, int __exponent);
float ldexpf(float __x, int __exponent);
-long double ldexpl(long double __x, int __exponent) __RENAME_LDBL(ldexp, 3, 3);
+long double ldexpl(long double __x, int __exponent);
double log(double __x);
float logf(float __x);
-long double logl(long double __x) __RENAME_LDBL(log, 3, 21);
+long double logl(long double __x);
double log10(double __x);
float log10f(float __x);
-long double log10l(long double __x) __RENAME_LDBL(log10, 3, 21);
+long double log10l(long double __x);
double log1p(double __x);
float log1pf(float __x);
-long double log1pl(long double __x) __RENAME_LDBL(log1p, 3, 21);
+long double log1pl(long double __x);
double log2(double __x) __INTRODUCED_IN(18);
float log2f(float __x) __INTRODUCED_IN(18);
-long double log2l(long double __x) __RENAME_LDBL(log2, 18, 18);
+long double log2l(long double __x);
double logb(double __x);
float logbf(float __x);
-long double logbl(long double __x) __RENAME_LDBL(logb, 3, 18);
+long double logbl(long double __x);
double modf(double __x, double* _Nonnull __integral_part);
float modff(float __x, float* _Nonnull __integral_part);
-long double modfl(long double __x, long double* _Nonnull __integral_part) __RENAME_LDBL(modf, 3, 21);
+long double modfl(long double __x, long double* _Nonnull __integral_part);
double scalbn(double __x, int __exponent);
float scalbnf(float __x, int __exponent);
-long double scalbnl(long double __x, int __exponent) __RENAME_LDBL(scalbn, 3, 3);
+long double scalbnl(long double __x, int __exponent);
-/* TODO: once the NDK only supports >= 18, use __RENAME_LDBL here too. */
-double scalbln(double __x, long __exponent) __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(18);
-float scalblnf(float __x, long __exponent) __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(18);
-long double scalblnl(long double __x, long __exponent) __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(18);
+double scalbln(double __x, long __exponent);
+float scalblnf(float __x, long __exponent);
+long double scalblnl(long double __x, long __exponent);
double cbrt(double __x);
float cbrtf(float __x);
-long double cbrtl(long double __x) __RENAME_LDBL(cbrt, 3, 21);
+long double cbrtl(long double __x);
double fabs(double __x) __attribute_const__;
float fabsf(float __x) __attribute_const__;
-long double fabsl(long double __x) __RENAME_LDBL(fabs, 3, 3) __attribute_const__;
+long double fabsl(long double __x) __attribute_const__;
double hypot(double __x, double __y);
float hypotf(float __x, float __y);
-long double hypotl(long double __x, long double __y) __RENAME_LDBL(hypot, 3, 21);
+long double hypotl(long double __x, long double __y);
double pow(double __x, double __y);
float powf(float __x, float __y);
-long double powl(long double __x, long double __y) __RENAME_LDBL(pow, 3, 21);
+long double powl(long double __x, long double __y);
double sqrt(double __x);
float sqrtf(float __x);
-long double sqrtl(long double __x) __RENAME_LDBL(sqrt, 3, 21);
+long double sqrtl(long double __x);
double erf(double __x);
float erff(float __x);
-long double erfl(long double __x) __RENAME_LDBL(erf, 3, 21);
+long double erfl(long double __x);
double erfc(double __x);
float erfcf(float __x);
-long double erfcl(long double __x) __RENAME_LDBL(erfc, 3, 21);
+long double erfcl(long double __x);
double lgamma(double __x);
float lgammaf(float __x);
-long double lgammal(long double __x) __RENAME_LDBL(lgamma, 3, 21);
+long double lgammal(long double __x);
double tgamma(double __x);
float tgammaf(float __x);
-long double tgammal(long double __x) __RENAME_LDBL(tgamma, 3, 21);
+long double tgammal(long double __x);
double ceil(double __x);
float ceilf(float __x);
-long double ceill(long double __x) __RENAME_LDBL(ceil, 3, 3);
+long double ceill(long double __x);
double floor(double __x);
float floorf(float __x);
-long double floorl(long double __x) __RENAME_LDBL(floor, 3, 3);
+long double floorl(long double __x);
double nearbyint(double __x);
float nearbyintf(float __x);
-long double nearbyintl(long double __x) __RENAME_LDBL(nearbyint, 3, 21);
+long double nearbyintl(long double __x);
double rint(double __x);
float rintf(float __x);
-long double rintl(long double __x) __RENAME_LDBL(rint, 3, 21);
+long double rintl(long double __x);
long lrint(double __x);
long lrintf(float __x);
-long lrintl(long double __x) __RENAME_LDBL(lrint, 3, 21);
+long lrintl(long double __x);
long long llrint(double __x);
long long llrintf(float __x);
-long long llrintl(long double __x) __RENAME_LDBL(llrint, 3, 21);
+long long llrintl(long double __x);
double round(double __x);
float roundf(float __x);
-long double roundl(long double __x) __RENAME_LDBL(roundl, 3, 3);
+long double roundl(long double __x);
long lround(double __x);
long lroundf(float __x);
-long lroundl(long double __x) __RENAME_LDBL(lround, 3, 3);
+long lroundl(long double __x);
long long llround(double __x);
long long llroundf(float __x);
-long long llroundl(long double __x) __RENAME_LDBL(llround, 3, 3);
+long long llroundl(long double __x);
double trunc(double __x);
float truncf(float __x);
-long double truncl(long double __x) __RENAME_LDBL(trunc, 3, 3);
+long double truncl(long double __x);
double fmod(double __x, double __y);
float fmodf(float __x, float __y);
-long double fmodl(long double __x, long double __y) __RENAME_LDBL(fmod, 3, 21);
+long double fmodl(long double __x, long double __y);
double remainder(double __x, double __y);
float remainderf(float __x, float __y);
-long double remainderl(long double __x, long double __y) __RENAME_LDBL(remainder, 3, 21);
+long double remainderl(long double __x, long double __y);
double remquo(double __x, double __y, int* _Nonnull __quotient_bits);
float remquof(float __x, float __y, int* _Nonnull __quotient_bits);
-long double remquol(long double __x, long double __y, int* _Nonnull __quotient_bits) __RENAME_LDBL(remquo, 3, 21);
+long double remquol(long double __x, long double __y, int* _Nonnull __quotient_bits);
double copysign(double __value, double __sign) __attribute_const__;
float copysignf(float __value, float __sign) __attribute_const__;
-long double copysignl(long double __value, long double __sign) __RENAME_LDBL(copysign, 3, 3) __attribute_const__;
+long double copysignl(long double __value, long double __sign) __attribute_const__;
double nan(const char* _Nonnull __kind) __attribute_const__;
float nanf(const char* _Nonnull __kind) __attribute_const__;
-long double nanl(const char* _Nonnull __kind) __RENAME_LDBL(nan, 13, 13) __attribute_const__;
+long double nanl(const char* _Nonnull __kind) __attribute_const__;
double nextafter(double __x, double __y);
float nextafterf(float __x, float __y);
-long double nextafterl(long double __x, long double __y) __RENAME_LDBL_NO_GUARD_FOR_NDK(nextafter, 3, 21);
+long double nextafterl(long double __x, long double __y);
-double nexttoward(double __x, long double __y) __INTRODUCED_IN_NO_GUARD_FOR_NDK(18);
+double nexttoward(double __x, long double __y);
float nexttowardf(float __x, long double __y);
-long double nexttowardl(long double __x, long double __y) __RENAME_LDBL_NO_GUARD_FOR_NDK(nexttoward, 18, 18);
+long double nexttowardl(long double __x, long double __y);
double fdim(double __x, double __y);
float fdimf(float __x, float __y);
-long double fdiml(long double __x, long double __y) __RENAME_LDBL(fdim, 3, 3);
+long double fdiml(long double __x, long double __y);
double fmax(double __x, double __y) __attribute_const__;
float fmaxf(float __x, float __y) __attribute_const__;
-long double fmaxl(long double __x, long double __y) __RENAME_LDBL(fmax, 3, 3) __attribute_const__;
+long double fmaxl(long double __x, long double __y) __attribute_const__;
double fmin(double __x, double __y) __attribute_const__;
float fminf(float __x, float __y) __attribute_const__;
-long double fminl(long double __x, long double __y) __RENAME_LDBL(fmin, 3, 3) __attribute_const__;
+long double fminl(long double __x, long double __y) __attribute_const__;
double fma(double __x, double __y, double __z);
float fmaf(float __x, float __y, float __z);
-long double fmal(long double __x, long double __y, long double __z) __RENAME_LDBL_NO_GUARD_FOR_NDK(fma, 3, 21);
+long double fmal(long double __x, long double __y, long double __z);
#define isgreater(x, y) __builtin_isgreater((x), (y))
#define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 26bc7423c..d11fddfb7 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -172,7 +172,7 @@ int sched_rr_get_interval(pid_t __pid, struct timespec* _Nonnull __quantum);
* Returns the pid of the child to the caller on success and
* returns -1 and sets `errno` on failure.
*/
-int clone(int (* __BIONIC_COMPLICATED_NULLNESS __fn)(void* __BIONIC_COMPLICATED_NULLNESS ), void* __BIONIC_COMPLICATED_NULLNESS __child_stack, int __flags, void* _Nullable __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
+int clone(int (* __BIONIC_COMPLICATED_NULLNESS __fn)(void* __BIONIC_COMPLICATED_NULLNESS ), void* __BIONIC_COMPLICATED_NULLNESS __child_stack, int __flags, void* _Nullable __arg, ...);
/**
* [unshare(2)](http://man7.org/linux/man-pages/man2/unshare.2.html)
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 2bcb870fd..ee4b12afb 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -78,7 +78,7 @@ int posix_memalign(void* _Nullable * _Nullable __memptr, size_t __alignment, siz
void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __RENAME_LDBL(strtod, 3, 21);
+long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr) __INTRODUCED_IN(21);
unsigned long strtoul_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(26);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 484757e26..4154e62af 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -201,39 +201,6 @@
# define __RENAME_IF_FILE_OFFSET64(func)
#endif
-/*
- * For LP32, `long double` == `double`. Historically many `long double` functions were incorrect
- * on x86, missing on most architectures, and even if they are present and correct, linking to
- * them just bloats your ELF file by adding extra relocations. The __BIONIC_LP32_USE_LONG_DOUBLE
- * macro lets us test the headers both ways (and adds an escape valve).
- *
- * Note that some functions have their __RENAME_LDBL commented out as a sign that although we could
- * use __RENAME_LDBL it would actually cause the function to be introduced later because the
- * `long double` variant appeared before the `double` variant.
- *
- * The _NO_GUARD_FOR_NDK variants keep the __VERSIONER_NO_GUARD behavior working for the NDK. This
- * allows libc++ to refer to these functions in inlines without needing to guard them, needed since
- * libc++ doesn't currently guard these calls. There's no risk to the apps though because using
- * those APIs will still cause a link error.
- */
-#if defined(__LP64__) || defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define __RENAME_LDBL(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN(regular_api_level)
-#define __RENAME_LDBL_NO_GUARD_FOR_NDK(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN_NO_GUARD_FOR_NDK(regular_api_level)
-#else
-#define __RENAME_LDBL(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
-#define __RENAME_LDBL_NO_GUARD_FOR_NDK(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN_NO_GUARD_FOR_NDK(rewrite_api_level)
-#endif
-
-/*
- * On all architectures, `struct stat` == `struct stat64`, but LP32 didn't gain the *64 functions
- * until API level 21.
- */
-#if defined(__LP64__) || defined(__BIONIC_LP32_USE_STAT64)
-#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN(regular_api_level)
-#else
-#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
-#endif
-
/* glibc compatibility. */
#if defined(__LP64__)
#define __WORDSIZE 64
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 54621b7b3..f773ff695 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -141,13 +141,13 @@ int fchmod(int __fd, mode_t __mode);
int mkdir(const char* _Nonnull __path, mode_t __mode);
int fstat(int __fd, struct stat* _Nonnull __buf);
-int fstat64(int __fd, struct stat64* _Nonnull __buf) __RENAME_STAT64(fstat, 3, 21);
+int fstat64(int __fd, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
int fstatat(int __dir_fd, const char* _Nonnull __path, struct stat* _Nonnull __buf, int __flags);
-int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags) __RENAME_STAT64(fstatat, 3, 21);
+int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags) __INTRODUCED_IN(21);
int lstat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
-int lstat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __RENAME_STAT64(lstat, 3, 21);
+int lstat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
int stat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
-int stat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __RENAME_STAT64(stat, 3, 21);
+int stat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf) __INTRODUCED_IN(21);
int mknod(const char* _Nonnull __path, mode_t __mode, dev_t __dev);
mode_t umask(mode_t __mask);
diff --git a/libc/include/sys/thread_properties.h b/libc/include/sys/thread_properties.h
index b5d30c77e..efd212a78 100644
--- a/libc/include/sys/thread_properties.h
+++ b/libc/include/sys/thread_properties.h
@@ -50,8 +50,8 @@ __BEGIN_DECLS
*
* Available since API level 31.
*/
-void __libc_get_static_tls_bounds(void** __static_tls_begin,
- void** __static_tls_end) __INTRODUCED_IN(31);
+void __libc_get_static_tls_bounds(void* _Nonnull * _Nonnull __static_tls_begin,
+ void* _Nonnull * _Nonnull __static_tls_end) __INTRODUCED_IN(31);
/**
@@ -66,7 +66,7 @@ void __libc_get_static_tls_bounds(void** __static_tls_begin,
*
* Available since API level 31.
*/
-void __libc_register_thread_exit_callback(void (*__cb)(void)) __INTRODUCED_IN(31);
+void __libc_register_thread_exit_callback(void (* _Nonnull __cb)(void)) __INTRODUCED_IN(31);
/**
* Iterates over all dynamic TLS chunks for the given thread.
@@ -76,11 +76,11 @@ void __libc_register_thread_exit_callback(void (*__cb)(void)) __INTRODUCED_IN(31
* Available since API level 31.
*/
void __libc_iterate_dynamic_tls(pid_t __tid,
- void (*__cb)(void* __dynamic_tls_begin,
- void* __dynamic_tls_end,
+ void (* _Nonnull __cb)(void* _Nonnull __dynamic_tls_begin,
+ void* _Nonnull __dynamic_tls_end,
size_t __dso_id,
- void* __arg),
- void* __arg) __INTRODUCED_IN(31);
+ void* _Nullable __arg),
+ void* _Nullable __arg) __INTRODUCED_IN(31);
/**
* Register on_creation and on_destruction callbacks, which will be called after a dynamic
@@ -89,9 +89,9 @@ void __libc_iterate_dynamic_tls(pid_t __tid,
* Available since API level 31.
*/
void __libc_register_dynamic_tls_listeners(
- void (*__on_creation)(void* __dynamic_tls_begin,
- void* __dynamic_tls_end),
- void (*__on_destruction)(void* __dynamic_tls_begin,
- void* __dynamic_tls_end)) __INTRODUCED_IN(31);
+ void (* _Nonnull __on_creation)(void* _Nonnull __dynamic_tls_begin,
+ void* _Nonnull __dynamic_tls_end),
+ void (* _Nonnull __on_destruction)(void* _Nonnull __dynamic_tls_begin,
+ void* _Nonnull __dynamic_tls_end)) __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 39f937479..cd09a1930 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -102,7 +102,7 @@ wchar_t* _Nullable wcstok(wchar_t* _Nullable __s, const wchar_t* _Nonnull __deli
long wcstol(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
long wcstol_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
long long wcstoll(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
-long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
+long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __INTRODUCED_IN(21);
unsigned long wcstoul(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
unsigned long wcstoul_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
unsigned long long wcstoull(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
diff --git a/libc/platform/bionic/page.h b/libc/platform/bionic/page.h
index d063a9863..5f4bb6f0f 100644
--- a/libc/platform/bionic/page.h
+++ b/libc/platform/bionic/page.h
@@ -16,15 +16,39 @@
#pragma once
-// Get PAGE_SIZE and PAGE_MASK.
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/auxv.h>
+
+// For PAGE_SIZE.
#include <sys/user.h>
+inline size_t page_size() {
+ /*
+ * PAGE_SIZE defines the maximum supported page size. Since 4096 is the
+ * minimum supported page size we can just let it be constant folded if it's
+ * also the maximum.
+ */
+#if PAGE_SIZE == 4096
+ return PAGE_SIZE;
+#else
+ static size_t size = getauxval(AT_PAGESZ);
+ return size;
+#endif
+}
+
// Returns the address of the page containing address 'x'.
-#define PAGE_START(x) ((x) & PAGE_MASK)
+inline uintptr_t page_start(uintptr_t x) {
+ return x & ~(page_size() - 1);
+}
// Returns the offset of address 'x' in its page.
-#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
+inline uintptr_t page_offset(uintptr_t x) {
+ return x & (page_size() - 1);
+}
// Returns the address of the next page after address 'x', unless 'x' is
// itself at the start of a page.
-#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
+inline uintptr_t page_end(uintptr_t x) {
+ return page_start(x + page_size() - 1);
+}
diff --git a/libc/stdio/scanf_common.h b/libc/stdio/scanf_common.h
new file mode 100644
index 000000000..8132e90de
--- /dev/null
+++ b/libc/stdio/scanf_common.h
@@ -0,0 +1,115 @@
+/* $OpenBSD: vfscanf.c,v 1.31 2014/03/19 05:17:01 guenther Exp $ */
+/*-
+ * 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 <ctype.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <wctype.h>
+#include "local.h"
+
+#include <platform/bionic/macros.h>
+#include <private/bionic_fortify.h>
+#include <private/bionic_mbstate.h>
+
+#define BUF 513 /* Maximum length of numeric string. */
+
+// Flags used during conversion.
+// Size/type:
+#define LONG 0x00001 // l: long or double
+#define LONGDBL 0x00002 // L: long double
+#define SHORT 0x00004 // h: short
+#define SHORTSHORT 0x00008 // hh: 8 bit integer
+#define LLONG 0x00010 // ll: long long (+ deprecated q: quad)
+#define POINTER 0x00020 // p: void* (as hex)
+#define SIZEINT 0x00040 // z: (signed) size_t
+#define MAXINT 0x00080 // j: intmax_t
+#define PTRINT 0x00100 // t: ptrdiff_t
+#define NOSKIP 0x00200 // [ or c: do not skip blanks
+// Modifiers:
+#define SUPPRESS 0x00400 // *: suppress assignment
+#define UNSIGNED 0x00800 // %[oupxX] conversions
+#define ALLOCATE 0x01000 // m: allocate a char*
+// Internal use during integer parsing:
+#define SIGNOK 0x02000 // +/- is (still) legal
+#define HAVESIGN 0x04000 // Sign detected
+#define NDIGITS 0x08000 // No digits detected
+#define PFXOK 0x10000 // "0x" prefix is (still) legal
+#define PFBOK 0x20000 // "0b" prefix is (still) legal
+#define NZDIGITS 0x40000 // No zero digits detected
+
+// Conversion types.
+#define CT_CHAR 0 // %c conversion
+#define CT_CCL 1 // %[...] conversion
+#define CT_STRING 2 // %s conversion
+#define CT_INT 3 // Integer: strtoimax/strtoumax
+#define CT_FLOAT 4 // Float: strtod
+
+#define to_digit(c) static_cast<int>((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+
+// Append a digit to a value and check for overflow.
+#define APPEND_DIGIT(val, dig) \
+ do { \
+ if ((val) > INT_MAX / 10) \
+ errno = ENOMEM; \
+ else { \
+ (val) *= 10; \
+ if ((val) > INT_MAX - to_digit((dig))) \
+ errno = ENOMEM; \
+ else \
+ (val) += to_digit((dig)); \
+ } \
+ } while (0)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+// Trasnlate a fixed size integer argument for the %w/%wf format to a
+// flag representation. Supported sizes are 8, 16, 32, and 64 so far.
+// See details in bionic/libc/include/stdint.h
+static int w_to_flag(int size, bool fast) {
+ static constexpr int fast_size = sizeof(void*) == 8 ? LLONG : 0;
+ if (size == 8) return SHORTSHORT;
+ if (size == 16) return fast ? fast_size : SHORT;
+ if (size == 32) return fast ? fast_size : 0;
+ if (size == 64) return LLONG;
+ __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
+}
+
+#pragma clang diagnostic pop \ No newline at end of file
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index dfd001d35..65f54a521 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -31,53 +31,7 @@
* SUCH DAMAGE.
*/
-#include <ctype.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <wctype.h>
-#include "local.h"
-
-#include <private/bionic_fortify.h>
-#include <platform/bionic/macros.h>
-#include <private/bionic_mbstate.h>
-
-#define BUF 513 /* Maximum length of numeric string. */
-
-// Flags used during conversion.
-// Size/type:
-#define LONG 0x00001 // l: long or double
-#define LONGDBL 0x00002 // L: long double
-#define SHORT 0x00004 // h: short
-#define SHORTSHORT 0x00008 // hh: 8 bit integer
-#define LLONG 0x00010 // ll: long long (+ deprecated q: quad)
-#define POINTER 0x00020 // p: void* (as hex)
-#define SIZEINT 0x00040 // z: (signed) size_t
-#define MAXINT 0x00080 // j: intmax_t
-#define PTRINT 0x00100 // t: ptrdiff_t
-#define NOSKIP 0x00200 // [ or c: do not skip blanks
-// Modifiers:
-#define SUPPRESS 0x00400 // *: suppress assignment
-#define UNSIGNED 0x00800 // %[oupxX] conversions
-#define ALLOCATE 0x01000 // m: allocate a char*
-// Internal use during integer parsing:
-#define SIGNOK 0x02000 // +/- is (still) legal
-#define HAVESIGN 0x04000 // Sign detected
-#define NDIGITS 0x08000 // No digits detected
-#define PFXOK 0x10000 // "0x" prefix is (still) legal
-#define PFBOK 0x20000 // "0b" prefix is (still) legal
-#define NZDIGITS 0x40000 // No zero digits detected
-
-// Conversion types.
-#define CT_CHAR 0 // %c conversion
-#define CT_CCL 1 // %[...] conversion
-#define CT_STRING 2 // %s conversion
-#define CT_INT 3 // Integer: strtoimax/strtoumax
-#define CT_FLOAT 4 // Float: strtod
+#include "scanf_common.h"
static const unsigned char* __sccl(char*, const unsigned char*);
@@ -122,6 +76,7 @@ int __svfscanf(FILE* fp, const char* fmt0, va_list ap) {
*/
again:
c = *fmt++;
+reswitch:
switch (c) {
case '%':
literal:
@@ -220,6 +175,18 @@ literal:
base = 10;
break;
+ case 'w': {
+ int size = 0;
+ bool fast = false;
+ c = *fmt++;
+ while (is_digit(c)) {
+ APPEND_DIGIT(size, c);
+ c = *fmt++;
+ }
+ flags |= w_to_flag(size, fast);
+ goto reswitch;
+ }
+
case 'X':
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 5f21acd0b..14b175415 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -31,62 +31,7 @@
* SUCH DAMAGE.
*/
-#include <inttypes.h>
-#include <limits.h>
-#include <locale.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wctype.h>
-#include "local.h"
-
-#include <platform/bionic/macros.h>
-
-#define BUF 513 /* Maximum length of numeric string. */
-
-/*
- * Flags used during conversion.
- */
-#define LONG 0x00001 /* l: long or double */
-#define LONGDBL 0x00002 /* L: long double */
-#define SHORT 0x00004 /* h: short */
-#define SHORTSHORT 0x00008 /* hh: 8 bit integer */
-#define LLONG 0x00010 /* ll: long long (+ deprecated q: quad) */
-#define POINTER 0x00020 /* p: void * (as hex) */
-#define SIZEINT 0x00040 /* z: (signed) size_t */
-#define MAXINT 0x00080 /* j: intmax_t */
-#define PTRINT 0x00100 /* t: ptrdiff_t */
-#define NOSKIP 0x00200 /* [ or c: do not skip blanks */
-#define SUPPRESS 0x00400 /* *: suppress assignment */
-#define UNSIGNED 0x00800 /* %[oupxX] conversions */
-
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK 0x01000 /* +/- is (still) legal */
-#define HAVESIGN 0x02000 /* sign detected */
-#define NDIGITS 0x04000 /* no digits detected */
-
-#define DPTOK 0x08000 /* (float) decimal point is still legal */
-#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */
-
-#define PFBOK 0x20000 /* 0x prefix is (still) legal */
-#define PFXOK 0x40000 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x80000 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0 /* %c conversion */
-#define CT_CCL 1 /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3 /* integer, i.e., strtoimax or strtoumax */
-#define CT_FLOAT 4 /* floating, i.e., strtod */
-
+#include "scanf_common.h"
// An interpretive version of __sccl from vfscanf.c --- a table of all wchar_t values would
// be a little too expensive, and some kind of compressed version isn't worth the trouble.
static inline bool in_ccl(wchar_t wc, const wchar_t* ccl) {
@@ -176,6 +121,7 @@ int __vfwscanf(FILE* __restrict fp, const wchar_t* __restrict fmt, __va_list ap)
*/
again:
c = *fmt++;
+ reswitch:
switch (c) {
case '%':
literal:
@@ -273,6 +219,18 @@ int __vfwscanf(FILE* __restrict fp, const wchar_t* __restrict fmt, __va_list ap)
base = 10;
break;
+ case 'w': {
+ int size = 0;
+ bool fast = false;
+ c = *fmt++;
+ while (is_digit(c)) {
+ APPEND_DIGIT(size, c);
+ c = *fmt++;
+ }
+ flags |= w_to_flag(size, fast);
+ goto reswitch;
+ }
+
case 'X':
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
diff --git a/libm/Android.bp b/libm/Android.bp
index 13fbf9a79..079fd9a2c 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -400,7 +400,6 @@ cc_library {
],
cflags: [
- "-D__BIONIC_LP32_USE_LONG_DOUBLE",
"-D_BSD_SOURCE",
"-DFLT_EVAL_METHOD=0",
"-include freebsd-compat.h",
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 17b574fc1..5c26944ff 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -962,7 +962,7 @@ static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
}
// Check if it is properly stored
- if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
+ if (entry.method != kCompressStored || (entry.offset % page_size()) != 0) {
close(fd);
return -1;
}
@@ -1171,7 +1171,7 @@ static bool load_library(android_namespace_t* ns,
"load_library(ns=%s, task=%s, flags=0x%x, realpath=%s, search_linked_namespaces=%d)",
ns->get_name(), name, rtld_flags, realpath.c_str(), search_linked_namespaces);
- if ((file_offset % PAGE_SIZE) != 0) {
+ if ((file_offset % page_size()) != 0) {
DL_OPEN_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
return false;
}
diff --git a/linker/linker_cfi.cpp b/linker/linker_cfi.cpp
index 6bc261545..247a25d57 100644
--- a/linker/linker_cfi.cpp
+++ b/linker/linker_cfi.cpp
@@ -50,8 +50,8 @@ class ShadowWrite {
ShadowWrite(uint16_t* s, uint16_t* e) {
shadow_start = reinterpret_cast<char*>(s);
shadow_end = reinterpret_cast<char*>(e);
- aligned_start = reinterpret_cast<char*>(PAGE_START(reinterpret_cast<uintptr_t>(shadow_start)));
- aligned_end = reinterpret_cast<char*>(PAGE_END(reinterpret_cast<uintptr_t>(shadow_end)));
+ aligned_start = reinterpret_cast<char*>(page_start(reinterpret_cast<uintptr_t>(shadow_start)));
+ aligned_end = reinterpret_cast<char*>(page_end(reinterpret_cast<uintptr_t>(shadow_end)));
tmp_start =
reinterpret_cast<char*>(mmap(nullptr, aligned_end - aligned_start, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
@@ -204,7 +204,7 @@ bool CFIShadowWriter::NotifyLibDl(soinfo* solist, uintptr_t p) {
shadow_start = reinterpret_cast<uintptr_t* (*)(uintptr_t)>(cfi_init)(p);
CHECK(shadow_start != nullptr);
CHECK(*shadow_start == p);
- mprotect(shadow_start, PAGE_SIZE, PROT_READ);
+ mprotect(shadow_start, page_size(), PROT_READ);
return true;
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 26e222876..f7c8ea959 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -580,8 +580,8 @@ static void set_bss_vma_name(soinfo* si) {
}
ElfW(Addr) seg_start = phdr->p_vaddr + si->load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(seg_start + phdr->p_memsz);
- ElfW(Addr) seg_file_end = PAGE_END(seg_start + phdr->p_filesz);
+ ElfW(Addr) seg_page_end = page_end(seg_start + phdr->p_memsz);
+ ElfW(Addr) seg_file_end = page_end(seg_start + phdr->p_filesz);
if (seg_page_end > seg_file_end) {
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
diff --git a/linker/linker_mapped_file_fragment.cpp b/linker/linker_mapped_file_fragment.cpp
index cbe5f6680..6be1b2bfe 100644
--- a/linker/linker_mapped_file_fragment.cpp
+++ b/linker/linker_mapped_file_fragment.cpp
@@ -29,6 +29,7 @@
#include "linker_mapped_file_fragment.h"
#include "linker_debug.h"
#include "linker_utils.h"
+#include "platform/bionic/page.h"
#include <inttypes.h>
#include <stdlib.h>
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 73cfced38..97ae7090f 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -116,7 +116,7 @@ static int GetTargetElfMachine() {
can only memory-map at page boundaries, this means that the bias is
computed as:
- load_bias = phdr0_load_address - PAGE_START(phdr0->p_vaddr)
+ load_bias = phdr0_load_address - page_start(phdr0->p_vaddr)
(NOTE: The value must be used as a 32-bit unsigned integer, to deal with
possible wrap around UINT32_MAX for possible large p_vaddr values).
@@ -124,11 +124,11 @@ static int GetTargetElfMachine() {
And that the phdr0_load_address must start at a page boundary, with
the segment's real content starting at:
- phdr0_load_address + PAGE_OFFSET(phdr0->p_vaddr)
+ phdr0_load_address + page_offset(phdr0->p_vaddr)
Note that ELF requires the following condition to make the mmap()-ing work:
- PAGE_OFFSET(phdr0->p_vaddr) == PAGE_OFFSET(phdr0->p_offset)
+ page_offset(phdr0->p_vaddr) == page_offset(phdr0->p_offset)
The load_bias must be added to any p_vaddr value read from the ELF file to
determine the corresponding memory address.
@@ -529,8 +529,8 @@ size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
min_vaddr = 0;
}
- min_vaddr = PAGE_START(min_vaddr);
- max_vaddr = PAGE_END(max_vaddr);
+ min_vaddr = page_start(min_vaddr);
+ max_vaddr = page_end(max_vaddr);
if (out_min_vaddr != nullptr) {
*out_min_vaddr = min_vaddr;
@@ -545,7 +545,7 @@ size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
// program header table. Used to determine whether the file should be loaded at
// a specific virtual address alignment for use with huge pages.
size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
- size_t maximum_alignment = PAGE_SIZE;
+ size_t maximum_alignment = page_size();
for (size_t i = 0; i < phdr_count; ++i) {
const ElfW(Phdr)* phdr = &phdr_table[i];
@@ -563,7 +563,7 @@ size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phd
#if defined(__LP64__)
return maximum_alignment;
#else
- return PAGE_SIZE;
+ return page_size();
#endif
}
@@ -574,7 +574,7 @@ static void* ReserveWithAlignmentPadding(size_t size, size_t mapping_align, size
int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
// Reserve enough space to properly align the library's start address.
mapping_align = std::max(mapping_align, start_align);
- if (mapping_align == PAGE_SIZE) {
+ if (mapping_align == page_size()) {
void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
if (mmap_ptr == MAP_FAILED) {
return nullptr;
@@ -593,7 +593,7 @@ static void* ReserveWithAlignmentPadding(size_t size, size_t mapping_align, size
constexpr size_t kMaxGapUnits = 32;
// Allocate enough space so that the end of the desired region aligned up is still inside the
// mapping.
- size_t mmap_size = align_up(size, mapping_align) + mapping_align - PAGE_SIZE;
+ size_t mmap_size = align_up(size, mapping_align) + mapping_align - page_size();
uint8_t* mmap_ptr =
reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
@@ -610,7 +610,7 @@ static void* ReserveWithAlignmentPadding(size_t size, size_t mapping_align, size
mapping_align = std::max(mapping_align, kGapAlignment);
gap_size =
kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
- mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - PAGE_SIZE;
+ mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - page_size();
mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
return nullptr;
@@ -665,12 +665,12 @@ bool ElfReader::ReserveAddressSpace(address_space_params* address_space) {
load_size_ - address_space->reserved_size, load_size_, name_.c_str());
return false;
}
- size_t start_alignment = PAGE_SIZE;
+ size_t start_alignment = page_size();
if (get_transparent_hugepages_supported() && get_application_target_sdk_version() >= 31) {
size_t maximum_alignment = phdr_table_get_maximum_alignment(phdr_table_, phdr_num_);
// Limit alignment to PMD size as other alignments reduce the number of
// bits available for ASLR for no benefit.
- start_alignment = maximum_alignment == kPmdSize ? kPmdSize : PAGE_SIZE;
+ start_alignment = maximum_alignment == kPmdSize ? kPmdSize : page_size();
}
start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, start_alignment, &gap_start_,
&gap_size_);
@@ -706,8 +706,8 @@ bool ElfReader::LoadSegments() {
ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
ElfW(Addr) seg_end = seg_start + phdr->p_memsz;
- ElfW(Addr) seg_page_start = PAGE_START(seg_start);
- ElfW(Addr) seg_page_end = PAGE_END(seg_end);
+ ElfW(Addr) seg_page_start = page_start(seg_start);
+ ElfW(Addr) seg_page_end = page_end(seg_end);
ElfW(Addr) seg_file_end = seg_start + phdr->p_filesz;
@@ -715,7 +715,7 @@ bool ElfReader::LoadSegments() {
ElfW(Addr) file_start = phdr->p_offset;
ElfW(Addr) file_end = file_start + phdr->p_filesz;
- ElfW(Addr) file_page_start = PAGE_START(file_start);
+ ElfW(Addr) file_page_start = page_start(file_start);
ElfW(Addr) file_length = file_end - file_page_start;
if (file_size_ <= 0) {
@@ -768,11 +768,11 @@ bool ElfReader::LoadSegments() {
// if the segment is writable, and does not end on a page boundary,
// zero-fill it until the page limit.
- if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
- memset(reinterpret_cast<void*>(seg_file_end), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
+ if ((phdr->p_flags & PF_W) != 0 && page_offset(seg_file_end) > 0) {
+ memset(reinterpret_cast<void*>(seg_file_end), 0, page_size() - page_offset(seg_file_end));
}
- seg_file_end = PAGE_END(seg_file_end);
+ seg_file_end = page_end(seg_file_end);
// seg_file_end is now the first page address after the file
// content. If seg_end is larger, we need to zero anything
@@ -811,8 +811,8 @@ static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_c
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
int prot = PFLAGS_TO_PROT(phdr->p_flags) | extra_prot_flags;
if ((prot & PROT_WRITE) != 0) {
@@ -912,8 +912,8 @@ static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t p
// the program is likely to fail at runtime. So in effect the
// linker must only emit a PT_GNU_RELRO segment if it ensures
// that it starts on a page boundary.
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
seg_page_end - seg_page_start,
@@ -972,8 +972,8 @@ int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
ssize_t size = seg_page_end - seg_page_start;
ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
@@ -1035,8 +1035,8 @@ int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
continue;
}
- ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
- ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
char* file_base = static_cast<char*>(temp_mapping) + *file_offset;
char* mem_base = reinterpret_cast<char*>(seg_page_start);
@@ -1053,15 +1053,15 @@ int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
while (match_offset < size) {
// Skip over dissimilar pages.
while (match_offset < size &&
- memcmp(mem_base + match_offset, file_base + match_offset, PAGE_SIZE) != 0) {
- match_offset += PAGE_SIZE;
+ memcmp(mem_base + match_offset, file_base + match_offset, page_size()) != 0) {
+ match_offset += page_size();
}
// Count similar pages.
size_t mismatch_offset = match_offset;
while (mismatch_offset < size &&
- memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, PAGE_SIZE) == 0) {
- mismatch_offset += PAGE_SIZE;
+ memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, page_size()) == 0) {
+ mismatch_offset += page_size();
}
// Map over similar pages.
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 29110ed56..cd03eedae 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -169,12 +169,6 @@ bool parse_zip_path(const char* input_path, std::string* zip_path, std::string*
return true;
}
-constexpr off64_t kPageMask = ~static_cast<off64_t>(PAGE_SIZE-1);
-
-off64_t page_start(off64_t offset) {
- return offset & kPageMask;
-}
-
bool safe_add(off64_t* out, off64_t a, size_t b) {
CHECK(a >= 0);
if (static_cast<uint64_t>(INT64_MAX - a) < b) {
@@ -185,10 +179,6 @@ bool safe_add(off64_t* out, off64_t a, size_t b) {
return true;
}
-size_t page_offset(off64_t offset) {
- return static_cast<size_t>(offset & (PAGE_SIZE-1));
-}
-
void split_path(const char* path, const char* delimiters,
std::vector<std::string>* paths) {
if (path != nullptr && path[0] != 0) {
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index 5073b1068..3049e5347 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -55,7 +55,5 @@ void split_path(const char* path, const char* delimiters, std::vector<std::strin
std::string dirname(const char* path);
-off64_t page_start(off64_t offset);
-size_t page_offset(off64_t offset);
bool safe_add(off64_t* out, off64_t a, size_t b);
bool is_first_stage_init();
diff --git a/linker/linker_utils_test.cpp b/linker/linker_utils_test.cpp
index 44907dabf..0b881d432 100644
--- a/linker/linker_utils_test.cpp
+++ b/linker/linker_utils_test.cpp
@@ -33,6 +33,7 @@
#include <gtest/gtest.h>
#include "linker_utils.h"
+#include "platform/bionic/page.h"
TEST(linker_utils, format_string) {
std::vector<std::pair<std::string, std::string>> params = {{ "LIB", "lib32"}, { "SDKVER", "42"}};
@@ -104,9 +105,9 @@ TEST(linker_utils, parse_zip_path_smoke) {
}
TEST(linker_utils, page_start) {
- ASSERT_EQ(0x0001000, page_start(0x0001000));
- ASSERT_EQ(0x3002000, page_start(0x300222f));
- ASSERT_EQ(0x6001000, page_start(0x6001fff));
+ ASSERT_EQ(0x0001000U, page_start(0x0001000));
+ ASSERT_EQ(0x3002000U, page_start(0x300222f));
+ ASSERT_EQ(0x6001000U, page_start(0x6001fff));
}
TEST(linker_utils, page_offset) {
diff --git a/tests/Android.bp b/tests/Android.bp
index 281e29d6a..36a3a3794 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -386,7 +386,6 @@ cc_test_library {
"bug_26110743_test.cpp",
"byteswap_test.cpp",
"complex_test.cpp",
- "complex_force_long_double_test.cpp",
"ctype_test.cpp",
"dirent_test.cpp",
"elf_test.cpp",
@@ -423,7 +422,6 @@ cc_test_library {
"malloc_iterate_test.cpp",
"malloc_test.cpp",
"math_test.cpp",
- "math_force_long_double_test.cpp",
"membarrier_test.cpp",
"memtag_stack_test.cpp",
"mntent_test.cpp",
diff --git a/tests/complex_force_long_double_test.cpp b/tests/complex_force_long_double_test.cpp
deleted file mode 100644
index 2ea7bd449..000000000
--- a/tests/complex_force_long_double_test.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-#include "complex_test.cpp"
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index f015b2c2d..6a1831f78 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -14,20 +14,11 @@
* limitations under the License.
*/
-#if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define COMPLEX_TEST complex_h_force_long_double
-#else
-#define COMPLEX_TEST complex_h
-#endif
-
// This file is compiled against both glibc and bionic, and our complex.h
// depends on bionic-specific macros, so hack around that.
#include <sys/cdefs.h>
#if !defined(__INTRODUCED_IN)
#define __INTRODUCED_IN(x)
-#define __INTRODUCED_IN_32(x)
-#define __INTRODUCED_IN_64(x)
-#define __RENAME_LDBL(a,b,c)
#endif
// libc++ actively gets in the way of including <complex.h> from C++, so we
@@ -62,259 +53,259 @@ inline void PrintTo(const long double _Complex& c, std::ostream* os) {
#include <gtest/gtest.h>
#pragma pop_macro("I")
-TEST(COMPLEX_TEST, cabs) {
+TEST(complex_h, cabs) {
ASSERT_EQ(0.0, cabs(0));
}
-TEST(COMPLEX_TEST, cabsf) {
+TEST(complex_h, cabsf) {
ASSERT_EQ(0.0, cabsf(0));
}
-TEST(COMPLEX_TEST, cabsl) {
+TEST(complex_h, cabsl) {
ASSERT_EQ(0.0, cabsl(0));
}
-TEST(COMPLEX_TEST, cacos) {
+TEST(complex_h, cacos) {
ASSERT_EQ(M_PI_2, cacos(0.0));
}
-TEST(COMPLEX_TEST, cacosf) {
+TEST(complex_h, cacosf) {
ASSERT_EQ(static_cast<float>(M_PI_2), cacosf(0.0));
}
-TEST(COMPLEX_TEST, cacosl) {
+TEST(complex_h, cacosl) {
ASSERT_EQ(M_PI_2l, cacosl(0.0));
}
-TEST(COMPLEX_TEST, cacosh) {
+TEST(complex_h, cacosh) {
ASSERT_EQ(0.0, cacosh(1.0));
}
-TEST(COMPLEX_TEST, cacoshl) {
+TEST(complex_h, cacoshl) {
ASSERT_EQ(0.0, cacoshl(1.0));
}
-TEST(COMPLEX_TEST, cacoshf) {
+TEST(complex_h, cacoshf) {
ASSERT_EQ(0.0, cacoshf(1.0));
}
-TEST(COMPLEX_TEST, carg) {
+TEST(complex_h, carg) {
ASSERT_EQ(0.0, carg(0));
}
-TEST(COMPLEX_TEST, cargf) {
+TEST(complex_h, cargf) {
ASSERT_EQ(0.0, cargf(0));
}
-TEST(COMPLEX_TEST, cargl) {
+TEST(complex_h, cargl) {
ASSERT_EQ(0.0, cargl(0));
}
-TEST(COMPLEX_TEST, casin) {
+TEST(complex_h, casin) {
ASSERT_EQ(0.0, casin(0));
}
-TEST(COMPLEX_TEST, casinf) {
+TEST(complex_h, casinf) {
ASSERT_EQ(0.0, casinf(0));
}
-TEST(COMPLEX_TEST, casinl) {
+TEST(complex_h, casinl) {
ASSERT_EQ(0.0, casinl(0));
}
-TEST(COMPLEX_TEST, casinh) {
+TEST(complex_h, casinh) {
ASSERT_EQ(0.0, casinh(0));
}
-TEST(COMPLEX_TEST, casinhf) {
+TEST(complex_h, casinhf) {
ASSERT_EQ(0.0, casinhf(0));
}
-TEST(COMPLEX_TEST, casinhl) {
+TEST(complex_h, casinhl) {
ASSERT_EQ(0.0, casinhl(0));
}
-TEST(COMPLEX_TEST, catan) {
+TEST(complex_h, catan) {
ASSERT_EQ(0.0, catan(0));
}
-TEST(COMPLEX_TEST, catanf) {
+TEST(complex_h, catanf) {
ASSERT_EQ(0.0, catanf(0));
}
-TEST(COMPLEX_TEST, catanl) {
+TEST(complex_h, catanl) {
ASSERT_EQ(0.0, catanl(0));
}
-TEST(COMPLEX_TEST, catanh) {
+TEST(complex_h, catanh) {
ASSERT_EQ(0.0, catanh(0));
}
-TEST(COMPLEX_TEST, catanhf) {
+TEST(complex_h, catanhf) {
ASSERT_EQ(0.0, catanhf(0));
}
-TEST(COMPLEX_TEST, catanhl) {
+TEST(complex_h, catanhl) {
ASSERT_EQ(0.0, catanhl(0));
}
-TEST(COMPLEX_TEST, ccos) {
+TEST(complex_h, ccos) {
ASSERT_EQ(1.0, ccos(0));
}
-TEST(COMPLEX_TEST, ccosf) {
+TEST(complex_h, ccosf) {
ASSERT_EQ(1.0, ccosf(0));
}
-TEST(COMPLEX_TEST, ccosl) {
+TEST(complex_h, ccosl) {
ASSERT_EQ(1.0, ccosl(0));
}
-TEST(COMPLEX_TEST, ccosh) {
+TEST(complex_h, ccosh) {
ASSERT_EQ(1.0, ccosh(0));
}
-TEST(COMPLEX_TEST, ccoshf) {
+TEST(complex_h, ccoshf) {
ASSERT_EQ(1.0, ccoshf(0));
}
-TEST(COMPLEX_TEST, ccoshl) {
+TEST(complex_h, ccoshl) {
ASSERT_EQ(1.0, ccoshl(0));
}
-TEST(COMPLEX_TEST, cexp) {
+TEST(complex_h, cexp) {
ASSERT_EQ(1.0, cexp(0));
}
-TEST(COMPLEX_TEST, cexpf) {
+TEST(complex_h, cexpf) {
ASSERT_EQ(1.0, cexpf(0));
}
-TEST(COMPLEX_TEST, cexpl) {
+TEST(complex_h, cexpl) {
ASSERT_EQ(1.0, cexpl(0));
}
-TEST(COMPLEX_TEST, cimag) {
+TEST(complex_h, cimag) {
ASSERT_EQ(0.0, cimag(0));
}
-TEST(COMPLEX_TEST, cimagf) {
+TEST(complex_h, cimagf) {
ASSERT_EQ(0.0f, cimagf(0));
}
-TEST(COMPLEX_TEST, cimagl) {
+TEST(complex_h, cimagl) {
ASSERT_EQ(0.0, cimagl(0));
}
-TEST(COMPLEX_TEST, clog) {
+TEST(complex_h, clog) {
ASSERT_EQ(0.0, clog(1.0));
}
-TEST(COMPLEX_TEST, clogf) {
+TEST(complex_h, clogf) {
ASSERT_EQ(0.0f, clogf(1.0f));
}
-TEST(COMPLEX_TEST, clogl) {
+TEST(complex_h, clogl) {
ASSERT_EQ(0.0L, clogl(1.0L));
}
-TEST(COMPLEX_TEST, conj) {
+TEST(complex_h, conj) {
ASSERT_EQ(0.0, conj(0));
}
-TEST(COMPLEX_TEST, conjf) {
+TEST(complex_h, conjf) {
ASSERT_EQ(0.0f, conjf(0));
}
-TEST(COMPLEX_TEST, conjl) {
+TEST(complex_h, conjl) {
ASSERT_EQ(0.0, conjl(0));
}
-TEST(COMPLEX_TEST, cpow) {
+TEST(complex_h, cpow) {
ASSERT_EQ(8.0, cpow(2.0, 3.0));
}
-TEST(COMPLEX_TEST, cpowf) {
+TEST(complex_h, cpowf) {
ASSERT_EQ(8.0f, cpowf(2.0f, 3.0f));
}
-TEST(COMPLEX_TEST, cpowl) {
+TEST(complex_h, cpowl) {
ASSERT_EQ(8.0L, cpowl(2.0L, 3.0L));
}
-TEST(COMPLEX_TEST, cproj) {
+TEST(complex_h, cproj) {
ASSERT_EQ(0.0, cproj(0));
}
-TEST(COMPLEX_TEST, cprojf) {
+TEST(complex_h, cprojf) {
ASSERT_EQ(0.0f, cprojf(0));
}
-TEST(COMPLEX_TEST, cprojl) {
+TEST(complex_h, cprojl) {
ASSERT_EQ(0.0, cprojl(0));
}
-TEST(COMPLEX_TEST, creal) {
+TEST(complex_h, creal) {
ASSERT_EQ(2.0, creal(2.0 + 3.0I));
}
-TEST(COMPLEX_TEST, crealf) {
+TEST(complex_h, crealf) {
ASSERT_EQ(2.0f, crealf(2.0f + 3.0fI));
}
-TEST(COMPLEX_TEST, creall) {
+TEST(complex_h, creall) {
ASSERT_EQ(2.0, creall(2.0L + 3.0LI));
}
-TEST(COMPLEX_TEST, csin) {
+TEST(complex_h, csin) {
ASSERT_EQ(0.0, csin(0));
}
-TEST(COMPLEX_TEST, csinf) {
+TEST(complex_h, csinf) {
ASSERT_EQ(0.0, csinf(0));
}
-TEST(COMPLEX_TEST, csinl) {
+TEST(complex_h, csinl) {
ASSERT_EQ(0.0, csinl(0));
}
-TEST(COMPLEX_TEST, csinh) {
+TEST(complex_h, csinh) {
ASSERT_EQ(0.0, csinh(0));
}
-TEST(COMPLEX_TEST, csinhf) {
+TEST(complex_h, csinhf) {
ASSERT_EQ(0.0, csinhf(0));
}
-TEST(COMPLEX_TEST, csinhl) {
+TEST(complex_h, csinhl) {
ASSERT_EQ(0.0, csinhl(0));
}
-TEST(COMPLEX_TEST, csqrt) {
+TEST(complex_h, csqrt) {
ASSERT_EQ(0.0, csqrt(0));
}
-TEST(COMPLEX_TEST, csqrtf) {
+TEST(complex_h, csqrtf) {
ASSERT_EQ(0.0f, csqrtf(0));
}
-TEST(COMPLEX_TEST, csqrtl) {
+TEST(complex_h, csqrtl) {
ASSERT_EQ(0.0, csqrtl(0));
}
-TEST(COMPLEX_TEST, ctan) {
+TEST(complex_h, ctan) {
ASSERT_EQ(0.0, ctan(0));
}
-TEST(COMPLEX_TEST, ctanf) {
+TEST(complex_h, ctanf) {
ASSERT_EQ(0.0, ctanf(0));
}
-TEST(COMPLEX_TEST, ctanl) {
+TEST(complex_h, ctanl) {
ASSERT_EQ(0.0, ctanl(0));
}
-TEST(COMPLEX_TEST, ctanh) {
+TEST(complex_h, ctanh) {
ASSERT_EQ(0.0, ctanh(0));
double complex z;
@@ -335,7 +326,7 @@ TEST(COMPLEX_TEST, ctanh) {
ASSERT_TRUE(isnan(cimag(z)));
}
-TEST(COMPLEX_TEST, ctanhf) {
+TEST(complex_h, ctanhf) {
ASSERT_EQ(0.0f, ctanhf(0.0f));
float complex z;
@@ -356,7 +347,7 @@ TEST(COMPLEX_TEST, ctanhf) {
ASSERT_TRUE(isnan(cimagf(z)));
}
-TEST(COMPLEX_TEST, ctanhl) {
+TEST(complex_h, ctanhl) {
ASSERT_EQ(0.0L, ctanhl(0.0L));
long double complex z;
diff --git a/tests/math_force_long_double_test.cpp b/tests/math_force_long_double_test.cpp
deleted file mode 100644
index 432182b72..000000000
--- a/tests/math_force_long_double_test.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#define __BIONIC_LP32_USE_LONG_DOUBLE
-#include "math_test.cpp"
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 60872f373..493f3aff7 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -48,12 +48,6 @@ template<typename T> inline int test_capture_isinf(const T in) {
}
}
-#if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
-#define MATH_TEST math_h_force_long_double
-#else
-#define MATH_TEST math_h
-#endif
-
#include "math_data_test.h"
#include <gtest/gtest.h>
@@ -103,7 +97,7 @@ static long double ldouble_subnormal() {
return u.e;
}
-TEST(MATH_TEST, fpclassify) {
+TEST(math_h, fpclassify) {
ASSERT_EQ(FP_INFINITE, fpclassify(INFINITY));
ASSERT_EQ(FP_INFINITE, fpclassify(HUGE_VALF));
ASSERT_EQ(FP_INFINITE, fpclassify(-HUGE_VALF));
@@ -129,7 +123,7 @@ TEST(MATH_TEST, fpclassify) {
ASSERT_EQ(FP_ZERO, fpclassify(0.0L));
}
-TEST(MATH_TEST, isfinite) {
+TEST(math_h, isfinite) {
ASSERT_TRUE(test_capture_isfinite(123.0f));
ASSERT_TRUE(test_capture_isfinite(123.0));
ASSERT_TRUE(test_capture_isfinite(123.0L));
@@ -141,7 +135,7 @@ TEST(MATH_TEST, isfinite) {
ASSERT_FALSE(test_capture_isfinite(-HUGE_VALL));
}
-TEST(MATH_TEST, isinf) {
+TEST(math_h, isinf) {
ASSERT_FALSE(test_capture_isinf(123.0f));
ASSERT_FALSE(test_capture_isinf(123.0));
ASSERT_FALSE(test_capture_isinf(123.0L));
@@ -153,7 +147,7 @@ TEST(MATH_TEST, isinf) {
ASSERT_TRUE(test_capture_isinf(-HUGE_VALL));
}
-TEST(MATH_TEST, isnan) {
+TEST(math_h, isnan) {
ASSERT_FALSE(test_capture_isnan(123.0f));
ASSERT_FALSE(test_capture_isnan(123.0));
ASSERT_FALSE(test_capture_isnan(123.0L));
@@ -162,7 +156,7 @@ TEST(MATH_TEST, isnan) {
ASSERT_TRUE(test_capture_isnan(nanl("")));
}
-TEST(MATH_TEST, isnormal) {
+TEST(math_h, isnormal) {
ASSERT_TRUE(isnormal(123.0f));
ASSERT_TRUE(isnormal(123.0));
ASSERT_TRUE(isnormal(123.0L));
@@ -172,7 +166,7 @@ TEST(MATH_TEST, isnormal) {
}
// TODO: isgreater, isgreaterequals, isless, islessequal, islessgreater, isunordered
-TEST(MATH_TEST, signbit) {
+TEST(math_h, signbit) {
ASSERT_EQ(0, test_capture_signbit(0.0f));
ASSERT_EQ(0, test_capture_signbit(0.0));
ASSERT_EQ(0, test_capture_signbit(0.0L));
@@ -192,7 +186,7 @@ extern "C" int __fpclassifyd(double);
extern "C" int __fpclassifyf(float);
extern "C" int __fpclassifyl(long double);
-TEST(MATH_TEST, __fpclassify) {
+TEST(math_h, __fpclassify) {
ASSERT_EQ(FP_INFINITE, __fpclassify(HUGE_VAL));
ASSERT_EQ(FP_INFINITE, __fpclassify(-HUGE_VAL));
ASSERT_EQ(FP_NAN, __fpclassify(nan("")));
@@ -201,7 +195,7 @@ TEST(MATH_TEST, __fpclassify) {
ASSERT_EQ(FP_ZERO, __fpclassify(0.0));
}
-TEST(MATH_TEST, __fpclassifyd) {
+TEST(math_h, __fpclassifyd) {
#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
#define __fpclassifyd __fpclassify
#endif
@@ -213,7 +207,7 @@ TEST(MATH_TEST, __fpclassifyd) {
ASSERT_EQ(FP_ZERO, __fpclassifyd(0.0));
}
-TEST(MATH_TEST, __fpclassifyf) {
+TEST(math_h, __fpclassifyf) {
ASSERT_EQ(FP_INFINITE, __fpclassifyf(HUGE_VALF));
ASSERT_EQ(FP_INFINITE, __fpclassifyf(-HUGE_VALF));
ASSERT_EQ(FP_NAN, __fpclassifyf(nanf("")));
@@ -222,7 +216,7 @@ TEST(MATH_TEST, __fpclassifyf) {
ASSERT_EQ(FP_ZERO, __fpclassifyf(0.0f));
}
-TEST(MATH_TEST, __fpclassifyl) {
+TEST(math_h, __fpclassifyl) {
EXPECT_EQ(FP_INFINITE, __fpclassifyl(HUGE_VALL));
EXPECT_EQ(FP_INFINITE, __fpclassifyl(-HUGE_VALL));
EXPECT_EQ(FP_NAN, __fpclassifyl(nanl("")));
@@ -231,7 +225,7 @@ TEST(MATH_TEST, __fpclassifyl) {
EXPECT_EQ(FP_ZERO, __fpclassifyl(0.0L));
}
-TEST(MATH_TEST, finitef) {
+TEST(math_h, finitef) {
ASSERT_TRUE(finitef(123.0f));
ASSERT_FALSE(finitef(HUGE_VALF));
ASSERT_FALSE(finitef(-HUGE_VALF));
@@ -244,7 +238,7 @@ extern "C" int isfinitef(float);
extern "C" int __isfinitel(long double);
extern "C" int isfinitel(long double);
-TEST(MATH_TEST, __isfinite) {
+TEST(math_h, __isfinite) {
#if defined(__GLIBC__)
#define __isfinite __finite
#elif defined(ANDROID_HOST_MUSL)
@@ -255,7 +249,7 @@ TEST(MATH_TEST, __isfinite) {
ASSERT_FALSE(__isfinite(-HUGE_VAL));
}
-TEST(MATH_TEST, __isfinitef) {
+TEST(math_h, __isfinitef) {
#if defined(__GLIBC__)
#define __isfinitef __finitef
#elif defined(ANDROID_HOST_MUSL)
@@ -266,7 +260,7 @@ TEST(MATH_TEST, __isfinitef) {
ASSERT_FALSE(__isfinitef(-HUGE_VALF));
}
-TEST(MATH_TEST, isfinitef) {
+TEST(math_h, isfinitef) {
#if defined(__GLIBC__)
#define isfinitef __finitef
#elif defined(ANDROID_HOST_MUSL)
@@ -277,7 +271,7 @@ TEST(MATH_TEST, isfinitef) {
ASSERT_FALSE(isfinitef(-HUGE_VALF));
}
-TEST(MATH_TEST, __isfinitel) {
+TEST(math_h, __isfinitel) {
#if defined(__GLIBC__)
#define __isfinitel __finitel
#elif defined(ANDROID_HOST_MUSL)
@@ -288,7 +282,7 @@ TEST(MATH_TEST, __isfinitel) {
ASSERT_FALSE(__isfinitel(-HUGE_VALL));
}
-TEST(MATH_TEST, isfinitel) {
+TEST(math_h, isfinitel) {
#if defined(__GLIBC__)
#define isfinitel __finitel
#elif defined(ANDROID_HOST_MUSL)
@@ -299,13 +293,13 @@ TEST(MATH_TEST, isfinitel) {
ASSERT_FALSE(isfinitel(-HUGE_VALL));
}
-TEST(MATH_TEST, finite) {
+TEST(math_h, finite) {
ASSERT_TRUE(finite(123.0));
ASSERT_FALSE(finite(HUGE_VAL));
ASSERT_FALSE(finite(-HUGE_VAL));
}
-TEST(MATH_TEST, isinf_function) {
+TEST(math_h, isinf_function) {
// The isinf macro deals with all three types; the isinf function is for doubles.
ASSERT_FALSE((isinf)(123.0));
ASSERT_TRUE((isinf)(HUGE_VAL));
@@ -319,7 +313,7 @@ extern "C" int isinff(float);
extern "C" int __isinfl(long double);
extern "C" int isinfl(long double);
-TEST(MATH_TEST, __isinf) {
+TEST(math_h, __isinf) {
#if defined(ANDROID_HOST_MUSL)
#define __isinf isinf
#endif
@@ -328,7 +322,7 @@ TEST(MATH_TEST, __isinf) {
ASSERT_TRUE(__isinf(-HUGE_VAL));
}
-TEST(MATH_TEST, __isinff) {
+TEST(math_h, __isinff) {
#if defined(ANDROID_HOST_MUSL)
#define __isinff isinf
#endif
@@ -337,7 +331,7 @@ TEST(MATH_TEST, __isinff) {
ASSERT_TRUE(__isinff(-HUGE_VALF));
}
-TEST(MATH_TEST, isinff) {
+TEST(math_h, isinff) {
#if defined(ANDROID_HOST_MUSL)
#define isinff isinf
#endif
@@ -346,7 +340,7 @@ TEST(MATH_TEST, isinff) {
ASSERT_TRUE(isinff(-HUGE_VALF));
}
-TEST(MATH_TEST, __isinfl) {
+TEST(math_h, __isinfl) {
#if defined(ANDROID_HOST_MUSL)
#define __isinfl isinf
#endif
@@ -355,7 +349,7 @@ TEST(MATH_TEST, __isinfl) {
ASSERT_TRUE(__isinfl(-HUGE_VALL));
}
-TEST(MATH_TEST, isinfl) {
+TEST(math_h, isinfl) {
#if defined(ANDROID_HOST_MUSL)
#define isinfl isinf
#endif
@@ -364,7 +358,7 @@ TEST(MATH_TEST, isinfl) {
ASSERT_TRUE(isinfl(-HUGE_VALL));
}
-TEST(MATH_TEST, isnan_function) {
+TEST(math_h, isnan_function) {
// The isnan macro deals with all three types; the isnan function is for doubles.
ASSERT_FALSE((isnan)(123.0));
ASSERT_TRUE((isnan)(nan("")));
@@ -377,7 +371,7 @@ extern "C" int isnanf(float);
extern "C" int __isnanl(long double);
extern "C" int isnanl(long double);
-TEST(MATH_TEST, __isnan) {
+TEST(math_h, __isnan) {
#if defined(ANDROID_HOST_MUSL)
#define __isnan isnan
#endif
@@ -385,7 +379,7 @@ TEST(MATH_TEST, __isnan) {
ASSERT_TRUE(__isnan(nan("")));
}
-TEST(MATH_TEST, __isnanf) {
+TEST(math_h, __isnanf) {
#if defined(ANDROID_HOST_MUSL)
#define __isnanf isnan
#endif
@@ -393,7 +387,7 @@ TEST(MATH_TEST, __isnanf) {
ASSERT_TRUE(__isnanf(nanf("")));
}
-TEST(MATH_TEST, isnanf) {
+TEST(math_h, isnanf) {
#if defined(ANDROID_HOST_MUSL)
#define isnanf isnan
#endif
@@ -401,7 +395,7 @@ TEST(MATH_TEST, isnanf) {
ASSERT_TRUE(isnanf(nanf("")));
}
-TEST(MATH_TEST, __isnanl) {
+TEST(math_h, __isnanl) {
#if defined(ANDROID_HOST_MUSL)
#define __isnanl isnan
#endif
@@ -409,7 +403,7 @@ TEST(MATH_TEST, __isnanl) {
ASSERT_TRUE(__isnanl(nanl("")));
}
-TEST(MATH_TEST, isnanl) {
+TEST(math_h, isnanl) {
#if defined(ANDROID_HOST_MUSL)
#define isnanl isnan
#endif
@@ -424,7 +418,7 @@ extern "C" int isnormalf(float);
extern "C" int __isnormall(long double);
extern "C" int isnormall(long double);
-TEST(MATH_TEST, __isnormal) {
+TEST(math_h, __isnormal) {
#if defined(__BIONIC__)
ASSERT_TRUE(__isnormal(123.0));
ASSERT_FALSE(__isnormal(double_subnormal()));
@@ -433,7 +427,7 @@ TEST(MATH_TEST, __isnormal) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, __isnormalf) {
+TEST(math_h, __isnormalf) {
#if defined(__BIONIC__)
ASSERT_TRUE(__isnormalf(123.0f));
ASSERT_FALSE(__isnormalf(float_subnormal()));
@@ -442,7 +436,7 @@ TEST(MATH_TEST, __isnormalf) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, isnormalf) {
+TEST(math_h, isnormalf) {
#if defined(__BIONIC__)
ASSERT_TRUE(isnormalf(123.0f));
ASSERT_FALSE(isnormalf(float_subnormal()));
@@ -451,7 +445,7 @@ TEST(MATH_TEST, isnormalf) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, __isnormall) {
+TEST(math_h, __isnormall) {
#if defined(__BIONIC__)
ASSERT_TRUE(__isnormall(123.0L));
ASSERT_FALSE(__isnormall(ldouble_subnormal()));
@@ -460,7 +454,7 @@ TEST(MATH_TEST, __isnormall) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, isnormall) {
+TEST(math_h, isnormall) {
#if defined(__BIONIC__)
ASSERT_TRUE(isnormall(123.0L));
ASSERT_FALSE(isnormall(ldouble_subnormal()));
@@ -474,370 +468,370 @@ extern "C" int __signbit(double);
extern "C" int __signbitf(float);
extern "C" int __signbitl(long double);
-TEST(MATH_TEST, __signbit) {
+TEST(math_h, __signbit) {
ASSERT_EQ(0, __signbit(0.0));
ASSERT_EQ(0, __signbit(1.0));
ASSERT_NE(0, __signbit(-1.0));
}
-TEST(MATH_TEST, __signbitf) {
+TEST(math_h, __signbitf) {
ASSERT_EQ(0, __signbitf(0.0f));
ASSERT_EQ(0, __signbitf(1.0f));
ASSERT_NE(0, __signbitf(-1.0f));
}
-TEST(MATH_TEST, __signbitl) {
+TEST(math_h, __signbitl) {
ASSERT_EQ(0L, __signbitl(0.0L));
ASSERT_EQ(0L, __signbitl(1.0L));
ASSERT_NE(0L, __signbitl(-1.0L));
}
-TEST(MATH_TEST, acos) {
+TEST(math_h, acos) {
ASSERT_DOUBLE_EQ(M_PI/2.0, acos(0.0));
}
-TEST(MATH_TEST, acosf) {
+TEST(math_h, acosf) {
ASSERT_FLOAT_EQ(static_cast<float>(M_PI)/2.0f, acosf(0.0f));
}
-TEST(MATH_TEST, acosl) {
+TEST(math_h, acosl) {
ASSERT_DOUBLE_EQ(M_PI/2.0L, acosl(0.0L));
}
-TEST(MATH_TEST, asin) {
+TEST(math_h, asin) {
ASSERT_DOUBLE_EQ(0.0, asin(0.0));
}
-TEST(MATH_TEST, asinf) {
+TEST(math_h, asinf) {
ASSERT_FLOAT_EQ(0.0f, asinf(0.0f));
}
-TEST(MATH_TEST, asinl) {
+TEST(math_h, asinl) {
ASSERT_DOUBLE_EQ(0.0L, asinl(0.0L));
}
-TEST(MATH_TEST, atan) {
+TEST(math_h, atan) {
ASSERT_DOUBLE_EQ(0.0, atan(0.0));
}
-TEST(MATH_TEST, atanf) {
+TEST(math_h, atanf) {
ASSERT_FLOAT_EQ(0.0f, atanf(0.0f));
}
-TEST(MATH_TEST, atanl) {
+TEST(math_h, atanl) {
ASSERT_DOUBLE_EQ(0.0L, atanl(0.0L));
}
-TEST(MATH_TEST, atan2) {
+TEST(math_h, atan2) {
ASSERT_DOUBLE_EQ(0.0, atan2(0.0, 0.0));
}
-TEST(MATH_TEST, atan2f) {
+TEST(math_h, atan2f) {
ASSERT_FLOAT_EQ(0.0f, atan2f(0.0f, 0.0f));
}
-TEST(MATH_TEST, atan2l) {
+TEST(math_h, atan2l) {
ASSERT_DOUBLE_EQ(0.0L, atan2l(0.0L, 0.0L));
}
-TEST(MATH_TEST, cos) {
+TEST(math_h, cos) {
ASSERT_DOUBLE_EQ(1.0, cos(0.0));
}
-TEST(MATH_TEST, cosf) {
+TEST(math_h, cosf) {
ASSERT_FLOAT_EQ(1.0f, cosf(0.0f));
}
-TEST(MATH_TEST, cosl) {
+TEST(math_h, cosl) {
ASSERT_DOUBLE_EQ(1.0L, cosl(0.0L));
}
-TEST(MATH_TEST, sin) {
+TEST(math_h, sin) {
ASSERT_DOUBLE_EQ(0.0, sin(0.0));
}
-TEST(MATH_TEST, sinf) {
+TEST(math_h, sinf) {
ASSERT_FLOAT_EQ(0.0f, sinf(0.0f));
}
-TEST(MATH_TEST, sinl) {
+TEST(math_h, sinl) {
ASSERT_DOUBLE_EQ(0.0L, sinl(0.0L));
}
-TEST(MATH_TEST, sincos) {
+TEST(math_h, sincos) {
double s, c;
sincos(0.0, &s, &c);
ASSERT_DOUBLE_EQ(0.0, s);
ASSERT_DOUBLE_EQ(1.0, c);
}
-TEST(MATH_TEST, sincosf) {
+TEST(math_h, sincosf) {
float s, c;
sincosf(0.0f, &s, &c);
ASSERT_FLOAT_EQ(0.0f, s);
ASSERT_FLOAT_EQ(1.0f, c);
}
-TEST(MATH_TEST, sincosl) {
+TEST(math_h, sincosl) {
long double s, c;
sincosl(0.0L, &s, &c);
ASSERT_DOUBLE_EQ(0.0L, s);
ASSERT_DOUBLE_EQ(1.0L, c);
}
-TEST(MATH_TEST, tan) {
+TEST(math_h, tan) {
ASSERT_DOUBLE_EQ(0.0, tan(0.0));
}
-TEST(MATH_TEST, tanf) {
+TEST(math_h, tanf) {
ASSERT_FLOAT_EQ(0.0f, tanf(0.0f));
}
-TEST(MATH_TEST, tanl) {
+TEST(math_h, tanl) {
ASSERT_DOUBLE_EQ(0.0L, tanl(0.0L));
}
-TEST(MATH_TEST, acosh) {
+TEST(math_h, acosh) {
ASSERT_DOUBLE_EQ(0.0, acosh(1.0));
}
-TEST(MATH_TEST, acoshf) {
+TEST(math_h, acoshf) {
ASSERT_FLOAT_EQ(0.0f, acoshf(1.0f));
}
-TEST(MATH_TEST, acoshl) {
+TEST(math_h, acoshl) {
ASSERT_DOUBLE_EQ(0.0L, acoshl(1.0L));
}
-TEST(MATH_TEST, asinh) {
+TEST(math_h, asinh) {
ASSERT_DOUBLE_EQ(0.0, asinh(0.0));
}
-TEST(MATH_TEST, asinhf) {
+TEST(math_h, asinhf) {
ASSERT_FLOAT_EQ(0.0f, asinhf(0.0f));
}
-TEST(MATH_TEST, asinhl) {
+TEST(math_h, asinhl) {
ASSERT_DOUBLE_EQ(0.0L, asinhl(0.0L));
}
-TEST(MATH_TEST, atanh) {
+TEST(math_h, atanh) {
ASSERT_DOUBLE_EQ(0.0, atanh(0.0));
}
-TEST(MATH_TEST, atanhf) {
+TEST(math_h, atanhf) {
ASSERT_FLOAT_EQ(0.0f, atanhf(0.0f));
}
-TEST(MATH_TEST, atanhl) {
+TEST(math_h, atanhl) {
ASSERT_DOUBLE_EQ(0.0L, atanhl(0.0L));
}
-TEST(MATH_TEST, cosh) {
+TEST(math_h, cosh) {
ASSERT_DOUBLE_EQ(1.0, cosh(0.0));
}
-TEST(MATH_TEST, coshf) {
+TEST(math_h, coshf) {
ASSERT_FLOAT_EQ(1.0f, coshf(0.0f));
}
-TEST(MATH_TEST, coshl) {
+TEST(math_h, coshl) {
ASSERT_DOUBLE_EQ(1.0L, coshl(0.0L));
}
-TEST(MATH_TEST, sinh) {
+TEST(math_h, sinh) {
ASSERT_DOUBLE_EQ(0.0, sinh(0.0));
}
-TEST(MATH_TEST, sinhf) {
+TEST(math_h, sinhf) {
ASSERT_FLOAT_EQ(0.0f, sinhf(0.0f));
}
-TEST(MATH_TEST, sinhl) {
+TEST(math_h, sinhl) {
ASSERT_DOUBLE_EQ(0.0L, sinhl(0.0L));
}
-TEST(MATH_TEST, tanh) {
+TEST(math_h, tanh) {
ASSERT_DOUBLE_EQ(0.0, tanh(0.0));
}
-TEST(MATH_TEST, tanhf) {
+TEST(math_h, tanhf) {
ASSERT_FLOAT_EQ(0.0f, tanhf(0.0f));
}
-TEST(MATH_TEST, tanhl) {
+TEST(math_h, tanhl) {
ASSERT_DOUBLE_EQ(0.0L, tanhl(0.0L));
}
-TEST(MATH_TEST, log) {
+TEST(math_h, log) {
ASSERT_DOUBLE_EQ(1.0, log(M_E));
}
-TEST(MATH_TEST, logf) {
+TEST(math_h, logf) {
ASSERT_FLOAT_EQ(1.0f, logf(static_cast<float>(M_E)));
}
-TEST(MATH_TEST, logl) {
+TEST(math_h, logl) {
ASSERT_DOUBLE_EQ(1.0L, logl(M_E));
}
-TEST(MATH_TEST, log2) {
+TEST(math_h, log2) {
ASSERT_DOUBLE_EQ(12.0, log2(4096.0));
}
-TEST(MATH_TEST, log2f) {
+TEST(math_h, log2f) {
ASSERT_FLOAT_EQ(12.0f, log2f(4096.0f));
}
-TEST(MATH_TEST, log2l) {
+TEST(math_h, log2l) {
ASSERT_DOUBLE_EQ(12.0L, log2l(4096.0L));
}
-TEST(MATH_TEST, log10) {
+TEST(math_h, log10) {
ASSERT_DOUBLE_EQ(3.0, log10(1000.0));
}
-TEST(MATH_TEST, log10f) {
+TEST(math_h, log10f) {
ASSERT_FLOAT_EQ(3.0f, log10f(1000.0f));
}
-TEST(MATH_TEST, log10l) {
+TEST(math_h, log10l) {
ASSERT_DOUBLE_EQ(3.0L, log10l(1000.0L));
}
-TEST(MATH_TEST, cbrt) {
+TEST(math_h, cbrt) {
ASSERT_DOUBLE_EQ(3.0, cbrt(27.0));
}
-TEST(MATH_TEST, cbrtf) {
+TEST(math_h, cbrtf) {
ASSERT_FLOAT_EQ(3.0f, cbrtf(27.0f));
}
-TEST(MATH_TEST, cbrtl) {
+TEST(math_h, cbrtl) {
ASSERT_DOUBLE_EQ(3.0L, cbrtl(27.0L));
}
-TEST(MATH_TEST, sqrt) {
+TEST(math_h, sqrt) {
ASSERT_DOUBLE_EQ(2.0, sqrt(4.0));
}
-TEST(MATH_TEST, sqrtf) {
+TEST(math_h, sqrtf) {
ASSERT_FLOAT_EQ(2.0f, sqrtf(4.0f));
}
-TEST(MATH_TEST, sqrtl) {
+TEST(math_h, sqrtl) {
ASSERT_DOUBLE_EQ(2.0L, sqrtl(4.0L));
}
-TEST(MATH_TEST, exp) {
+TEST(math_h, exp) {
ASSERT_DOUBLE_EQ(1.0, exp(0.0));
ASSERT_DOUBLE_EQ(M_E, exp(1.0));
}
-TEST(MATH_TEST, expf) {
+TEST(math_h, expf) {
ASSERT_FLOAT_EQ(1.0f, expf(0.0f));
ASSERT_FLOAT_EQ(static_cast<float>(M_E), expf(1.0f));
}
-TEST(MATH_TEST, expl) {
+TEST(math_h, expl) {
ASSERT_DOUBLE_EQ(1.0L, expl(0.0L));
ASSERT_DOUBLE_EQ(M_E, expl(1.0L));
}
-TEST(MATH_TEST, exp2) {
+TEST(math_h, exp2) {
ASSERT_DOUBLE_EQ(8.0, exp2(3.0));
}
-TEST(MATH_TEST, exp2f) {
+TEST(math_h, exp2f) {
ASSERT_FLOAT_EQ(8.0f, exp2f(3.0f));
}
-TEST(MATH_TEST, exp2l) {
+TEST(math_h, exp2l) {
ASSERT_DOUBLE_EQ(8.0L, exp2l(3.0L));
}
-TEST(MATH_TEST, expm1) {
+TEST(math_h, expm1) {
ASSERT_DOUBLE_EQ(M_E - 1.0, expm1(1.0));
}
-TEST(MATH_TEST, expm1f) {
+TEST(math_h, expm1f) {
ASSERT_FLOAT_EQ(static_cast<float>(M_E) - 1.0f, expm1f(1.0f));
}
-TEST(MATH_TEST, expm1l) {
+TEST(math_h, expm1l) {
ASSERT_DOUBLE_EQ(M_E - 1.0L, expm1l(1.0L));
}
-TEST(MATH_TEST, pow) {
+TEST(math_h, pow) {
ASSERT_TRUE(isnan(pow(nan(""), 3.0)));
ASSERT_DOUBLE_EQ(1.0, (pow(1.0, nan(""))));
ASSERT_TRUE(isnan(pow(2.0, nan(""))));
ASSERT_DOUBLE_EQ(8.0, pow(2.0, 3.0));
}
-TEST(MATH_TEST, powf) {
+TEST(math_h, powf) {
ASSERT_TRUE(isnanf(powf(nanf(""), 3.0f)));
ASSERT_FLOAT_EQ(1.0f, (powf(1.0f, nanf(""))));
ASSERT_TRUE(isnanf(powf(2.0f, nanf(""))));
ASSERT_FLOAT_EQ(8.0f, powf(2.0f, 3.0f));
}
-TEST(MATH_TEST, powl) {
+TEST(math_h, powl) {
ASSERT_TRUE(__isnanl(powl(nanl(""), 3.0L)));
ASSERT_DOUBLE_EQ(1.0L, (powl(1.0L, nanl(""))));
ASSERT_TRUE(__isnanl(powl(2.0L, nanl(""))));
ASSERT_DOUBLE_EQ(8.0L, powl(2.0L, 3.0L));
}
-TEST(MATH_TEST, ceil) {
+TEST(math_h, ceil) {
ASSERT_DOUBLE_EQ(1.0, ceil(0.9));
}
-TEST(MATH_TEST, ceilf) {
+TEST(math_h, ceilf) {
ASSERT_FLOAT_EQ(1.0f, ceilf(0.9f));
}
-TEST(MATH_TEST, ceill) {
+TEST(math_h, ceill) {
ASSERT_DOUBLE_EQ(1.0L, ceill(0.9L));
}
-TEST(MATH_TEST, floor) {
+TEST(math_h, floor) {
ASSERT_DOUBLE_EQ(1.0, floor(1.1));
}
-TEST(MATH_TEST, floorf) {
+TEST(math_h, floorf) {
ASSERT_FLOAT_EQ(1.0f, floorf(1.1f));
}
-TEST(MATH_TEST, floorl) {
+TEST(math_h, floorl) {
ASSERT_DOUBLE_EQ(1.0L, floorl(1.1L));
}
-TEST(MATH_TEST, fabs) {
+TEST(math_h, fabs) {
ASSERT_DOUBLE_EQ(1.0, fabs(-1.0));
}
-TEST(MATH_TEST, fabsf) {
+TEST(math_h, fabsf) {
ASSERT_FLOAT_EQ(1.0f, fabsf(-1.0f));
}
-TEST(MATH_TEST, fabsl) {
+TEST(math_h, fabsl) {
ASSERT_DOUBLE_EQ(1.0L, fabsl(-1.0L));
}
-TEST(MATH_TEST, ldexp) {
+TEST(math_h, ldexp) {
ASSERT_DOUBLE_EQ(16.0, ldexp(2.0, 3.0));
}
-TEST(MATH_TEST, ldexpf) {
+TEST(math_h, ldexpf) {
ASSERT_FLOAT_EQ(16.0f, ldexpf(2.0f, 3.0f));
}
-TEST(MATH_TEST, ldexpl) {
+TEST(math_h, ldexpl) {
ASSERT_DOUBLE_EQ(16.0L, ldexpl(2.0L, 3.0));
}
-TEST(MATH_TEST, fmod) {
+TEST(math_h, fmod) {
ASSERT_DOUBLE_EQ(2.0, fmod(12.0, 10.0));
// If x is an infinity, NaN is returned.
@@ -852,7 +846,7 @@ TEST(MATH_TEST, fmod) {
ASSERT_TRUE(isnan(fmod(3.0, 0.0)));
}
-TEST(MATH_TEST, fmodf) {
+TEST(math_h, fmodf) {
ASSERT_FLOAT_EQ(2.0f, fmodf(12.0f, 10.0f));
// If x is an infinity, NaN is returned.
@@ -867,7 +861,7 @@ TEST(MATH_TEST, fmodf) {
ASSERT_TRUE(isnanf(fmodf(3.0f, 0.0f)));
}
-TEST(MATH_TEST, fmodl) {
+TEST(math_h, fmodl) {
ASSERT_DOUBLE_EQ(2.0L, fmodl(12.0L, 10.0L));
// If x is an infinity, NaN is returned.
@@ -882,7 +876,7 @@ TEST(MATH_TEST, fmodl) {
ASSERT_TRUE(isnanl(fmodl(3.0L, 0.0L)));
}
-TEST(MATH_TEST, remainder) {
+TEST(math_h, remainder) {
ASSERT_DOUBLE_EQ(2.0, remainder(12.0, 10.0));
// If x or y is a NaN, NaN is returned.
@@ -897,7 +891,7 @@ TEST(MATH_TEST, remainder) {
ASSERT_TRUE(isnan(remainder(12.0, 0.0)));
}
-TEST(MATH_TEST, remainderf) {
+TEST(math_h, remainderf) {
ASSERT_FLOAT_EQ(2.0f, remainderf(12.0f, 10.0f));
// If x or y is a NaN, NaN is returned.
@@ -912,7 +906,7 @@ TEST(MATH_TEST, remainderf) {
ASSERT_TRUE(isnanf(remainderf(12.0f, 0.0f)));
}
-TEST(MATH_TEST, remainderl) {
+TEST(math_h, remainderl) {
ASSERT_DOUBLE_EQ(2.0L, remainderl(12.0L, 10.0L));
// If x or y is a NaN, NaN is returned.
@@ -927,63 +921,63 @@ TEST(MATH_TEST, remainderl) {
ASSERT_TRUE(isnanl(remainderl(12.0L, 0.0L)));
}
-TEST(MATH_TEST, drem) {
+TEST(math_h, drem) {
ASSERT_DOUBLE_EQ(2.0, drem(12.0, 10.0));
}
-TEST(MATH_TEST, dremf) {
+TEST(math_h, dremf) {
ASSERT_FLOAT_EQ(2.0f, dremf(12.0f, 10.0f));
}
-TEST(MATH_TEST, fmax) {
+TEST(math_h, fmax) {
ASSERT_DOUBLE_EQ(12.0, fmax(12.0, 10.0));
ASSERT_DOUBLE_EQ(12.0, fmax(12.0, nan("")));
ASSERT_DOUBLE_EQ(12.0, fmax(nan(""), 12.0));
}
-TEST(MATH_TEST, fmaxf) {
+TEST(math_h, fmaxf) {
ASSERT_FLOAT_EQ(12.0f, fmaxf(12.0f, 10.0f));
ASSERT_FLOAT_EQ(12.0f, fmaxf(12.0f, nanf("")));
ASSERT_FLOAT_EQ(12.0f, fmaxf(nanf(""), 12.0f));
}
-TEST(MATH_TEST, fmaxl) {
+TEST(math_h, fmaxl) {
ASSERT_DOUBLE_EQ(12.0L, fmaxl(12.0L, 10.0L));
ASSERT_DOUBLE_EQ(12.0L, fmaxl(12.0L, nanl("")));
ASSERT_DOUBLE_EQ(12.0L, fmaxl(nanl(""), 12.0L));
}
-TEST(MATH_TEST, fmin) {
+TEST(math_h, fmin) {
ASSERT_DOUBLE_EQ(10.0, fmin(12.0, 10.0));
ASSERT_DOUBLE_EQ(12.0, fmin(12.0, nan("")));
ASSERT_DOUBLE_EQ(12.0, fmin(nan(""), 12.0));
}
-TEST(MATH_TEST, fminf) {
+TEST(math_h, fminf) {
ASSERT_FLOAT_EQ(10.0f, fminf(12.0f, 10.0f));
ASSERT_FLOAT_EQ(12.0f, fminf(12.0f, nanf("")));
ASSERT_FLOAT_EQ(12.0f, fminf(nanf(""), 12.0f));
}
-TEST(MATH_TEST, fminl) {
+TEST(math_h, fminl) {
ASSERT_DOUBLE_EQ(10.0L, fminl(12.0L, 10.0L));
ASSERT_DOUBLE_EQ(12.0L, fminl(12.0L, nanl("")));
ASSERT_DOUBLE_EQ(12.0L, fminl(nanl(""), 12.0L));
}
-TEST(MATH_TEST, fma) {
+TEST(math_h, fma) {
ASSERT_DOUBLE_EQ(10.0, fma(2.0, 3.0, 4.0));
}
-TEST(MATH_TEST, fmaf) {
+TEST(math_h, fmaf) {
ASSERT_FLOAT_EQ(10.0f, fmaf(2.0f, 3.0f, 4.0f));
}
-TEST(MATH_TEST, fmal) {
+TEST(math_h, fmal) {
ASSERT_DOUBLE_EQ(10.0L, fmal(2.0L, 3.0L, 4.0L));
}
-TEST(MATH_TEST, hypot) {
+TEST(math_h, hypot) {
ASSERT_DOUBLE_EQ(5.0, hypot(3.0, 4.0));
// If x or y is an infinity, returns positive infinity.
@@ -997,7 +991,7 @@ TEST(MATH_TEST, hypot) {
ASSERT_TRUE(isnan(hypot(nan(""), 4.0)));
}
-TEST(MATH_TEST, hypotf) {
+TEST(math_h, hypotf) {
ASSERT_FLOAT_EQ(5.0f, hypotf(3.0f, 4.0f));
// If x or y is an infinity, returns positive infinity.
@@ -1011,7 +1005,7 @@ TEST(MATH_TEST, hypotf) {
ASSERT_TRUE(isnanf(hypotf(nanf(""), 4.0f)));
}
-TEST(MATH_TEST, hypotl) {
+TEST(math_h, hypotl) {
ASSERT_DOUBLE_EQ(5.0L, hypotl(3.0L, 4.0L));
// If x or y is an infinity, returns positive infinity.
@@ -1025,31 +1019,31 @@ TEST(MATH_TEST, hypotl) {
ASSERT_TRUE(isnanl(hypotl(nanl(""), 4.0L)));
}
-TEST(MATH_TEST, erf) {
+TEST(math_h, erf) {
ASSERT_DOUBLE_EQ(0.84270079294971489, erf(1.0));
}
-TEST(MATH_TEST, erff) {
+TEST(math_h, erff) {
ASSERT_FLOAT_EQ(0.84270078f, erff(1.0f));
}
-TEST(MATH_TEST, erfl) {
+TEST(math_h, erfl) {
ASSERT_DOUBLE_EQ(0.84270079294971489L, erfl(1.0L));
}
-TEST(MATH_TEST, erfc) {
+TEST(math_h, erfc) {
ASSERT_DOUBLE_EQ(0.15729920705028513, erfc(1.0));
}
-TEST(MATH_TEST, erfcf) {
+TEST(math_h, erfcf) {
ASSERT_FLOAT_EQ(0.15729921f, erfcf(1.0f));
}
-TEST(MATH_TEST, erfcl) {
+TEST(math_h, erfcl) {
ASSERT_DOUBLE_EQ(0.15729920705028513L, erfcl(1.0L));
}
-TEST(MATH_TEST, lrint) {
+TEST(math_h, lrint) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // lrint/lrintf/lrintl obey the rounding mode.
@@ -1071,7 +1065,7 @@ TEST(MATH_TEST, lrint) {
EXPECT_EQ(1234L, llrintl(1234.01L));
}
-TEST(MATH_TEST, rint) {
+TEST(math_h, rint) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // rint/rintf/rintl obey the rounding mode.
@@ -1099,7 +1093,7 @@ TEST(MATH_TEST, rint) {
ASSERT_EQ(1234.0, rintl(1234.01L));
}
-TEST(MATH_TEST, nearbyint) {
+TEST(math_h, nearbyint) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // nearbyint/nearbyintf/nearbyintl obey the rounding mode.
feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag.
@@ -1126,7 +1120,7 @@ TEST(MATH_TEST, nearbyint) {
ASSERT_EQ(1234.0, nearbyintl(1234.01L));
}
-TEST(MATH_TEST, lround) {
+TEST(math_h, lround) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // lround ignores the rounding mode.
ASSERT_EQ(1234, lround(1234.01));
@@ -1134,7 +1128,7 @@ TEST(MATH_TEST, lround) {
ASSERT_EQ(1234, lroundl(1234.01L));
}
-TEST(MATH_TEST, llround) {
+TEST(math_h, llround) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // llround ignores the rounding mode.
ASSERT_EQ(1234L, llround(1234.01));
@@ -1142,7 +1136,7 @@ TEST(MATH_TEST, llround) {
ASSERT_EQ(1234L, llroundl(1234.01L));
}
-TEST(MATH_TEST, ilogb) {
+TEST(math_h, ilogb) {
ASSERT_EQ(FP_ILOGB0, ilogb(0.0));
ASSERT_EQ(FP_ILOGBNAN, ilogb(nan("")));
ASSERT_EQ(INT_MAX, ilogb(HUGE_VAL));
@@ -1151,7 +1145,7 @@ TEST(MATH_TEST, ilogb) {
ASSERT_EQ(3, ilogb(10.0));
}
-TEST(MATH_TEST, ilogbf) {
+TEST(math_h, ilogbf) {
ASSERT_EQ(FP_ILOGB0, ilogbf(0.0f));
ASSERT_EQ(FP_ILOGBNAN, ilogbf(nanf("")));
ASSERT_EQ(INT_MAX, ilogbf(HUGE_VALF));
@@ -1160,7 +1154,7 @@ TEST(MATH_TEST, ilogbf) {
ASSERT_EQ(3, ilogbf(10.0f));
}
-TEST(MATH_TEST, ilogbl) {
+TEST(math_h, ilogbl) {
ASSERT_EQ(FP_ILOGB0, ilogbl(0.0L));
ASSERT_EQ(FP_ILOGBNAN, ilogbl(nanl("")));
ASSERT_EQ(INT_MAX, ilogbl(HUGE_VALL));
@@ -1169,7 +1163,7 @@ TEST(MATH_TEST, ilogbl) {
ASSERT_EQ(3L, ilogbl(10.0L));
}
-TEST(MATH_TEST, logb) {
+TEST(math_h, logb) {
ASSERT_EQ(-HUGE_VAL, logb(0.0));
ASSERT_TRUE(isnan(logb(nan(""))));
ASSERT_TRUE(isinf(logb(HUGE_VAL)));
@@ -1178,7 +1172,7 @@ TEST(MATH_TEST, logb) {
ASSERT_EQ(3.0, logb(10.0));
}
-TEST(MATH_TEST, logbf) {
+TEST(math_h, logbf) {
ASSERT_EQ(-HUGE_VALF, logbf(0.0f));
ASSERT_TRUE(isnanf(logbf(nanf(""))));
ASSERT_TRUE(isinff(logbf(HUGE_VALF)));
@@ -1187,7 +1181,7 @@ TEST(MATH_TEST, logbf) {
ASSERT_EQ(3.0f, logbf(10.0f));
}
-TEST(MATH_TEST, logbl) {
+TEST(math_h, logbl) {
ASSERT_EQ(-HUGE_VAL, logbl(0.0L));
ASSERT_TRUE(isnan(logbl(nanl(""))));
ASSERT_TRUE(isinf(logbl(HUGE_VALL)));
@@ -1196,7 +1190,7 @@ TEST(MATH_TEST, logbl) {
ASSERT_EQ(3.0L, logbl(10.0L));
}
-TEST(MATH_TEST, log1p) {
+TEST(math_h, log1p) {
ASSERT_EQ(-HUGE_VAL, log1p(-1.0));
ASSERT_TRUE(isnan(log1p(nan(""))));
ASSERT_TRUE(isinf(log1p(HUGE_VAL)));
@@ -1204,7 +1198,7 @@ TEST(MATH_TEST, log1p) {
ASSERT_DOUBLE_EQ(1.0, log1p(M_E - 1.0));
}
-TEST(MATH_TEST, log1pf) {
+TEST(math_h, log1pf) {
ASSERT_EQ(-HUGE_VALF, log1pf(-1.0f));
ASSERT_TRUE(isnanf(log1pf(nanf(""))));
ASSERT_TRUE(isinff(log1pf(HUGE_VALF)));
@@ -1212,7 +1206,7 @@ TEST(MATH_TEST, log1pf) {
ASSERT_FLOAT_EQ(1.0f, log1pf(static_cast<float>(M_E) - 1.0f));
}
-TEST(MATH_TEST, log1pl) {
+TEST(math_h, log1pl) {
ASSERT_EQ(-HUGE_VALL, log1pl(-1.0L));
ASSERT_TRUE(isnanl(log1pl(nanl(""))));
ASSERT_TRUE(isinfl(log1pl(HUGE_VALL)));
@@ -1220,25 +1214,25 @@ TEST(MATH_TEST, log1pl) {
ASSERT_DOUBLE_EQ(1.0L, log1pl(M_E - 1.0L));
}
-TEST(MATH_TEST, fdim) {
+TEST(math_h, fdim) {
ASSERT_DOUBLE_EQ(0.0, fdim(1.0, 1.0));
ASSERT_DOUBLE_EQ(1.0, fdim(2.0, 1.0));
ASSERT_DOUBLE_EQ(0.0, fdim(1.0, 2.0));
}
-TEST(MATH_TEST, fdimf) {
+TEST(math_h, fdimf) {
ASSERT_FLOAT_EQ(0.0f, fdimf(1.0f, 1.0f));
ASSERT_FLOAT_EQ(1.0f, fdimf(2.0f, 1.0f));
ASSERT_FLOAT_EQ(0.0f, fdimf(1.0f, 2.0f));
}
-TEST(MATH_TEST, fdiml) {
+TEST(math_h, fdiml) {
ASSERT_DOUBLE_EQ(0.0L, fdiml(1.0L, 1.0L));
ASSERT_DOUBLE_EQ(1.0L, fdiml(2.0L, 1.0L));
ASSERT_DOUBLE_EQ(0.0L, fdiml(1.0L, 2.0L));
}
-TEST(MATH_TEST, round) {
+TEST(math_h, round) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_TOWARDZERO); // round ignores the rounding mode and always rounds away from zero.
ASSERT_DOUBLE_EQ(1.0, round(0.5));
@@ -1250,7 +1244,7 @@ TEST(MATH_TEST, round) {
ASSERT_DOUBLE_EQ(-HUGE_VAL, round(-HUGE_VAL));
}
-TEST(MATH_TEST, roundf) {
+TEST(math_h, roundf) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_TOWARDZERO); // roundf ignores the rounding mode and always rounds away from zero.
ASSERT_FLOAT_EQ(1.0f, roundf(0.5f));
@@ -1262,7 +1256,7 @@ TEST(MATH_TEST, roundf) {
ASSERT_FLOAT_EQ(-HUGE_VALF, roundf(-HUGE_VALF));
}
-TEST(MATH_TEST, roundl) {
+TEST(math_h, roundl) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_TOWARDZERO); // roundl ignores the rounding mode and always rounds away from zero.
ASSERT_DOUBLE_EQ(1.0L, roundl(0.5L));
@@ -1274,7 +1268,7 @@ TEST(MATH_TEST, roundl) {
ASSERT_DOUBLE_EQ(-HUGE_VALL, roundl(-HUGE_VALL));
}
-TEST(MATH_TEST, trunc) {
+TEST(math_h, trunc) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // trunc ignores the rounding mode and always rounds toward zero.
ASSERT_DOUBLE_EQ(1.0, trunc(1.5));
@@ -1286,7 +1280,7 @@ TEST(MATH_TEST, trunc) {
ASSERT_DOUBLE_EQ(-HUGE_VAL, trunc(-HUGE_VAL));
}
-TEST(MATH_TEST, truncf) {
+TEST(math_h, truncf) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // truncf ignores the rounding mode and always rounds toward zero.
ASSERT_FLOAT_EQ(1.0f, truncf(1.5f));
@@ -1298,7 +1292,7 @@ TEST(MATH_TEST, truncf) {
ASSERT_FLOAT_EQ(-HUGE_VALF, truncf(-HUGE_VALF));
}
-TEST(MATH_TEST, truncl) {
+TEST(math_h, truncl) {
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // truncl ignores the rounding mode and always rounds toward zero.
ASSERT_DOUBLE_EQ(1.0L, truncl(1.5L));
@@ -1310,19 +1304,19 @@ TEST(MATH_TEST, truncl) {
ASSERT_DOUBLE_EQ(-HUGE_VALL, truncl(-HUGE_VALL));
}
-TEST(MATH_TEST, nextafter) {
+TEST(math_h, nextafter) {
ASSERT_DOUBLE_EQ(0.0, nextafter(0.0, 0.0));
ASSERT_DOUBLE_EQ(4.9406564584124654e-324, nextafter(0.0, 1.0));
ASSERT_DOUBLE_EQ(-4.9406564584124654e-324, nextafter(0.0, -1.0));
}
-TEST(MATH_TEST, nextafterf) {
+TEST(math_h, nextafterf) {
ASSERT_FLOAT_EQ(0.0f, nextafterf(0.0f, 0.0f));
ASSERT_FLOAT_EQ(1.4012985e-45f, nextafterf(0.0f, 1.0f));
ASSERT_FLOAT_EQ(-1.4012985e-45f, nextafterf(0.0f, -1.0f));
}
-TEST(MATH_TEST, nextafterl) {
+TEST(math_h, nextafterl) {
ASSERT_DOUBLE_EQ(0.0L, nextafterl(0.0L, 0.0L));
// Use a runtime value to accomodate the case when
// sizeof(double) == sizeof(long double)
@@ -1331,19 +1325,19 @@ TEST(MATH_TEST, nextafterl) {
ASSERT_DOUBLE_EQ(-smallest_positive, nextafterl(0.0L, -1.0L));
}
-TEST(MATH_TEST, nexttoward) {
+TEST(math_h, nexttoward) {
ASSERT_DOUBLE_EQ(0.0, nexttoward(0.0, 0.0L));
ASSERT_DOUBLE_EQ(4.9406564584124654e-324, nexttoward(0.0, 1.0L));
ASSERT_DOUBLE_EQ(-4.9406564584124654e-324, nexttoward(0.0, -1.0L));
}
-TEST(MATH_TEST, nexttowardf) {
+TEST(math_h, nexttowardf) {
ASSERT_FLOAT_EQ(0.0f, nexttowardf(0.0f, 0.0L));
ASSERT_FLOAT_EQ(1.4012985e-45f, nexttowardf(0.0f, 1.0L));
ASSERT_FLOAT_EQ(-1.4012985e-45f, nexttowardf(0.0f, -1.0L));
}
-TEST(MATH_TEST, nexttowardl) {
+TEST(math_h, nexttowardl) {
ASSERT_DOUBLE_EQ(0.0L, nexttowardl(0.0L, 0.0L));
// Use a runtime value to accomodate the case when
// sizeof(double) == sizeof(long double)
@@ -1352,40 +1346,40 @@ TEST(MATH_TEST, nexttowardl) {
ASSERT_DOUBLE_EQ(-smallest_positive, nexttowardl(0.0L, -1.0L));
}
-TEST(MATH_TEST, copysign) {
+TEST(math_h, copysign) {
ASSERT_DOUBLE_EQ(0.0, copysign(0.0, 1.0));
ASSERT_DOUBLE_EQ(-0.0, copysign(0.0, -1.0));
ASSERT_DOUBLE_EQ(2.0, copysign(2.0, 1.0));
ASSERT_DOUBLE_EQ(-2.0, copysign(2.0, -1.0));
}
-TEST(MATH_TEST, copysignf) {
+TEST(math_h, copysignf) {
ASSERT_FLOAT_EQ(0.0f, copysignf(0.0f, 1.0f));
ASSERT_FLOAT_EQ(-0.0f, copysignf(0.0f, -1.0f));
ASSERT_FLOAT_EQ(2.0f, copysignf(2.0f, 1.0f));
ASSERT_FLOAT_EQ(-2.0f, copysignf(2.0f, -1.0f));
}
-TEST(MATH_TEST, copysignl) {
+TEST(math_h, copysignl) {
ASSERT_DOUBLE_EQ(0.0L, copysignl(0.0L, 1.0L));
ASSERT_DOUBLE_EQ(-0.0L, copysignl(0.0L, -1.0L));
ASSERT_DOUBLE_EQ(2.0L, copysignl(2.0L, 1.0L));
ASSERT_DOUBLE_EQ(-2.0L, copysignl(2.0L, -1.0L));
}
-TEST(MATH_TEST, significand) {
+TEST(math_h, significand) {
ASSERT_DOUBLE_EQ(0.0, significand(0.0));
ASSERT_DOUBLE_EQ(1.2, significand(1.2));
ASSERT_DOUBLE_EQ(1.53125, significand(12.25));
}
-TEST(MATH_TEST, significandf) {
+TEST(math_h, significandf) {
ASSERT_FLOAT_EQ(0.0f, significandf(0.0f));
ASSERT_FLOAT_EQ(1.2f, significandf(1.2f));
ASSERT_FLOAT_EQ(1.53125f, significandf(12.25f));
}
-TEST(MATH_TEST, significandl) {
+TEST(math_h, significandl) {
#if !defined(ANDROID_HOST_MUSL)
ASSERT_DOUBLE_EQ(0.0L, significandl(0.0L));
ASSERT_DOUBLE_EQ(1.2L, significandl(1.2L));
@@ -1395,40 +1389,39 @@ TEST(MATH_TEST, significandl) {
#endif
}
-
-TEST(MATH_TEST, scalb) {
+TEST(math_h, scalb) {
ASSERT_DOUBLE_EQ(12.0, scalb(3.0, 2.0));
}
-TEST(MATH_TEST, scalbf) {
+TEST(math_h, scalbf) {
ASSERT_FLOAT_EQ(12.0f, scalbf(3.0f, 2.0f));
}
-TEST(MATH_TEST, scalbln) {
+TEST(math_h, scalbln) {
ASSERT_DOUBLE_EQ(12.0, scalbln(3.0, 2L));
}
-TEST(MATH_TEST, scalblnf) {
+TEST(math_h, scalblnf) {
ASSERT_FLOAT_EQ(12.0f, scalblnf(3.0f, 2L));
}
-TEST(MATH_TEST, scalblnl) {
+TEST(math_h, scalblnl) {
ASSERT_DOUBLE_EQ(12.0L, scalblnl(3.0L, 2L));
}
-TEST(MATH_TEST, scalbn) {
+TEST(math_h, scalbn) {
ASSERT_DOUBLE_EQ(12.0, scalbn(3.0, 2));
}
-TEST(MATH_TEST, scalbnf) {
+TEST(math_h, scalbnf) {
ASSERT_FLOAT_EQ(12.0f, scalbnf(3.0f, 2));
}
-TEST(MATH_TEST, scalbnl) {
+TEST(math_h, scalbnl) {
ASSERT_DOUBLE_EQ(12.0L, scalbnl(3.0L, 2));
}
-TEST(MATH_TEST, gamma) {
+TEST(math_h, gamma) {
#if !defined(ANDROID_HOST_MUSL)
ASSERT_DOUBLE_EQ(log(24.0), gamma(5.0));
#else
@@ -1436,7 +1429,7 @@ TEST(MATH_TEST, gamma) {
#endif
}
-TEST(MATH_TEST, gammaf) {
+TEST(math_h, gammaf) {
#if !defined(ANDROID_HOST_MUSL)
ASSERT_FLOAT_EQ(logf(24.0f), gammaf(5.0f));
#else
@@ -1444,7 +1437,7 @@ TEST(MATH_TEST, gammaf) {
#endif
}
-TEST(MATH_TEST, gamma_r) {
+TEST(math_h, gamma_r) {
#if defined(__BIONIC__)
int sign;
ASSERT_DOUBLE_EQ(log(24.0), gamma_r(5.0, &sign));
@@ -1454,7 +1447,7 @@ TEST(MATH_TEST, gamma_r) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, gammaf_r) {
+TEST(math_h, gammaf_r) {
#if defined(__BIONIC__)
int sign;
ASSERT_FLOAT_EQ(logf(24.0f), gammaf_r(5.0f, &sign));
@@ -1464,25 +1457,25 @@ TEST(MATH_TEST, gammaf_r) {
#endif // __BIONIC__
}
-TEST(MATH_TEST, lgamma) {
+TEST(math_h, lgamma) {
ASSERT_DOUBLE_EQ(log(24.0), lgamma(5.0));
}
-TEST(MATH_TEST, lgammaf) {
+TEST(math_h, lgammaf) {
ASSERT_FLOAT_EQ(logf(24.0f), lgammaf(5.0f));
}
-TEST(MATH_TEST, lgammal) {
+TEST(math_h, lgammal) {
ASSERT_DOUBLE_EQ(logl(24.0L), lgammal(5.0L));
}
-TEST(MATH_TEST, lgamma_r) {
+TEST(math_h, lgamma_r) {
int sign;
ASSERT_DOUBLE_EQ(log(24.0), lgamma_r(5.0, &sign));
ASSERT_EQ(1, sign);
}
-TEST(MATH_TEST, lgamma_r_17471883) {
+TEST(math_h, lgamma_r_17471883) {
int sign;
sign = 0;
@@ -1493,13 +1486,13 @@ TEST(MATH_TEST, lgamma_r_17471883) {
ASSERT_EQ(-1, sign);
}
-TEST(MATH_TEST, lgammaf_r) {
+TEST(math_h, lgammaf_r) {
int sign;
ASSERT_FLOAT_EQ(logf(24.0f), lgammaf_r(5.0f, &sign));
ASSERT_EQ(1, sign);
}
-TEST(MATH_TEST, lgammaf_r_17471883) {
+TEST(math_h, lgammaf_r_17471883) {
int sign;
sign = 0;
@@ -1510,13 +1503,13 @@ TEST(MATH_TEST, lgammaf_r_17471883) {
ASSERT_EQ(-1, sign);
}
-TEST(MATH_TEST, lgammal_r) {
+TEST(math_h, lgammal_r) {
int sign;
ASSERT_DOUBLE_EQ(log(24.0L), lgamma_r(5.0L, &sign));
ASSERT_EQ(1, sign);
}
-TEST(MATH_TEST, lgammal_r_17471883) {
+TEST(math_h, lgammal_r_17471883) {
int sign;
sign = 0;
@@ -1527,142 +1520,142 @@ TEST(MATH_TEST, lgammal_r_17471883) {
ASSERT_EQ(-1, sign);
}
-TEST(MATH_TEST, tgamma_NaN) {
+TEST(math_h, tgamma_NaN) {
ASSERT_TRUE(isnan(tgamma(nan(""))));
ASSERT_TRUE(isnanf(tgammaf(nanf(""))));
ASSERT_TRUE(isnanl(tgammal(nanl(""))));
}
-TEST(MATH_TEST, tgamma_inf) {
+TEST(math_h, tgamma_inf) {
ASSERT_TRUE(isinf(tgamma(HUGE_VAL)));
ASSERT_TRUE(isinff(tgammaf(HUGE_VALF)));
ASSERT_TRUE(isinfl(tgammal(HUGE_VALL)));
}
-TEST(MATH_TEST, tgamma_negative) {
+TEST(math_h, tgamma_negative) {
ASSERT_TRUE(isnan(tgamma(-1.0)));
ASSERT_TRUE(isnanf(tgammaf(-1.0f)));
ASSERT_TRUE(isnanl(tgammal(-1.0L)));
}
-TEST(MATH_TEST, tgamma) {
+TEST(math_h, tgamma) {
ASSERT_DOUBLE_EQ(24.0, tgamma(5.0));
ASSERT_DOUBLE_EQ(120.0, tgamma(6.0));
ASSERT_TRUE(isinf(tgamma(172.0)));
}
-TEST(MATH_TEST, tgammaf) {
+TEST(math_h, tgammaf) {
ASSERT_FLOAT_EQ(24.0f, tgammaf(5.0f));
ASSERT_FLOAT_EQ(120.0f, tgammaf(6.0f));
ASSERT_TRUE(isinff(tgammaf(172.0f)));
}
-TEST(MATH_TEST, tgammal) {
+TEST(math_h, tgammal) {
ASSERT_DOUBLE_EQ(24.0L, tgammal(5.0L));
ASSERT_DOUBLE_EQ(120.0L, tgammal(6.0L));
ASSERT_TRUE(isinf(tgammal(172.0L)));
}
-TEST(MATH_TEST, j0) {
+TEST(math_h, j0) {
ASSERT_DOUBLE_EQ(1.0, j0(0.0));
ASSERT_DOUBLE_EQ(0.76519768655796661, j0(1.0));
}
-TEST(MATH_TEST, j0f) {
+TEST(math_h, j0f) {
ASSERT_FLOAT_EQ(1.0f, j0f(0.0f));
ASSERT_FLOAT_EQ(0.76519769f, j0f(1.0f));
}
-TEST(MATH_TEST, j1) {
+TEST(math_h, j1) {
ASSERT_DOUBLE_EQ(0.0, j1(0.0));
ASSERT_DOUBLE_EQ(0.44005058574493355, j1(1.0));
}
-TEST(MATH_TEST, j1f) {
+TEST(math_h, j1f) {
ASSERT_FLOAT_EQ(0.0f, j1f(0.0f));
ASSERT_FLOAT_EQ(0.44005057f, j1f(1.0f));
}
-TEST(MATH_TEST, jn) {
+TEST(math_h, jn) {
ASSERT_DOUBLE_EQ(0.0, jn(4, 0.0));
ASSERT_DOUBLE_EQ(0.0024766389641099553, jn(4, 1.0));
}
-TEST(MATH_TEST, jnf) {
+TEST(math_h, jnf) {
ASSERT_FLOAT_EQ(0.0f, jnf(4, 0.0f));
ASSERT_FLOAT_EQ(0.0024766389f, jnf(4, 1.0f));
}
-TEST(MATH_TEST, y0) {
+TEST(math_h, y0) {
ASSERT_DOUBLE_EQ(-HUGE_VAL, y0(0.0));
ASSERT_DOUBLE_EQ(0.08825696421567697, y0(1.0));
}
-TEST(MATH_TEST, y0f) {
+TEST(math_h, y0f) {
ASSERT_FLOAT_EQ(-HUGE_VALF, y0f(0.0f));
ASSERT_FLOAT_EQ(0.088256963f, y0f(1.0f));
}
-TEST(MATH_TEST, y1) {
+TEST(math_h, y1) {
ASSERT_DOUBLE_EQ(-HUGE_VAL, y1(0.0));
ASSERT_DOUBLE_EQ(-0.78121282130028868, y1(1.0));
}
-TEST(MATH_TEST, y1f) {
+TEST(math_h, y1f) {
ASSERT_FLOAT_EQ(-HUGE_VALF, y1f(0.0f));
ASSERT_FLOAT_EQ(-0.78121281f, y1f(1.0f));
}
-TEST(MATH_TEST, yn) {
+TEST(math_h, yn) {
ASSERT_DOUBLE_EQ(-HUGE_VAL, yn(4, 0.0));
ASSERT_DOUBLE_EQ(-33.278423028972114, yn(4, 1.0));
}
-TEST(MATH_TEST, ynf) {
+TEST(math_h, ynf) {
ASSERT_FLOAT_EQ(-HUGE_VALF, ynf(4, 0.0f));
ASSERT_FLOAT_EQ(-33.278423f, ynf(4, 1.0f));
}
-TEST(MATH_TEST, frexp) {
+TEST(math_h, frexp) {
int exp;
double dr = frexp(1024.0, &exp);
ASSERT_DOUBLE_EQ(1024.0, scalbn(dr, exp));
}
-TEST(MATH_TEST, frexpf) {
+TEST(math_h, frexpf) {
int exp;
float fr = frexpf(1024.0f, &exp);
ASSERT_FLOAT_EQ(1024.0f, scalbnf(fr, exp));
}
-TEST(MATH_TEST, frexpl) {
+TEST(math_h, frexpl) {
int exp;
long double ldr = frexpl(1024.0L, &exp);
ASSERT_DOUBLE_EQ(1024.0L, scalbnl(ldr, exp));
}
-TEST(MATH_TEST, modf) {
+TEST(math_h, modf) {
double di;
double df = modf(123.75, &di);
ASSERT_DOUBLE_EQ(123.0, di);
ASSERT_DOUBLE_EQ(0.75, df);
}
-TEST(MATH_TEST, modff) {
+TEST(math_h, modff) {
float fi;
float ff = modff(123.75f, &fi);
ASSERT_FLOAT_EQ(123.0f, fi);
ASSERT_FLOAT_EQ(0.75f, ff);
}
-TEST(MATH_TEST, modfl) {
+TEST(math_h, modfl) {
long double ldi;
long double ldf = modfl(123.75L, &ldi);
ASSERT_DOUBLE_EQ(123.0L, ldi);
ASSERT_DOUBLE_EQ(0.75L, ldf);
}
-TEST(MATH_TEST, remquo) {
+TEST(math_h, remquo) {
int q;
double d = remquo(13.0, 4.0, &q);
ASSERT_EQ(3, q);
@@ -1680,7 +1673,7 @@ TEST(MATH_TEST, remquo) {
ASSERT_TRUE(isnan(remquo(12.0, 0.0, &q)));
}
-TEST(MATH_TEST, remquof) {
+TEST(math_h, remquof) {
int q;
float f = remquof(13.0f, 4.0f, &q);
ASSERT_EQ(3, q);
@@ -1698,7 +1691,7 @@ TEST(MATH_TEST, remquof) {
ASSERT_TRUE(isnanf(remquof(12.0f, 0.0f, &q)));
}
-TEST(MATH_TEST, remquol) {
+TEST(math_h, remquol) {
int q;
long double ld = remquol(13.0L, 4.0L, &q);
ASSERT_DOUBLE_EQ(3L, q);
@@ -1717,13 +1710,13 @@ TEST(MATH_TEST, remquol) {
}
// https://code.google.com/p/android/issues/detail?id=6697
-TEST(MATH_TEST, frexpf_public_bug_6697) {
+TEST(math_h, frexpf_public_bug_6697) {
int exp;
float fr = frexpf(14.1f, &exp);
ASSERT_FLOAT_EQ(14.1f, scalbnf(fr, exp));
}
-TEST(MATH_TEST, exp2_STRICT_ALIGN_OpenBSD_bug) {
+TEST(math_h, exp2_STRICT_ALIGN_OpenBSD_bug) {
// OpenBSD/x86's libm had a bug here, but it was already fixed in FreeBSD:
// http://svnweb.FreeBSD.org/base/head/lib/msun/src/math_private.h?revision=240827&view=markup
ASSERT_DOUBLE_EQ(5.0, exp2(log2(5)));
@@ -1731,7 +1724,7 @@ TEST(MATH_TEST, exp2_STRICT_ALIGN_OpenBSD_bug) {
ASSERT_DOUBLE_EQ(5.0L, exp2l(log2l(5)));
}
-TEST(MATH_TEST, nextafterl_OpenBSD_bug) {
+TEST(math_h, nextafterl_OpenBSD_bug) {
// OpenBSD/x86's libm had a bug here.
ASSERT_TRUE(nextafter(1.0, 0.0) - 1.0 < 0.0);
ASSERT_TRUE(nextafterf(1.0f, 0.0f) - 1.0f < 0.0f);
@@ -1739,511 +1732,511 @@ TEST(MATH_TEST, nextafterl_OpenBSD_bug) {
}
#include "math_data/acos_intel_data.h"
-TEST(MATH_TEST, acos_intel) {
+TEST(math_h, acos_intel) {
DoMathDataTest<1>(g_acos_intel_data, acos);
}
#include "math_data/acosf_intel_data.h"
-TEST(MATH_TEST, acosf_intel) {
+TEST(math_h, acosf_intel) {
DoMathDataTest<1>(g_acosf_intel_data, acosf);
}
#include "math_data/acosh_intel_data.h"
-TEST(MATH_TEST, acosh_intel) {
+TEST(math_h, acosh_intel) {
DoMathDataTest<2>(g_acosh_intel_data, acosh);
}
#include "math_data/acoshf_intel_data.h"
-TEST(MATH_TEST, acoshf_intel) {
+TEST(math_h, acoshf_intel) {
DoMathDataTest<2>(g_acoshf_intel_data, acoshf);
}
#include "math_data/asin_intel_data.h"
-TEST(MATH_TEST, asin_intel) {
+TEST(math_h, asin_intel) {
DoMathDataTest<1>(g_asin_intel_data, asin);
}
#include "math_data/asinf_intel_data.h"
-TEST(MATH_TEST, asinf_intel) {
+TEST(math_h, asinf_intel) {
DoMathDataTest<1>(g_asinf_intel_data, asinf);
}
#include "math_data/asinh_intel_data.h"
-TEST(MATH_TEST, asinh_intel) {
+TEST(math_h, asinh_intel) {
DoMathDataTest<2>(g_asinh_intel_data, asinh);
}
#include "math_data/asinhf_intel_data.h"
-TEST(MATH_TEST, asinhf_intel) {
+TEST(math_h, asinhf_intel) {
DoMathDataTest<2>(g_asinhf_intel_data, asinhf);
}
#include "math_data/atan2_intel_data.h"
-TEST(MATH_TEST, atan2_intel) {
+TEST(math_h, atan2_intel) {
DoMathDataTest<2>(g_atan2_intel_data, atan2);
}
#include "math_data/atan2f_intel_data.h"
-TEST(MATH_TEST, atan2f_intel) {
+TEST(math_h, atan2f_intel) {
DoMathDataTest<2>(g_atan2f_intel_data, atan2f);
}
#include "math_data/atan_intel_data.h"
-TEST(MATH_TEST, atan_intel) {
+TEST(math_h, atan_intel) {
DoMathDataTest<1>(g_atan_intel_data, atan);
}
#include "math_data/atanf_intel_data.h"
-TEST(MATH_TEST, atanf_intel) {
+TEST(math_h, atanf_intel) {
DoMathDataTest<1>(g_atanf_intel_data, atanf);
}
#include "math_data/atanh_intel_data.h"
-TEST(MATH_TEST, atanh_intel) {
+TEST(math_h, atanh_intel) {
DoMathDataTest<2>(g_atanh_intel_data, atanh);
}
#include "math_data/atanhf_intel_data.h"
-TEST(MATH_TEST, atanhf_intel) {
+TEST(math_h, atanhf_intel) {
DoMathDataTest<2>(g_atanhf_intel_data, atanhf);
}
#include "math_data/cbrt_intel_data.h"
-TEST(MATH_TEST, cbrt_intel) {
+TEST(math_h, cbrt_intel) {
DoMathDataTest<1>(g_cbrt_intel_data, cbrt);
}
#include "math_data/cbrtf_intel_data.h"
-TEST(MATH_TEST, cbrtf_intel) {
+TEST(math_h, cbrtf_intel) {
DoMathDataTest<1>(g_cbrtf_intel_data, cbrtf);
}
#include "math_data/ceil_intel_data.h"
-TEST(MATH_TEST, ceil_intel) {
+TEST(math_h, ceil_intel) {
DoMathDataTest<1>(g_ceil_intel_data, ceil);
}
#include "math_data/ceilf_intel_data.h"
-TEST(MATH_TEST, ceilf_intel) {
+TEST(math_h, ceilf_intel) {
DoMathDataTest<1>(g_ceilf_intel_data, ceilf);
}
#include "math_data/copysign_intel_data.h"
-TEST(MATH_TEST, copysign_intel) {
+TEST(math_h, copysign_intel) {
DoMathDataTest<1>(g_copysign_intel_data, copysign);
}
#include "math_data/copysignf_intel_data.h"
-TEST(MATH_TEST, copysignf_intel) {
+TEST(math_h, copysignf_intel) {
DoMathDataTest<1>(g_copysignf_intel_data, copysignf);
}
#include "math_data/cos_intel_data.h"
-TEST(MATH_TEST, cos_intel) {
+TEST(math_h, cos_intel) {
DoMathDataTest<1>(g_cos_intel_data, cos);
}
#include "math_data/cosf_intel_data.h"
-TEST(MATH_TEST, cosf_intel) {
+TEST(math_h, cosf_intel) {
DoMathDataTest<1>(g_cosf_intel_data, cosf);
}
#include "math_data/cosh_intel_data.h"
-TEST(MATH_TEST, cosh_intel) {
+TEST(math_h, cosh_intel) {
DoMathDataTest<2>(g_cosh_intel_data, cosh);
}
#include "math_data/coshf_intel_data.h"
-TEST(MATH_TEST, coshf_intel) {
+TEST(math_h, coshf_intel) {
DoMathDataTest<2>(g_coshf_intel_data, coshf);
}
#include "math_data/exp_intel_data.h"
-TEST(MATH_TEST, exp_intel) {
+TEST(math_h, exp_intel) {
DoMathDataTest<1>(g_exp_intel_data, exp);
}
#include "math_data/expf_intel_data.h"
-TEST(MATH_TEST, expf_intel) {
+TEST(math_h, expf_intel) {
DoMathDataTest<1>(g_expf_intel_data, expf);
}
#include "math_data/exp2_intel_data.h"
-TEST(MATH_TEST, exp2_intel) {
+TEST(math_h, exp2_intel) {
DoMathDataTest<1>(g_exp2_intel_data, exp2);
}
#include "math_data/exp2f_intel_data.h"
-TEST(MATH_TEST, exp2f_intel) {
+TEST(math_h, exp2f_intel) {
DoMathDataTest<1>(g_exp2f_intel_data, exp2f);
}
#include "math_data/expm1_intel_data.h"
-TEST(MATH_TEST, expm1_intel) {
+TEST(math_h, expm1_intel) {
DoMathDataTest<1>(g_expm1_intel_data, expm1);
}
#include "math_data/expm1f_intel_data.h"
-TEST(MATH_TEST, expm1f_intel) {
+TEST(math_h, expm1f_intel) {
DoMathDataTest<1>(g_expm1f_intel_data, expm1f);
}
#include "math_data/fabs_intel_data.h"
-TEST(MATH_TEST, fabs_intel) {
+TEST(math_h, fabs_intel) {
DoMathDataTest<1>(g_fabs_intel_data, fabs);
}
#include "math_data/fabsf_intel_data.h"
-TEST(MATH_TEST, fabsf_intel) {
+TEST(math_h, fabsf_intel) {
DoMathDataTest<1>(g_fabsf_intel_data, fabsf);
}
#include "math_data/fdim_intel_data.h"
-TEST(MATH_TEST, fdim_intel) {
+TEST(math_h, fdim_intel) {
DoMathDataTest<1>(g_fdim_intel_data, fdim);
}
#include "math_data/fdimf_intel_data.h"
-TEST(MATH_TEST, fdimf_intel) {
+TEST(math_h, fdimf_intel) {
DoMathDataTest<1>(g_fdimf_intel_data, fdimf);
}
#include "math_data/floor_intel_data.h"
-TEST(MATH_TEST, floor_intel) {
+TEST(math_h, floor_intel) {
DoMathDataTest<1>(g_floor_intel_data, floor);
}
#include "math_data/floorf_intel_data.h"
-TEST(MATH_TEST, floorf_intel) {
+TEST(math_h, floorf_intel) {
DoMathDataTest<1>(g_floorf_intel_data, floorf);
}
#include "math_data/fma_intel_data.h"
-TEST(MATH_TEST, fma_intel) {
+TEST(math_h, fma_intel) {
DoMathDataTest<1>(g_fma_intel_data, fma);
}
#include "math_data/fmaf_intel_data.h"
-TEST(MATH_TEST, fmaf_intel) {
+TEST(math_h, fmaf_intel) {
DoMathDataTest<1>(g_fmaf_intel_data, fmaf);
}
#include "math_data/fmax_intel_data.h"
-TEST(MATH_TEST, fmax_intel) {
+TEST(math_h, fmax_intel) {
DoMathDataTest<1>(g_fmax_intel_data, fmax);
}
#include "math_data/fmaxf_intel_data.h"
-TEST(MATH_TEST, fmaxf_intel) {
+TEST(math_h, fmaxf_intel) {
DoMathDataTest<1>(g_fmaxf_intel_data, fmaxf);
}
#include "math_data/fmin_intel_data.h"
-TEST(MATH_TEST, fmin_intel) {
+TEST(math_h, fmin_intel) {
DoMathDataTest<1>(g_fmin_intel_data, fmin);
}
#include "math_data/fminf_intel_data.h"
-TEST(MATH_TEST, fminf_intel) {
+TEST(math_h, fminf_intel) {
DoMathDataTest<1>(g_fminf_intel_data, fminf);
}
#include "math_data/fmod_intel_data.h"
-TEST(MATH_TEST, fmod_intel) {
+TEST(math_h, fmod_intel) {
DoMathDataTest<1>(g_fmod_intel_data, fmod);
}
#include "math_data/fmodf_intel_data.h"
-TEST(MATH_TEST, fmodf_intel) {
+TEST(math_h, fmodf_intel) {
DoMathDataTest<1>(g_fmodf_intel_data, fmodf);
}
#include "math_data/frexp_intel_data.h"
-TEST(MATH_TEST, frexp_intel) {
+TEST(math_h, frexp_intel) {
DoMathDataTest<1>(g_frexp_intel_data, frexp);
}
#include "math_data/frexpf_intel_data.h"
-TEST(MATH_TEST, frexpf_intel) {
+TEST(math_h, frexpf_intel) {
DoMathDataTest<1>(g_frexpf_intel_data, frexpf);
}
#include "math_data/hypot_intel_data.h"
-TEST(MATH_TEST, hypot_intel) {
+TEST(math_h, hypot_intel) {
DoMathDataTest<1>(g_hypot_intel_data, hypot);
}
#include "math_data/hypotf_intel_data.h"
-TEST(MATH_TEST, hypotf_intel) {
+TEST(math_h, hypotf_intel) {
DoMathDataTest<1>(g_hypotf_intel_data, hypotf);
}
#include "math_data/ilogb_intel_data.h"
-TEST(MATH_TEST, ilogb_intel) {
+TEST(math_h, ilogb_intel) {
DoMathDataTest<1>(g_ilogb_intel_data, ilogb);
}
#include "math_data/ilogbf_intel_data.h"
-TEST(MATH_TEST, ilogbf_intel) {
+TEST(math_h, ilogbf_intel) {
DoMathDataTest<1>(g_ilogbf_intel_data, ilogbf);
}
#include "math_data/ldexp_intel_data.h"
-TEST(MATH_TEST, ldexp_intel) {
+TEST(math_h, ldexp_intel) {
DoMathDataTest<1>(g_ldexp_intel_data, ldexp);
}
#include "math_data/ldexpf_intel_data.h"
-TEST(MATH_TEST, ldexpf_intel) {
+TEST(math_h, ldexpf_intel) {
DoMathDataTest<1>(g_ldexpf_intel_data, ldexpf);
}
#include "math_data/llrint_intel_data.h"
-TEST(MATH_TEST, llrint_intel) {
+TEST(math_h, llrint_intel) {
DoMathDataTest<1>(g_llrint_intel_data, llrint);
}
#include "math_data/llrintf_intel_data.h"
-TEST(MATH_TEST, llrintf_intel) {
+TEST(math_h, llrintf_intel) {
DoMathDataTest<1>(g_llrintf_intel_data, llrintf);
}
#include "math_data/log_intel_data.h"
-TEST(MATH_TEST, log_intel) {
+TEST(math_h, log_intel) {
DoMathDataTest<1>(g_log_intel_data, log);
}
#include "math_data/logf_intel_data.h"
-TEST(MATH_TEST, logf_intel) {
+TEST(math_h, logf_intel) {
DoMathDataTest<1>(g_logf_intel_data, logf);
}
#include "math_data/log10_intel_data.h"
-TEST(MATH_TEST, log10_intel) {
+TEST(math_h, log10_intel) {
DoMathDataTest<1>(g_log10_intel_data, log10);
}
#include "math_data/log10f_intel_data.h"
-TEST(MATH_TEST, log10f_intel) {
+TEST(math_h, log10f_intel) {
DoMathDataTest<1>(g_log10f_intel_data, log10f);
}
#include "math_data/log1p_intel_data.h"
-TEST(MATH_TEST, log1p_intel) {
+TEST(math_h, log1p_intel) {
DoMathDataTest<1>(g_log1p_intel_data, log1p);
}
#include "math_data/log1pf_intel_data.h"
-TEST(MATH_TEST, log1pf_intel) {
+TEST(math_h, log1pf_intel) {
DoMathDataTest<1>(g_log1pf_intel_data, log1pf);
}
#include "math_data/log2_intel_data.h"
-TEST(MATH_TEST, log2_intel) {
+TEST(math_h, log2_intel) {
DoMathDataTest<1>(g_log2_intel_data, log2);
}
#include "math_data/log2f_intel_data.h"
-TEST(MATH_TEST, log2f_intel) {
+TEST(math_h, log2f_intel) {
DoMathDataTest<1>(g_log2f_intel_data, log2f);
}
#include "math_data/logb_intel_data.h"
-TEST(MATH_TEST, logb_intel) {
+TEST(math_h, logb_intel) {
DoMathDataTest<1>(g_logb_intel_data, logb);
}
#include "math_data/logbf_intel_data.h"
-TEST(MATH_TEST, logbf_intel) {
+TEST(math_h, logbf_intel) {
DoMathDataTest<1>(g_logbf_intel_data, logbf);
}
#include "math_data/lrint_intel_data.h"
-TEST(MATH_TEST, lrint_intel) {
+TEST(math_h, lrint_intel) {
DoMathDataTest<1>(g_lrint_intel_data, lrint);
}
#include "math_data/lrintf_intel_data.h"
-TEST(MATH_TEST, lrintf_intel) {
+TEST(math_h, lrintf_intel) {
DoMathDataTest<1>(g_lrintf_intel_data, lrintf);
}
#include "math_data/modf_intel_data.h"
-TEST(MATH_TEST, modf_intel) {
+TEST(math_h, modf_intel) {
DoMathDataTest<1>(g_modf_intel_data, modf);
}
#include "math_data/modff_intel_data.h"
-TEST(MATH_TEST, modff_intel) {
+TEST(math_h, modff_intel) {
DoMathDataTest<1>(g_modff_intel_data, modff);
}
#include "math_data/nearbyint_intel_data.h"
-TEST(MATH_TEST, nearbyint_intel) {
+TEST(math_h, nearbyint_intel) {
DoMathDataTest<1>(g_nearbyint_intel_data, nearbyint);
}
#include "math_data/nearbyintf_intel_data.h"
-TEST(MATH_TEST, nearbyintf_intel) {
+TEST(math_h, nearbyintf_intel) {
DoMathDataTest<1>(g_nearbyintf_intel_data, nearbyintf);
}
#include "math_data/nextafter_intel_data.h"
-TEST(MATH_TEST, nextafter_intel) {
+TEST(math_h, nextafter_intel) {
DoMathDataTest<1>(g_nextafter_intel_data, nextafter);
}
#include "math_data/nextafterf_intel_data.h"
-TEST(MATH_TEST, nextafterf_intel) {
+TEST(math_h, nextafterf_intel) {
DoMathDataTest<1>(g_nextafterf_intel_data, nextafterf);
}
#include "math_data/pow_intel_data.h"
-TEST(MATH_TEST, pow_intel) {
+TEST(math_h, pow_intel) {
DoMathDataTest<1>(g_pow_intel_data, pow);
}
#include "math_data/powf_intel_data.h"
-TEST(MATH_TEST, powf_intel) {
+TEST(math_h, powf_intel) {
DoMathDataTest<1>(g_powf_intel_data, powf);
}
#include "math_data/remainder_intel_data.h"
-TEST(MATH_TEST, remainder_intel) {
+TEST(math_h, remainder_intel) {
DoMathDataTest<1>(g_remainder_intel_data, remainder);
}
#include "math_data/remainderf_intel_data.h"
-TEST(MATH_TEST, remainderf_intel) {
+TEST(math_h, remainderf_intel) {
DoMathDataTest<1>(g_remainderf_intel_data, remainderf);
}
#include "math_data/remquo_intel_data.h"
-TEST(MATH_TEST, remquo_intel) {
+TEST(math_h, remquo_intel) {
DoMathDataTest<1>(g_remquo_intel_data, remquo);
}
#include "math_data/remquof_intel_data.h"
-TEST(MATH_TEST, remquof_intel) {
+TEST(math_h, remquof_intel) {
DoMathDataTest<1>(g_remquof_intel_data, remquof);
}
#include "math_data/rint_intel_data.h"
-TEST(MATH_TEST, rint_intel) {
+TEST(math_h, rint_intel) {
DoMathDataTest<1>(g_rint_intel_data, rint);
}
#include "math_data/rintf_intel_data.h"
-TEST(MATH_TEST, rintf_intel) {
+TEST(math_h, rintf_intel) {
DoMathDataTest<1>(g_rintf_intel_data, rintf);
}
#include "math_data/round_intel_data.h"
-TEST(MATH_TEST, round_intel) {
+TEST(math_h, round_intel) {
DoMathDataTest<1>(g_round_intel_data, round);
}
#include "math_data/roundf_intel_data.h"
-TEST(MATH_TEST, roundf_intel) {
+TEST(math_h, roundf_intel) {
DoMathDataTest<1>(g_roundf_intel_data, roundf);
}
#include "math_data/scalb_intel_data.h"
-TEST(MATH_TEST, scalb_intel) {
+TEST(math_h, scalb_intel) {
DoMathDataTest<1>(g_scalb_intel_data, scalb);
}
#include "math_data/scalbf_intel_data.h"
-TEST(MATH_TEST, scalbf_intel) {
+TEST(math_h, scalbf_intel) {
DoMathDataTest<1>(g_scalbf_intel_data, scalbf);
}
#include "math_data/scalbn_intel_data.h"
-TEST(MATH_TEST, scalbn_intel) {
+TEST(math_h, scalbn_intel) {
DoMathDataTest<1>(g_scalbn_intel_data, scalbn);
}
#include "math_data/scalbnf_intel_data.h"
-TEST(MATH_TEST, scalbnf_intel) {
+TEST(math_h, scalbnf_intel) {
DoMathDataTest<1>(g_scalbnf_intel_data, scalbnf);
}
#include "math_data/significand_intel_data.h"
-TEST(MATH_TEST, significand_intel) {
+TEST(math_h, significand_intel) {
DoMathDataTest<1>(g_significand_intel_data, significand);
}
#include "math_data/significandf_intel_data.h"
-TEST(MATH_TEST, significandf_intel) {
+TEST(math_h, significandf_intel) {
DoMathDataTest<1>(g_significandf_intel_data, significandf);
}
#include "math_data/sin_intel_data.h"
-TEST(MATH_TEST, sin_intel) {
+TEST(math_h, sin_intel) {
DoMathDataTest<1>(g_sin_intel_data, sin);
}
#include "math_data/sinf_intel_data.h"
-TEST(MATH_TEST, sinf_intel) {
+TEST(math_h, sinf_intel) {
DoMathDataTest<1>(g_sinf_intel_data, sinf);
}
#include "math_data/sinh_intel_data.h"
-TEST(MATH_TEST, sinh_intel) {
+TEST(math_h, sinh_intel) {
DoMathDataTest<2>(g_sinh_intel_data, sinh);
}
#include "math_data/sinhf_intel_data.h"
-TEST(MATH_TEST, sinhf_intel) {
+TEST(math_h, sinhf_intel) {
DoMathDataTest<2>(g_sinhf_intel_data, sinhf);
}
#include "math_data/sincos_intel_data.h"
-TEST(MATH_TEST, sincos_intel) {
+TEST(math_h, sincos_intel) {
DoMathDataTest<1>(g_sincos_intel_data, sincos);
}
#include "math_data/sincosf_intel_data.h"
-TEST(MATH_TEST, sincosf_intel) {
+TEST(math_h, sincosf_intel) {
DoMathDataTest<1>(g_sincosf_intel_data, sincosf);
}
#include "math_data/sqrt_intel_data.h"
-TEST(MATH_TEST, sqrt_intel) {
+TEST(math_h, sqrt_intel) {
DoMathDataTest<1>(g_sqrt_intel_data, sqrt);
}
#include "math_data/sqrtf_intel_data.h"
-TEST(MATH_TEST, sqrtf_intel) {
+TEST(math_h, sqrtf_intel) {
DoMathDataTest<1>(g_sqrtf_intel_data, sqrtf);
}
#include "math_data/tan_intel_data.h"
-TEST(MATH_TEST, tan_intel) {
+TEST(math_h, tan_intel) {
DoMathDataTest<1>(g_tan_intel_data, tan);
}
#include "math_data/tanf_intel_data.h"
-TEST(MATH_TEST, tanf_intel) {
+TEST(math_h, tanf_intel) {
DoMathDataTest<1>(g_tanf_intel_data, tanf);
}
#include "math_data/tanh_intel_data.h"
-TEST(MATH_TEST, tanh_intel) {
+TEST(math_h, tanh_intel) {
DoMathDataTest<2>(g_tanh_intel_data, tanh);
}
#include "math_data/tanhf_intel_data.h"
-TEST(MATH_TEST, tanhf_intel) {
+TEST(math_h, tanhf_intel) {
DoMathDataTest<2>(g_tanhf_intel_data, tanhf);
}
#include "math_data/trunc_intel_data.h"
-TEST(MATH_TEST, trunc_intel) {
+TEST(math_h, trunc_intel) {
DoMathDataTest<1>(g_trunc_intel_data, trunc);
}
#include "math_data/truncf_intel_data.h"
-TEST(MATH_TEST, truncf_intel) {
+TEST(math_h, truncf_intel) {
DoMathDataTest<1>(g_truncf_intel_data, truncf);
}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index b85edfb2a..c20597b37 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -3486,3 +3486,141 @@ TEST(STDIO_TEST, swprintf_invalid_wf_width) {
GTEST_SKIP() << "no %w in glibc";
#endif
}
+
+TEST(STDIO_TEST, sscanf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int8_t a;
+ EXPECT_EQ(1, sscanf("<0b101>", "<%w8b>", &a));
+ EXPECT_EQ(0b101, a);
+ int8_t b1;
+ EXPECT_EQ(1, sscanf("<0xFF>", "<%w8i>", &b1));
+ EXPECT_EQ(-1, b1);
+ int8_t b2;
+ EXPECT_EQ(1, sscanf("<0x1FF>", "<%w8i>", &b2));
+ EXPECT_EQ(-1, b2);
+ int16_t c1;
+ EXPECT_EQ(1, sscanf("<0xFFFF>", "<%w16i>", &c1));
+ EXPECT_EQ(-1, c1);
+ uint16_t c2;
+ EXPECT_EQ(1, sscanf("<64>", "<%w16d>", &c2));
+ EXPECT_EQ(64, c2);
+ int32_t d;
+ EXPECT_EQ(1, sscanf("<021>", "<%w32o>", &d));
+ EXPECT_EQ(021, d);
+ uint32_t e;
+ EXPECT_EQ(1, sscanf("<-1>", "<%w32u>", &e));
+ EXPECT_EQ(4294967295, e);
+ int64_t f;
+ EXPECT_EQ(1, sscanf("<0x3b>", "<%w64x>", &f));
+ EXPECT_EQ(0x3b, f);
+ EXPECT_EQ(1, sscanf("<0x3b>", "<%w64X>", &f));
+ EXPECT_EQ(0x3B, f);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, sscanf_w_combination) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+ uint32_t a;
+ int64_t b;
+ char c;
+
+ EXPECT_EQ(3, sscanf("<0b10101010101010101010101010101010 0x3333333344444444 1>",
+ "<%w32b %w64x %c>", &a, &b, &c));
+ EXPECT_EQ(0xaaaaaaaa, a);
+ EXPECT_EQ(0x3333333344444444, b);
+ EXPECT_EQ('1', c);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, sscanf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int32_t a;
+ EXPECT_DEATH(sscanf("<100>", "<%w20d>", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int8_t a;
+ EXPECT_EQ(1, swscanf(L"<0b101>", L"<%w8b>", &a));
+ EXPECT_EQ(0b101, a);
+ int8_t b1;
+ EXPECT_EQ(1, swscanf(L"<0xFF>", L"<%w8i>", &b1));
+ EXPECT_EQ(-1, b1);
+ int8_t b2;
+ EXPECT_EQ(1, swscanf(L"<0x1FF>", L"<%w8i>", &b2));
+ EXPECT_EQ(-1, b2);
+ int16_t c1;
+ EXPECT_EQ(1, swscanf(L"<0xFFFF>", L"<%w16i>", &c1));
+ EXPECT_EQ(-1, c1);
+ uint16_t c2;
+ EXPECT_EQ(1, swscanf(L"<64>", L"<%w16d>", &c2));
+ EXPECT_EQ(64, c2);
+ int32_t d;
+ EXPECT_EQ(1, swscanf(L"<021>", L"<%w32o>", &d));
+ EXPECT_EQ(021, d);
+ uint32_t e;
+ EXPECT_EQ(1, swscanf(L"<-1>", L"<%w32u>", &e));
+ EXPECT_EQ(4294967295, e);
+ int64_t f;
+ EXPECT_EQ(1, swscanf(L"<0x3b>", L"<%w64x>", &f));
+ EXPECT_EQ(0x3b, f);
+ EXPECT_EQ(1, swscanf(L"<0x3b>", L"<%w64X>", &f));
+ EXPECT_EQ(0x3B, f);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_w_combination) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+ uint32_t a;
+ int64_t b;
+ char c;
+
+ EXPECT_EQ(3, swscanf(L"<0b10101010101010101010101010101010 0x3333333344444444 1>",
+ L"<%w32b %w64x %c>", &a, &b, &c));
+ EXPECT_EQ(0xaaaaaaaa, a);
+ EXPECT_EQ(0x3333333344444444, b);
+ EXPECT_EQ('1', c);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swscanf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int32_t a;
+ EXPECT_DEATH(swscanf(L"<100>", L"<%w20d>", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+} \ No newline at end of file
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index c818197a0..5afa00baa 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -284,8 +284,8 @@ static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
// If a function is declared as an inline before a certain version, the inline definition
// should have no version tag.
// 3. Each availability type must only be present globally or on a per-arch basis.
-// (e.g. __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(10) __DEPRECATED_IN(11) is fine,
-// but not __INTRODUCED_IN(9) __INTRODUCED_IN_X86(10))
+// (e.g. __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(22) __DEPRECATED_IN(23) is fine,
+// but not __INTRODUCED_IN(9) __INTRODUCED_IN_32(10))
static bool checkSymbol(const Symbol& symbol) {
std::string cwd = getWorkingDir() + "/";
diff --git a/tools/versioner/tests/preprocessor/expected/foo.h b/tools/versioner/tests/preprocessor/expected/foo.h
index d7de9a0f8..4f74927dc 100644
--- a/tools/versioner/tests/preprocessor/expected/foo.h
+++ b/tools/versioner/tests/preprocessor/expected/foo.h
@@ -54,15 +54,16 @@ int multiple_archs() __INTRODUCED_IN(14);
// __INTRODUCED_IN_64(21) should be ignored.
-#if (!defined(__LP64__) && __ANDROID_API__ >= 13) || (defined(__LP64__))
-int multiple_introduced_1() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_X86(13) __INTRODUCED_IN_64(21);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 13) || (defined(__LP64__)) */
+#if (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__))
+int multiple_introduced_1() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
+#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__)) */
+// This needs different guards for 32 vs 64.
-#if (!defined(__LP64__) && __ANDROID_API__ >= 13) || (defined(__LP64__) && __ANDROID_API__ >= 22)
-int multiple_introduced_2() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_X86(13) __INTRODUCED_IN_64(22);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 13) || (defined(__LP64__) && __ANDROID_API__ >= 22) */
+#if (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__) && __ANDROID_API__ >= 26)
+int multiple_introduced_2() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(26);
+#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__) && __ANDROID_API__ >= 26) */
// This produces both an LP64 and a not-LP64 check, but it doesn't need to check for all 64-bit
@@ -74,9 +75,9 @@ int multiple_introduced_3() __INTRODUCED_IN_32(23) __INTRODUCED_IN_64(23);
-#if (!defined(__LP64__) && __ANDROID_API__ >= 12) || (defined(__LP64__))
-int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 12) || (defined(__LP64__)) */
+#if (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28)
+int added_to_lp64_late() __INTRODUCED_IN_64(28);
+#endif /* (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28) */
#if defined(__cplusplus)
diff --git a/tools/versioner/tests/preprocessor/headers/foo.h b/tools/versioner/tests/preprocessor/headers/foo.h
index 7b39f29c5..b01d8a981 100644
--- a/tools/versioner/tests/preprocessor/headers/foo.h
+++ b/tools/versioner/tests/preprocessor/headers/foo.h
@@ -37,15 +37,16 @@ int multiple_archs() __INTRODUCED_IN(14);
#endif
// __INTRODUCED_IN_64(21) should be ignored.
-int multiple_introduced_1() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_X86(13) __INTRODUCED_IN_64(21);
+int multiple_introduced_1() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
-int multiple_introduced_2() __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_X86(13) __INTRODUCED_IN_64(22);
+// This needs different guards for 32 vs 64.
+int multiple_introduced_2() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(26);
// This produces both an LP64 and a not-LP64 check, but it doesn't need to check for all 64-bit
// targets separately.
int multiple_introduced_3() __INTRODUCED_IN_32(23) __INTRODUCED_IN_64(23);
-int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12);
+int added_to_lp64_late() __INTRODUCED_IN_64(28);
#if defined(__cplusplus)
}