Merge changes from topic "appcompat_override" into main
* changes:
Move __system_properties_reload to LIBC from LIBC_PLATFORM
Write appcompat_override system properties
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index ffb5921..75e607c 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -72,6 +72,7 @@
target: {
android: {
+ header_libs: ["bionic_libc_platform_headers"],
static_libs: [
"libmeminfo",
"libprocinfo",
diff --git a/benchmarks/ScopedDecayTimeRestorer.h b/benchmarks/ScopedDecayTimeRestorer.h
new file mode 100644
index 0000000..5835b43
--- /dev/null
+++ b/benchmarks/ScopedDecayTimeRestorer.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <malloc.h>
+
+#if defined(__BIONIC__)
+
+#include "platform/bionic/malloc.h"
+
+class ScopedDecayTimeRestorer {
+ public:
+ ScopedDecayTimeRestorer() {
+ bool value;
+ if (android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value))) {
+ saved_value_ = value ? 1 : 0;
+ }
+ }
+
+ virtual ~ScopedDecayTimeRestorer() { mallopt(M_DECAY_TIME, saved_value_); }
+
+ private:
+ int saved_value_ = 0;
+};
+
+#endif
diff --git a/benchmarks/malloc_benchmark.cpp b/benchmarks/malloc_benchmark.cpp
index 258343f..8f467d2 100644
--- a/benchmarks/malloc_benchmark.cpp
+++ b/benchmarks/malloc_benchmark.cpp
@@ -36,11 +36,14 @@
#include <vector>
#include <benchmark/benchmark.h>
+#include "ScopedDecayTimeRestorer.h"
#include "util.h"
#if defined(__BIONIC__)
static void RunMalloptPurge(benchmark::State& state, int purge_value) {
+ ScopedDecayTimeRestorer restorer;
+
static size_t sizes[] = {8, 16, 32, 64, 128, 1024, 4096, 16384, 65536, 131072, 1048576};
static int pagesize = getpagesize();
mallopt(M_DECAY_TIME, 1);
@@ -69,7 +72,6 @@
mallopt(purge_value, 0);
}
- mallopt(M_DECAY_TIME, 0);
}
static void RunThreadsThroughput(benchmark::State& state, size_t size, size_t num_threads) {
diff --git a/benchmarks/malloc_sql_benchmark.cpp b/benchmarks/malloc_sql_benchmark.cpp
index 383325c..d5b17f6 100644
--- a/benchmarks/malloc_sql_benchmark.cpp
+++ b/benchmarks/malloc_sql_benchmark.cpp
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <benchmark/benchmark.h>
+#include "ScopedDecayTimeRestorer.h"
#include "util.h"
#if defined(__BIONIC__)
@@ -104,6 +105,8 @@
#include "malloc_sql.h"
static void BM_malloc_sql_trace_default(benchmark::State& state) {
+ ScopedDecayTimeRestorer restorer;
+
// The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
@@ -115,14 +118,14 @@
BIONIC_BENCHMARK(BM_malloc_sql_trace_default);
static void BM_malloc_sql_trace_decay1(benchmark::State& state) {
+ ScopedDecayTimeRestorer restorer;
+
mallopt(M_DECAY_TIME, 1);
for (auto _ : state) {
BenchmarkMalloc(g_sql_entries, sizeof(g_sql_entries) / sizeof(MallocEntry),
kMaxSqlAllocSlots);
}
-
- mallopt(M_DECAY_TIME, 0);
}
BIONIC_BENCHMARK(BM_malloc_sql_trace_decay1);
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 14b380a..9be72e7 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <benchmark/benchmark.h>
+#include "ScopedDecayTimeRestorer.h"
#include "util.h"
static void MallocFree(benchmark::State& state) {
@@ -40,6 +41,8 @@
static void BM_stdlib_malloc_free_default(benchmark::State& state) {
#if defined(__BIONIC__)
+ ScopedDecayTimeRestorer restorer;
+
// The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
#endif
@@ -50,11 +53,11 @@
#if defined(__BIONIC__)
static void BM_stdlib_malloc_free_decay1(benchmark::State& state) {
+ ScopedDecayTimeRestorer restorer;
+
mallopt(M_DECAY_TIME, 1);
MallocFree(state);
-
- mallopt(M_DECAY_TIME, 0);
}
BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_free_decay1, "AT_COMMON_SIZES");
#endif
@@ -75,6 +78,8 @@
static void BM_stdlib_calloc_free_default(benchmark::State& state) {
#if defined(__BIONIC__)
+ ScopedDecayTimeRestorer restorer;
+
// The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
#endif
@@ -113,8 +118,9 @@
}
void BM_stdlib_malloc_forty_default(benchmark::State& state) {
-
#if defined(__BIONIC__)
+ ScopedDecayTimeRestorer restorer;
+
// The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
#endif
@@ -125,17 +131,19 @@
#if defined(__BIONIC__)
void BM_stdlib_malloc_forty_decay1(benchmark::State& state) {
+ ScopedDecayTimeRestorer restorer;
+
mallopt(M_DECAY_TIME, 1);
MallocMultiple(state, state.range(0), 40);
-
- mallopt(M_DECAY_TIME, 0);
}
BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_forty_decay1, "AT_COMMON_SIZES");
#endif
void BM_stdlib_malloc_multiple_8192_allocs_default(benchmark::State& state) {
#if defined(__BIONIC__)
+ ScopedDecayTimeRestorer restorer;
+
// The default is expected to be a zero decay time.
mallopt(M_DECAY_TIME, 0);
#endif
@@ -146,11 +154,11 @@
#if defined(__BIONIC__)
void BM_stdlib_malloc_multiple_8192_allocs_decay1(benchmark::State& state) {
+ ScopedDecayTimeRestorer restorer;
+
mallopt(M_DECAY_TIME, 1);
MallocMultiple(state, 8192, state.range(0));
-
- mallopt(M_DECAY_TIME, 0);
}
BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_decay1, "AT_SMALL_SIZES");
#endif
diff --git a/libc/Android.bp b/libc/Android.bp
index fe5f6de..390cc0c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -136,6 +136,8 @@
},
apex_available: ["com.android.runtime"],
+
+ tidy_disabled_srcs: ["upstream-*/**/*.c"],
}
libc_scudo_product_variables = {
@@ -251,7 +253,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"tzcode/**/*.c",
"tzcode/bionic.cpp",
@@ -302,7 +303,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"dns/**/*.c*",
@@ -345,7 +345,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"upstream-freebsd/lib/libc/stdlib/getopt_long.c",
"upstream-freebsd/lib/libc/stdlib/hcreate.c",
@@ -411,7 +410,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"upstream-freebsd/lib/libc/gen/glob.c",
],
@@ -439,7 +437,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"upstream-netbsd/common/lib/libc/stdlib/random.c",
"upstream-netbsd/lib/libc/gen/nice.c",
@@ -497,7 +494,6 @@
cc_library_static {
name: "libc_openbsd_ndk",
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"upstream-openbsd/lib/libc/gen/alarm.c",
"upstream-openbsd/lib/libc/gen/ctype_.c",
@@ -616,7 +612,6 @@
cc_library_static {
name: "libc_openbsd_large_stack",
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"stdio/vfprintf.cpp",
"stdio/vfwprintf.cpp",
@@ -646,78 +641,54 @@
// automatically included.
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
// These two depend on getentropy, which isn't in libc_ndk.a.
"upstream-openbsd/lib/libc/crypt/arc4random.c",
"upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
-
- // May be overriden by per-arch optimized versions
- "upstream-openbsd/lib/libc/string/memchr.c",
- "upstream-openbsd/lib/libc/string/memrchr.c",
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strcat.c",
- "upstream-openbsd/lib/libc/string/strcpy.c",
- "upstream-openbsd/lib/libc/string/strlcat.c",
- "upstream-openbsd/lib/libc/string/strlcpy.c",
- "upstream-openbsd/lib/libc/string/strncat.c",
- "upstream-openbsd/lib/libc/string/strncmp.c",
- "upstream-openbsd/lib/libc/string/strncpy.c",
],
+ // Each architecture has optimized versions of some routines,
+ // and only includes the portable C versions of ones it's missing.
arch: {
arm: {
- exclude_srcs: [
- "upstream-openbsd/lib/libc/string/strcpy.c",
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/strcat.c",
+ srcs: [
+ "upstream-openbsd/lib/libc/string/memchr.c",
+ "upstream-openbsd/lib/libc/string/memrchr.c",
+ "upstream-openbsd/lib/libc/string/stpncpy.c",
+ "upstream-openbsd/lib/libc/string/strlcat.c",
+ "upstream-openbsd/lib/libc/string/strlcpy.c",
+ "upstream-openbsd/lib/libc/string/strncat.c",
+ "upstream-openbsd/lib/libc/string/strncmp.c",
+ "upstream-openbsd/lib/libc/string/strncpy.c",
],
},
arm64: {
- exclude_srcs: [
- "upstream-openbsd/lib/libc/string/memchr.c",
- "upstream-openbsd/lib/libc/string/memrchr.c",
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/strcpy.c",
- "upstream-openbsd/lib/libc/string/strncmp.c",
+ srcs: [
+ "upstream-openbsd/lib/libc/string/stpncpy.c",
+ "upstream-openbsd/lib/libc/string/strcat.c",
+ "upstream-openbsd/lib/libc/string/strlcat.c",
+ "upstream-openbsd/lib/libc/string/strlcpy.c",
+ "upstream-openbsd/lib/libc/string/strncat.c",
+ "upstream-openbsd/lib/libc/string/strncpy.c",
],
},
riscv64: {
srcs: [
- "upstream-freebsd/lib/libc/string/memcmp.c",
- "upstream-freebsd/lib/libc/string/memcpy.c",
- "upstream-freebsd/lib/libc/string/memmove.c",
- "upstream-freebsd/lib/libc/string/memset.c",
- "upstream-openbsd/lib/libc/string/strcmp.c",
- "upstream-openbsd/lib/libc/string/strlen.c",
+ "upstream-openbsd/lib/libc/string/memrchr.c",
+ "upstream-openbsd/lib/libc/string/stpncpy.c",
+ "upstream-openbsd/lib/libc/string/strlcat.c",
+ "upstream-openbsd/lib/libc/string/strlcpy.c",
],
},
x86: {
- exclude_srcs: [
+ // This space intentionally left blank.
+ },
+ x86_64: {
+ srcs: [
"upstream-openbsd/lib/libc/string/memchr.c",
"upstream-openbsd/lib/libc/string/memrchr.c",
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strcat.c",
- "upstream-openbsd/lib/libc/string/strcpy.c",
- "upstream-openbsd/lib/libc/string/strncmp.c",
- "upstream-openbsd/lib/libc/string/strncpy.c",
"upstream-openbsd/lib/libc/string/strlcat.c",
"upstream-openbsd/lib/libc/string/strlcpy.c",
- "upstream-openbsd/lib/libc/string/strncat.c",
- ],
- },
-
- x86_64: {
- exclude_srcs: [
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strcat.c",
- "upstream-openbsd/lib/libc/string/strcpy.c",
- "upstream-openbsd/lib/libc/string/strncat.c",
- "upstream-openbsd/lib/libc/string/strncmp.c",
- "upstream-openbsd/lib/libc/string/strncpy.c",
],
},
},
@@ -745,7 +716,6 @@
cc_library_static {
defaults: ["libc_defaults"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"upstream-openbsd/android/gdtoa_support.cpp",
"upstream-openbsd/lib/libc/gdtoa/dmisc.c",
@@ -861,26 +831,12 @@
// The following must not be statically linked into libc_ndk.a, because
// debuggerd will look for the abort message in libc.so's copy.
"bionic/android_set_abort_message.cpp",
-
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.c",
- "bionic/strrchr.cpp",
],
arch: {
arm: {
asflags: libc_common_flags + ["-mno-restrict-it"],
srcs: [
- "arch-arm/generic/bionic/memcmp.S",
- "arch-arm/generic/bionic/memmove.S",
- "arch-arm/generic/bionic/memset.S",
- "arch-arm/generic/bionic/stpcpy.c",
- "arch-arm/generic/bionic/strcat.c",
- "arch-arm/generic/bionic/strcmp.S",
- "arch-arm/generic/bionic/strcpy.S",
- "arch-arm/generic/bionic/strlen.c",
-
"arch-arm/bionic/__aeabi_read_tp.S",
"arch-arm/bionic/__bionic_clone.S",
"arch-arm/bionic/__restore.S",
@@ -893,6 +849,20 @@
"arch-arm/bionic/syscall.S",
"arch-arm/bionic/vfork.S",
+ "bionic/strchr.cpp",
+ "bionic/strchrnul.cpp",
+ "bionic/strnlen.c",
+ "bionic/strrchr.cpp",
+
+ "arch-arm/generic/bionic/memcmp.S",
+ "arch-arm/generic/bionic/memmove.S",
+ "arch-arm/generic/bionic/memset.S",
+ "arch-arm/generic/bionic/stpcpy.c",
+ "arch-arm/generic/bionic/strcat.c",
+ "arch-arm/generic/bionic/strcmp.S",
+ "arch-arm/generic/bionic/strcpy.S",
+ "arch-arm/generic/bionic/strlen.c",
+
"arch-arm/cortex-a15/bionic/memcpy.S",
"arch-arm/cortex-a15/bionic/memmove.S",
"arch-arm/cortex-a15/bionic/memset.S",
@@ -930,12 +900,6 @@
"arch-arm64/bionic/syscall.S",
"arch-arm64/bionic/vfork.S",
],
- exclude_srcs: [
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.c",
- "bionic/strrchr.cpp",
- ],
},
riscv64: {
@@ -946,26 +910,40 @@
"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/stpcpy_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",
+ "bionic/strchrnul.cpp",
+ "bionic/strrchr.cpp",
+
+ "arch-riscv64/string/memchr.S",
+ "arch-riscv64/string/memcmp.S",
+ "arch-riscv64/string/memcpy.S",
+ "arch-riscv64/string/memmove.S",
+ "arch-riscv64/string/memset.S",
+ "arch-riscv64/string/stpcpy.S",
+ "arch-riscv64/string/strcat.S",
+ "arch-riscv64/string/strchr.S",
+ "arch-riscv64/string/strcmp.S",
+ "arch-riscv64/string/strcpy.S",
+ "arch-riscv64/string/strlen.S",
+ "arch-riscv64/string/strncat.S",
+ "arch-riscv64/string/strncmp.S",
+ "arch-riscv64/string/strncpy.S",
+ "arch-riscv64/string/strnlen.S",
],
},
x86: {
srcs: [
+ "arch-x86/bionic/__bionic_clone.S",
+ "arch-x86/bionic/_exit_with_stack_teardown.S",
+ "arch-x86/bionic/libcrt_compat.c",
+ "arch-x86/bionic/__restore.S",
+ "arch-x86/bionic/setjmp.S",
+ "arch-x86/bionic/syscall.S",
+ "arch-x86/bionic/vfork.S",
+ "arch-x86/bionic/__x86.get_pc_thunk.S",
+
+ "bionic/strchrnul.cpp",
+
"arch-x86/generic/string/memcmp.S",
"arch-x86/generic/string/strcmp.S",
"arch-x86/generic/string/strncmp.S",
@@ -1013,25 +991,22 @@
"arch-x86/string/sse4-memcmp-slm.S",
"arch-x86/string/sse4-wmemcmp-slm.S",
-
- "arch-x86/bionic/__bionic_clone.S",
- "arch-x86/bionic/_exit_with_stack_teardown.S",
- "arch-x86/bionic/libcrt_compat.c",
- "arch-x86/bionic/__restore.S",
- "arch-x86/bionic/setjmp.S",
- "arch-x86/bionic/syscall.S",
- "arch-x86/bionic/vfork.S",
- "arch-x86/bionic/__x86.get_pc_thunk.S",
- ],
-
- exclude_srcs: [
- "bionic/strchr.cpp",
- "bionic/strnlen.c",
- "bionic/strrchr.cpp",
],
},
x86_64: {
srcs: [
+ "arch-x86_64/bionic/__bionic_clone.S",
+ "arch-x86_64/bionic/_exit_with_stack_teardown.S",
+ "arch-x86_64/bionic/__restore_rt.S",
+ "arch-x86_64/bionic/setjmp.S",
+ "arch-x86_64/bionic/syscall.S",
+ "arch-x86_64/bionic/vfork.S",
+
+ "bionic/strchr.cpp",
+ "bionic/strchrnul.cpp",
+ "bionic/strnlen.c",
+ "bionic/strrchr.cpp",
+
"arch-x86_64/string/avx2-memset-kbl.S",
"arch-x86_64/string/sse2-memmove-slm.S",
"arch-x86_64/string/sse2-memset-slm.S",
@@ -1045,13 +1020,6 @@
"arch-x86_64/string/sse4-memcmp-slm.S",
"arch-x86_64/string/ssse3-strcmp-slm.S",
"arch-x86_64/string/ssse3-strncmp-slm.S",
-
- "arch-x86_64/bionic/__bionic_clone.S",
- "arch-x86_64/bionic/_exit_with_stack_teardown.S",
- "arch-x86_64/bionic/__restore_rt.S",
- "arch-x86_64/bionic/setjmp.S",
- "arch-x86_64/bionic/syscall.S",
- "arch-x86_64/bionic/vfork.S",
],
},
},
@@ -1569,9 +1537,6 @@
arm64: {
srcs: ["arch-arm64/static_function_dispatch.S"],
},
- riscv64: {
- srcs: ["arch-riscv64/static_function_dispatch.S"]
- },
},
}
@@ -1600,9 +1565,6 @@
arm64: {
srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
},
- riscv64: {
- srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"]
- },
},
}
@@ -2921,7 +2883,6 @@
cc_library_host_static {
name: "libfts",
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: [
"bionic/fts.c",
"upstream-openbsd/lib/libc/stdlib/recallocarray.c",
@@ -2964,7 +2925,6 @@
cc_library_host_static {
name: "libb64",
visibility: ["//external/musl"],
- tidy_disabled_srcs: ["upstream-*/**/*.c"],
srcs: ["upstream-openbsd/lib/libc/net/base64.c"],
export_include_dirs: ["b64/include"],
local_include_dirs: [
diff --git a/libc/NOTICE b/libc/NOTICE
index ef64e0c..b345544 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -942,6 +942,35 @@
-------------------------------------------------------------------
+Copyright (c) 1982, 1986, 1988, 1993
+ The Regents of the University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
Copyright (c) 1982, 1986, 1993
The Regents of the University of California. All rights reserved.
@@ -2048,38 +2077,6 @@
Copyright (c) 1990, 1993
The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Mike Hibler and Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
(c) UNIX System Laboratories, Inc.
All or some portions of this file are derived from material licensed
to the University of California by American Telephone and Telegraph
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
deleted file mode 100644
index 5866fe4..0000000
--- a/libc/arch-riscv64/dynamic_function_dispatch.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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* stpcpy_func(char*, const char*);
-DEFINE_IFUNC_FOR(stpcpy) {
- RETURN_FUNC(stpcpy_func, stpcpy_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
deleted file mode 100644
index f96d40e..0000000
--- a/libc/arch-riscv64/static_function_dispatch.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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(stpcpy, stpcpy_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.S
similarity index 97%
rename from libc/arch-riscv64/string/memchr_vext.S
rename to libc/arch-riscv64/string/memchr.S
index ed76a05..8833436 100644
--- a/libc/arch-riscv64/string/memchr_vext.S
+++ b/libc/arch-riscv64/string/memchr.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define iResult a0
@@ -70,7 +68,7 @@
#define vData v0
#define vMask v8
-ENTRY(memchr_vext)
+ENTRY(memchr)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -95,6 +93,4 @@
add iResult, pSrc, iTemp
ret
-END(memchr_vext)
-
-#endif
+END(memchr)
diff --git a/libc/arch-riscv64/string/memcmp_vext.S b/libc/arch-riscv64/string/memcmp.S
similarity index 97%
rename from libc/arch-riscv64/string/memcmp_vext.S
rename to libc/arch-riscv64/string/memcmp.S
index 1bb381c..9c1ecdc 100644
--- a/libc/arch-riscv64/string/memcmp_vext.S
+++ b/libc/arch-riscv64/string/memcmp.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define iResult a0
@@ -73,7 +71,7 @@
#define vData2 v8
#define vMask v16
-ENTRY(memcmp_vext)
+ENTRY(memcmp)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -105,6 +103,4 @@
sub iResult, iTemp1, iTemp2
ret
-END(memcmp_vext)
-
-#endif
+END(memcmp)
diff --git a/libc/arch-riscv64/string/memcpy_vext.S b/libc/arch-riscv64/string/memcpy.S
similarity index 97%
rename from libc/arch-riscv64/string/memcpy_vext.S
rename to libc/arch-riscv64/string/memcpy.S
index 668973f..def1d9b 100644
--- a/libc/arch-riscv64/string/memcpy_vext.S
+++ b/libc/arch-riscv64/string/memcpy.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -67,7 +65,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memcpy_vext)
+ENTRY(memcpy)
mv pDstPtr, pDst
@@ -84,6 +82,4 @@
ret
-END(memcpy_vext)
-
-#endif
+END(memcpy)
diff --git a/libc/arch-riscv64/string/memmove_vext.S b/libc/arch-riscv64/string/memmove.S
similarity index 97%
rename from libc/arch-riscv64/string/memmove_vext.S
rename to libc/arch-riscv64/string/memmove.S
index 03f10c5..fa70f76 100644
--- a/libc/arch-riscv64/string/memmove_vext.S
+++ b/libc/arch-riscv64/string/memmove.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -69,7 +67,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memmove_vext)
+ENTRY(memmove)
mv pDstPtr, pDst
@@ -101,6 +99,4 @@
bnez iNum, L(backward_copy_loop)
ret
-END(memmove_vext)
-
-#endif
+END(memmove)
diff --git a/libc/arch-riscv64/string/memset_vext.S b/libc/arch-riscv64/string/memset.S
similarity index 97%
rename from libc/arch-riscv64/string/memset_vext.S
rename to libc/arch-riscv64/string/memset.S
index 554d6bd..5aa525e 100644
--- a/libc/arch-riscv64/string/memset_vext.S
+++ b/libc/arch-riscv64/string/memset.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -68,7 +66,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memset_vext)
+ENTRY(memset)
mv pDstPtr, pDst
@@ -84,6 +82,4 @@
ret
-END(memset_vext)
-
-#endif
+END(memset)
diff --git a/libc/arch-riscv64/string/stpcpy_vext.S b/libc/arch-riscv64/string/stpcpy.S
similarity index 94%
rename from libc/arch-riscv64/string/stpcpy_vext.S
rename to libc/arch-riscv64/string/stpcpy.S
index 3096e76..c5d0945 100644
--- a/libc/arch-riscv64/string/stpcpy_vext.S
+++ b/libc/arch-riscv64/string/stpcpy.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDstPtr a0
@@ -70,7 +68,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(stpcpy_vext)
+ENTRY(stpcpy)
L(stpcpy_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
vle8ff.v vStr1, (pSrc)
@@ -83,9 +81,8 @@
add pDstPtr, pDstPtr, iCurrentVL
bltz iActiveElemPos, L(stpcpy_loop)
- // stpcpy() returns a pointer to the '\0', not the byte after it.
- addi pDstPtr, pDstPtr, -1
+ // stpcpy() returns a pointer to the '\0' in the destination.
+ sub pDstPtr, pDstPtr, iCurrentVL
+ add pDstPtr, pDstPtr, iActiveElemPos
ret
-END(stpcpy_vext)
-
-#endif
+END(stpcpy)
diff --git a/libc/arch-riscv64/string/strcat_vext.S b/libc/arch-riscv64/string/strcat.S
similarity index 97%
rename from libc/arch-riscv64/string/strcat_vext.S
rename to libc/arch-riscv64/string/strcat.S
index 05e0dfc..5abf295 100644
--- a/libc/arch-riscv64/string/strcat_vext.S
+++ b/libc/arch-riscv64/string/strcat.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -71,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcat_vext)
+ENTRY(strcat)
mv pDstPtr, pDst
@@ -106,6 +104,4 @@
ret
-END(strcat_vext)
-
-#endif
+END(strcat)
diff --git a/libc/arch-riscv64/string/strchr_vext.S b/libc/arch-riscv64/string/strchr.S
similarity index 97%
rename from libc/arch-riscv64/string/strchr_vext.S
rename to libc/arch-riscv64/string/strchr.S
index 4c7bac1..ea13c5d 100644
--- a/libc/arch-riscv64/string/strchr_vext.S
+++ b/libc/arch-riscv64/string/strchr.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pStr a0
@@ -71,7 +69,7 @@
#define vMaskEnd v8
#define vMaskCh v9
-ENTRY(strchr_vext)
+ENTRY(strchr)
L(strchr_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
@@ -93,6 +91,4 @@
add pStr, pStr, iChOffset
ret
-END(strchr_vext)
-
-#endif
+END(strchr)
diff --git a/libc/arch-riscv64/string/strcmp_vext.S b/libc/arch-riscv64/string/strcmp.S
similarity index 98%
rename from libc/arch-riscv64/string/strcmp_vext.S
rename to libc/arch-riscv64/string/strcmp.S
index b793c9a..3332c83 100644
--- a/libc/arch-riscv64/string/strcmp_vext.S
+++ b/libc/arch-riscv64/string/strcmp.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define iResult a0
@@ -76,7 +74,7 @@
#define vMask1 v16
#define vMask2 v17
-ENTRY(strcmp_vext)
+ENTRY(strcmp)
# increase the lmul using the following sequences:
# 1/2, 1/2, 1, 2, 4, 4, 4, ...
@@ -168,6 +166,4 @@
sub iResult, iTemp1, iTemp2
ret
-END(strcmp_vext)
-
-#endif
+END(strcmp)
diff --git a/libc/arch-riscv64/string/strcpy_vext.S b/libc/arch-riscv64/string/strcpy.S
similarity index 97%
rename from libc/arch-riscv64/string/strcpy_vext.S
rename to libc/arch-riscv64/string/strcpy.S
index ab8da48..b89b1a8 100644
--- a/libc/arch-riscv64/string/strcpy_vext.S
+++ b/libc/arch-riscv64/string/strcpy.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -71,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcpy_vext)
+ENTRY(strcpy)
mv pDstPtr, pDst
@@ -90,6 +88,4 @@
ret
-END(strcpy_vext)
-
-#endif
+END(strcpy)
diff --git a/libc/arch-riscv64/string/strlen_vext.S b/libc/arch-riscv64/string/strlen.S
similarity index 98%
rename from libc/arch-riscv64/string/strlen_vext.S
rename to libc/arch-riscv64/string/strlen.S
index 694f95c..7f7d2dd 100644
--- a/libc/arch-riscv64/string/strlen_vext.S
+++ b/libc/arch-riscv64/string/strlen.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define iResult a0
@@ -68,7 +66,7 @@
#define vStr v0
#define vMaskEnd v2
-ENTRY(strlen_vext)
+ENTRY(strlen)
mv pCopyStr, pStr
L(loop):
@@ -87,5 +85,3 @@
ret
END(strlen)
-
-#endif
diff --git a/libc/arch-riscv64/string/strncat_vext.S b/libc/arch-riscv64/string/strncat.S
similarity index 97%
rename from libc/arch-riscv64/string/strncat_vext.S
rename to libc/arch-riscv64/string/strncat.S
index 9fcd37d..01cb14f 100644
--- a/libc/arch-riscv64/string/strncat_vext.S
+++ b/libc/arch-riscv64/string/strncat.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -72,7 +70,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncat_vext)
+ENTRY(strncat)
mv pDstPtr, pDst
@@ -116,6 +114,4 @@
L(fill_zero_end):
ret
-END(strncat_vext)
-
-#endif
+END(strncat)
diff --git a/libc/arch-riscv64/string/strncmp_vext.S b/libc/arch-riscv64/string/strncmp.S
similarity index 97%
rename from libc/arch-riscv64/string/strncmp_vext.S
rename to libc/arch-riscv64/string/strncmp.S
index ec3ec50..b9e6ee2 100644
--- a/libc/arch-riscv64/string/strncmp_vext.S
+++ b/libc/arch-riscv64/string/strncmp.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define iResult a0
@@ -73,7 +71,7 @@
#define vMask1 v8
#define vMask2 v9
-ENTRY(strncmp_vext)
+ENTRY(strncmp)
beqz iLength, L(zero_length)
@@ -118,6 +116,4 @@
li iResult, 0
ret
-END(strncmp_vext)
-
-#endif
+END(strncmp)
diff --git a/libc/arch-riscv64/string/strncpy_vext.S b/libc/arch-riscv64/string/strncpy.S
similarity index 97%
rename from libc/arch-riscv64/string/strncpy_vext.S
rename to libc/arch-riscv64/string/strncpy.S
index eff6293..651a064 100644
--- a/libc/arch-riscv64/string/strncpy_vext.S
+++ b/libc/arch-riscv64/string/strncpy.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pDst a0
@@ -73,7 +71,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncpy_vext)
+ENTRY(strncpy)
mv pDstPtr, pDst
@@ -113,6 +111,4 @@
ret
-END(strncpy_vext)
-
-#endif
+END(strncpy)
diff --git a/libc/arch-riscv64/string/strnlen_vext.S b/libc/arch-riscv64/string/strnlen.S
similarity index 97%
rename from libc/arch-riscv64/string/strnlen_vext.S
rename to libc/arch-riscv64/string/strnlen.S
index ca07231..66366f0 100644
--- a/libc/arch-riscv64/string/strnlen_vext.S
+++ b/libc/arch-riscv64/string/strnlen.S
@@ -53,8 +53,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if defined(__riscv_v)
-
#include <private/bionic_asm.h>
#define pStr a0
@@ -68,7 +66,7 @@
#define vStr v0
#define vMaskEnd v8
-ENTRY(strnlen_vext)
+ENTRY(strnlen)
mv pCopyStr, pStr
mv iRetValue, iMaxlen
@@ -88,6 +86,4 @@
L(end_strnlen_loop):
ret
-END(strnlen_vext)
-
-#endif
+END(strnlen)
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 1591785..8068fc2 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -179,26 +179,10 @@
}
#ifdef __aarch64__
-static bool __read_memtag_note(const ElfW(Nhdr)* note, const char* name, const char* desc,
- unsigned* result) {
- if (note->n_type != NT_ANDROID_TYPE_MEMTAG) {
- return false;
- }
- if (note->n_namesz != 8 || strncmp(name, "Android", 8) != 0) {
- return false;
- }
- // Previously (in Android 12), if the note was != 4 bytes, we check-failed
- // here. Let's be more permissive to allow future expansion.
- if (note->n_descsz < 4) {
- async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
- note->n_descsz);
- }
- *result = *reinterpret_cast<const ElfW(Word)*>(desc);
- return true;
-}
-
-static unsigned __get_memtag_note(const ElfW(Phdr)* phdr_start, size_t phdr_ct,
- const ElfW(Addr) load_bias) {
+static bool __get_elf_note(const ElfW(Phdr) * phdr_start, size_t phdr_ct,
+ const ElfW(Addr) load_bias, unsigned desired_type,
+ const char* desired_name, const ElfW(Nhdr) * *note_out,
+ const char** desc_out) {
for (size_t i = 0; i < phdr_ct; ++i) {
const ElfW(Phdr)* phdr = &phdr_start[i];
if (phdr->p_type != PT_NOTE) {
@@ -216,13 +200,68 @@
if (p > note_end) {
break;
}
- unsigned ret;
- if (__read_memtag_note(note, name, desc, &ret)) {
- return ret;
+ if (note->n_type != desired_type) {
+ continue;
}
+ size_t desired_name_len = strlen(desired_name);
+ if (note->n_namesz != desired_name_len + 1 ||
+ strncmp(desired_name, name, desired_name_len) != 0) {
+ break;
+ }
+ *note_out = note;
+ *desc_out = desc;
+ return true;
}
}
- return 0;
+ return false;
+}
+
+static HeapTaggingLevel __get_memtag_level_from_note(const ElfW(Phdr) * phdr_start, size_t phdr_ct,
+ const ElfW(Addr) load_bias, bool* stack) {
+ const ElfW(Nhdr) * note;
+ const char* desc;
+ if (!__get_elf_note(phdr_start, phdr_ct, load_bias, NT_ANDROID_TYPE_MEMTAG, "Android", ¬e,
+ &desc)) {
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ }
+
+ // Previously (in Android 12), if the note was != 4 bytes, we check-failed
+ // here. Let's be more permissive to allow future expansion.
+ if (note->n_descsz < 4) {
+ async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
+ note->n_descsz);
+ }
+
+ // `desc` is always aligned due to ELF requirements, enforced in __get_elf_note().
+ ElfW(Word) note_val = *reinterpret_cast<const ElfW(Word)*>(desc);
+ *stack = (note_val & NT_MEMTAG_STACK) != 0;
+
+ // Warning: In Android 12, any value outside of bits [0..3] resulted in a check-fail.
+ if (!(note_val & (NT_MEMTAG_HEAP | NT_MEMTAG_STACK))) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "unrecognised memtag note_val did not specificy heap or stack: %u",
+ note_val);
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ }
+
+ unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
+ switch (mode) {
+ case NT_MEMTAG_LEVEL_NONE:
+ // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
+ // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
+ // by anyone, but we note it (heh) here for posterity, in case the zero
+ // level becomes meaningful, and binaries with this note can be executed
+ // on Android 12 devices.
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ case NT_MEMTAG_LEVEL_ASYNC:
+ return M_HEAP_TAGGING_LEVEL_ASYNC;
+ case NT_MEMTAG_LEVEL_SYNC:
+ default:
+ // We allow future extensions to specify mode 3 (currently unused), with
+ // the idea that it might be used for ASYMM mode or something else. On
+ // this version of Android, it falls back to SYNC mode.
+ return M_HEAP_TAGGING_LEVEL_SYNC;
+ }
}
// Returns true if there's an environment setting (either sysprop or env var)
@@ -273,48 +312,57 @@
// Returns the initial heap tagging level. Note: This function will never return
// M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable
// M_HEAP_TAGGING_LEVEL_TBI.
-static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t phdr_ct,
- uintptr_t load_bias, bool* stack) {
- unsigned note_val =
- __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
- *stack = note_val & NT_MEMTAG_STACK;
+static HeapTaggingLevel __get_tagging_level(const memtag_dynamic_entries_t* memtag_dynamic_entries,
+ const void* phdr_start, size_t phdr_ct,
+ uintptr_t load_bias, bool* stack) {
+ HeapTaggingLevel level = M_HEAP_TAGGING_LEVEL_TBI;
- HeapTaggingLevel level;
- if (get_environment_memtag_setting(&level)) return level;
-
- // Note, previously (in Android 12), any value outside of bits [0..3] resulted
- // in a check-fail. In order to be permissive of further extensions, we
- // relaxed this restriction.
- if (!(note_val & (NT_MEMTAG_HEAP | NT_MEMTAG_STACK))) return M_HEAP_TAGGING_LEVEL_TBI;
-
- unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
- switch (mode) {
- case NT_MEMTAG_LEVEL_NONE:
- // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
- // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
- // by anyone, but we note it (heh) here for posterity, in case the zero
- // level becomes meaningful, and binaries with this note can be executed
- // on Android 12 devices.
- return M_HEAP_TAGGING_LEVEL_TBI;
- case NT_MEMTAG_LEVEL_ASYNC:
- return M_HEAP_TAGGING_LEVEL_ASYNC;
- case NT_MEMTAG_LEVEL_SYNC:
- default:
- // We allow future extensions to specify mode 3 (currently unused), with
- // the idea that it might be used for ASYMM mode or something else. On
- // this version of Android, it falls back to SYNC mode.
- return M_HEAP_TAGGING_LEVEL_SYNC;
+ // If the dynamic entries exist, use those. Otherwise, fall back to the old
+ // Android note, which is still used for fully static executables. When
+ // -fsanitize=memtag* is used in newer toolchains, currently both the dynamic
+ // entries and the old note are created, but we'd expect to move to just the
+ // dynamic entries for dynamically linked executables in the future. In
+ // addition, there's still some cleanup of the build system (that uses a
+ // manually-constructed note) needed. For more information about the dynamic
+ // entries, see:
+ // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#dynamic-section
+ if (memtag_dynamic_entries && memtag_dynamic_entries->has_memtag_mode) {
+ switch (memtag_dynamic_entries->memtag_mode) {
+ case 0:
+ level = M_HEAP_TAGGING_LEVEL_SYNC;
+ break;
+ case 1:
+ level = M_HEAP_TAGGING_LEVEL_ASYNC;
+ break;
+ default:
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "unrecognised DT_AARCH64_MEMTAG_MODE value: %u",
+ memtag_dynamic_entries->memtag_mode);
+ }
+ *stack = memtag_dynamic_entries->memtag_stack;
+ } else {
+ level = __get_memtag_level_from_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct,
+ load_bias, stack);
}
+
+ // We can't short-circuit the environment override, as `stack` is still inherited from the
+ // binary's settings.
+ if (get_environment_memtag_setting(&level)) {
+ if (level == M_HEAP_TAGGING_LEVEL_NONE || level == M_HEAP_TAGGING_LEVEL_TBI) {
+ *stack = false;
+ }
+ }
+ return level;
}
// Figure out the desired memory tagging mode (sync/async, heap/globals/stack) for this executable.
// This function is called from the linker before the main executable is relocated.
-__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const void* phdr_start,
- size_t phdr_ct,
- uintptr_t load_bias,
- void* stack_top) {
- bool memtag_stack;
- HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias, &memtag_stack);
+__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(
+ const memtag_dynamic_entries_t* memtag_dynamic_entries, const void* phdr_start, size_t phdr_ct,
+ uintptr_t load_bias, void* stack_top) {
+ bool memtag_stack = false;
+ HeapTaggingLevel level =
+ __get_tagging_level(memtag_dynamic_entries, phdr_start, phdr_ct, load_bias, &memtag_stack);
char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
static const char kAppProcessName[] = "app_process64";
const char* progname = __libc_shared_globals()->init_progname;
@@ -385,7 +433,7 @@
__libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
}
#else // __aarch64__
-void __libc_init_mte(const void*, size_t, uintptr_t, void*) {}
+void __libc_init_mte(const memtag_dynamic_entries_t*, const void*, size_t, uintptr_t, void*) {}
#endif // __aarch64__
void __libc_init_profiling_handlers() {
@@ -412,7 +460,8 @@
layout_static_tls(args);
__libc_init_main_thread_final();
__libc_init_common();
- __libc_init_mte(reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM),
+ __libc_init_mte(/*memtag_dynamic_entries=*/nullptr,
+ reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM),
/*load_bias = */ 0, /*stack_top = */ raw_args);
__libc_init_scudo();
__libc_init_profiling_handlers();
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index e159fdc..3c4884b 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -110,12 +110,27 @@
if (param == M_BIONIC_ZERO_INIT) {
return SetHeapZeroInitialize(value);
}
+
// The rest we pass on...
+ int retval;
auto dispatch_table = GetDispatchTable();
if (__predict_false(dispatch_table != nullptr)) {
- return dispatch_table->mallopt(param, value);
+ retval = dispatch_table->mallopt(param, value);
+ } else {
+ retval = Malloc(mallopt)(param, value);
}
- return Malloc(mallopt)(param, value);
+
+ // Track the M_DECAY_TIME mallopt calls.
+ if (param == M_DECAY_TIME && retval == 1) {
+ __libc_globals.mutate([value](libc_globals* globals) {
+ if (value == 0) {
+ atomic_store(&globals->decay_time_enabled, false);
+ } else {
+ atomic_store(&globals->decay_time_enabled, true);
+ }
+ });
+ }
+ return retval;
}
extern "C" void* malloc(size_t bytes) {
@@ -341,6 +356,14 @@
*reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->memtag_stack);
return true;
}
+ if (opcode == M_GET_DECAY_TIME_ENABLED) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->decay_time_enabled);
+ return true;
+ }
errno = ENOTSUP;
return false;
}
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 802a94f..792a114 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -543,6 +543,14 @@
*reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->memtag_stack);
return true;
}
+ if (opcode == M_GET_DECAY_TIME_ENABLED) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->decay_time_enabled);
+ return true;
+ }
// Try heapprofd's mallopt, as it handles options not covered here.
return HeapprofdMallopt(opcode, arg, arg_size);
}
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 1dfc008..04a73f7 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -266,4 +266,6 @@
/* TODO: upstream these to FreeBSD? */
#define R_ARM_TLS_DESC 13
#define R_ARM_IRELATIVE 160
-#define R_X86_64_JUMP_SLOT 7
+
+/* BSD spells this slightly differently to Linux. */
+#define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index ef81c83..2830a49 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -87,6 +87,22 @@
long long atoll(const char* _Nonnull __s) __attribute_pure__;
__wur char* _Nullable realpath(const char* _Nonnull __path, char* _Nullable __resolved);
+
+/**
+ * [system(3)](http://man7.org/linux/man-pages/man3/system.3.html) executes
+ * the given command in a new shell process.
+ *
+ * On Android, the special case of `system(NULL)` always returns 1,
+ * as specified by POSIX. Passing `NULL` to determine whether or
+ * not a shell is available is not portable. Callers should just try
+ * the command they actually want to run, since there are many reasons
+ * why it might fail, both temporarily (for lack of resources, say)
+ * or permanently (for lack of permission, say).
+ *
+ * Returns -1 and sets errno if process creation fails; returns a
+ * [waitpid(2)](http://man7.org/linux/man-pages/man2/waitpid.2.html)
+ * status otherwise.
+ */
int system(const char* _Nonnull __command);
void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index 90ea76e..1e2fcc4 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -25,6 +25,34 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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.
+ */
#pragma once
@@ -129,6 +157,60 @@
*/
#define LOG_PERROR 0x20
+#if defined(SYSLOG_NAMES)
+/** A mapping from name to value, used by `facilitynames` and `prioritynames`. */
+typedef struct _code {
+ char* c_name;
+ int c_val;
+} CODE;
+/* A bogus facility value for "mark". */
+#define INTERNAL_MARK LOG_MAKEPRI((LOG_NFACILITIES<<3), 0)
+/** A table mapping facility names to values. */
+static const CODE facilitynames[] = {
+ { "auth", LOG_AUTH, },
+ { "authpriv", LOG_AUTHPRIV, },
+ { "cron", LOG_CRON, },
+ { "daemon", LOG_DAEMON, },
+ { "ftp", LOG_FTP, },
+ { "kern", LOG_KERN, },
+ { "lpr", LOG_LPR, },
+ { "mail", LOG_MAIL, },
+ { "mark", INTERNAL_MARK, },
+ { "news", LOG_NEWS, },
+ { "security", LOG_AUTH, },
+ { "syslog", LOG_SYSLOG, },
+ { "user", LOG_USER, },
+ { "uucp", LOG_UUCP, },
+ { "local0", LOG_LOCAL0, },
+ { "local1", LOG_LOCAL1, },
+ { "local2", LOG_LOCAL2, },
+ { "local3", LOG_LOCAL3, },
+ { "local4", LOG_LOCAL4, },
+ { "local5", LOG_LOCAL5, },
+ { "local6", LOG_LOCAL6, },
+ { "local7", LOG_LOCAL7, },
+ { NULL, -1, },
+};
+/* A bogus priority value for "none". */
+#define INTERNAL_NOPRI 8
+/** A table mapping priority names to values. */
+static const CODE prioritynames[] = {
+ { "alert", LOG_ALERT, },
+ { "crit", LOG_CRIT, },
+ { "debug", LOG_DEBUG, },
+ { "emerg", LOG_EMERG, },
+ { "err", LOG_ERR, },
+ { "error", LOG_ERR, },
+ { "info", LOG_INFO, },
+ { "none", INTERNAL_NOPRI, },
+ { "notice", LOG_NOTICE, },
+ { "panic", LOG_EMERG, },
+ { "warn", LOG_WARNING, },
+ { "warning", LOG_WARNING, },
+ { NULL, -1, },
+};
+#endif
+
/**
* [closelog(3)](http://man7.org/linux/man-pages/man3/closelog.3.html) does
* nothing on Android.
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 40e1f26..c0b379b 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1471,9 +1471,18 @@
made_change = True
i += 1
- if b.isDefine() and b.define_id in replacements:
- b.define_id = replacements[b.define_id]
- made_change = True
+ if b.isDefine():
+ tokens = CppStringTokenizer(b.define_id).tokens
+ id_change = False
+ for tok in tokens:
+ if tok.kind == TokenKind.IDENTIFIER:
+ if tok.id in replacements:
+ tok.id = replacements[tok.id]
+ id_change = True
+ if id_change:
+ b.define_id = ''.join([tok.id for tok in tokens])
+ made_change = True
+
if made_change and b.isIf():
# Keep 'expr' in sync with 'tokens'.
@@ -2578,10 +2587,12 @@
text = """\
#define SIGRTMIN 32
#define SIGRTMAX _NSIG
+#define SIGRTMAX(a,class) some_func(a, class)
"""
expected = """\
#define __SIGRTMIN 32
#define __SIGRTMAX _KERNEL__NSIG
+#define __SIGRTMAX(a,__linux_class) some_func(a, __linux_class)
"""
self.assertEqual(self.parse(text), expected)
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 91d26ce..65e0117 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -63,6 +63,7 @@
# The kernel usage of __unused for unused struct fields conflicts with the macro defined in <sys/cdefs.h>.
"__unused": "__linux_unused",
# The kernel usage of C++ keywords causes problems for C++ code so rename.
+ "class": "__linux_class",
"private": "__linux_private",
"virtual": "__linux_virtual",
# The non-64 stuff is legacy; msqid64_ds/ipc64_perm is what userspace wants.
@@ -125,6 +126,8 @@
# These are required to support the above functions.
"__fswahw32",
"__fswahb32",
+ # This is used by various macros in <linux/ioprio.h>.
+ "ioprio_value",
]
)
diff --git a/libc/kernel/uapi/linux/ioprio.h b/libc/kernel/uapi/linux/ioprio.h
index c6dc42a..9ae9dae 100644
--- a/libc/kernel/uapi/linux/ioprio.h
+++ b/libc/kernel/uapi/linux/ioprio.h
@@ -61,6 +61,10 @@
IOPRIO_HINT_DEV_DURATION_LIMIT_7 = 7,
};
#define IOPRIO_BAD_VALUE(val,max) ((val) < 0 || (val) >= (max))
-#define IOPRIO_PRIO_VALUE(class,level) ioprio_value(class, level, IOPRIO_HINT_NONE)
-#define IOPRIO_PRIO_VALUE_HINT(class,level,hint) ioprio_value(class, level, hint)
+static __always_inline __u16 ioprio_value(int __linux_class, int level, int hint) {
+ if(IOPRIO_BAD_VALUE(__linux_class, IOPRIO_NR_CLASSES) || IOPRIO_BAD_VALUE(level, IOPRIO_NR_LEVELS) || IOPRIO_BAD_VALUE(hint, IOPRIO_NR_HINTS)) return IOPRIO_CLASS_INVALID << IOPRIO_CLASS_SHIFT;
+ return(__linux_class << IOPRIO_CLASS_SHIFT) | (hint << IOPRIO_HINT_SHIFT) | level;
+}
+#define IOPRIO_PRIO_VALUE(__linux_class,level) ioprio_value(__linux_class, level, IOPRIO_HINT_NONE)
+#define IOPRIO_PRIO_VALUE_HINT(__linux_class,level,hint) ioprio_value(__linux_class, level, hint)
#endif
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index 0a6546e..a06b8ee 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -104,6 +104,13 @@
// Query whether memtag stack is enabled for this process.
M_MEMTAG_STACK_IS_ON = 11,
#define M_MEMTAG_STACK_IS_ON M_MEMTAG_STACK_IS_ON
+ // Query whether the current process has the decay time enabled so that
+ // the memory from allocations are not immediately released to the OS.
+ // Result is assigned to the arg pointer's destination.
+ // arg = bool*
+ // arg_size = sizeof(bool)
+ M_GET_DECAY_TIME_ENABLED = 12,
+#define M_GET_DECAY_TIME_ENABLED M_GET_DECAY_TIME_ENABLED
};
#pragma clang diagnostic push
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 510d556..15b570d 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -49,6 +49,7 @@
long setjmp_cookie;
uintptr_t heap_pointer_tag;
_Atomic(bool) memtag_stack;
+ _Atomic(bool) decay_time_enabled;
// In order to allow a complete switch between dispatch tables without
// the need for copying each function by function in the structure,
@@ -66,6 +67,15 @@
MallocDispatch malloc_dispatch_table;
};
+struct memtag_dynamic_entries_t {
+ void* memtag_globals;
+ size_t memtag_globalssz;
+ bool has_memtag_mode;
+ unsigned memtag_mode;
+ bool memtag_heap;
+ bool memtag_stack;
+};
+
#ifdef __aarch64__
static_assert(OFFSETOF_libc_globals_memtag_stack == offsetof(libc_globals, memtag_stack));
#endif
diff --git a/libc/upstream-freebsd/lib/libc/string/bcopy.c b/libc/upstream-freebsd/lib/libc/string/bcopy.c
deleted file mode 100644
index 84715d0..0000000
--- a/libc/upstream-freebsd/lib/libc/string/bcopy.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-
-typedef intptr_t word; /* "word" used for optimal copy speed */
-
-#define wsize sizeof(word)
-#define wmask (wsize - 1)
-
-/*
- * Copy a block of memory, handling overlap.
- * This is the routine that actually implements
- * (the portable versions of) bcopy, memcpy, and memmove.
- */
-#if defined(MEMCOPY) || defined(MEMMOVE)
-#include <string.h>
-
-void *
-#ifdef MEMCOPY
-memcpy
-#else
-memmove
-#endif
-(void *dst0, const void *src0, size_t length)
-#else
-#include <strings.h>
-
-void
-bcopy(const void *src0, void *dst0, size_t length)
-#endif
-{
- char *dst = dst0;
- const char *src = src0;
- size_t t;
-
- if (length == 0 || dst == src) /* nothing to do */
- goto done;
-
- /*
- * Macros: loop-t-times; and loop-t-times, t>0
- */
-#define TLOOP(s) if (t) TLOOP1(s)
-#define TLOOP1(s) do { s; } while (--t)
-
- if ((unsigned long)dst < (unsigned long)src) {
- /*
- * Copy forward.
- */
- t = (uintptr_t)src; /* only need low bits */
- if ((t | (uintptr_t)dst) & wmask) {
- /*
- * Try to align operands. This cannot be done
- * unless the low bits match.
- */
- if ((t ^ (uintptr_t)dst) & wmask || length < wsize)
- t = length;
- else
- t = wsize - (t & wmask);
- length -= t;
- TLOOP1(*dst++ = *src++);
- }
- /*
- * Copy whole words, then mop up any trailing bytes.
- */
- t = length / wsize;
- TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src;
- src += wsize; dst += wsize);
- t = length & wmask;
- TLOOP(*dst++ = *src++);
- } else {
- /*
- * Copy backwards. Otherwise essentially the same.
- * Alignment works as before, except that it takes
- * (t&wmask) bytes to align, not wsize-(t&wmask).
- */
- src += length;
- dst += length;
- t = (uintptr_t)src;
- if ((t | (uintptr_t)dst) & wmask) {
- if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)
- t = length;
- else
- t &= wmask;
- length -= t;
- TLOOP1(*--dst = *--src);
- }
- t = length / wsize;
- TLOOP(src -= wsize; dst -= wsize;
- *(word *)(void *)dst = *(const word *)(const void *)src);
- t = length & wmask;
- TLOOP(*--dst = *--src);
- }
-done:
-#if defined(MEMCOPY) || defined(MEMMOVE)
- return (dst0);
-#else
- return;
-#endif
-}
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/upstream-freebsd/lib/libc/string/memcmp.c
deleted file mode 100644
index c8d5d92..0000000
--- a/libc/upstream-freebsd/lib/libc/string/memcmp.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <string.h>
-
-/*
- * Compare memory regions.
- */
-int
-memcmp(const void *s1, const void *s2, size_t n)
-{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
-}
diff --git a/libc/upstream-freebsd/lib/libc/string/memcpy.c b/libc/upstream-freebsd/lib/libc/string/memcpy.c
deleted file mode 100644
index ed03856..0000000
--- a/libc/upstream-freebsd/lib/libc/string/memcpy.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define MEMCOPY
-#include "bcopy.c"
diff --git a/libc/upstream-freebsd/lib/libc/string/memmove.c b/libc/upstream-freebsd/lib/libc/string/memmove.c
deleted file mode 100644
index 05cf75a..0000000
--- a/libc/upstream-freebsd/lib/libc/string/memmove.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define MEMMOVE
-#include "bcopy.c"
diff --git a/libc/upstream-freebsd/lib/libc/string/memset.c b/libc/upstream-freebsd/lib/libc/string/memset.c
deleted file mode 100644
index e2d4027..0000000
--- a/libc/upstream-freebsd/lib/libc/string/memset.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Hibler and Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-#define wsize sizeof(u_long)
-#define wmask (wsize - 1)
-
-#ifdef BZERO
-#include <strings.h>
-
-#define RETURN return
-#define VAL 0
-#define WIDEVAL 0
-
-void
-bzero(void *dst0, size_t length)
-#else
-#include <string.h>
-
-#define RETURN return (dst0)
-#define VAL c0
-#define WIDEVAL c
-
-void *
-memset(void *dst0, int c0, size_t length)
-#endif
-{
- size_t t;
-#ifndef BZERO
- u_long c;
-#endif
- u_char *dst;
-
- dst = dst0;
- /*
- * If not enough words, just fill bytes. A length >= 2 words
- * guarantees that at least one of them is `complete' after
- * any necessary alignment. For instance:
- *
- * |-----------|-----------|-----------|
- * |00|01|02|03|04|05|06|07|08|09|0A|00|
- * ^---------------------^
- * dst dst+length-1
- *
- * but we use a minimum of 3 here since the overhead of the code
- * to do word writes is substantial.
- *
- * TODO: This threshold might not be sensible for 64-bit u_long.
- * We should benchmark and revisit this decision.
- */
- if (length < 3 * wsize) {
- while (length != 0) {
- *dst++ = VAL;
- --length;
- }
- RETURN;
- }
-
-#ifndef BZERO
- if ((c = (u_char)c0) != 0) { /* Fill the word. */
- c = (c << 8) | c; /* u_long is 16 bits. */
-#if ULONG_MAX > 0xffff
- c = (c << 16) | c; /* u_long is 32 bits. */
-#endif
-#if ULONG_MAX > 0xffffffff
- c = (c << 32) | c; /* u_long is 64 bits. */
-#endif
- }
-#endif
- /* Align destination by filling in bytes. */
- if ((t = (long)dst & wmask) != 0) {
- t = wsize - t;
- length -= t;
- do {
- *dst++ = VAL;
- } while (--t != 0);
- }
-
- /* Fill words. Length was >= 2*words so we know t >= 1 here. */
- t = length / wsize;
- do {
- *(u_long *)(void *)dst = WIDEVAL;
- dst += wsize;
- } while (--t != 0);
-
- /* Mop up trailing bytes, if any. */
- t = length & wmask;
- if (t != 0)
- do {
- *dst++ = VAL;
- } while (--t != 0);
- RETURN;
-}
diff --git a/libc/upstream-openbsd/lib/libc/string/strcmp.c b/libc/upstream-openbsd/lib/libc/string/strcmp.c
deleted file mode 100644
index be17556..0000000
--- a/libc/upstream-openbsd/lib/libc/string/strcmp.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $OpenBSD: strcmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * 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 <string.h>
-
-/*
- * Compare strings.
- */
-int
-strcmp(const char *s1, const char *s2)
-{
- while (*s1 == *s2++)
- if (*s1++ == 0)
- return (0);
- return (*(unsigned char *)s1 - *(unsigned char *)--s2);
-}
-DEF_STRONG(strcmp);
diff --git a/libc/upstream-openbsd/lib/libc/string/strcpy.c b/libc/upstream-openbsd/lib/libc/string/strcpy.c
deleted file mode 100644
index 290eefe..0000000
--- a/libc/upstream-openbsd/lib/libc/string/strcpy.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $OpenBSD: strcpy.c,v 1.10 2017/11/28 06:55:49 tb Exp $ */
-
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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 <string.h>
-
-#if defined(APIWARN)
-__warn_references(strcpy,
- "strcpy() is almost always misused, please use strlcpy()");
-#endif
-
-char *
-strcpy(char *to, const char *from)
-{
- char *save = to;
-
- for (; (*to = *from) != '\0'; ++from, ++to);
- return(save);
-}
diff --git a/libc/upstream-openbsd/lib/libc/string/strlen.c b/libc/upstream-openbsd/lib/libc/string/strlen.c
deleted file mode 100644
index a5721d3..0000000
--- a/libc/upstream-openbsd/lib/libc/string/strlen.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $OpenBSD: strlen.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * 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 <string.h>
-
-size_t
-strlen(const char *str)
-{
- const char *s;
-
- for (s = str; *s; ++s)
- ;
- return (s - str);
-}
-
-DEF_STRONG(strlen);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 1553ba9..135eaa3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -71,11 +71,12 @@
#include "linker_translate_path.h"
#include "linker_utils.h"
+#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
+#include "android-base/strings.h"
+#include "private/bionic_asm_note.h"
#include "private/bionic_call_ifunc_resolver.h"
#include "private/bionic_globals.h"
-#include "android-base/macros.h"
-#include "android-base/strings.h"
-#include "android-base/stringprintf.h"
#include "ziparchive/zip_archive.h"
static std::unordered_map<void*, size_t> g_dso_handle_counters;
@@ -3194,13 +3195,32 @@
case DT_AARCH64_VARIANT_PCS:
// Ignored: AArch64 processor-specific dynamic array tags.
break;
- // TODO(mitchp): Add support to libc_init_mte to use these dynamic array entries instead of
- // the Android-specific ELF note.
case DT_AARCH64_MEMTAG_MODE:
+ memtag_dynamic_entries_.has_memtag_mode = true;
+ memtag_dynamic_entries_.memtag_mode = d->d_un.d_val;
+ break;
case DT_AARCH64_MEMTAG_HEAP:
+ memtag_dynamic_entries_.memtag_heap = d->d_un.d_val;
+ break;
+ // The AArch64 MemtagABI originally erroneously defined
+ // DT_AARCH64_MEMTAG_STACK as `d_ptr`, which is why the dynamic tag value
+ // is odd (`0x7000000c`). `d_val` is clearly the correct semantics, and so
+ // this was fixed in the ABI, but the value (0x7000000c) didn't change
+ // because we already had Android binaries floating around with dynamic
+ // entries, and didn't want to create a whole new dynamic entry and
+ // reserve a value just to fix that tiny mistake. P.S. lld was always
+ // outputting DT_AARCH64_MEMTAG_STACK as `d_val` anyway.
case DT_AARCH64_MEMTAG_STACK:
+ memtag_dynamic_entries_.memtag_stack = d->d_un.d_val;
+ break;
+ // Same as above, except DT_AARCH64_MEMTAG_GLOBALS was incorrectly defined
+ // as `d_val` (hence an even value of `0x7000000d`), when it should have
+ // been `d_ptr` all along. lld has always outputted this as `d_ptr`.
case DT_AARCH64_MEMTAG_GLOBALS:
+ memtag_dynamic_entries_.memtag_globals = reinterpret_cast<void*>(load_bias + d->d_un.d_ptr);
+ break;
case DT_AARCH64_MEMTAG_GLOBALSSZ:
+ memtag_dynamic_entries_.memtag_globalssz = d->d_un.d_val;
break;
#endif
diff --git a/linker/linker_auxv.cpp b/linker/linker_auxv.cpp
index d8e4a3e..95413a0 100644
--- a/linker/linker_auxv.cpp
+++ b/linker/linker_auxv.cpp
@@ -87,6 +87,12 @@
#if defined(AT_L2_CACHEGEOMETRY)
case AT_L2_CACHEGEOMETRY: return "AT_L2_CACHEGEOMETRY";
#endif
+#if defined(AT_L3_CACHESIZE)
+ case AT_L3_CACHESIZE: return "AT_L3_CACHESIZE";
+#endif
+#if defined(AT_L3_CACHEGEOMETRY)
+ case AT_L3_CACHEGEOMETRY: return "AT_L3_CACHEGEOMETRY";
+#endif
}
static char name[32];
snprintf(name, sizeof(name), "AT_??? (%d)", at);
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 5a33a63..5f5eba4 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -68,8 +68,8 @@
static void set_bss_vma_name(soinfo* si);
-void __libc_init_mte(const void* phdr_start, size_t phdr_count, uintptr_t load_bias,
- void* stack_top);
+void __libc_init_mte(const memtag_dynamic_entries_t* memtag_dynamic_entries, const void* phdr_start,
+ size_t phdr_count, uintptr_t load_bias, void* stack_top);
// These should be preserved static to avoid emitting
// RELATIVE relocations for the part of the code running
@@ -405,7 +405,8 @@
}
}
- __libc_init_mte(somain->phdr, somain->phnum, somain->load_bias, args.argv);
+ __libc_init_mte(somain->memtag_dynamic_entries(), somain->phdr, somain->phnum, somain->load_bias,
+ args.argv);
#endif
// Register the main executable and the linker upfront to have
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 97ae709..0ad0fd5 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -849,7 +849,7 @@
* load_bias -> load bias
* prop -> GnuPropertySection or nullptr
* Return:
- * 0 on error, -1 on failure (error code in errno).
+ * 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, const GnuPropertySection* prop __unused) {
@@ -876,7 +876,7 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* Return:
- * 0 on error, -1 on failure (error code in errno).
+ * 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table,
size_t phdr_count, ElfW(Addr) load_bias) {
@@ -939,7 +939,7 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* Return:
- * 0 on error, -1 on failure (error code in errno).
+ * 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count, ElfW(Addr) load_bias) {
@@ -957,7 +957,7 @@
* fd -> writable file descriptor to use
* file_offset -> pointer to offset into file descriptor to use/update
* Return:
- * 0 on error, -1 on failure (error code in errno).
+ * 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count,
@@ -1005,7 +1005,7 @@
* fd -> readable file descriptor to use
* file_offset -> pointer to offset into file descriptor to use/update
* Return:
- * 0 on error, -1 on failure (error code in errno).
+ * 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count,
@@ -1102,7 +1102,7 @@
* arm_exidx -> address of table in memory (null on failure).
* arm_exidx_count -> number of items in table (0 on failure).
* Return:
- * 0 on error, -1 on failure (_no_ error code in errno)
+ * 0 on success, -1 on failure (_no_ error code in errno)
*/
int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias,
diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h
index 37a7880..54aad18 100644
--- a/linker/linker_relocs.h
+++ b/linker/linker_relocs.h
@@ -84,8 +84,7 @@
#define R_GENERIC_TLS_DTPMOD R_RISCV_TLS_DTPMOD64
#define R_GENERIC_TLS_DTPREL R_RISCV_TLS_DTPREL64
#define R_GENERIC_TLS_TPREL R_RISCV_TLS_TPREL64
-// TODO: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/94
-// #define R_GENERIC_TLSDESC R_RISCV_TLS_DESC
+#define R_GENERIC_TLSDESC R_RISCV_TLSDESC
#elif defined (__x86_64__)
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 9c589d6..622719d 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -34,9 +34,11 @@
#include <string>
#include <vector>
-#include "private/bionic_elf_tls.h"
+#include "async_safe/CHECK.h"
#include "linker_namespaces.h"
#include "linker_tls.h"
+#include "private/bionic_elf_tls.h"
+#include "private/bionic_globals.h"
#define FLAG_LINKED 0x00000001
#define FLAG_EXE 0x00000004 // The main executable
@@ -351,6 +353,17 @@
void set_gap_size(size_t gap_size);
size_t get_gap_size() const;
+ const memtag_dynamic_entries_t* memtag_dynamic_entries() const {
+ CHECK(has_min_version(7));
+ return &memtag_dynamic_entries_;
+ }
+ void* memtag_globals() const { return memtag_dynamic_entries()->memtag_globals; }
+ size_t memtag_globalssz() const { return memtag_dynamic_entries()->memtag_globalssz; }
+ bool has_memtag_mode() const { return memtag_dynamic_entries()->has_memtag_mode; }
+ unsigned memtag_mode() const { return memtag_dynamic_entries()->memtag_mode; }
+ bool memtag_heap() const { return memtag_dynamic_entries()->memtag_heap; }
+ bool memtag_stack() const { return memtag_dynamic_entries()->memtag_stack; }
+
private:
bool is_image_linked() const;
void set_image_linked();
@@ -433,6 +446,9 @@
// version >= 6
ElfW(Addr) gap_start_;
size_t gap_size_;
+
+ // version >= 7
+ memtag_dynamic_entries_t memtag_dynamic_entries_;
};
// This function is used by dlvsym() to calculate hash of sym_ver
diff --git a/tests/bionic_allocator_test.cpp b/tests/bionic_allocator_test.cpp
index fdcf868..d543d26 100644
--- a/tests/bionic_allocator_test.cpp
+++ b/tests/bionic_allocator_test.cpp
@@ -238,23 +238,27 @@
TEST(bionic_allocator, test_memalign_large) {
BionicAllocator allocator;
void* ptr;
+ size_t alignment;
- // a large object with alignment < PAGE_SIZE
- ptr = allocator.memalign(0x100, 0x2000);
+ // a large object with alignment < kPageSize
+ alignment = kPageSize >> 1;
+ ptr = allocator.memalign(alignment, 0x2000);
ASSERT_TRUE(ptr != nullptr);
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % 0x100);
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % alignment);
allocator.free(ptr);
- // a large object with alignment == PAGE_SIZE
- ptr = allocator.memalign(0x1000, 0x2000);
+ // a large object with alignment == kPageSize
+ alignment = kPageSize;
+ ptr = allocator.memalign(alignment, 0x2000);
ASSERT_TRUE(ptr != nullptr);
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % 0x1000);
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % alignment);
allocator.free(ptr);
- // A large object with alignment > PAGE_SIZE is only guaranteed to have page
+ // A large object with alignment > kPageSize is only guaranteed to have page
// alignment.
- ptr = allocator.memalign(0x2000, 0x4000);
+ alignment = kPageSize << 1;
+ ptr = allocator.memalign(alignment, 0x4000);
ASSERT_TRUE(ptr != nullptr);
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % 0x1000);
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) % kPageSize);
allocator.free(ptr);
}
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 3c2dcf2..d078e50 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -85,6 +85,7 @@
}
void* handle_;
+ const size_t kPageSize = getpagesize();
};
TEST_F(DlExtTest, ExtInfoNull) {
@@ -159,12 +160,12 @@
ASSERT_STREQ("dlopen failed: file offset for the library \"libname_placeholder\" is not page-aligned: 17", dlerror());
// Test an address above 2^44, for http://b/18178121 .
- extinfo.library_fd_offset = (5LL<<48) + PAGE_SIZE;
+ extinfo.library_fd_offset = (5LL << 48) + kPageSize;
handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
ASSERT_TRUE(handle_ == nullptr);
ASSERT_SUBSTR("dlopen failed: file offset for the library \"libname_placeholder\" >= file size", dlerror());
- extinfo.library_fd_offset = 0LL - PAGE_SIZE;
+ extinfo.library_fd_offset = 0LL - kPageSize;
handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
ASSERT_TRUE(handle_ == nullptr);
ASSERT_SUBSTR("dlopen failed: file offset for the library \"libname_placeholder\" is negative", dlerror());
@@ -340,17 +341,17 @@
dlclose(handle_);
handle_ = nullptr;
- void* new_start = mmap(start, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* new_start = mmap(start, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(start, new_start) << "dlclose unmapped reserved space";
}
TEST_F(DlExtTest, ReservedTooSmall) {
- void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* start = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_TRUE(start != MAP_FAILED);
android_dlextinfo extinfo;
extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
extinfo.reserved_addr = start;
- extinfo.reserved_size = PAGE_SIZE;
+ extinfo.reserved_size = kPageSize;
handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
EXPECT_EQ(nullptr, handle_);
}
@@ -389,12 +390,12 @@
}
TEST_F(DlExtTest, ReservedRecursiveTooSmall) {
- void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* start = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_TRUE(start != MAP_FAILED);
android_dlextinfo extinfo;
extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
extinfo.reserved_addr = start;
- extinfo.reserved_size = PAGE_SIZE;
+ extinfo.reserved_size = kPageSize;
handle_ = android_dlopen_ext(kLibNameRecursive, RTLD_NOW, &extinfo);
EXPECT_EQ(nullptr, handle_);
}
@@ -417,19 +418,18 @@
}
TEST_F(DlExtTest, ReservedHintTooSmall) {
- void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* start = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_TRUE(start != MAP_FAILED);
android_dlextinfo extinfo;
extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
extinfo.reserved_addr = start;
- extinfo.reserved_size = PAGE_SIZE;
+ extinfo.reserved_size = kPageSize;
handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
ASSERT_DL_NOTNULL(handle_);
fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
ASSERT_DL_NOTNULL(f);
EXPECT_TRUE(reinterpret_cast<void*>(f) < start ||
- (reinterpret_cast<void*>(f) >=
- reinterpret_cast<char*>(start) + PAGE_SIZE));
+ (reinterpret_cast<void*>(f) >= reinterpret_cast<char*>(start) + kPageSize));
EXPECT_EQ(4, f());
}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 67f1973..5b3eaf8 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -824,6 +824,8 @@
}
TEST(dlfcn, dlclose_unload) {
+ const size_t kPageSize = getpagesize();
+
void* handle = dlopen("libtest_simple.so", RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
uint32_t* taxicab_number = static_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
@@ -833,8 +835,8 @@
// Making sure that the library has been unmapped as part of library unload
// process. Note that mprotect somewhat counter-intuitively returns ENOMEM in
// this case.
- uintptr_t page_start = reinterpret_cast<uintptr_t>(taxicab_number) & ~(PAGE_SIZE - 1);
- ASSERT_TRUE(mprotect(reinterpret_cast<void*>(page_start), PAGE_SIZE, PROT_NONE) != 0);
+ uintptr_t page_start = reinterpret_cast<uintptr_t>(taxicab_number) & ~(kPageSize - 1);
+ ASSERT_TRUE(mprotect(reinterpret_cast<void*>(page_start), kPageSize, PROT_NONE) != 0);
ASSERT_ERRNO(ENOMEM);
}
diff --git a/tests/libs/stack_tagging_helper.cpp b/tests/libs/stack_tagging_helper.cpp
index d29844d..7396dd0 100644
--- a/tests/libs/stack_tagging_helper.cpp
+++ b/tests/libs/stack_tagging_helper.cpp
@@ -240,14 +240,14 @@
}
void test_longjmp_sigaltstack() {
- constexpr size_t kAltStackSize = kStackAllocationSize + PAGE_SIZE * 16;
+ const size_t kAltStackSize = kStackAllocationSize + getpagesize() * 16;
SigAltStackScoped sigAltStackScoped(kAltStackSize);
SigActionScoped sigActionScoped(
SIGUSR1, [](int, siginfo_t*, void*) { check_longjmp_restores_tags(); });
raise(SIGUSR1);
// same for a secondary thread
- std::thread t([]() {
+ std::thread t([&]() {
SigAltStackScoped sigAltStackScoped(kAltStackSize);
raise(SIGUSR1);
});
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 2411753..14a426f 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -1734,3 +1734,36 @@
}
}
}
+
+TEST(android_mallopt, get_decay_time_enabled_errors) {
+#if defined(__BIONIC__)
+ errno = 0;
+ EXPECT_FALSE(android_mallopt(M_GET_DECAY_TIME_ENABLED, nullptr, sizeof(bool)));
+ EXPECT_ERRNO(EINVAL);
+
+ errno = 0;
+ int value;
+ EXPECT_FALSE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
+ EXPECT_ERRNO(EINVAL);
+#else
+ GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
+TEST(android_mallopt, get_decay_time_enabled) {
+#if defined(__BIONIC__)
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
+
+ EXPECT_EQ(1, mallopt(M_DECAY_TIME, 0));
+
+ bool value;
+ EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
+ EXPECT_FALSE(value);
+
+ EXPECT_EQ(1, mallopt(M_DECAY_TIME, 1));
+ EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
+ EXPECT_TRUE(value);
+#else
+ GTEST_SKIP() << "bionic-only test";
+#endif
+}
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 4cd89cc..6e1fcfc 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -319,33 +319,34 @@
// one byte target with "\0" source
TEST(STRING_TEST, stpcpy2) {
char buf[1];
+ memset(buf, 'A', sizeof(buf));
char* orig = strdup("");
- ASSERT_EQ(buf, stpcpy(buf, orig));
- ASSERT_EQ('\0', buf[0]);
+ EXPECT_EQ(buf, stpcpy(buf, orig));
+ EXPECT_EQ('\0', buf[0]);
free(orig);
}
// multibyte target where we under fill target
TEST(STRING_TEST, stpcpy3) {
char buf[10];
- char* orig = strdup("12345");
memset(buf, 'A', sizeof(buf));
- ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
- ASSERT_STREQ("12345", buf);
- ASSERT_EQ('A', buf[6]);
- ASSERT_EQ('A', buf[7]);
- ASSERT_EQ('A', buf[8]);
- ASSERT_EQ('A', buf[9]);
+ char* orig = strdup("12345");
+ EXPECT_EQ(buf+strlen(orig), stpcpy(buf, orig));
+ EXPECT_STREQ("12345", buf);
+ EXPECT_EQ('A', buf[6]);
+ EXPECT_EQ('A', buf[7]);
+ EXPECT_EQ('A', buf[8]);
+ EXPECT_EQ('A', buf[9]);
free(orig);
}
// multibyte target where we fill target exactly
TEST(STRING_TEST, stpcpy4) {
char buf[10];
- char* orig = strdup("123456789");
memset(buf, 'A', sizeof(buf));
- ASSERT_EQ(buf+strlen(orig), stpcpy(buf, orig));
- ASSERT_STREQ("123456789", buf);
+ char* orig = strdup("123456789");
+ EXPECT_EQ(buf+strlen(orig), stpcpy(buf, orig));
+ EXPECT_STREQ("123456789", buf);
free(orig);
}
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index e785ff4..df13e07 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -25,6 +25,8 @@
#include "utils.h"
+static const size_t kPageSize = getpagesize();
+
TEST(sys_mman, mmap_std) {
void* map = mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
ASSERT_NE(MAP_FAILED, map);
@@ -233,42 +235,42 @@
}
TEST(sys_mman, mremap_PTRDIFF_MAX) {
- void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* map = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(MAP_FAILED, map);
- ASSERT_EQ(MAP_FAILED, mremap(map, PAGE_SIZE, kHuge, MREMAP_MAYMOVE));
+ ASSERT_EQ(MAP_FAILED, mremap(map, kPageSize, kHuge, MREMAP_MAYMOVE));
- ASSERT_EQ(0, munmap(map, PAGE_SIZE));
+ ASSERT_EQ(0, munmap(map, kPageSize));
}
TEST(sys_mman, mmap_bug_27265969) {
- char* base = reinterpret_cast<char*>(mmap(nullptr, PAGE_SIZE * 2, PROT_EXEC | PROT_READ,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
+ char* base = reinterpret_cast<char*>(
+ mmap(nullptr, kPageSize * 2, PROT_EXEC | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
// Some kernels had bugs that would cause segfaults here...
- __builtin___clear_cache(base, base + (PAGE_SIZE * 2));
+ __builtin___clear_cache(base, base + (kPageSize * 2));
}
TEST(sys_mman, mlock) {
- void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* map = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(MAP_FAILED, map);
// Not really anything we can assert about this.
- mlock(map, PAGE_SIZE);
+ mlock(map, kPageSize);
- ASSERT_EQ(0, munmap(map, PAGE_SIZE));
+ ASSERT_EQ(0, munmap(map, kPageSize));
}
TEST(sys_mman, mlock2) {
#if defined(__GLIBC__)
GTEST_SKIP() << "needs glibc 2.27";
#else
- void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* map = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(MAP_FAILED, map);
// Not really anything we can assert about this.
- mlock2(map, PAGE_SIZE, MLOCK_ONFAULT);
+ mlock2(map, kPageSize, MLOCK_ONFAULT);
- ASSERT_EQ(0, munmap(map, PAGE_SIZE));
+ ASSERT_EQ(0, munmap(map, kPageSize));
#endif
}
diff --git a/tests/syslog_test.cpp b/tests/syslog_test.cpp
index 3ec3337..623d8a3 100644
--- a/tests/syslog_test.cpp
+++ b/tests/syslog_test.cpp
@@ -26,6 +26,9 @@
* SUCH DAMAGE.
*/
+#include <stddef.h> // glibc's <syslog.h> breaks without this; musl seems fine.
+
+#define SYSLOG_NAMES
#include <syslog.h>
#include <errno.h>
@@ -72,3 +75,34 @@
},
0, "bar: x{1023}\n");
}
+
+static int by_name(const CODE* array, const char* name) {
+ for (auto c = array; c->c_name != nullptr; c++) {
+ if (!strcmp(c->c_name, name)) return c->c_val;
+ }
+ return -1;
+}
+
+static const char* by_value(const CODE* array, int value) {
+ for (auto c = array; c->c_name != nullptr; c++) {
+ if (c->c_val == value) return c->c_name;
+ }
+ return nullptr;
+}
+
+TEST(syslog, facilitynames) {
+ ASSERT_STREQ("auth", by_value(facilitynames, LOG_AUTH));
+ ASSERT_STREQ("local7", by_value(facilitynames, LOG_LOCAL7));
+ ASSERT_EQ(LOG_AUTH, by_name(facilitynames, "auth"));
+ ASSERT_EQ(LOG_LOCAL7, by_name(facilitynames, "local7"));
+}
+
+TEST(syslog, prioritynames) {
+ ASSERT_STREQ("alert", by_value(prioritynames, LOG_ALERT));
+ ASSERT_STREQ("err", by_value(prioritynames, LOG_ERR));
+ ASSERT_STREQ("warn", by_value(prioritynames, LOG_WARNING));
+ ASSERT_EQ(LOG_ALERT, by_name(prioritynames, "alert"));
+ ASSERT_EQ(LOG_ERR, by_name(prioritynames, "err"));
+ ASSERT_EQ(LOG_WARNING, by_name(prioritynames, "warn"));
+ ASSERT_EQ(LOG_WARNING, by_name(prioritynames, "warning"));
+}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index c4cc0bd..5256b08 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -297,14 +297,20 @@
// mbrtowc returns 0 "if the next n or fewer bytes complete the multibyte
// character that corresponds to the null wide character"
//
- // mbrtoc says: "If s is not a null pointer, the mbtowc function either
- // returns 0 (if s points to the null character)..."
+ // mbrtoc (C23 7.24.7.2.4) says:
//
- // So mbrtowc will not provide the correct mbtowc return value for "" and
- // n = 0.
+ // If s is not a null pointer, the mbtowc function either returns 0 (if s
+ // points to the null character), or returns the number of bytes that are
+ // contained in the converted multibyte character (if the next n or fewer
+ // bytes form a valid multibyte character), or returns -1 (if they do not
+ // form a valid multibyte character).
//
- // glibc gets this right, but all the BSDs (including macOS) and bionic (by
- // way of openbsd) return -1 instead of 0.
+ // glibc's interpretation differs from all the BSDs (including macOS) and
+ // bionic (by way of openbsd). glibc returns 0 since s does point to the null
+ // character, whereas the BSDs return -1 because the next 0 bytes do not form
+ // a valid multibyte chatacter. glibc's interpretation is probably more
+ // correct from a strict interpretation of the spec, but considering the other
+ // APIs behave more like the BSD interpretation that may be a bug in the spec.
#ifdef __GLIBC__
int expected_result_for_zero_length_empty_string = 0;
#else