Merge "Revert "libc: point some x86_64 function impls at llvm-libc"" into main
diff --git a/OWNERS b/OWNERS
index 3818b1d..1859b9e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,3 +5,5 @@
danalbert@google.com
rprichard@google.com
yabinc@google.com
+
+per-file docs/mte.md=eugenis@google.com,fmayer@google.com,pcc@google.com
diff --git a/docs/status.md b/docs/status.md
index 94784de..e7111d9 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -62,6 +62,7 @@
New libc functions in API level 36:
* `qsort_r`, `sig2str`/`str2sig` (POSIX Issue 8 additions).
* GNU/BSD extension `lchmod`.
+ * GNU extensions `pthread_getaffinity_np`/`pthread_setaffinity_np`.
* New system call wrapper: `mseal` (`<sys/mman.h>`).
New libc functions in V (API level 35):
diff --git a/libc/Android.bp b/libc/Android.bp
index 5ae8c4f..e0d8994 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -941,6 +941,7 @@
"bionic/pthread_detach.cpp",
"bionic/pthread_equal.cpp",
"bionic/pthread_exit.cpp",
+ "bionic/pthread_getaffinity.cpp",
"bionic/pthread_getcpuclockid.cpp",
"bionic/pthread_getschedparam.cpp",
"bionic/pthread_gettid_np.cpp",
@@ -954,6 +955,7 @@
"bionic/pthread_sigqueue.cpp",
"bionic/pthread_self.cpp",
"bionic/pthread_setname_np.cpp",
+ "bionic/pthread_setaffinity.cpp",
"bionic/pthread_setschedparam.cpp",
"bionic/pthread_spinlock.cpp",
"bionic/ptrace.cpp",
diff --git a/libc/bionic/pthread_getaffinity.cpp b/libc/bionic/pthread_getaffinity.cpp
new file mode 100644
index 0000000..9ce436c
--- /dev/null
+++ b/libc/bionic/pthread_getaffinity.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "private/ErrnoRestorer.h"
+#include "pthread_internal.h"
+
+int pthread_getaffinity_np(pthread_t t, size_t cpu_set_size, cpu_set_t* cpu_set) {
+ ErrnoRestorer errno_restorer;
+
+ pid_t tid = __pthread_internal_gettid(t, "pthread_getaffinity_np");
+ if (tid == -1) return ESRCH;
+
+ if (sched_getaffinity(tid, cpu_set_size, cpu_set) == -1) return errno;
+ return 0;
+}
diff --git a/libc/bionic/pthread_setaffinity.cpp b/libc/bionic/pthread_setaffinity.cpp
new file mode 100644
index 0000000..6db418e
--- /dev/null
+++ b/libc/bionic/pthread_setaffinity.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include "private/ErrnoRestorer.h"
+#include "pthread_internal.h"
+
+int pthread_setaffinity_np(pthread_t t, size_t cpu_set_size, const cpu_set_t* cpu_set) {
+ ErrnoRestorer errno_restorer;
+
+ pid_t tid = __pthread_internal_gettid(t, "pthread_setaffinity_np");
+ if (tid == -1) return ESRCH;
+
+ if (sched_setaffinity(tid, cpu_set_size, cpu_set) == -1) return errno;
+ return 0;
+}
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 8b78a74..71ea8f9 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -314,17 +314,60 @@
pthread_t pthread_self(void) __attribute_const__;
-#if defined(__USE_GNU)
-
-#if __BIONIC_AVAILABILITY_GUARD(26)
+#if __USE_GNU && __BIONIC_AVAILABILITY_GUARD(26)
+/**
+ * [pthread_getname_np(3)](https://man7.org/linux/man-pages/man3/pthread_getname_np.3.html)
+ * gets the name of the given thread.
+ * Names are at most 16 bytes (including '\0').
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 26.
+ */
int pthread_getname_np(pthread_t __pthread, char* _Nonnull __buf, size_t __n) __INTRODUCED_IN(26);
-#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
-
#endif
-/* TODO: this should be __USE_GNU too. */
+
+/**
+ * [pthread_setname_np(3)](https://man7.org/linux/man-pages/man3/pthread_setname_np.3.html)
+ * sets the name of the given thread.
+ * Names are at most 16 bytes (including '\0').
+ * Truncation must be done by the caller;
+ * calls with longer names will fail with ERANGE.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * This should only have been available under _GNU_SOURCE,
+ * but is always available on Android by historical accident.
+ */
int pthread_setname_np(pthread_t __pthread, const char* _Nonnull __name);
/**
+ * [pthread_getaffinity_np(3)](https://man7.org/linux/man-pages/man3/pthread_getaffinity_np.3.html)
+ * gets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 36.
+ * See sched_getaffinity() and pthread_gettid_np() for greater portability.
+ */
+#if __USE_GNU && __BIONIC_AVAILABILITY_GUARD(36)
+int pthread_getaffinity_np(pthread_t __pthread, size_t __cpu_set_size, cpu_set_t* __cpu_set) __INTRODUCED_IN(36);
+#endif
+
+/**
+ * [pthread_setaffinity_np(3)](https://man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html)
+ * sets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 36.
+ * See sched_getaffinity() and pthread_gettid_np() for greater portability.
+ */
+#if __USE_GNU && __BIONIC_AVAILABILITY_GUARD(36)
+int pthread_setaffinity_np(pthread_t __pthread, size_t __cpu_set_size, const cpu_set_t* __cpu_set) __INTRODUCED_IN(36);
+#endif
+
+/**
* [pthread_setschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html)
* sets the scheduler policy and parameters of the given thread.
*
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index d8636a2..86dcc39 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1612,6 +1612,8 @@
global:
lchmod;
mseal;
+ pthread_getaffinity_np;
+ pthread_setaffinity_np;
qsort_r;
sig2str;
str2sig;
diff --git a/libdl/libdl_android.cpp b/libdl/libdl_android.cpp
index 47a164a..f0959eb 100644
--- a/libdl/libdl_android.cpp
+++ b/libdl/libdl_android.cpp
@@ -59,6 +59,9 @@
__attribute__((__weak__, visibility("default")))
struct android_namespace_t* __loader_android_get_exported_namespace(const char* name);
+__attribute__((__weak__, visibility("default"))) void __loader_android_set_16kb_appcompat_mode(
+ bool enable_app_compat);
+
// Proxy calls to bionic loader
__attribute__((__weak__))
void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
@@ -115,4 +118,8 @@
return __loader_android_get_exported_namespace(name);
}
+__attribute__((__weak__)) void android_set_16kb_appcompat_mode(bool enable_app_compat) {
+ __loader_android_set_16kb_appcompat_mode(enable_app_compat);
+}
+
} // extern "C"
diff --git a/libdl/libdl_android.map.txt b/libdl/libdl_android.map.txt
index 7afcd9c..efbc841 100644
--- a/libdl/libdl_android.map.txt
+++ b/libdl/libdl_android.map.txt
@@ -24,6 +24,7 @@
android_init_anonymous_namespace; # apex
android_link_namespaces; # apex
android_set_application_target_sdk_version; # apex
+ android_set_16kb_appcompat_mode; #apex
local:
*;
};
diff --git a/linker/Android.bp b/linker/Android.bp
index 847a9b2..4863b92 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -500,6 +500,7 @@
"linker_mapped_file_fragment.cpp",
"linker_sdk_versions.cpp",
"linker_dlwarning.cpp",
+ "linker_phdr_16kib_compat.cpp"
],
static_libs: [
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 82f2728..f811d6d 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -89,6 +89,7 @@
const void* caller_addr) __LINKER_PUBLIC__;
void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
+void __loader_android_set_16kb_appcompat_mode(bool enable_app_compat) __LINKER_PUBLIC__;
libc_shared_globals* __loader_shared_globals() __LINKER_PUBLIC__;
#if defined(__arm__)
_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
@@ -301,6 +302,11 @@
decrement_dso_handle_reference_counter(dso_handle);
}
+void __loader_android_set_16kb_appcompat_mode(bool enable_app_compat) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ set_16kb_appcompat_mode(enable_app_compat);
+}
+
libc_shared_globals* __loader_shared_globals() {
return __libc_shared_globals();
}
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
index 1c03106..c938a16 100644
--- a/linker/ld_android.cpp
+++ b/linker/ld_android.cpp
@@ -55,6 +55,7 @@
__strong_alias(__loader_add_thread_local_dtor, __internal_linker_error);
__strong_alias(__loader_remove_thread_local_dtor, __internal_linker_error);
__strong_alias(__loader_shared_globals, __internal_linker_error);
+__strong_alias(__loader_android_set_16kb_appcompat_mode, __internal_linker_error);
#if defined(__arm__)
__strong_alias(__loader_dl_unwind_find_exidx, __internal_linker_error);
#endif
diff --git a/linker/linker.arm.map b/linker/linker.arm.map
index b805cd6..edfa249 100644
--- a/linker/linker.arm.map
+++ b/linker/linker.arm.map
@@ -25,6 +25,7 @@
__loader_shared_globals;
rtld_db_dlactivity;
__loader_android_handle_signal;
+ __loader_android_set_16kb_appcompat_mode;
local:
*;
};
diff --git a/linker/linker.generic.map b/linker/linker.generic.map
index 4d7f236..2beae65 100644
--- a/linker/linker.generic.map
+++ b/linker/linker.generic.map
@@ -24,6 +24,7 @@
__loader_shared_globals;
rtld_db_dlactivity;
__loader_android_handle_signal;
+ __loader_android_set_16kb_appcompat_mode;
local:
*;
};
diff --git a/linker/linker.h b/linker/linker.h
index b696fd9..7afa0d7 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -108,6 +108,9 @@
bool get_transparent_hugepages_supported();
+void set_16kb_appcompat_mode(bool enable_app_compat);
+bool get_16kb_appcompat_mode();
+
enum {
/* A regular namespace is the namespace with a custom search path that does
* not impose any restrictions on the location of native libraries.
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index c37066b..14bf208 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -186,7 +186,8 @@
// It cannot be cached since the developer may toggle app compat on/off.
// This check will be removed once app compat is made the default on 16KiB devices.
should_use_16kib_app_compat_ =
- ::android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false);
+ ::android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false) ||
+ get_16kb_appcompat_mode();
}
return did_read_;
diff --git a/linker/linker_phdr_16kib_compat.cpp b/linker/linker_phdr_16kib_compat.cpp
index a4d8459..bad20ba 100644
--- a/linker/linker_phdr_16kib_compat.cpp
+++ b/linker/linker_phdr_16kib_compat.cpp
@@ -42,10 +42,20 @@
#include <string>
+static bool g_enable_16kb_app_compat;
+
static inline bool segment_contains_prefix(const ElfW(Phdr)* segment, const ElfW(Phdr)* prefix) {
return segment && prefix && segment->p_vaddr == prefix->p_vaddr;
}
+void set_16kb_appcompat_mode(bool enable_app_compat) {
+ g_enable_16kb_app_compat = enable_app_compat;
+}
+
+bool get_16kb_appcompat_mode() {
+ return g_enable_16kb_app_compat;
+}
+
/*
* Returns true if the ELF contains at most 1 RELRO segment; and populates @relro_phdr
* with the relro phdr or nullptr if none.
diff --git a/tests/page_size_16kib_compat_test.cpp b/tests/page_size_16kib_compat_test.cpp
index 9aecfba..a5d91b8 100644
--- a/tests/page_size_16kib_compat_test.cpp
+++ b/tests/page_size_16kib_compat_test.cpp
@@ -30,6 +30,8 @@
#include <android-base/properties.h>
+extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
+
TEST(PageSize16KiBCompatTest, ElfAlignment4KiB_LoadElf) {
if (getpagesize() != 0x4000) {
GTEST_SKIP() << "This test is only applicable to 16kB page-size devices";
@@ -44,3 +46,17 @@
if (app_compat_enabled) CallTestFunction(handle);
}
+
+TEST(PageSize16KiBCompatTest, ElfAlignment4KiB_LoadElf_perAppOption) {
+ if (getpagesize() != 0x4000) {
+ GTEST_SKIP() << "This test is only applicable to 16kB page-size devices";
+ }
+
+ android_set_16kb_appcompat_mode(true);
+ std::string lib = GetTestLibRoot() + "/libtest_elf_max_page_size_4kib.so";
+ void* handle = nullptr;
+
+ OpenTestLibrary(lib, false /*should_fail*/, &handle);
+ CallTestFunction(handle);
+ android_set_16kb_appcompat_mode(false);
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 7223784..1421365 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -3137,3 +3137,23 @@
GTEST_SKIP() << "bionic-only test";
#endif
}
+
+TEST(pthread, pthread_getaffinity_np_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ errno = 0;
+ ASSERT_EQ(EINVAL, pthread_getaffinity_np(pthread_self(), 0, nullptr));
+ ASSERT_ERRNO(0);
+#pragma clang diagnostic pop
+}
+
+TEST(pthread, pthread_setaffinity_np_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ errno = 0;
+ ASSERT_EQ(EINVAL, pthread_setaffinity_np(pthread_self(), 0, nullptr));
+ ASSERT_ERRNO(0);
+#pragma clang diagnostic pop
+}
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 0231de4..396d3b7 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -305,8 +305,19 @@
}
TEST(sched, sched_getaffinity_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+ ASSERT_ERRNO(EINVAL);
+#pragma clang diagnostic pop
+}
+
+TEST(sched, sched_setaffinity_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ ASSERT_EQ(-1, sched_setaffinity(getpid(), 0, nullptr));
+ ASSERT_ERRNO(EINVAL);
#pragma clang diagnostic pop
}