Merge "Migrate to the new APIs in clang-r522817" into main
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 8d507d1..e9cfbac 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -445,6 +445,18 @@
| No `dlclose` | Works | Works | Works |
+## ELF TLS (Available for API level >= 29)
+
+Android supports [ELF TLS](docs/elf-tls.md) starting at API level 29. Since
+NDK r26, clang will automatically enable ELF TLS for `minSdkVersion 29` or
+higher. Otherwise, the existing emutls implementation (which uses
+`pthread_key_create()` behind the scenes) will continue to be used. This
+means that convenient C/C++ thread-local syntax is available at any API level;
+at worst it will perform similarly to "roll your own" thread locals using
+`pthread_key_create()` but at best you'll get the performance benefit of
+ELF TLS, and the NDK will take care of the details.
+
+
## Use of IFUNC in libc (True for all API levels on devices running Android 10)
On devices running API level 29, libc uses
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
index 81f1842..b88c6e5 100644
--- a/benchmarks/bionic_benchmarks.cpp
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -372,7 +372,7 @@
void RegisterGoogleBenchmarks(bench_opts_t primary_opts, bench_opts_t secondary_opts,
const std::string& fn_name, args_vector_t* run_args) {
- if (g_str_to_func.find(fn_name) == g_str_to_func.end()) {
+ if (!g_str_to_func.contains(fn_name)) {
errx(1, "ERROR: No benchmark for function %s", fn_name.c_str());
}
long iterations_to_use = primary_opts.num_iterations ? primary_opts.num_iterations :
diff --git a/docs/elf-tls.md b/docs/elf-tls.md
index d408b3f..450f362 100644
--- a/docs/elf-tls.md
+++ b/docs/elf-tls.md
@@ -1,9 +1,10 @@
-# Android ELF TLS (Draft)
+# Android ELF TLS
-Internal links:
- * [go/android-elf-tls](http://go/android-elf-tls)
- * [One-pager](https://docs.google.com/document/d/1leyPTnwSs24P2LGiqnU6HetnN5YnDlZkihigi6qdf_M)
- * Tracking bugs: http://b/110100012, http://b/78026329
+App developers probably just want to read the
+[quick ELS TLS status summary](../android-changes-for-ndk-developers.md#elf-tls-available-for-api-level-29)
+instead.
+
+This document covers the detailed design and implementation choices.
[TOC]
@@ -215,7 +216,7 @@
* https://bugzilla.redhat.com/show_bug.cgi?id=1124987
* web search: [`"dlopen: cannot load any more object with static TLS"`][glibc-static-tls-error]
-Neither musl nor the Bionic TLS prototype currently allocate any surplus TLS memory.
+Neither bionic nor musl currently allocate any surplus TLS memory.
In general, supporting surplus TLS memory probably requires maintaining a thread list so that
`dlopen` can initialize the new static TLS memory in all existing threads. A thread list could be
@@ -489,19 +490,6 @@
[quietly ignored]: https://android.googlesource.com/platform/bionic/+/android-8.1.0_r48/linker/linker.cpp#2784
[added compatibility checks]: https://android-review.googlesource.com/c/platform/bionic/+/648760
-# Bionic Prototype Notes
-
-There is an [ELF TLS prototype] uploaded on Gerrit. It implements:
- * Static TLS Block allocation for static and dynamic executables
- * TLS for dynamically loaded and unloaded modules (`__tls_get_addr`)
- * TLSDESC for arm64 only
-
-Missing:
- * `dlsym` of a TLS variable
- * debugger support
-
-[ELF TLS prototype]: https://android-review.googlesource.com/q/topic:%22elf-tls-prototype%22+(status:open%20OR%20status:merged)
-
## Loader/libc Communication
The loader exposes a list of TLS modules ([`struct TlsModules`][TlsModules]) to `libc.so` using the
@@ -515,13 +503,14 @@
## TLS Allocator
-The prototype currently allocates a `pthread_internal_t` object and static TLS in a single mmap'ed
+bionic currently allocates a `pthread_internal_t` object and static TLS in a single mmap'ed
region, along with a thread's stack if it needs one allocated. It doesn't place TLS memory on a
preallocated stack (either the main thread's stack or one provided with `pthread_attr_setstack`).
The DTV and blocks for dlopen'ed modules are instead allocated using the Bionic loader's
-`LinkerMemoryAllocator`, adapted to avoid the STL and to provide `memalign`. The prototype tries to
-achieve async-signal safety by blocking signals and acquiring a lock.
+`LinkerMemoryAllocator`, adapted to avoid the STL and to provide `memalign`.
+The implementation tries to achieve async-signal safety by blocking signals and
+acquiring a lock.
There are three "entry points" to dynamically locate a TLS variable's address:
* libc.so: `__tls_get_addr`
@@ -529,10 +518,10 @@
* loader: dlsym
The loader's entry points need to call `__tls_get_addr`, which needs to allocate memory. Currently,
-the prototype uses a [special function pointer] to call libc.so's `__tls_get_addr` from the loader.
+the implementation uses a [special function pointer] to call libc.so's `__tls_get_addr` from the loader.
(This should probably be removed.)
-The prototype currently allows for arbitrarily-large TLS variable alignment. IIRC, different
+The implementation currently allows for arbitrarily-large TLS variable alignment. IIRC, different
implementations (glibc, musl, FreeBSD) vary in their level of respect for TLS alignment. It looks
like the Bionic loader ignores segments' alignment and aligns loaded libraries to 256 KiB. See
`ReserveAligned`.
@@ -541,7 +530,7 @@
## Async-Signal Safety
-The prototype's `__tls_get_addr` might be async-signal safe. Making it AS-safe is a good idea if
+The implementation's `__tls_get_addr` might be async-signal safe. Making it AS-safe is a good idea if
it's feasible. musl's function is AS-safe, but glibc's isn't (or wasn't). Google had a patch to make
glibc AS-safe back in 2012-2013. See:
* https://sourceware.org/glibc/wiki/TLSandSignals
@@ -550,7 +539,7 @@
## Out-of-Memory Handling (abort)
-The prototype lazily allocates TLS memory for dlopen'ed modules (see `__tls_get_addr`), and an
+The implementation lazily allocates TLS memory for dlopen'ed modules (see `__tls_get_addr`), and an
out-of-memory error on a TLS access aborts the process. musl, on the other hand, preallocates TLS
memory on `pthread_create` and `dlopen`, so either function can return out-of-memory. Both functions
probably need to acquire the same lock.
@@ -572,7 +561,7 @@
FWIW: emutls also aborts on out-of-memory.
-## ELF TLS Not Usable in libc
+## ELF TLS Not Usable in libc Itself
The dynamic loader currently can't use ELF TLS, so any part of libc linked into the loader (i.e.
most of it) also can't use ELF TLS. It might be possible to lift this restriction, perhaps with
@@ -649,7 +638,7 @@
It seems easy to fix the incompatibility for variant 2 (x86 and x86_64) by splitting out the Bionic
slots into a new data structure. Variant 1 is a harder problem.
-The TLS prototype currently uses a patched LLD that uses a variant 1 TLS layout with a 16-word TCB
+The TLS prototype used a patched LLD that uses a variant 1 TLS layout with a 16-word TCB
on all architectures.
Aside: gcc's arm64ilp32 target uses a 32-bit unsigned offset for a TLS IE access
@@ -821,8 +810,8 @@
### Workaround for Go: place pthread keys after the executable's TLS
-Most Android executables do not use any `thread_local` variables. In the current prototype, with the
-AOSP hikey960 build, only `/system/bin/netd` has a TLS segment, and it's only 32 bytes. As long as
+Most Android executables do not use any `thread_local` variables. In the prototype, with the
+AOSP hikey960 build, only `/system/bin/netd` had a TLS segment, and it was only 32 bytes. As long as
`/system/bin/app_process{32,64}` limits its use of TLS memory, then the pthread keys could be
allocated after `app_process`' TLS segment, and Go will still find them.
@@ -847,6 +836,12 @@
* It looks like glibc's ld.so re-relocates itself after loading a program, so a program's symbols
can interpose call in the loader: https://sourceware.org/ml/libc-alpha/2014-01/msg00501.html
+## TODO: Other
+
+Missing:
+ * `dlsym` of a TLS variable
+ * debugger support
+
# References
General (and x86/x86-64)
diff --git a/docs/fdsan.md b/docs/fdsan.md
index f5d1ab5..5aeb7de 100644
--- a/docs/fdsan.md
+++ b/docs/fdsan.md
@@ -62,7 +62,9 @@
- fatal (`ANDROID_FDSAN_ERROR_LEVEL_FATAL`)
- Abort upon detecting an error.
-In Android Q, fdsan has a global default of warn-once. fdsan can be made more or less strict at runtime via the `android_fdsan_set_error_level` function in [`<android/fdsan.h>`](https://android.googlesource.com/platform/bionic/+/main/libc/include/android/fdsan.h).
+In API level 29, fdsan had a global default of warn-once.
+In API level 30 and higher, fdsan has a global default of fatal.
+fdsan can be made more or less strict at runtime via the `android_fdsan_set_error_level` function in [`<android/fdsan.h>`](https://android.googlesource.com/platform/bionic/+/main/libc/include/android/fdsan.h).
The likelihood of fdsan catching a file descriptor error is proportional to the percentage of file descriptors in your process that are tagged with an owner.
@@ -344,7 +346,8 @@
// These functions are marked with __attribute__((weak)), so that their
// availability can be determined at runtime. These wrappers will use them
- // if available, and fall back to no-ops or regular close on pre-Q devices.
+ // if available, and fall back to no-ops or regular close on devices older
+ // than API level 29.
static void exchange_tag(int fd, uint64_t old_tag, uint64_t new_tag) {
if (android_fdsan_exchange_owner_tag) {
android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
diff --git a/docs/status.md b/docs/status.md
index bc8ab6a..e0364a8 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -125,6 +125,7 @@
* `getloadavg` (BSD/GNU extension in <stdlib.h>)
New libc behavior in Q (API level 29):
+ * Support for [ELF TLS](elf-tls.md).
* Whole printf family now supports the GNU `%m` extension, rather than a
special-case hack in `syslog`.
* `popen` now always uses `O_CLOEXEC`, not just with the `e` extension.
diff --git a/libc/Android.bp b/libc/Android.bp
index d8467a8..80b24b4 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1,5 +1,3 @@
-// Define the common source files for all the libc instances
-// =========================================================
package {
default_applicable_licenses: ["bionic_libc_license"],
}
@@ -89,10 +87,6 @@
recovery_available: true,
native_bridge_supported: true,
- // lld complains about duplicate symbols in libcrt and libgcc. Suppress the
- // warning since this is intended right now.
- ldflags: ["-Wl,-z,muldefs"],
-
product_variables: {
malloc_zero_contents: {
cflags: ["-DSCUDO_ZERO_CONTENTS"],
@@ -114,6 +108,26 @@
tidy_disabled_srcs: ["upstream-*/**/*.c"],
}
+// Workaround for b/24465209.
+// We're unlikely to be able to remove this before we just
+// remove ILP32 support completely.
+// Note that we also still have `pack_relocations: false`
+// for both libc and libm, even on LP64.
+// ========================================================
+cc_defaults {
+ name: "bug_24465209_workaround",
+ target: {
+ android_arm: {
+ pack_relocations: false,
+ ldflags: ["-Wl,--hash-style=both"],
+ },
+ android_x86: {
+ pack_relocations: false,
+ ldflags: ["-Wl,--hash-style=both"],
+ },
+ },
+}
+
// Defaults for native allocator libs/includes to make it
// easier to change.
// ========================================================
@@ -879,7 +893,6 @@
"bionic/mkfifo.cpp",
"bionic/mknod.cpp",
"bionic/mntent.cpp",
- "bionic/mremap.cpp",
"bionic/netdb.cpp",
"bionic/net_if.cpp",
"bionic/netinet_ether.cpp",
@@ -1530,6 +1543,7 @@
defaults: [
"libc_defaults",
"libc_native_allocator_defaults",
+ "bug_24465209_workaround",
],
name: "libc_library_defaults",
product_variables: {
@@ -1542,7 +1556,6 @@
cflags: ["-DLIBC_STATIC"],
whole_static_libs: [
"gwp_asan",
- "gwp_asan_crash_handler",
"libc_init_static",
"libc_common_static",
"libc_unwind_static",
@@ -1552,7 +1565,6 @@
srcs: [":libc_sources_shared"],
whole_static_libs: [
"gwp_asan",
- "gwp_asan_crash_handler",
"libc_init_dynamic",
"libc_common_shared",
"libunwind-exported",
@@ -1567,14 +1579,6 @@
// Do not pack libc.so relocations; see http://b/20645321 for details.
pack_relocations: false,
- // WARNING: The only libraries libc.so should depend on are libdl.so and ld-android.so!
- // If you add other libraries, make sure to add -Wl,--exclude-libs=libgcc.a to the
- // LOCAL_LDFLAGS for those libraries. This ensures that symbols that are pulled into
- // those new libraries from libgcc.a are not declared external; if that were the case,
- // then libc would not pull those symbols from libgcc.a as it should, instead relying
- // on the external symbols from the dependent libraries. That would create a "cloaked"
- // dependency on libgcc.a in libc though the libraries, which is not what you wanted!
-
shared_libs: [
"ld-android",
"libdl",
@@ -1587,10 +1591,7 @@
arch: {
arm: {
- // TODO: This is to work around b/24465209. Remove after root cause is fixed.
- pack_relocations: false,
ldflags: [
- "-Wl,--hash-style=both",
// Since we are preserving the debug_frame, do not compress
// in this case to make unwinds as fast as possible.
"-Wl,--compress-debug-sections=none",
@@ -1634,10 +1635,6 @@
},
},
x86: {
- // TODO: This is to work around b/24465209. Remove after root cause is fixed.
- pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
-
version_script: ":libc.x86.map",
no_libcrt: true,
@@ -1917,7 +1914,10 @@
// ========================================================
cc_library {
- defaults: ["libc_defaults"],
+ defaults: [
+ "libc_defaults",
+ "bug_24465209_workaround",
+ ],
include_dirs: ["bionic/libstdc++/include"],
srcs: [
"bionic/__cxa_guard.cpp",
@@ -1942,12 +1942,8 @@
},
},
- //TODO (dimitry): This is to work around b/24465209. Remove after root cause is fixed
arch: {
arm: {
- // TODO: This is to work around b/24465209. Remove after root cause is fixed.
- pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
version_script: ":libstdc++.arm.map",
},
arm64: {
@@ -1957,8 +1953,6 @@
version_script: ":libstdc++.riscv64.map",
},
x86: {
- pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
version_script: ":libstdc++.x86.map",
},
x86_64: {
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index ce14e49..a8c70e5 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -118,7 +118,6 @@
pid_t __getpid:getpid() all
int memfd_create(const char*, unsigned) all
int munmap(void*, size_t) all
-void* __mremap:mremap(void*, size_t, size_t, int, void*) all
int msync(const void*, size_t, int) all
int mprotect(const void*, size_t, int) all
int madvise(void*, size_t, int) all
@@ -190,6 +189,10 @@
void* __mmap2:mmap2(void*, size_t, int, int, int, long) lp32
void* mmap|mmap64(void*, size_t, int, int, int, off_t) lp64
+# mremap is in C++ for 32-bit so we can add the PTRDIFF_MAX check.
+void* __mremap:mremap(void*, size_t, size_t, int, void*) lp32
+void* mremap(void*, size_t, size_t, int, void*) lp64
+
# posix_fadvise64 is awkward: arm has shuffled arguments,
# the POSIX functions don't set errno, and no architecture has posix_fadvise.
int __arm_fadvise64_64:arm_fadvise64_64(int, int, off64_t, off64_t) arm
diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp
index a42c361..f9e4263 100644
--- a/libc/arch-arm64/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm64/dynamic_function_dispatch.cpp
@@ -66,7 +66,9 @@
typedef void* memcpy_func(void*, const void*, size_t);
DEFINE_IFUNC_FOR(memcpy) {
- if (__bionic_is_oryon(arg->_hwcap)) {
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memcpy_func, __memmove_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
RETURN_FUNC(memcpy_func, __memcpy_aarch64_nt);
} else if (arg->_hwcap & HWCAP_ASIMD) {
RETURN_FUNC(memcpy_func, __memcpy_aarch64_simd);
@@ -77,7 +79,9 @@
typedef void* memmove_func(void*, const void*, size_t);
DEFINE_IFUNC_FOR(memmove) {
- if (__bionic_is_oryon(arg->_hwcap)) {
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memmove_func, __memmove_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
RETURN_FUNC(memcpy_func, __memmove_aarch64_nt);
} else if (arg->_hwcap & HWCAP_ASIMD) {
RETURN_FUNC(memmove_func, __memmove_aarch64_simd);
@@ -93,7 +97,9 @@
typedef int memset_func(void*, int, size_t);
DEFINE_IFUNC_FOR(memset) {
- if (__bionic_is_oryon(arg->_hwcap)) {
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memset_func, __memset_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
RETURN_FUNC(memset_func, __memset_aarch64_nt);
} else {
RETURN_FUNC(memset_func, __memset_aarch64);
diff --git a/libc/bionic/NetdClientDispatch.cpp b/libc/bionic/NetdClientDispatch.cpp
index e6f4a97..be5fb11 100644
--- a/libc/bionic/NetdClientDispatch.cpp
+++ b/libc/bionic/NetdClientDispatch.cpp
@@ -20,18 +20,12 @@
#include "private/bionic_fdtrack.h"
-#ifdef __i386__
-#define __socketcall __attribute__((__cdecl__))
-#else
-#define __socketcall
-#endif
-
-extern "C" __socketcall int __accept4(int, sockaddr*, socklen_t*, int);
-extern "C" __socketcall int __connect(int, const sockaddr*, socklen_t);
-extern "C" __socketcall int __sendmmsg(int, const mmsghdr*, unsigned int, int);
-extern "C" __socketcall ssize_t __sendmsg(int, const msghdr*, unsigned int);
-extern "C" __socketcall int __sendto(int, const void*, size_t, int, const sockaddr*, socklen_t);
-extern "C" __socketcall int __socket(int, int, int);
+extern "C" int __accept4(int, sockaddr*, socklen_t*, int);
+extern "C" int __connect(int, const sockaddr*, socklen_t);
+extern "C" int __sendmmsg(int, const mmsghdr*, unsigned int, int);
+extern "C" ssize_t __sendmsg(int, const msghdr*, unsigned int);
+extern "C" int __sendto(int, const void*, size_t, int, const sockaddr*, socklen_t);
+extern "C" int __socket(int, int, int);
static unsigned fallBackNetIdForResolv(unsigned netId) {
return netId;
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index cadab3c..6741be3 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -53,6 +53,8 @@
heap_tagging_level = __libc_shared_globals()->initial_heap_tagging_level;
#endif
+ __libc_memtag_stack_abi = __libc_shared_globals()->initial_memtag_stack_abi;
+
__libc_globals.mutate([](libc_globals* globals) {
switch (heap_tagging_level) {
case M_HEAP_TAGGING_LEVEL_TBI:
@@ -184,6 +186,9 @@
#ifdef __aarch64__
static inline __attribute__((no_sanitize("memtag"))) void untag_memory(void* from, void* to) {
+ if (from == to) {
+ return;
+ }
__asm__ __volatile__(
".arch_extension mte\n"
"1:\n"
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 314fe9b..4e19ebf 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -30,6 +30,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <stdarg.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/resource.h>
@@ -135,3 +136,28 @@
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
return mmap64(addr, size, prot, flags, fd, static_cast<off64_t>(offset));
}
+
+// The only difference here is that the libc API uses varargs for the
+// optional `new_address` argument that's only used by MREMAP_FIXED.
+extern "C" void* __mremap(void*, size_t, size_t, int, void*);
+
+void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
+ // Prevent allocations large enough for `end - start` to overflow,
+ // to avoid security bugs.
+ size_t rounded = __BIONIC_ALIGN(new_size, page_size());
+ if (rounded < new_size || rounded > PTRDIFF_MAX) {
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+
+ // The optional argument is only valid if the MREMAP_FIXED flag is set,
+ // so we assume it's not present otherwise.
+ void* new_address = nullptr;
+ if ((flags & MREMAP_FIXED) != 0) {
+ va_list ap;
+ va_start(ap, flags);
+ new_address = va_arg(ap, void*);
+ va_end(ap);
+ }
+ return __mremap(old_address, old_size, new_size, flags, new_address);
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index c82c52e..939e4e1 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -58,6 +58,7 @@
__LIBC_HIDDEN__ constinit WriteProtected<libc_globals> __libc_globals;
__LIBC_HIDDEN__ constinit _Atomic(bool) __libc_memtag_stack;
+__LIBC_HIDDEN__ constinit bool __libc_memtag_stack_abi;
// Not public, but well-known in the BSDs.
__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 2dde2f1..541e71c 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -61,8 +61,9 @@
};
void memtag_stack_dlopen_callback() {
- async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "remapping stacks as PROT_MTE");
- __pthread_internal_remap_stack_with_mte();
+ if (__pthread_internal_remap_stack_with_mte()) {
+ async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "remapped stacks as PROT_MTE");
+ }
}
// Use an initializer so __libc_sysinfo will have a fallback implementation
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3da0a92..ac97376 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -289,11 +289,7 @@
// 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;
- }
- }
+ get_environment_memtag_setting(&level);
return level;
}
@@ -329,13 +325,14 @@
bool memtag_stack = false;
HeapTaggingLevel level =
__get_tagging_level(memtag_dynamic_entries, phdr_start, phdr_ct, load_bias, &memtag_stack);
- // This is used by the linker (in linker.cpp) to communicate than any library linked by this
- // executable enables memtag-stack.
- if (__libc_shared_globals()->initial_memtag_stack) {
- if (!memtag_stack) {
- async_safe_format_log(ANDROID_LOG_INFO, "libc", "enabling PROT_MTE as requested by linker");
- }
+ // initial_memtag_stack is used by the linker (in linker.cpp) to communicate than any library
+ // linked by this executable enables memtag-stack.
+ // memtag_stack is also set for static executables if they request memtag stack via the note,
+ // in which case it will differ from initial_memtag_stack.
+ if (__libc_shared_globals()->initial_memtag_stack || memtag_stack) {
memtag_stack = true;
+ __libc_shared_globals()->initial_memtag_stack_abi = true;
+ __get_bionic_tcb()->tls_slot(TLS_SLOT_STACK_MTE) = __allocate_stack_mte_ringbuffer(0, nullptr);
}
if (int64_t timed_upgrade = __get_memtag_upgrade_secs()) {
if (level == M_HEAP_TAGGING_LEVEL_ASYNC) {
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index 2f4d206..a1d6909 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -35,17 +35,8 @@
#include <time.h>
#include <wchar.h>
-#include "platform/bionic/macros.h"
-
-#if defined(__BIONIC_BUILD_FOR_ANDROID_SUPPORT)
-#define USE_TLS_SLOT 0
-#else
-#define USE_TLS_SLOT 1
-#endif
-
-#if USE_TLS_SLOT
#include "bionic/pthread_internal.h"
-#endif
+#include "platform/bionic/macros.h"
// We only support two locales, the "C" locale (also known as "POSIX"),
// and the "C.UTF-8" locale (also known as "en_US.UTF-8").
@@ -82,10 +73,6 @@
return get_locale_mb_cur_max(uselocale(nullptr));
}
-#if !USE_TLS_SLOT
-static thread_local locale_t g_current_locale;
-#endif
-
static pthread_once_t g_locale_once = PTHREAD_ONCE_INIT;
static lconv g_locale;
@@ -180,11 +167,7 @@
}
static locale_t* get_current_locale_ptr() {
-#if USE_TLS_SLOT
return &__get_bionic_tls().locale;
-#else
- return &g_current_locale;
-#endif
}
locale_t uselocale(locale_t new_locale) {
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
deleted file mode 100644
index 88ec829..0000000
--- a/libc/bionic/mremap.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 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 <sys/mman.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include "platform/bionic/macros.h"
-#include "platform/bionic/page.h"
-
-extern "C" void* __mremap(void*, size_t, size_t, int, void*);
-
-void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
- // prevent allocations large enough for `end - start` to overflow
- size_t rounded = __BIONIC_ALIGN(new_size, page_size());
- if (rounded < new_size || rounded > PTRDIFF_MAX) {
- errno = ENOMEM;
- return MAP_FAILED;
- }
-
- void* new_address = nullptr;
- // The optional argument is only valid if the MREMAP_FIXED flag is set,
- // so we assume it's not present otherwise.
- if ((flags & MREMAP_FIXED) != 0) {
- va_list ap;
- va_start(ap, flags);
- new_address = va_arg(ap, void*);
- va_end(ap);
- }
- return __mremap(old_address, old_size, new_size, flags, new_address);
-}
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 5bd4f16..a8d09eb 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -65,6 +65,7 @@
}
void __init_bionic_tls_ptrs(bionic_tcb* tcb, bionic_tls* tls) {
+ tcb->thread()->bionic_tcb = tcb;
tcb->thread()->bionic_tls = tls;
tcb->tls_slot(TLS_SLOT_BIONIC_TLS) = tls;
}
@@ -443,6 +444,14 @@
ScopedReadLock locker(&g_thread_creation_lock);
+// This has to be done under g_thread_creation_lock or g_thread_list_lock to avoid racing with
+// __pthread_internal_remap_stack_with_mte.
+#ifdef __aarch64__
+ if (__libc_memtag_stack_abi) {
+ tcb->tls_slot(TLS_SLOT_STACK_MTE) = __allocate_stack_mte_ringbuffer(0, thread);
+ }
+#endif
+
sigset64_t block_all_mask;
sigfillset64(&block_all_mask);
__rt_sigprocmask(SIG_SETMASK, &block_all_mask, &thread->start_mask, sizeof(thread->start_mask));
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 2342aff..14cc7da 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -33,9 +33,12 @@
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/prctl.h>
#include <async_safe/log.h>
+#include <bionic/mte.h>
#include <bionic/reserved_signals.h>
+#include <bionic/tls_defines.h>
#include "private/ErrnoRestorer.h"
#include "private/ScopedRWLock.h"
@@ -73,6 +76,15 @@
}
static void __pthread_internal_free(pthread_internal_t* thread) {
+#ifdef __aarch64__
+ if (void* stack_mte_tls = thread->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE)) {
+ size_t size =
+ stack_mte_ringbuffer_size_from_pointer(reinterpret_cast<uintptr_t>(stack_mte_tls));
+ void* ptr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(stack_mte_tls) &
+ ((1ULL << 56ULL) - 1ULL));
+ munmap(ptr, size);
+ }
+#endif
if (thread->mmap_size != 0) {
// Free mapped space, including thread stack and pthread_internal_t.
munmap(thread->mmap_base, thread->mmap_size);
@@ -176,12 +188,40 @@
async_safe_fatal("stack not found in /proc/self/maps");
}
-void __pthread_internal_remap_stack_with_mte() {
#if defined(__aarch64__)
- // If process doesn't have MTE enabled, we don't need to do anything.
- if (!atomic_load(&__libc_globals->memtag)) return;
- bool prev = atomic_exchange(&__libc_memtag_stack, true);
- if (prev) return;
+__LIBC_HIDDEN__ void* __allocate_stack_mte_ringbuffer(size_t n, pthread_internal_t* thread) {
+ const char* name;
+ if (thread == nullptr) {
+ name = "stack_mte_ring:main";
+ } else {
+ // The kernel doesn't copy the name string, but this variable will last at least as long as the
+ // mapped area. We unmap the ring buffer before unmapping the rest of the thread storage.
+ auto& name_buffer = thread->stack_mte_ringbuffer_vma_name_buffer;
+ static_assert(arraysize(name_buffer) >= arraysize("stack_mte_ring:") + 11 + 1);
+ async_safe_format_buffer(name_buffer, arraysize(name_buffer), "stack_mte_ring:%d", thread->tid);
+ name = name_buffer;
+ }
+ void* ret = stack_mte_ringbuffer_allocate(n, name);
+ if (!ret) async_safe_fatal("error: failed to allocate stack mte ring buffer");
+ return ret;
+}
+#endif
+
+bool __pthread_internal_remap_stack_with_mte() {
+#if defined(__aarch64__)
+ ScopedWriteLock creation_locker(&g_thread_creation_lock);
+ ScopedReadLock list_locker(&g_thread_list_lock);
+ // If process already uses memtag-stack ABI, we don't need to do anything.
+ if (__libc_memtag_stack_abi) return false;
+ __libc_memtag_stack_abi = true;
+
+ for (pthread_internal_t* t = g_thread_list; t != nullptr; t = t->next) {
+ if (t->terminating) continue;
+ t->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE) =
+ __allocate_stack_mte_ringbuffer(0, t->is_main() ? nullptr : t);
+ }
+ if (!atomic_load(&__libc_globals->memtag)) return false;
+ if (atomic_exchange(&__libc_memtag_stack, true)) return false;
uintptr_t lo, hi;
__find_main_stack_limits(&lo, &hi);
@@ -189,8 +229,6 @@
PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
async_safe_fatal("error: failed to set PROT_MTE on main thread");
}
- ScopedWriteLock creation_locker(&g_thread_creation_lock);
- ScopedReadLock list_locker(&g_thread_list_lock);
for (pthread_internal_t* t = g_thread_list; t != nullptr; t = t->next) {
if (t->terminating || t->is_main()) continue;
if (mprotect(t->mmap_base_unguarded, t->mmap_size_unguarded,
@@ -198,7 +236,10 @@
async_safe_fatal("error: failed to set PROT_MTE on thread: %d", t->tid);
}
}
-#endif
+ return true;
+#else
+ return false;
+#endif // defined(__aarch64__)
}
bool android_run_on_all_threads(bool (*func)(void*), void* arg) {
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index c2abdea..5db42ab 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -178,6 +178,10 @@
bionic_tls* bionic_tls;
int errno_value;
+
+ bionic_tcb* bionic_tcb;
+ char stack_mte_ringbuffer_vma_name_buffer[32];
+
bool is_main() { return start_routine == nullptr; }
};
@@ -209,6 +213,9 @@
__LIBC_HIDDEN__ void __pthread_internal_remove(pthread_internal_t* thread);
__LIBC_HIDDEN__ void __pthread_internal_remove_and_free(pthread_internal_t* thread);
__LIBC_HIDDEN__ void __find_main_stack_limits(uintptr_t* low, uintptr_t* high);
+#if defined(__aarch64__)
+__LIBC_HIDDEN__ void* __allocate_stack_mte_ringbuffer(size_t n, pthread_internal_t* thread);
+#endif
static inline __always_inline bionic_tcb* __get_bionic_tcb() {
return reinterpret_cast<bionic_tcb*>(&__get_tls()[MIN_TLS_SLOT]);
@@ -268,8 +275,9 @@
__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent();
-// Re-map all threads and successively launched threads with PROT_MTE.
-__LIBC_HIDDEN__ void __pthread_internal_remap_stack_with_mte();
+// Re-map all threads and successively launched threads with PROT_MTE. Returns 'true' if remapping
+// took place, 'false' on error or if the stacks were already remapped in the past.
+__LIBC_HIDDEN__ bool __pthread_internal_remap_stack_with_mte();
extern "C" bool android_run_on_all_threads(bool (*func)(void*), void* arg);
diff --git a/libc/bionic/sys_msg.cpp b/libc/bionic/sys_msg.cpp
index 462c83b..9780d38 100644
--- a/libc/bionic/sys_msg.cpp
+++ b/libc/bionic/sys_msg.cpp
@@ -36,33 +36,17 @@
// Annoyingly, the kernel requires this for 32-bit but rejects it for 64-bit.
cmd |= IPC_64;
#endif
-#if defined(SYS_msgctl)
return syscall(SYS_msgctl, id, cmd, buf);
-#else
- return syscall(SYS_ipc, MSGCTL, id, cmd, 0, buf, 0);
-#endif
}
int msgget(key_t key, int flags) {
-#if defined(SYS_msgget)
return syscall(SYS_msgget, key, flags);
-#else
- return syscall(SYS_ipc, MSGGET, key, flags, 0, 0, 0);
-#endif
}
ssize_t msgrcv(int id, void* msg, size_t n, long type, int flags) {
-#if defined(SYS_msgrcv)
return syscall(SYS_msgrcv, id, msg, n, type, flags);
-#else
- return syscall(SYS_ipc, IPCCALL(1, MSGRCV), id, n, flags, msg, type);
-#endif
}
int msgsnd(int id, const void* msg, size_t n, int flags) {
-#if defined(SYS_msgsnd)
return syscall(SYS_msgsnd, id, msg, n, flags);
-#else
- return syscall(SYS_ipc, MSGSND, id, n, flags, msg, 0);
-#endif
}
diff --git a/libc/bionic/sys_sem.cpp b/libc/bionic/sys_sem.cpp
index 058cfef..b97bf46 100644
--- a/libc/bionic/sys_sem.cpp
+++ b/libc/bionic/sys_sem.cpp
@@ -41,19 +41,11 @@
va_start(ap, cmd);
semun arg = va_arg(ap, semun);
va_end(ap);
-#if defined(SYS_semctl)
return syscall(SYS_semctl, id, num, cmd, arg);
-#else
- return syscall(SYS_ipc, SEMCTL, id, num, cmd, &arg, 0);
-#endif
}
int semget(key_t key, int n, int flags) {
-#if defined(SYS_semget)
return syscall(SYS_semget, key, n, flags);
-#else
- return syscall(SYS_ipc, SEMGET, key, n, flags, 0, 0);
-#endif
}
int semop(int id, sembuf* ops, size_t op_count) {
@@ -64,6 +56,9 @@
#if defined(SYS_semtimedop)
return syscall(SYS_semtimedop, id, ops, op_count, ts);
#else
+ // 32-bit x86 -- the only architecture without semtimedop(2) -- only has
+ // semtimedop_time64(2), but since we don't have any timespec64 stuff,
+ // it's less painful for us to just stick with the legacy ipc(2) here.
return syscall(SYS_ipc, SEMTIMEDOP, id, op_count, 0, ops, ts);
#endif
}
diff --git a/libc/bionic/sys_shm.cpp b/libc/bionic/sys_shm.cpp
index f780e04..777b3ad 100644
--- a/libc/bionic/sys_shm.cpp
+++ b/libc/bionic/sys_shm.cpp
@@ -32,16 +32,7 @@
#include <unistd.h>
void* shmat(int id, const void* address, int flags) {
-#if defined(SYS_shmat)
return reinterpret_cast<void*>(syscall(SYS_shmat, id, address, flags));
-#else
- // See the kernel's ipc/syscall.c for the other side of this dance.
- void* result = nullptr;
- if (syscall(SYS_ipc, SHMAT, id, flags, &result, address, 0) == -1) {
- return reinterpret_cast<void*>(-1);
- }
- return result;
-#endif
}
int shmctl(int id, int cmd, struct shmid_ds* buf) {
@@ -49,25 +40,13 @@
// Annoyingly, the kernel requires this for 32-bit but rejects it for 64-bit.
cmd |= IPC_64;
#endif
-#if defined(SYS_shmctl)
return syscall(SYS_shmctl, id, cmd, buf);
-#else
- return syscall(SYS_ipc, SHMCTL, id, cmd, 0, buf, 0);
-#endif
}
int shmdt(const void* address) {
-#if defined(SYS_shmdt)
return syscall(SYS_shmdt, address);
-#else
- return syscall(SYS_ipc, SHMDT, 0, 0, 0, address, 0);
-#endif
}
int shmget(key_t key, size_t size, int flags) {
-#if defined(SYS_shmget)
return syscall(SYS_shmget, key, size, flags);
-#else
- return syscall(SYS_ipc, SHMGET, key, size, flags, 0, 0);
-#endif
}
diff --git a/libc/dns/include/resolv_private.h b/libc/dns/include/resolv_private.h
index 3054555..1593aca 100644
--- a/libc/dns/include/resolv_private.h
+++ b/libc/dns/include/resolv_private.h
@@ -504,15 +504,7 @@
// ...but NetBSD calls it res_randomid.
#define res_randomid __res_randomid
-#ifdef __i386__
-# define __socketcall extern __attribute__((__cdecl__))
-#else
-# define __socketcall extern
-#endif
-
-__socketcall int __connect(int, const struct sockaddr*, socklen_t);
-
-#undef __socketcall
+int __connect(int, const struct sockaddr*, socklen_t);
// Symbols that are supposed to be in resolv.h, but that we aren't exporting.
int ns_parserr2(ns_msg*, ns_sect, int, ns_rr2*);
diff --git a/libc/include/fts.h b/libc/include/fts.h
index 8dfd213..aabe2db 100644
--- a/libc/include/fts.h
+++ b/libc/include/fts.h
@@ -119,7 +119,7 @@
FTSENT* _Nullable fts_children(FTS* _Nonnull __fts, int __options);
int fts_close(FTS* _Nonnull __fts);
-FTS* _Nullable fts_open(char* _Nonnull const* _Nonnull __path, int __options, int (* _Nullable __comparator)(const FTSENT* _Nonnull * _Nonnull __lhs, const FTSENT* _Nonnull * _Nonnull __rhs));
+FTS* _Nullable fts_open(char* _Nullable const* _Nonnull __path, int __options, int (* _Nullable __comparator)(const FTSENT* _Nonnull * _Nonnull __lhs, const FTSENT* _Nonnull * _Nonnull __rhs));
FTSENT* _Nullable fts_read(FTS* _Nonnull __fts);
int fts_set(FTS* _Nonnull __fts, FTSENT* _Nonnull __entry, int __options);
diff --git a/libc/include/math.h b/libc/include/math.h
index fc6c228..343ab98 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -68,10 +68,7 @@
#define isnormal(x) __builtin_isnormal(x)
-#define signbit(x) \
- ((sizeof(x) == sizeof(float)) ? __builtin_signbitf(x) \
- : (sizeof(x) == sizeof(double)) ? __builtin_signbit(x) \
- : __builtin_signbitl(x))
+#define signbit(x) __builtin_signbit(x)
double acos(double __x);
float acosf(float __x);
@@ -308,20 +305,6 @@
#define islessgreater(x, y) __builtin_islessgreater((x), (y))
#define isunordered(x, y) __builtin_isunordered((x), (y))
-/*
- * https://code.google.com/p/android/issues/detail?id=271629
- * To be fully compliant with C++, we need to not define these (C doesn't
- * specify them either). Exposing these means that isinf and isnan will have a
- * return type of int in C++ rather than bool like they're supposed to be.
- *
- * GNU libstdc++ 4.9 isn't able to handle a standard compliant C library. Its
- * <cmath> will `#undef isnan` from math.h and only adds the function overloads
- * to the std namespace, making it impossible to use both <cmath> (which gets
- * included by a lot of other standard headers) and ::isnan.
- */
-int (isinf)(double __x) __attribute_const__;
-int (isnan)(double __x) __attribute_const__;
-
/* POSIX extensions. */
extern int signgam;
@@ -362,6 +345,7 @@
double scalb(double __x, double __exponent);
double drem(double __x, double __y);
int finite(double __x) __attribute_const__;
+int isinff(float __x) __attribute_const__;
int isnanf(float __x) __attribute_const__;
double gamma_r(double __x, int* _Nonnull __sign);
double lgamma_r(double __x, int* _Nonnull __sign);
@@ -402,6 +386,8 @@
#define M_2_SQRTPIl 1.128379167095512573896158903121545172L /* 2/sqrt(pi) */
#define M_SQRT2l 1.414213562373095048801688724209698079L /* sqrt(2) */
#define M_SQRT1_2l 0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+int isinfl(long double __x) __attribute_const__;
+int isnanl(long double __x) __attribute_const__;
#endif
__END_DECLS
diff --git a/libc/include/netinet/igmp.h b/libc/include/netinet/igmp.h
new file mode 100644
index 0000000..497d02d
--- /dev/null
+++ b/libc/include/netinet/igmp.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/**
+ * @file netinet/igmp.h
+ * @brief Internet Group Management Protocol (IGMP).
+ */
+
+#include <sys/cdefs.h>
+#include <netinet/in.h>
+
+#include <linux/igmp.h>
+
+/**
+ * The uapi type is called `igmphdr`,
+ * doesn't have the `igmp_` prefix on each field,
+ * and uses a `__be32` for the group address.
+ *
+ * This is the type that BSDs and musl/glibc expose to userspace.
+ */
+struct igmp {
+ uint8_t igmp_type;
+ uint8_t igmp_code;
+ uint16_t igmp_cksum;
+ struct in_addr igmp_group;
+};
+
+/** Commonly-used BSD synonym for the Linux constant. */
+#define IGMP_MEMBERSHIP_QUERY IGMP_HOST_MEMBERSHIP_QUERY
diff --git a/libc/include/sys/io.h b/libc/include/sys/io.h
new file mode 100644
index 0000000..d187b78
--- /dev/null
+++ b/libc/include/sys/io.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/**
+ * @file sys/io.h
+ * @brief The x86/x86-64 I/O port functions iopl() and ioperm().
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+__BEGIN_DECLS
+
+/**
+ * [iopl(2)](http://man7.org/linux/man-pages/man2/iopl.2.html) changes the I/O
+ * privilege level for all x86/x8-64 I/O ports, for the calling thread.
+ *
+ * New callers should use ioperm() instead.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ *
+ * Only available for x86/x86-64.
+ */
+#if defined(__NR_iopl)
+__attribute__((__deprecated__("use ioperm() instead"))) static __inline int iopl(int __level) {
+ return syscall(__NR_iopl, __level);
+}
+#endif
+
+/**
+ * [ioperm(2)](http://man7.org/linux/man-pages/man2/ioperm.2.html) sets the I/O
+ * permissions for the given number of x86/x86-64 I/O ports, starting at the
+ * given port.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ *
+ * Only available for x86/x86-64.
+ */
+#if defined(__NR_iopl)
+static __inline int ioperm(unsigned long __from, unsigned long __n, int __enabled) {
+ return syscall(__NR_ioperm, __from, __n, __enabled);
+}
+#endif
+
+__END_DECLS
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 9402e70..47ddce0 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -277,41 +277,33 @@
#define IPX_TYPE 1
-#ifdef __i386__
-# define __socketcall extern __attribute__((__cdecl__))
-#else
-# define __socketcall extern
-#endif
-
-__socketcall int accept(int __fd, struct sockaddr* _Nullable __addr, socklen_t* _Nullable __addr_length);
-__socketcall int accept4(int __fd, struct sockaddr* _Nullable __addr, socklen_t* _Nullable __addr_length, int __flags);
-__socketcall int bind(int __fd, const struct sockaddr* _Nonnull __addr, socklen_t __addr_length);
-__socketcall int connect(int __fd, const struct sockaddr* _Nonnull __addr, socklen_t __addr_length);
-__socketcall int getpeername(int __fd, struct sockaddr* _Nonnull __addr, socklen_t* _Nonnull __addr_length);
-__socketcall int getsockname(int __fd, struct sockaddr* _Nonnull __addr, socklen_t* _Nonnull __addr_length);
-__socketcall int getsockopt(int __fd, int __level, int __option, void* _Nullable __value, socklen_t* _Nonnull __value_length);
-__socketcall int listen(int __fd, int __backlog);
-__socketcall int recvmmsg(int __fd, struct mmsghdr* _Nonnull __msgs, unsigned int __msg_count, int __flags, const struct timespec* _Nullable __timeout);
-__socketcall ssize_t recvmsg(int __fd, struct msghdr* _Nonnull __msg, int __flags);
-__socketcall int sendmmsg(int __fd, const struct mmsghdr* _Nonnull __msgs, unsigned int __msg_count, int __flags);
-__socketcall ssize_t sendmsg(int __fd, const struct msghdr* _Nonnull __msg, int __flags);
-__socketcall int setsockopt(int __fd, int __level, int __option, const void* _Nullable __value, socklen_t __value_length);
-__socketcall int shutdown(int __fd, int __how);
-__socketcall int socket(int __af, int __type, int __protocol);
-__socketcall int socketpair(int __af, int __type, int __protocol, int __fds[_Nonnull 2]);
+int accept(int __fd, struct sockaddr* _Nullable __addr, socklen_t* _Nullable __addr_length);
+int accept4(int __fd, struct sockaddr* _Nullable __addr, socklen_t* _Nullable __addr_length, int __flags);
+int bind(int __fd, const struct sockaddr* _Nonnull __addr, socklen_t __addr_length);
+int connect(int __fd, const struct sockaddr* _Nonnull __addr, socklen_t __addr_length);
+int getpeername(int __fd, struct sockaddr* _Nonnull __addr, socklen_t* _Nonnull __addr_length);
+int getsockname(int __fd, struct sockaddr* _Nonnull __addr, socklen_t* _Nonnull __addr_length);
+int getsockopt(int __fd, int __level, int __option, void* _Nullable __value, socklen_t* _Nonnull __value_length);
+int listen(int __fd, int __backlog);
+int recvmmsg(int __fd, struct mmsghdr* _Nonnull __msgs, unsigned int __msg_count, int __flags, const struct timespec* _Nullable __timeout);
+ssize_t recvmsg(int __fd, struct msghdr* _Nonnull __msg, int __flags);
+int sendmmsg(int __fd, const struct mmsghdr* _Nonnull __msgs, unsigned int __msg_count, int __flags);
+ssize_t sendmsg(int __fd, const struct msghdr* _Nonnull __msg, int __flags);
+int setsockopt(int __fd, int __level, int __option, const void* _Nullable __value, socklen_t __value_length);
+int shutdown(int __fd, int __how);
+int socket(int __af, int __type, int __protocol);
+int socketpair(int __af, int __type, int __protocol, int __fds[_Nonnull 2]);
ssize_t recv(int __fd, void* _Nullable __buf, size_t __n, int __flags);
ssize_t send(int __fd, const void* _Nonnull __buf, size_t __n, int __flags);
-__socketcall ssize_t sendto(int __fd, const void* _Nonnull __buf, size_t __n, int __flags, const struct sockaddr* _Nullable __dst_addr, socklen_t __dst_addr_length);
-__socketcall ssize_t recvfrom(int __fd, void* _Nullable __buf, size_t __n, int __flags, struct sockaddr* _Nullable __src_addr, socklen_t* _Nullable __src_addr_length);
+ssize_t sendto(int __fd, const void* _Nonnull __buf, size_t __n, int __flags, const struct sockaddr* _Nullable __dst_addr, socklen_t __dst_addr_length);
+ssize_t recvfrom(int __fd, void* _Nullable __buf, size_t __n, int __flags, struct sockaddr* _Nullable __src_addr, socklen_t* _Nullable __src_addr_length);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#include <bits/fortify/socket.h>
#endif
-#undef __socketcall
-
__END_DECLS
#endif
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 89a7ce7..0d442b4 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -187,6 +187,10 @@
"record_allocs_file",
{0, &Config::SetRecordAllocsFile},
},
+ {
+ "record_allocs_on_exit",
+ {0, &Config::SetRecordAllocsOnExit},
+ },
{
"verify_pointers",
@@ -401,6 +405,14 @@
return true;
}
+bool Config::SetRecordAllocsOnExit(const std::string& option, const std::string& value) {
+ if (Config::VerifyValueEmpty(option, value)) {
+ record_allocs_on_exit_ = true;
+ return true;
+ }
+ return false;
+}
+
bool Config::VerifyValueEmpty(const std::string& option, const std::string& value) {
if (!value.empty()) {
// This is not valid.
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index 754970f..8551712 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -98,6 +98,7 @@
int record_allocs_signal() const { return record_allocs_signal_; }
size_t record_allocs_num_entries() const { return record_allocs_num_entries_; }
const std::string& record_allocs_file() const { return record_allocs_file_; }
+ bool record_allocs_on_exit() const { return record_allocs_on_exit_; }
int check_unreachable_signal() const { return check_unreachable_signal_; }
@@ -139,6 +140,7 @@
bool SetRecordAllocs(const std::string& option, const std::string& value);
bool SetRecordAllocsFile(const std::string& option, const std::string& value);
+ bool SetRecordAllocsOnExit(const std::string& option, const std::string& value);
bool VerifyValueEmpty(const std::string& option, const std::string& value);
@@ -170,6 +172,7 @@
int record_allocs_signal_ = 0;
size_t record_allocs_num_entries_ = 0;
std::string record_allocs_file_;
+ bool record_allocs_on_exit_ = false;
uint64_t options_ = 0;
uint8_t fill_alloc_value_;
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index 4e39bed..750a469 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -456,6 +456,19 @@
**NOTE**: This option is not available until the O release of Android.
+### record\_allocs\_on\_exit
+This option only has meaning if record\_allocs is set. It indicates that
+when the process terminates, the record file should be created
+automatically.
+
+The only caveat to this option is that when the process terminates,
+the file that will contain the records will be the normal file name
+with **.PID** appended. Where PID is the pid of the process that has
+terminated. This is to avoid cases where a number of processes exit
+at the same time and attempt to write to the same file.
+
+**NOTE**: This option is not available until the V release of Android.
+
### verify\_pointers
Track all live allocations to determine if a pointer is used that does not
exist. This option is a lightweight way to verify that all
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 8a77170..79e051b 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -131,17 +131,30 @@
record_obj_->WriteEntries();
}
+void RecordData::WriteEntriesOnExit() {
+ if (record_obj_ == nullptr) return;
+
+ // Append the current pid to the file name to avoid multiple processes
+ // writing to the same file.
+ std::string file(record_obj_->file());
+ file += "." + std::to_string(getpid());
+ record_obj_->WriteEntries(file);
+}
+
void RecordData::WriteEntries() {
+ WriteEntries(file_);
+}
+
+void RecordData::WriteEntries(const std::string& file) {
std::lock_guard<std::mutex> entries_lock(entries_lock_);
if (cur_index_ == 0) {
info_log("No alloc entries to write.");
return;
}
- int dump_fd =
- open(dump_file_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 0755);
+ int dump_fd = open(file.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 0755);
if (dump_fd == -1) {
- error_log("Cannot create record alloc file %s: %s", dump_file_.c_str(), strerror(errno));
+ error_log("Cannot create record alloc file %s: %s", file.c_str(), strerror(errno));
return;
}
@@ -179,7 +192,7 @@
entries_.resize(config.record_allocs_num_entries());
cur_index_ = 0U;
- dump_file_ = config.record_allocs_file();
+ file_ = config.record_allocs_file();
return true;
}
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index a02c956..7efa1f7 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -162,19 +162,23 @@
void AddEntry(const RecordEntry* entry);
void AddEntryOnly(const RecordEntry* entry);
+ const std::string& file() { return file_; }
pthread_key_t key() { return key_; }
+ static void WriteEntriesOnExit();
+
private:
static void WriteData(int, siginfo_t*, void*);
static RecordData* record_obj_;
void WriteEntries();
+ void WriteEntries(const std::string& file);
std::mutex entries_lock_;
pthread_key_t key_;
std::vector<std::unique_ptr<const RecordEntry>> entries_;
size_t cur_index_;
- std::string dump_file_;
+ std::string file_;
BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
};
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index b66b8e2..6d88092 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -451,6 +451,10 @@
PointerData::LogLeaks();
}
+ if ((g_debug->config().options() & RECORD_ALLOCS) && g_debug->config().record_allocs_on_exit()) {
+ RecordData::WriteEntriesOnExit();
+ }
+
if ((g_debug->config().options() & BACKTRACE) && g_debug->config().backtrace_dump_on_exit()) {
debug_dump_heap(android::base::StringPrintf("%s.%d.exit.txt",
g_debug->config().backtrace_dump_prefix().c_str(),
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index 84c9145..c79d052 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -571,6 +571,25 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugConfigTest, record_allocs_on_exit) {
+ ASSERT_TRUE(InitConfig("record_allocs_on_exit")) << getFakeLogPrint();
+ ASSERT_EQ(0U, config->options());
+ ASSERT_TRUE(config->record_allocs_on_exit());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, record_allocs_on_exit_error) {
+ ASSERT_FALSE(InitConfig("record_allocs_on_exit=something")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg(
+ "6 malloc_debug malloc_testing: value set for option 'record_allocs_on_exit' "
+ "which does not take a value\n");
+ ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugConfigTest, guard_min_error) {
ASSERT_FALSE(InitConfig("guard=0"));
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index aee2572..d7a7a4f 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -77,7 +77,7 @@
// This avoids accidentally grabbing data from a previous process with
// the same pid.
log_start_time_ = {};
- logger_list* list = android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, 1000, 0);
+ logger_list* list = android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, INT_MAX, 0);
if (list == nullptr) {
return;
}
@@ -111,7 +111,7 @@
while (true) {
// Do not use non-blocking mode so that the two threads
// are essentially asleep and not consuming any cpu.
- list = android_logger_list_open(log, 0, 1000, pid);
+ list = android_logger_list_open(log, 0, INT_MAX, pid);
if (list != nullptr) {
break;
}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 334dada..ef8d235 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -185,6 +185,7 @@
}
static void VerifyRecords(std::vector<std::string>& expected, std::string& actual) {
+ ASSERT_TRUE(expected.size() != 0);
size_t offset = 0;
for (std::string& str : expected) {
ASSERT_STREQ(str.c_str(), actual.substr(offset, str.size()).c_str());
@@ -1512,7 +1513,7 @@
// Call the exit function manually.
debug_finalize();
- exit(0);
+ _exit(0);
}
ASSERT_NE(-1, pid);
ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
@@ -1561,7 +1562,7 @@
// Call the exit function manually.
debug_finalize();
- exit(0);
+ _exit(0);
}
ASSERT_NE(-1, pid);
ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
@@ -1619,7 +1620,7 @@
// Call the exit function manually.
debug_finalize();
- exit(0);
+ _exit(0);
}
ASSERT_NE(-1, pid);
ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0)));
@@ -2429,6 +2430,33 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, record_allocs_on_exit) {
+ InitRecordAllocs("record_allocs record_allocs_on_exit");
+
+ // The filename created on exit always appends the pid.
+ // Modify the variable so the file is deleted at the end of the test.
+ record_filename += '.' + std::to_string(getpid());
+
+ std::vector<std::string> expected;
+ void* ptr = debug_malloc(100);
+ expected.push_back(android::base::StringPrintf("%d: malloc %p 100", getpid(), ptr));
+ ptr = debug_malloc(200);
+ expected.push_back(android::base::StringPrintf("%d: malloc %p 200", getpid(), ptr));
+ ptr = debug_malloc(400);
+ expected.push_back(android::base::StringPrintf("%d: malloc %p 400", getpid(), ptr));
+
+ // Call the exit function manually.
+ debug_finalize();
+
+ // Read all of the contents.
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
+ VerifyRecords(expected, actual);
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, verify_pointers) {
Init("verify_pointers");
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index 73cd821..98b3d27 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -29,8 +29,11 @@
#pragma once
#include <sys/auxv.h>
+#include <sys/mman.h>
#include <sys/prctl.h>
+#include "page.h"
+
// Note: Most PR_MTE_* constants come from the upstream kernel. This tag mask
// allows for the hardware to provision any nonzero tag. Zero tags are reserved
// for scudo to use for the chunk headers in order to prevent linear heap
@@ -63,6 +66,65 @@
}
}
};
+
+// N.B. that this is NOT the pagesize, but 4096. This is hardcoded in the codegen.
+// See
+// https://github.com/search?q=repo%3Allvm/llvm-project%20AArch64StackTagging%3A%3AinsertBaseTaggedPointer&type=code
+constexpr size_t kStackMteRingbufferSizeMultiplier = 4096;
+
+inline size_t stack_mte_ringbuffer_size(uintptr_t size_cls) {
+ return kStackMteRingbufferSizeMultiplier * (1 << size_cls);
+}
+
+inline size_t stack_mte_ringbuffer_size_from_pointer(uintptr_t ptr) {
+ // The size in the top byte is not the size_cls, but the number of "pages" (not OS pages, but
+ // kStackMteRingbufferSizeMultiplier).
+ return kStackMteRingbufferSizeMultiplier * (ptr >> 56ULL);
+}
+
+inline uintptr_t stack_mte_ringbuffer_size_add_to_pointer(uintptr_t ptr, uintptr_t size_cls) {
+ return ptr | ((1ULL << size_cls) << 56ULL);
+}
+
+inline void* stack_mte_ringbuffer_allocate(size_t n, const char* name) {
+ if (n > 7) return nullptr;
+ // Allocation needs to be aligned to 2*size to make the fancy code-gen work.
+ // So we allocate 3*size - pagesz bytes, which will always contain size bytes
+ // aligned to 2*size, and unmap the unneeded part.
+ // See
+ // https://github.com/search?q=repo%3Allvm/llvm-project%20AArch64StackTagging%3A%3AinsertBaseTaggedPointer&type=code
+ //
+ // In the worst case, we get an allocation that is one page past the properly
+ // aligned address, in which case we have to unmap the previous
+ // 2*size - pagesz bytes. In that case, we still have size properly aligned
+ // bytes left.
+ size_t size = stack_mte_ringbuffer_size(n);
+ size_t pgsize = page_size();
+
+ size_t alloc_size = __BIONIC_ALIGN(3 * size - pgsize, pgsize);
+ void* allocation_ptr =
+ mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (allocation_ptr == MAP_FAILED)
+ return nullptr;
+ uintptr_t allocation = reinterpret_cast<uintptr_t>(allocation_ptr);
+
+ size_t alignment = 2 * size;
+ uintptr_t aligned_allocation = __BIONIC_ALIGN(allocation, alignment);
+ if (allocation != aligned_allocation) {
+ munmap(reinterpret_cast<void*>(allocation), aligned_allocation - allocation);
+ }
+ if (aligned_allocation + size != allocation + alloc_size) {
+ munmap(reinterpret_cast<void*>(aligned_allocation + size),
+ (allocation + alloc_size) - (aligned_allocation + size));
+ }
+
+ if (name) {
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<void*>(aligned_allocation), size, name);
+ }
+
+ // We store the size in the top byte of the pointer (which is ignored)
+ return reinterpret_cast<void*>(stack_mte_ringbuffer_size_add_to_pointer(aligned_allocation, n));
+}
#else
struct ScopedDisableMTE {
// Silence unused variable warnings in non-aarch64 builds.
diff --git a/libc/platform/bionic/tls_defines.h b/libc/platform/bionic/tls_defines.h
index 8fe8701..06c6617 100644
--- a/libc/platform/bionic/tls_defines.h
+++ b/libc/platform/bionic/tls_defines.h
@@ -85,7 +85,8 @@
// [1] "Addenda to, and Errata in, the ABI for the ARM Architecture". Section 3.
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045e/IHI0045E_ABI_addenda.pdf
-#define MIN_TLS_SLOT (-2) // update this value when reserving a slot
+#define MIN_TLS_SLOT (-3) // update this value when reserving a slot
+#define TLS_SLOT_STACK_MTE (-3)
#define TLS_SLOT_NATIVE_BRIDGE_GUEST_STATE (-2)
#define TLS_SLOT_BIONIC_TLS (-1)
#define TLS_SLOT_DTV 0
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 0949056..a1bebda 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -76,10 +76,23 @@
};
__LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
-// This cannot be in __libc_globals, because we cannot access the
+// These cannot be in __libc_globals, because we cannot access the
// WriteProtected in a thread-safe way.
// See b/328256432.
+//
+// __libc_memtag_stack says whether stack MTE is enabled on the process, i.e.
+// whether the stack pages are mapped with PROT_MTE. This is always false if
+// MTE is disabled for the process (i.e. libc_globals.memtag is false).
__LIBC_HIDDEN__ extern _Atomic(bool) __libc_memtag_stack;
+// __libc_memtag_stack_abi says whether the process contains any code that was
+// compiled with memtag-stack. This is true even if the process does not have
+// MTE enabled (e.g. because it was overridden using MEMTAG_OPTIONS, or because
+// MTE is disabled for the device).
+// Code compiled with memtag-stack needs a stack history buffer in
+// TLS_SLOT_STACK_MTE, because the codegen will emit an unconditional
+// (to keep the code branchless) write to it.
+// Protected by g_heap_creation_lock.
+__LIBC_HIDDEN__ extern bool __libc_memtag_stack_abi;
struct abort_msg_t;
struct crash_detail_page_t;
@@ -133,7 +146,9 @@
size_t scudo_stack_depot_size = 0;
HeapTaggingLevel initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
+ // See comments for __libc_memtag_stack / __libc_memtag_stack_abi above.
bool initial_memtag_stack = false;
+ bool initial_memtag_stack_abi = false;
int64_t heap_tagging_upgrade_timer_sec = 0;
void (*memtag_stack_dlopen_callback)() = nullptr;
diff --git a/libc/system_properties/Android.bp b/libc/system_properties/Android.bp
index d45a2e3..16ea73f 100644
--- a/libc/system_properties/Android.bp
+++ b/libc/system_properties/Android.bp
@@ -11,7 +11,10 @@
cc_library_static {
name: "libsystemproperties",
- defaults: ["libc_defaults"],
+ defaults: [
+ "libc_defaults",
+ "large_system_property_node_defaults",
+ ],
native_bridge_supported: true,
srcs: [
"context_node.cpp",
@@ -54,3 +57,28 @@
"libasync_safe",
],
}
+
+soong_config_module_type {
+ name: "large_system_property_node_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "bionic",
+ bool_variables: [
+ "large_system_property_node",
+ ],
+ properties: [
+ "cflags",
+ ],
+}
+
+soong_config_bool_variable {
+ name: "large_system_property_node",
+}
+
+large_system_property_node_cc_defaults {
+ name: "large_system_property_node_defaults",
+ soong_config_variables: {
+ large_system_property_node: {
+ cflags: ["-DLARGE_SYSTEM_PROPERTY_NODE=1"]
+ }
+ }
+}
diff --git a/libc/system_properties/prop_area.cpp b/libc/system_properties/prop_area.cpp
index 4668eed..a816a38 100644
--- a/libc/system_properties/prop_area.cpp
+++ b/libc/system_properties/prop_area.cpp
@@ -41,7 +41,11 @@
#include <async_safe/log.h>
+#ifdef LARGE_SYSTEM_PROPERTY_NODE
+constexpr size_t PA_SIZE = 1024 * 1024;
+#else
constexpr size_t PA_SIZE = 128 * 1024;
+#endif
constexpr uint32_t PROP_AREA_MAGIC = 0x504f5250;
constexpr uint32_t PROP_AREA_VERSION = 0xfc6ed0ab;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 8c457c8..d7afe2a 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -27,7 +27,7 @@
# ARM assembler templates for each syscall stub
#
-arm_eabi_call_default = syscall_stub_header + """\
+arm_call_default = syscall_stub_header + """\
mov ip, r7
.cfi_register r7, ip
ldr r7, =%(__NR_name)s
@@ -41,7 +41,7 @@
END(%(func)s)
"""
-arm_eabi_call_long = syscall_stub_header + """\
+arm_call_long = syscall_stub_header + """\
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
@@ -230,11 +230,11 @@
return stub
-def arm_eabi_genstub(syscall):
+def arm_genstub(syscall):
num_regs = count_arm_param_registers(syscall["params"])
if num_regs > 4:
- return arm_eabi_call_long % syscall
- return arm_eabi_call_default % syscall
+ return arm_call_long % syscall
+ return arm_call_default % syscall
def arm64_genstub(syscall):
@@ -456,7 +456,7 @@
syscall["__NR_name"] = make__NR_name(syscall["name"])
if "arm" in syscall:
- syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall)
+ syscall["asm-arm"] = add_footer(32, arm_genstub(syscall), syscall)
if "arm64" in syscall:
syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 95b412b..1bbd902 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -60,33 +60,14 @@
native_bridge_supported: true,
static_ndk_lib: true,
- defaults: ["linux_bionic_supported"],
-
- // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
- // libgcc.a are made static to libdl.so. This in turn ensures that libraries that
- // a) pull symbols from libgcc.a and b) depend on libdl.so will not rely on libdl.so
- // to provide those symbols, but will instead pull them from libgcc.a. Specifically,
- // we use this property to make sure libc.so has its own copy of the code from
- // libgcc.a it uses.
- //
- // DO NOT REMOVE --exclude-libs!
-
- ldflags: [
- "-Wl,--exclude-libs=libgcc.a",
- "-Wl,--exclude-libs=libgcc_stripped.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
+ defaults: [
+ "linux_bionic_supported",
+ "bug_24465209_workaround",
],
- // for x86, exclude libgcc_eh.a for the same reasons as above
arch: {
arm: {
version_script: ":libdl.arm.map",
- pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
},
arm64: {
version_script: ":libdl.arm64.map",
@@ -95,15 +76,9 @@
version_script: ":libdl.riscv64.map",
},
x86: {
- pack_relocations: false,
- ldflags: [
- "-Wl,--exclude-libs=libgcc_eh.a",
- "-Wl,--hash-style=both",
- ],
version_script: ":libdl.x86.map",
},
x86_64: {
- ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
version_script: ":libdl.x86_64.map",
},
},
@@ -162,37 +137,6 @@
recovery_available: true,
native_bridge_supported: true,
- // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
- // libgcc.a are made static to libdl.so. This in turn ensures that libraries that
- // a) pull symbols from libgcc.a and b) depend on libdl.so will not rely on libdl.so
- // to provide those symbols, but will instead pull them from libgcc.a. Specifically,
- // we use this property to make sure libc.so has its own copy of the code from
- // libgcc.a it uses.
- //
- // DO NOT REMOVE --exclude-libs!
-
- ldflags: [
- "-Wl,--exclude-libs=libgcc.a",
- "-Wl,--exclude-libs=libgcc_stripped.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
- ],
-
- // for x86, exclude libgcc_eh.a for the same reasons as above
- arch: {
- x86: {
- ldflags: [
- "-Wl,--exclude-libs=libgcc_eh.a",
- ],
- },
- x86_64: {
- ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
- },
- },
-
srcs: ["libdl_android.cpp"],
version_script: "libdl_android.map.txt",
diff --git a/libm/Android.bp b/libm/Android.bp
index cc37fb7..00d90a0 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -21,7 +21,10 @@
cc_library {
name: "libm",
- defaults: ["linux_bionic_supported"],
+ defaults: [
+ "linux_bionic_supported",
+ "bug_24465209_workaround",
+ ],
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
@@ -196,11 +199,6 @@
"upstream-netbsd/lib/libm/complex/ctanhl.c",
"upstream-netbsd/lib/libm/complex/ctanl.c",
- // TODO: this comes from from upstream's libc, not libm, but it's an
- // implementation detail that should have hidden visibility, so it needs
- // to be in whatever library the math code is in.
- "digittoint.c",
-
// Functionality not in the BSDs.
"significandl.c",
"fake_long_double.c",
@@ -282,8 +280,6 @@
"upstream-freebsd/lib/msun/src/s_ceilf.c",
],
instruction_set: "arm",
- pack_relocations: false,
- ldflags: ["-Wl,--hash-style=both"],
version_script: ":libm.arm.map",
no_libcrt: true,
shared: {
@@ -368,11 +364,9 @@
"upstream-freebsd/lib/msun/src/s_truncf.c",
],
local_include_dirs: ["i387"],
- pack_relocations: false,
// The x86 ABI doesn't include this, which is needed for the
// roundss/roundsd instructions that we've used since Android M.
cflags: ["-msse4.1"],
- ldflags: ["-Wl,--hash-style=both"],
version_script: ":libm.x86.map",
},
diff --git a/libm/NOTICE b/libm/NOTICE
index 424725e..3c0e783 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -140,15 +140,6 @@
-------------------------------------------------------------------
====================================================
-Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
-
-Permission to use, copy, modify, and distribute this
-software is freely granted, provided that this notice
-is preserved.
-
--------------------------------------------------------------------
-
-====================================================
Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
Permission to use, copy, modify, and distribute this
@@ -423,32 +414,6 @@
-------------------------------------------------------------------
-Copyright (c) 2007 David Schultz
-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.
-
-THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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) 2007 The NetBSD Foundation, Inc.
All rights reserved.
@@ -1273,33 +1238,3 @@
-------------------------------------------------------------------
-SPDX-License-Identifier: BSD-3-Clause
-
-Copyright (c) 2003 Dag-Erling Smørgrav
-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
- in this position and unchanged.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-
--------------------------------------------------------------------
-
diff --git a/libm/digittoint.c b/libm/digittoint.c
deleted file mode 100644
index 1824788..0000000
--- a/libm/digittoint.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 2007 David Schultz
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-
-/* digittoint is in the FreeBSD C library, but implemented in terms of locale stuff. */
-__LIBC_HIDDEN__ int digittoint(char ch) {
- int d = ch - '0';
- if ((unsigned) d < 10) {
- return d;
- }
- d = ch - 'a';
- if ((unsigned) d < 6) {
- return d + 10;
- }
- d = ch - 'A';
- if ((unsigned) d < 6) {
- return d + 10;
- }
- return -1;
-}
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index 7accc55..a3c7cd4 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -27,18 +27,12 @@
#define __strong_reference(sym,aliassym) \
extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
-#define __warn_references(sym,msg) /* ignored */
-
-// digittoint is in BSD's <ctype.h>, but not ours, so we have a secret
-// implementation in libm. We reuse parts of libm in the NDK's
-// libandroid_support, where it's a static library, so we want all our
-// "hidden" functions start with a double underscore --- being HIDDEN
-// in the ELF sense is not sufficient.
-#define digittoint __libm_digittoint
-int digittoint(char ch);
-
-// Similarly rename _scan_nan.
-#define _scan_nan __libm_scan_nan
+// digittoint is in BSD's <ctype.h> but not ours.
+#include <ctype.h>
+static inline int digittoint(char ch) {
+ if (!isxdigit(ch)) return -1;
+ return isdigit(ch) ? (ch - '0') : (_tolower(ch) - 'a');
+}
// FreeBSD exports these in <math.h> but we don't.
double cospi(double);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_exp.c b/libm/upstream-freebsd/lib/msun/src/e_exp.c
deleted file mode 100644
index 59da392..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_exp.c
+++ /dev/null
@@ -1,164 +0,0 @@
-
-/* @(#)e_exp.c 1.6 04/04/22 */
-/*
- * ====================================================
- * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* exp(x)
- * Returns the exponential of x.
- *
- * Method
- * 1. Argument reduction:
- * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
- * Given x, find r and integer k such that
- *
- * x = k*ln2 + r, |r| <= 0.5*ln2.
- *
- * Here r will be represented as r = hi-lo for better
- * accuracy.
- *
- * 2. Approximation of exp(r) by a special rational function on
- * the interval [0,0.34658]:
- * Write
- * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
- * We use a special Remes algorithm on [0,0.34658] to generate
- * a polynomial of degree 5 to approximate R. The maximum error
- * of this polynomial approximation is bounded by 2**-59. In
- * other words,
- * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
- * (where z=r*r, and the values of P1 to P5 are listed below)
- * and
- * | 5 | -59
- * | 2.0+P1*z+...+P5*z - R(z) | <= 2
- * | |
- * The computation of exp(r) thus becomes
- * 2*r
- * exp(r) = 1 + -------
- * R - r
- * r*R1(r)
- * = 1 + r + ----------- (for better accuracy)
- * 2 - R1(r)
- * where
- * 2 4 10
- * R1(r) = r - (P1*r + P2*r + ... + P5*r ).
- *
- * 3. Scale back to obtain exp(x):
- * From step 1, we have
- * exp(x) = 2^k * exp(r)
- *
- * Special cases:
- * exp(INF) is INF, exp(NaN) is NaN;
- * exp(-INF) is 0, and
- * for finite argument, only exp(0)=1 is exact.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Misc. info.
- * For IEEE double
- * if x > 7.09782712893383973096e+02 then exp(x) overflow
- * if x < -7.45133219101941108420e+02 then exp(x) underflow
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-static const double
-one = 1.0,
-halF[2] = {0.5,-0.5,},
-o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
-u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
-ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
- -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
-ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
- -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
-invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
-P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
-P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
-P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
-P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
-P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
-
-static volatile double
-huge = 1.0e+300,
-twom1000= 9.33263618503218878990e-302; /* 2**-1000=0x01700000,0*/
-
-double
-exp(double x) /* default IEEE double exp */
-{
- double y,hi=0.0,lo=0.0,c,t,twopk;
- int32_t k=0,xsb;
- u_int32_t hx;
-
- GET_HIGH_WORD(hx,x);
- xsb = (hx>>31)&1; /* sign bit of x */
- hx &= 0x7fffffff; /* high word of |x| */
-
- /* filter out non-finite argument */
- if(hx >= 0x40862E42) { /* if |x|>=709.78... */
- if(hx>=0x7ff00000) {
- u_int32_t lx;
- GET_LOW_WORD(lx,x);
- if(((hx&0xfffff)|lx)!=0)
- return x+x; /* NaN */
- else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
- }
- if(x > o_threshold) return huge*huge; /* overflow */
- if(x < u_threshold) return twom1000*twom1000; /* underflow */
- }
-
- /* argument reduction */
- if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
- if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
- hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
- } else {
- k = (int)(invln2*x+halF[xsb]);
- t = k;
- hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
- lo = t*ln2LO[0];
- }
- STRICT_ASSIGN(double, x, hi - lo);
- }
- else if(hx < 0x3e300000) { /* when |x|<2**-28 */
- if(huge+x>one) return one+x;/* trigger inexact */
- }
- else k = 0;
-
- /* x is now in primary range */
- t = x*x;
- if(k >= -1021)
- INSERT_WORDS(twopk,((u_int32_t)(0x3ff+k))<<20, 0);
- else
- INSERT_WORDS(twopk,((u_int32_t)(0x3ff+(k+1000)))<<20, 0);
- c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- if(k==0) return one-((x*c)/(c-2.0)-x);
- else y = one-((lo-(x*c)/(2.0-c))-hi);
- if(k >= -1021) {
- if (k==1024) return y*2.0*0x1p1023;
- return y*twopk;
- } else {
- return y*twopk*twom1000;
- }
-}
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(exp, expl);
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/e_expf.c b/libm/upstream-freebsd/lib/msun/src/e_expf.c
deleted file mode 100644
index 620d341..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_expf.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* e_expf.c -- float version of e_exp.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-static const float
-one = 1.0,
-halF[2] = {0.5,-0.5,},
-o_threshold= 8.8721679688e+01, /* 0x42b17180 */
-u_threshold= -1.0397208405e+02, /* 0xc2cff1b5 */
-ln2HI[2] ={ 6.9314575195e-01, /* 0x3f317200 */
- -6.9314575195e-01,}, /* 0xbf317200 */
-ln2LO[2] ={ 1.4286067653e-06, /* 0x35bfbe8e */
- -1.4286067653e-06,}, /* 0xb5bfbe8e */
-invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
-/*
- * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
- * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
- */
-P1 = 1.6666625440e-1, /* 0xaaaa8f.0p-26 */
-P2 = -2.7667332906e-3; /* -0xb55215.0p-32 */
-
-static volatile float
-huge = 1.0e+30,
-twom100 = 7.8886090522e-31; /* 2**-100=0x0d800000 */
-
-float
-expf(float x)
-{
- float y,hi=0.0,lo=0.0,c,t,twopk;
- int32_t k=0,xsb;
- u_int32_t hx;
-
- GET_FLOAT_WORD(hx,x);
- xsb = (hx>>31)&1; /* sign bit of x */
- hx &= 0x7fffffff; /* high word of |x| */
-
- /* filter out non-finite argument */
- if(hx >= 0x42b17218) { /* if |x|>=88.721... */
- if(hx>0x7f800000)
- return x+x; /* NaN */
- if(hx==0x7f800000)
- return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
- if(x > o_threshold) return huge*huge; /* overflow */
- if(x < u_threshold) return twom100*twom100; /* underflow */
- }
-
- /* argument reduction */
- if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
- if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
- hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
- } else {
- k = invln2*x+halF[xsb];
- t = k;
- hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
- lo = t*ln2LO[0];
- }
- STRICT_ASSIGN(float, x, hi - lo);
- }
- else if(hx < 0x39000000) { /* when |x|<2**-14 */
- if(huge+x>one) return one+x;/* trigger inexact */
- }
- else k = 0;
-
- /* x is now in primary range */
- t = x*x;
- if(k >= -125)
- SET_FLOAT_WORD(twopk,((u_int32_t)(0x7f+k))<<23);
- else
- SET_FLOAT_WORD(twopk,((u_int32_t)(0x7f+(k+100)))<<23);
- c = x - t*(P1+t*P2);
- if(k==0) return one-((x*c)/(c-(float)2.0)-x);
- else y = one-((lo-(x*c)/((float)2.0-c))-hi);
- if(k >= -125) {
- if(k==128) return y*2.0F*0x1p127F;
- return y*twopk;
- } else {
- return y*twopk*twom100;
- }
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log.c b/libm/upstream-freebsd/lib/msun/src/e_log.c
deleted file mode 100644
index 03ce820..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_log.c
+++ /dev/null
@@ -1,147 +0,0 @@
-
-/* @(#)e_log.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* log(x)
- * Return the logrithm of x
- *
- * Method :
- * 1. Argument Reduction: find k and f such that
- * x = 2^k * (1+f),
- * where sqrt(2)/2 < 1+f < sqrt(2) .
- *
- * 2. Approximation of log(1+f).
- * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
- * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
- * = 2s + s*R
- * We use a special Reme algorithm on [0,0.1716] to generate
- * a polynomial of degree 14 to approximate R The maximum error
- * of this polynomial approximation is bounded by 2**-58.45. In
- * other words,
- * 2 4 6 8 10 12 14
- * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
- * (the values of Lg1 to Lg7 are listed in the program)
- * and
- * | 2 14 | -58.45
- * | Lg1*s +...+Lg7*s - R(z) | <= 2
- * | |
- * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
- * In order to guarantee error in log below 1ulp, we compute log
- * by
- * log(1+f) = f - s*(f - R) (if f is not too large)
- * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
- *
- * 3. Finally, log(x) = k*ln2 + log(1+f).
- * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
- * Here ln2 is split into two floating point number:
- * ln2_hi + ln2_lo,
- * where n*ln2_hi is always exact for |n| < 2000.
- *
- * Special cases:
- * log(x) is NaN with signal if x < 0 (including -INF) ;
- * log(+INF) is +INF; log(0) is -INF with signal;
- * log(NaN) is that NaN with no signal.
- *
- * Accuracy:
- * according to an error analysis, the error is always less than
- * 1 ulp (unit in the last place).
- *
- * Constants:
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-static const double
-ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
-ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
-two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
-Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
-Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
-Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
-Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
-Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
-Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
-Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
-
-static const double zero = 0.0;
-static volatile double vzero = 0.0;
-
-double
-log(double x)
-{
- double hfsq,f,s,z,R,w,t1,t2,dk;
- int32_t k,hx,i,j;
- u_int32_t lx;
-
- EXTRACT_WORDS(hx,lx,x);
-
- k=0;
- if (hx < 0x00100000) { /* x < 2**-1022 */
- if (((hx&0x7fffffff)|lx)==0)
- return -two54/vzero; /* log(+-0)=-inf */
- if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 54; x *= two54; /* subnormal number, scale up x */
- GET_HIGH_WORD(hx,x);
- }
- if (hx >= 0x7ff00000) return x+x;
- k += (hx>>20)-1023;
- hx &= 0x000fffff;
- i = (hx+0x95f64)&0x100000;
- SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
- k += (i>>20);
- f = x-1.0;
- if((0x000fffff&(2+hx))<3) { /* -2**-20 <= f < 2**-20 */
- if(f==zero) {
- if(k==0) {
- return zero;
- } else {
- dk=(double)k;
- return dk*ln2_hi+dk*ln2_lo;
- }
- }
- R = f*f*(0.5-0.33333333333333333*f);
- if(k==0) return f-R; else {dk=(double)k;
- return dk*ln2_hi-((R-dk*ln2_lo)-f);}
- }
- s = f/(2.0+f);
- dk = (double)k;
- z = s*s;
- i = hx-0x6147a;
- w = z*z;
- j = 0x6b851-hx;
- t1= w*(Lg2+w*(Lg4+w*Lg6));
- t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
- i |= j;
- R = t2+t1;
- if(i>0) {
- hfsq=0.5*f*f;
- if(k==0) return f-(hfsq-s*(hfsq+R)); else
- return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
- } else {
- if(k==0) return f-s*(f-R); else
- return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
- }
-}
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(log, logl);
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log2.c b/libm/upstream-freebsd/lib/msun/src/e_log2.c
deleted file mode 100644
index 10b1c00..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_log2.c
+++ /dev/null
@@ -1,117 +0,0 @@
-
-/* @(#)e_log10.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Return the base 2 logarithm of x. See e_log.c and k_log.h for most
- * comments.
- *
- * This reduces x to {k, 1+f} exactly as in e_log.c, then calls the kernel,
- * then does the combining and scaling steps
- * log2(x) = (f - 0.5*f*f + k_log1p(f)) / ln2 + k
- * in not-quite-routine extra precision.
- */
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-#include "k_log.h"
-
-static const double
-two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
-ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */
-
-static const double zero = 0.0;
-static volatile double vzero = 0.0;
-
-double
-log2(double x)
-{
- double f,hfsq,hi,lo,r,val_hi,val_lo,w,y;
- int32_t i,k,hx;
- u_int32_t lx;
-
- EXTRACT_WORDS(hx,lx,x);
-
- k=0;
- if (hx < 0x00100000) { /* x < 2**-1022 */
- if (((hx&0x7fffffff)|lx)==0)
- return -two54/vzero; /* log(+-0)=-inf */
- if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 54; x *= two54; /* subnormal number, scale up x */
- GET_HIGH_WORD(hx,x);
- }
- if (hx >= 0x7ff00000) return x+x;
- if (hx == 0x3ff00000 && lx == 0)
- return zero; /* log(1) = +0 */
- k += (hx>>20)-1023;
- hx &= 0x000fffff;
- i = (hx+0x95f64)&0x100000;
- SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
- k += (i>>20);
- y = (double)k;
- f = x - 1.0;
- hfsq = 0.5*f*f;
- r = k_log1p(f);
-
- /*
- * f-hfsq must (for args near 1) be evaluated in extra precision
- * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
- * This is fairly efficient since f-hfsq only depends on f, so can
- * be evaluated in parallel with R. Not combining hfsq with R also
- * keeps R small (though not as small as a true `lo' term would be),
- * so that extra precision is not needed for terms involving R.
- *
- * Compiler bugs involving extra precision used to break Dekker's
- * theorem for spitting f-hfsq as hi+lo, unless double_t was used
- * or the multi-precision calculations were avoided when double_t
- * has extra precision. These problems are now automatically
- * avoided as a side effect of the optimization of combining the
- * Dekker splitting step with the clear-low-bits step.
- *
- * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
- * precision to avoid a very large cancellation when x is very near
- * these values. Unlike the above cancellations, this problem is
- * specific to base 2. It is strange that adding +-1 is so much
- * harder than adding +-ln2 or +-log10_2.
- *
- * This uses Dekker's theorem to normalize y+val_hi, so the
- * compiler bugs are back in some configurations, sigh. And I
- * don't want to used double_t to avoid them, since that gives a
- * pessimization and the support for avoiding the pessimization
- * is not yet available.
- *
- * The multi-precision calculations for the multiplications are
- * routine.
- */
- hi = f - hfsq;
- SET_LOW_WORD(hi,0);
- lo = (f - hi) - hfsq + r;
- val_hi = hi*ivln2hi;
- val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
-
- /* spadd(val_hi, val_lo, y), except for not using double_t: */
- w = y + val_hi;
- val_lo += (y - w) + val_hi;
- val_hi = w;
-
- return val_lo + val_hi;
-}
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(log2, log2l);
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log2f.c b/libm/upstream-freebsd/lib/msun/src/e_log2f.c
deleted file mode 100644
index 956f33a..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_log2f.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Float version of e_log2.c. See the latter for most comments.
- */
-
-#include "math.h"
-#include "math_private.h"
-#include "k_logf.h"
-
-static const float
-two25 = 3.3554432000e+07, /* 0x4c000000 */
-ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */
-ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */
-
-static const float zero = 0.0;
-static volatile float vzero = 0.0;
-
-float
-log2f(float x)
-{
- float f,hfsq,hi,lo,r,y;
- int32_t i,k,hx;
-
- GET_FLOAT_WORD(hx,x);
-
- k=0;
- if (hx < 0x00800000) { /* x < 2**-126 */
- if ((hx&0x7fffffff)==0)
- return -two25/vzero; /* log(+-0)=-inf */
- if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 25; x *= two25; /* subnormal number, scale up x */
- GET_FLOAT_WORD(hx,x);
- }
- if (hx >= 0x7f800000) return x+x;
- if (hx == 0x3f800000)
- return zero; /* log(1) = +0 */
- k += (hx>>23)-127;
- hx &= 0x007fffff;
- i = (hx+(0x4afb0d))&0x800000;
- SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */
- k += (i>>23);
- y = (float)k;
- f = x - (float)1.0;
- hfsq = (float)0.5*f*f;
- r = k_log1pf(f);
-
- /*
- * We no longer need to avoid falling into the multi-precision
- * calculations due to compiler bugs breaking Dekker's theorem.
- * Keep avoiding this as an optimization. See e_log2.c for more
- * details (some details are here only because the optimization
- * is not yet available in double precision).
- *
- * Another compiler bug turned up. With gcc on i386,
- * (ivln2lo + ivln2hi) would be evaluated in float precision
- * despite runtime evaluations using double precision. So we
- * must cast one of its terms to float_t. This makes the whole
- * expression have type float_t, so return is forced to waste
- * time clobbering its extra precision.
- */
- if (sizeof(float_t) > sizeof(float))
- return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y;
-
- hi = f - hfsq;
- GET_FLOAT_WORD(hx,hi);
- SET_FLOAT_WORD(hi,hx&0xfffff000);
- lo = (f - hi) - hfsq + r;
- return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/e_logf.c b/libm/upstream-freebsd/lib/msun/src/e_logf.c
deleted file mode 100644
index 68a4d5d..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_logf.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* e_logf.c -- float version of e_log.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "math.h"
-#include "math_private.h"
-
-static const float
-ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
-ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
-two25 = 3.355443200e+07, /* 0x4c000000 */
-/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
-Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
-Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
-Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
-Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
-
-static const float zero = 0.0;
-static volatile float vzero = 0.0;
-
-float
-logf(float x)
-{
- float hfsq,f,s,z,R,w,t1,t2,dk;
- int32_t k,ix,i,j;
-
- GET_FLOAT_WORD(ix,x);
-
- k=0;
- if (ix < 0x00800000) { /* x < 2**-126 */
- if ((ix&0x7fffffff)==0)
- return -two25/vzero; /* log(+-0)=-inf */
- if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
- k -= 25; x *= two25; /* subnormal number, scale up x */
- GET_FLOAT_WORD(ix,x);
- }
- if (ix >= 0x7f800000) return x+x;
- k += (ix>>23)-127;
- ix &= 0x007fffff;
- i = (ix+(0x95f64<<3))&0x800000;
- SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
- k += (i>>23);
- f = x-(float)1.0;
- if((0x007fffff&(0x8000+ix))<0xc000) { /* -2**-9 <= f < 2**-9 */
- if(f==zero) {
- if(k==0) {
- return zero;
- } else {
- dk=(float)k;
- return dk*ln2_hi+dk*ln2_lo;
- }
- }
- R = f*f*((float)0.5-(float)0.33333333333333333*f);
- if(k==0) return f-R; else {dk=(float)k;
- return dk*ln2_hi-((R-dk*ln2_lo)-f);}
- }
- s = f/((float)2.0+f);
- dk = (float)k;
- z = s*s;
- i = ix-(0x6147a<<3);
- w = z*z;
- j = (0x6b851<<3)-ix;
- t1= w*(Lg2+w*Lg4);
- t2= z*(Lg1+w*Lg3);
- i |= j;
- R = t2+t1;
- if(i>0) {
- hfsq=(float)0.5*f*f;
- if(k==0) return f-(hfsq-s*(hfsq+R)); else
- return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
- } else {
- if(k==0) return f-s*(f-R); else
- return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
- }
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/e_pow.c b/libm/upstream-freebsd/lib/msun/src/e_pow.c
deleted file mode 100644
index adc64c9..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_pow.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* @(#)e_pow.c 1.5 04/04/22 SMI */
-/*
- * ====================================================
- * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* pow(x,y) return x**y
- *
- * n
- * Method: Let x = 2 * (1+f)
- * 1. Compute and return log2(x) in two pieces:
- * log2(x) = w1 + w2,
- * where w1 has 53-24 = 29 bit trailing zeros.
- * 2. Perform y*log2(x) = n+y' by simulating multi-precision
- * arithmetic, where |y'|<=0.5.
- * 3. Return x**y = 2**n*exp(y'*log2)
- *
- * Special cases:
- * 1. (anything) ** 0 is 1
- * 2. (anything) ** 1 is itself
- * 3. (anything) ** NAN is NAN except 1 ** NAN = 1
- * 4. NAN ** (anything except 0) is NAN
- * 5. +-(|x| > 1) ** +INF is +INF
- * 6. +-(|x| > 1) ** -INF is +0
- * 7. +-(|x| < 1) ** +INF is +0
- * 8. +-(|x| < 1) ** -INF is +INF
- * 9. +-1 ** +-INF is 1
- * 10. +0 ** (+anything except 0, NAN) is +0
- * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
- * 12. +0 ** (-anything except 0, NAN) is +INF
- * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
- * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
- * 15. +INF ** (+anything except 0,NAN) is +INF
- * 16. +INF ** (-anything except 0,NAN) is +0
- * 17. -INF ** (anything) = -0 ** (-anything)
- * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
- * 19. (-anything except 0 and inf) ** (non-integer) is NAN
- *
- * Accuracy:
- * pow(x,y) returns x**y nearly rounded. In particular
- * pow(integer,integer)
- * always returns the correct integer provided it is
- * representable.
- *
- * Constants :
- * The hexadecimal values are the intended ones for the following
- * constants. The decimal values may be used, provided that the
- * compiler will convert from decimal to binary accurately enough
- * to produce the hexadecimal values shown.
- */
-
-#include <float.h>
-#include "math.h"
-#include "math_private.h"
-
-static const double
-bp[] = {1.0, 1.5,},
-dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
-dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
-zero = 0.0,
-half = 0.5,
-qrtr = 0.25,
-thrd = 3.3333333333333331e-01, /* 0x3fd55555, 0x55555555 */
-one = 1.0,
-two = 2.0,
-two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
-huge = 1.0e300,
-tiny = 1.0e-300,
- /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
-L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
-L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
-L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
-L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
-L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
-L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
-P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
-P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
-P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
-P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
-P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
-lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
-lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
-lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
-ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
-cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
-cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
-cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
-ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
-ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
-ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
-
-double
-pow(double x, double y)
-{
- double z,ax,z_h,z_l,p_h,p_l;
- double y1,t1,t2,r,s,t,u,v,w;
- int32_t i,j,k,yisint,n;
- int32_t hx,hy,ix,iy;
- u_int32_t lx,ly;
-
- EXTRACT_WORDS(hx,lx,x);
- EXTRACT_WORDS(hy,ly,y);
- ix = hx&0x7fffffff; iy = hy&0x7fffffff;
-
- /* y==zero: x**0 = 1 */
- if((iy|ly)==0) return one;
-
- /* x==1: 1**y = 1, even if y is NaN */
- if (hx==0x3ff00000 && lx == 0) return one;
-
- /* y!=zero: result is NaN if either arg is NaN */
- if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
- iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
- return nan_mix(x, y);
-
- /* determine if y is an odd int when x < 0
- * yisint = 0 ... y is not an integer
- * yisint = 1 ... y is an odd int
- * yisint = 2 ... y is an even int
- */
- yisint = 0;
- if(hx<0) {
- if(iy>=0x43400000) yisint = 2; /* even integer y */
- else if(iy>=0x3ff00000) {
- k = (iy>>20)-0x3ff; /* exponent */
- if(k>20) {
- j = ly>>(52-k);
- if(((u_int32_t)j<<(52-k))==ly) yisint = 2-(j&1);
- } else if(ly==0) {
- j = iy>>(20-k);
- if((j<<(20-k))==iy) yisint = 2-(j&1);
- }
- }
- }
-
- /* special value of y */
- if(ly==0) {
- if (iy==0x7ff00000) { /* y is +-inf */
- if(((ix-0x3ff00000)|lx)==0)
- return one; /* (-1)**+-inf is 1 */
- else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
- return (hy>=0)? y: zero;
- else /* (|x|<1)**-,+inf = inf,0 */
- return (hy<0)?-y: zero;
- }
- if(iy==0x3ff00000) { /* y is +-1 */
- if(hy<0) return one/x; else return x;
- }
- if(hy==0x40000000) return x*x; /* y is 2 */
- if(hy==0x3fe00000) { /* y is 0.5 */
- if(hx>=0) /* x >= +0 */
- return sqrt(x);
- }
- }
-
- ax = fabs(x);
- /* special value of x */
- if(lx==0) {
- if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
- z = ax; /*x is +-0,+-inf,+-1*/
- if(hy<0) z = one/z; /* z = (1/|x|) */
- if(hx<0) {
- if(((ix-0x3ff00000)|yisint)==0) {
- z = (z-z)/(z-z); /* (-1)**non-int is NaN */
- } else if(yisint==1)
- z = -z; /* (x<0)**odd = -(|x|**odd) */
- }
- return z;
- }
- }
-
- /* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be
- n = (hx>>31)+1;
- but ANSI C says a right shift of a signed negative quantity is
- implementation defined. */
- n = ((u_int32_t)hx>>31)-1;
-
- /* (x<0)**(non-int) is NaN */
- if((n|yisint)==0) return (x-x)/(x-x);
-
- s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
- if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
-
- /* |y| is huge */
- if(iy>0x41e00000) { /* if |y| > 2**31 */
- if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
- if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
- if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
- }
- /* over/underflow if x is not close to one */
- if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
- if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
- /* now |1-x| is tiny <= 2**-20, suffice to compute
- log(x) by x-x^2/2+x^3/3-x^4/4 */
- t = ax-one; /* t has 20 trailing zeros */
- w = (t*t)*(half-t*(thrd-t*qrtr));
- u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
- v = t*ivln2_l-w*ivln2;
- t1 = u+v;
- SET_LOW_WORD(t1,0);
- t2 = v-(t1-u);
- } else {
- double ss,s2,s_h,s_l,t_h,t_l;
- n = 0;
- /* take care subnormal number */
- if(ix<0x00100000)
- {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
- n += ((ix)>>20)-0x3ff;
- j = ix&0x000fffff;
- /* determine interval */
- ix = j|0x3ff00000; /* normalize ix */
- if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
- else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
- else {k=0;n+=1;ix -= 0x00100000;}
- SET_HIGH_WORD(ax,ix);
-
- /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
- u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
- v = one/(ax+bp[k]);
- ss = u*v;
- s_h = ss;
- SET_LOW_WORD(s_h,0);
- /* t_h=ax+bp[k] High */
- t_h = zero;
- SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
- t_l = ax - (t_h-bp[k]);
- s_l = v*((u-s_h*t_h)-s_h*t_l);
- /* compute log(ax) */
- s2 = ss*ss;
- r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
- r += s_l*(s_h+ss);
- s2 = s_h*s_h;
- t_h = 3+s2+r;
- SET_LOW_WORD(t_h,0);
- t_l = r-((t_h-3)-s2);
- /* u+v = ss*(1+...) */
- u = s_h*t_h;
- v = s_l*t_h+t_l*ss;
- /* 2/(3log2)*(ss+...) */
- p_h = u+v;
- SET_LOW_WORD(p_h,0);
- p_l = v-(p_h-u);
- z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
- z_l = cp_l*p_h+p_l*cp+dp_l[k];
- /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
- t = n;
- t1 = (((z_h+z_l)+dp_h[k])+t);
- SET_LOW_WORD(t1,0);
- t2 = z_l-(((t1-t)-dp_h[k])-z_h);
- }
-
- /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
- y1 = y;
- SET_LOW_WORD(y1,0);
- p_l = (y-y1)*t1+y*t2;
- p_h = y1*t1;
- z = p_l+p_h;
- EXTRACT_WORDS(j,i,z);
- if (j>=0x40900000) { /* z >= 1024 */
- if(((j-0x40900000)|i)!=0) /* if z > 1024 */
- return s*huge*huge; /* overflow */
- else {
- if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
- }
- } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
- if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
- return s*tiny*tiny; /* underflow */
- else {
- if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
- }
- }
- /*
- * compute 2**(p_h+p_l)
- */
- i = j&0x7fffffff;
- k = (i>>20)-0x3ff;
- n = 0;
- if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
- n = j+(0x00100000>>(k+1));
- k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
- t = zero;
- SET_HIGH_WORD(t,n&~(0x000fffff>>k));
- n = ((n&0x000fffff)|0x00100000)>>(20-k);
- if(j<0) n = -n;
- p_h -= t;
- }
- t = p_l+p_h;
- SET_LOW_WORD(t,0);
- u = t*lg2_h;
- v = (p_l-(t-p_h))*lg2+t*lg2_l;
- z = u+v;
- w = v-(z-u);
- t = z*z;
- t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- r = (z*t1)/(t1-two)-(w+z*w);
- z = one-(r-z);
- GET_HIGH_WORD(j,z);
- j += (n<<20);
- if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
- else SET_HIGH_WORD(z,j);
- return s*z;
-}
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(pow, powl);
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/e_powf.c b/libm/upstream-freebsd/lib/msun/src/e_powf.c
deleted file mode 100644
index f5a2c70..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_powf.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* e_powf.c -- float version of e_pow.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "math.h"
-#include "math_private.h"
-
-static const float
-bp[] = {1.0, 1.5,},
-dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
-dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
-zero = 0.0,
-half = 0.5,
-qrtr = 0.25,
-thrd = 3.33333343e-01, /* 0x3eaaaaab */
-one = 1.0,
-two = 2.0,
-two24 = 16777216.0, /* 0x4b800000 */
-huge = 1.0e30,
-tiny = 1.0e-30,
- /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
-L1 = 6.0000002384e-01, /* 0x3f19999a */
-L2 = 4.2857143283e-01, /* 0x3edb6db7 */
-L3 = 3.3333334327e-01, /* 0x3eaaaaab */
-L4 = 2.7272811532e-01, /* 0x3e8ba305 */
-L5 = 2.3066075146e-01, /* 0x3e6c3255 */
-L6 = 2.0697501302e-01, /* 0x3e53f142 */
-P1 = 1.6666667163e-01, /* 0x3e2aaaab */
-P2 = -2.7777778450e-03, /* 0xbb360b61 */
-P3 = 6.6137559770e-05, /* 0x388ab355 */
-P4 = -1.6533901999e-06, /* 0xb5ddea0e */
-P5 = 4.1381369442e-08, /* 0x3331bb4c */
-lg2 = 6.9314718246e-01, /* 0x3f317218 */
-lg2_h = 6.93145752e-01, /* 0x3f317200 */
-lg2_l = 1.42860654e-06, /* 0x35bfbe8c */
-ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
-cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
-cp_h = 9.6191406250e-01, /* 0x3f764000 =12b cp */
-cp_l = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */
-ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
-ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
-ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
-
-float
-powf(float x, float y)
-{
- float z,ax,z_h,z_l,p_h,p_l;
- float y1,t1,t2,r,s,sn,t,u,v,w;
- int32_t i,j,k,yisint,n;
- int32_t hx,hy,ix,iy,is;
-
- GET_FLOAT_WORD(hx,x);
- GET_FLOAT_WORD(hy,y);
- ix = hx&0x7fffffff; iy = hy&0x7fffffff;
-
- /* y==zero: x**0 = 1 */
- if(iy==0) return one;
-
- /* x==1: 1**y = 1, even if y is NaN */
- if (hx==0x3f800000) return one;
-
- /* y!=zero: result is NaN if either arg is NaN */
- if(ix > 0x7f800000 ||
- iy > 0x7f800000)
- return nan_mix(x, y);
-
- /* determine if y is an odd int when x < 0
- * yisint = 0 ... y is not an integer
- * yisint = 1 ... y is an odd int
- * yisint = 2 ... y is an even int
- */
- yisint = 0;
- if(hx<0) {
- if(iy>=0x4b800000) yisint = 2; /* even integer y */
- else if(iy>=0x3f800000) {
- k = (iy>>23)-0x7f; /* exponent */
- j = iy>>(23-k);
- if((j<<(23-k))==iy) yisint = 2-(j&1);
- }
- }
-
- /* special value of y */
- if (iy==0x7f800000) { /* y is +-inf */
- if (ix==0x3f800000)
- return one; /* (-1)**+-inf is NaN */
- else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
- return (hy>=0)? y: zero;
- else /* (|x|<1)**-,+inf = inf,0 */
- return (hy<0)?-y: zero;
- }
- if(iy==0x3f800000) { /* y is +-1 */
- if(hy<0) return one/x; else return x;
- }
- if(hy==0x40000000) return x*x; /* y is 2 */
- if(hy==0x3f000000) { /* y is 0.5 */
- if(hx>=0) /* x >= +0 */
- return sqrtf(x);
- }
-
- ax = fabsf(x);
- /* special value of x */
- if(ix==0x7f800000||ix==0||ix==0x3f800000){
- z = ax; /*x is +-0,+-inf,+-1*/
- if(hy<0) z = one/z; /* z = (1/|x|) */
- if(hx<0) {
- if(((ix-0x3f800000)|yisint)==0) {
- z = (z-z)/(z-z); /* (-1)**non-int is NaN */
- } else if(yisint==1)
- z = -z; /* (x<0)**odd = -(|x|**odd) */
- }
- return z;
- }
-
- n = ((u_int32_t)hx>>31)-1;
-
- /* (x<0)**(non-int) is NaN */
- if((n|yisint)==0) return (x-x)/(x-x);
-
- sn = one; /* s (sign of result -ve**odd) = -1 else = 1 */
- if((n|(yisint-1))==0) sn = -one;/* (-ve)**(odd int) */
-
- /* |y| is huge */
- if(iy>0x4d000000) { /* if |y| > 2**27 */
- /* over/underflow if x is not close to one */
- if(ix<0x3f7ffff6) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
- if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny;
- /* now |1-x| is tiny <= 2**-20, suffice to compute
- log(x) by x-x^2/2+x^3/3-x^4/4 */
- t = ax-1; /* t has 20 trailing zeros */
- w = (t*t)*(half-t*(thrd-t*qrtr));
- u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
- v = t*ivln2_l-w*ivln2;
- t1 = u+v;
- GET_FLOAT_WORD(is,t1);
- SET_FLOAT_WORD(t1,is&0xfffff000);
- t2 = v-(t1-u);
- } else {
- float s2,s_h,s_l,t_h,t_l;
- n = 0;
- /* take care subnormal number */
- if(ix<0x00800000)
- {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
- n += ((ix)>>23)-0x7f;
- j = ix&0x007fffff;
- /* determine interval */
- ix = j|0x3f800000; /* normalize ix */
- if(j<=0x1cc471) k=0; /* |x|<sqrt(3/2) */
- else if(j<0x5db3d7) k=1; /* |x|<sqrt(3) */
- else {k=0;n+=1;ix -= 0x00800000;}
- SET_FLOAT_WORD(ax,ix);
-
- /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
- u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
- v = one/(ax+bp[k]);
- s = u*v;
- s_h = s;
- GET_FLOAT_WORD(is,s_h);
- SET_FLOAT_WORD(s_h,is&0xfffff000);
- /* t_h=ax+bp[k] High */
- is = ((ix>>1)&0xfffff000)|0x20000000;
- SET_FLOAT_WORD(t_h,is+0x00400000+(k<<21));
- t_l = ax - (t_h-bp[k]);
- s_l = v*((u-s_h*t_h)-s_h*t_l);
- /* compute log(ax) */
- s2 = s*s;
- r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
- r += s_l*(s_h+s);
- s2 = s_h*s_h;
- t_h = 3+s2+r;
- GET_FLOAT_WORD(is,t_h);
- SET_FLOAT_WORD(t_h,is&0xfffff000);
- t_l = r-((t_h-3)-s2);
- /* u+v = s*(1+...) */
- u = s_h*t_h;
- v = s_l*t_h+t_l*s;
- /* 2/(3log2)*(s+...) */
- p_h = u+v;
- GET_FLOAT_WORD(is,p_h);
- SET_FLOAT_WORD(p_h,is&0xfffff000);
- p_l = v-(p_h-u);
- z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
- z_l = cp_l*p_h+p_l*cp+dp_l[k];
- /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
- t = n;
- t1 = (((z_h+z_l)+dp_h[k])+t);
- GET_FLOAT_WORD(is,t1);
- SET_FLOAT_WORD(t1,is&0xfffff000);
- t2 = z_l-(((t1-t)-dp_h[k])-z_h);
- }
-
- /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
- GET_FLOAT_WORD(is,y);
- SET_FLOAT_WORD(y1,is&0xfffff000);
- p_l = (y-y1)*t1+y*t2;
- p_h = y1*t1;
- z = p_l+p_h;
- GET_FLOAT_WORD(j,z);
- if (j>0x43000000) /* if z > 128 */
- return sn*huge*huge; /* overflow */
- else if (j==0x43000000) { /* if z == 128 */
- if(p_l+ovt>z-p_h) return sn*huge*huge; /* overflow */
- }
- else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */
- return sn*tiny*tiny; /* underflow */
- else if (j==0xc3160000){ /* z == -150 */
- if(p_l<=z-p_h) return sn*tiny*tiny; /* underflow */
- }
- /*
- * compute 2**(p_h+p_l)
- */
- i = j&0x7fffffff;
- k = (i>>23)-0x7f;
- n = 0;
- if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
- n = j+(0x00800000>>(k+1));
- k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */
- SET_FLOAT_WORD(t,n&~(0x007fffff>>k));
- n = ((n&0x007fffff)|0x00800000)>>(23-k);
- if(j<0) n = -n;
- p_h -= t;
- }
- t = p_l+p_h;
- GET_FLOAT_WORD(is,t);
- SET_FLOAT_WORD(t,is&0xffff8000);
- u = t*lg2_h;
- v = (p_l-(t-p_h))*lg2+t*lg2_l;
- z = u+v;
- w = v-(z-u);
- t = z*z;
- t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- r = (z*t1)/(t1-two)-(w+z*w);
- z = one-(r-z);
- GET_FLOAT_WORD(j,z);
- j += (n<<23);
- if((j>>23)<=0) z = scalbnf(z,n); /* subnormal output */
- else SET_FLOAT_WORD(z,j);
- return sn*z;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_copysign.c b/libm/upstream-freebsd/lib/msun/src/s_copysign.c
deleted file mode 100644
index a5f3870..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_copysign.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* @(#)s_copysign.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * copysign(double x, double y)
- * copysign(x,y) returns a value with the magnitude of x and
- * with the sign bit of y.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-double
-copysign(double x, double y)
-{
- u_int32_t hx,hy;
- GET_HIGH_WORD(hx,x);
- GET_HIGH_WORD(hy,y);
- SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
- return x;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_copysignf.c b/libm/upstream-freebsd/lib/msun/src/s_copysignf.c
deleted file mode 100644
index 05ca1e3..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_copysignf.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* s_copysignf.c -- float version of s_copysign.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * copysignf(float x, float y)
- * copysignf(x,y) returns a value with the magnitude of x and
- * with the sign bit of y.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-float
-copysignf(float x, float y)
-{
- u_int32_t ix,iy;
- GET_FLOAT_WORD(ix,x);
- GET_FLOAT_WORD(iy,y);
- SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
- return x;
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c b/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
deleted file mode 100644
index 666a2ba..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2004 Stefan Farfeleder
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#include <math.h>
-
-#include "fpmath.h"
-
-long double
-copysignl(long double x, long double y)
-{
- union IEEEl2bits ux, uy;
-
- ux.e = x;
- uy.e = y;
- ux.bits.sign = uy.bits.sign;
- return (ux.e);
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cosf.c b/libm/upstream-freebsd/lib/msun/src/s_cosf.c
deleted file mode 100644
index b701fd2..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_cosf.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* s_cosf.c -- float version of s_cos.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- * Optimized by Bruce D. Evans.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#define INLINE_KERNEL_COSDF
-#define INLINE_KERNEL_SINDF
-#define INLINE_REM_PIO2F
-#include "math_private.h"
-#include "e_rem_pio2f.c"
-#include "k_cosf.c"
-#include "k_sinf.c"
-
-/* Small multiples of pi/2 rounded to double precision. */
-static const double
-c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
-c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
-c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
-c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
-
-float
-cosf(float x)
-{
- double y;
- int32_t n, hx, ix;
-
- GET_FLOAT_WORD(hx,x);
- ix = hx & 0x7fffffff;
-
- if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
- if(ix<0x39800000) /* |x| < 2**-12 */
- if(((int)x)==0) return 1.0; /* 1 with inexact if x != 0 */
- return __kernel_cosdf(x);
- }
- if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */
- if(ix>0x4016cbe3) /* |x| ~> 3*pi/4 */
- return -__kernel_cosdf(x + (hx > 0 ? -c2pio2 : c2pio2));
- else {
- if(hx>0)
- return __kernel_sindf(c1pio2 - x);
- else
- return __kernel_sindf(x + c1pio2);
- }
- }
- if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */
- if(ix>0x40afeddf) /* |x| ~> 7*pi/4 */
- return __kernel_cosdf(x + (hx > 0 ? -c4pio2 : c4pio2));
- else {
- if(hx>0)
- return __kernel_sindf(x - c3pio2);
- else
- return __kernel_sindf(-c3pio2 - x);
- }
- }
-
- /* cos(Inf or NaN) is NaN */
- else if (ix>=0x7f800000) return x-x;
-
- /* general argument reduction needed */
- else {
- n = __ieee754_rem_pio2f(x,&y);
- switch(n&3) {
- case 0: return __kernel_cosdf(y);
- case 1: return __kernel_sindf(-y);
- case 2: return -__kernel_cosdf(y);
- default:
- return __kernel_sindf(y);
- }
- }
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2.c b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
deleted file mode 100644
index 1dd9673..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-#define TBLBITS 8
-#define TBLSIZE (1 << TBLBITS)
-
-static const double
- redux = 0x1.8p52 / TBLSIZE,
- P1 = 0x1.62e42fefa39efp-1,
- P2 = 0x1.ebfbdff82c575p-3,
- P3 = 0x1.c6b08d704a0a6p-5,
- P4 = 0x1.3b2ab88f70400p-7,
- P5 = 0x1.5d88003875c74p-10;
-
-static volatile double
- huge = 0x1p1000,
- twom1000 = 0x1p-1000;
-
-static const double tbl[TBLSIZE * 2] = {
-/* exp2(z + eps) eps */
- 0x1.6a09e667f3d5dp-1, 0x1.9880p-44,
- 0x1.6b052fa751744p-1, 0x1.8000p-50,
- 0x1.6c012750bd9fep-1, -0x1.8780p-45,
- 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46,
- 0x1.6dfb23c651a29p-1, -0x1.8000p-50,
- 0x1.6ef9298593ae3p-1, -0x1.c000p-52,
- 0x1.6ff7df9519386p-1, -0x1.fd80p-45,
- 0x1.70f7466f42da3p-1, -0x1.c880p-45,
- 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46,
- 0x1.72f8286eacf05p-1, -0x1.8300p-44,
- 0x1.73f9a48a58152p-1, -0x1.0c00p-47,
- 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45,
- 0x1.75feb564267f1p-1, 0x1.3e00p-47,
- 0x1.77024b1ab6d48p-1, -0x1.7d00p-45,
- 0x1.780694fde5d38p-1, -0x1.d000p-50,
- 0x1.790b938ac1d00p-1, 0x1.3000p-49,
- 0x1.7a11473eb0178p-1, -0x1.d000p-49,
- 0x1.7b17b0976d060p-1, 0x1.0400p-45,
- 0x1.7c1ed0130c133p-1, 0x1.0000p-53,
- 0x1.7d26a62ff8636p-1, -0x1.6900p-45,
- 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,
- 0x1.7f3878491c3e8p-1, -0x1.4580p-45,
- 0x1.80427543e1b4ep-1, 0x1.3000p-44,
- 0x1.814d2add1071ap-1, 0x1.f000p-47,
- 0x1.82589994ccd7ep-1, -0x1.1c00p-45,
- 0x1.8364c1eb942d0p-1, 0x1.9d00p-45,
- 0x1.8471a4623cab5p-1, 0x1.7100p-43,
- 0x1.857f4179f5bbcp-1, 0x1.2600p-45,
- 0x1.868d99b4491afp-1, -0x1.2c40p-44,
- 0x1.879cad931a395p-1, -0x1.3000p-45,
- 0x1.88ac7d98a65b8p-1, -0x1.a800p-45,
- 0x1.89bd0a4785800p-1, -0x1.d000p-49,
- 0x1.8ace5422aa223p-1, 0x1.3280p-44,
- 0x1.8be05bad619fap-1, 0x1.2b40p-43,
- 0x1.8cf3216b54383p-1, -0x1.ed00p-45,
- 0x1.8e06a5e08664cp-1, -0x1.0500p-45,
- 0x1.8f1ae99157807p-1, 0x1.8280p-45,
- 0x1.902fed0282c0ep-1, -0x1.cb00p-46,
- 0x1.9145b0b91ff96p-1, -0x1.5e00p-47,
- 0x1.925c353aa2ff9p-1, 0x1.5400p-48,
- 0x1.93737b0cdc64ap-1, 0x1.7200p-46,
- 0x1.948b82b5f98aep-1, -0x1.9000p-47,
- 0x1.95a44cbc852cbp-1, 0x1.5680p-45,
- 0x1.96bdd9a766f21p-1, -0x1.6d00p-44,
- 0x1.97d829fde4e2ap-1, -0x1.1000p-47,
- 0x1.98f33e47a23a3p-1, 0x1.d000p-45,
- 0x1.9a0f170ca0604p-1, -0x1.8a40p-44,
- 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44,
- 0x1.9c49182a3f15bp-1, 0x1.6b80p-45,
- 0x1.9d674194bb8c5p-1, -0x1.c000p-49,
- 0x1.9e86319e3238ep-1, 0x1.7d00p-46,
- 0x1.9fa5e8d07f302p-1, 0x1.6400p-46,
- 0x1.a0c667b5de54dp-1, -0x1.5000p-48,
- 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47,
- 0x1.a309bec4a2e27p-1, 0x1.ad80p-45,
- 0x1.a42c980460a5dp-1, -0x1.af00p-46,
- 0x1.a5503b23e259bp-1, 0x1.b600p-47,
- 0x1.a674a8af46213p-1, 0x1.8880p-44,
- 0x1.a799e1330b3a7p-1, 0x1.1200p-46,
- 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47,
- 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,
- 0x1.ab0e521356fb8p-1, 0x1.b700p-45,
- 0x1.ac36bbfd3f381p-1, 0x1.9000p-50,
- 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49,
- 0x1.ae89f995ad2a3p-1, -0x1.c900p-45,
- 0x1.afb4ce622f367p-1, 0x1.6500p-46,
- 0x1.b0e07298db790p-1, 0x1.fd40p-45,
- 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46,
- 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43,
- 0x1.b468415b747e7p-1, -0x1.8380p-44,
- 0x1.b59728de5593ap-1, 0x1.8000p-54,
- 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47,
- 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50,
- 0x1.b928cf22749b2p-1, -0x1.4c00p-47,
- 0x1.ba5b030a10603p-1, -0x1.d700p-47,
- 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47,
- 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47,
- 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,
- 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,
- 0x1.c06286141b2e9p-1, -0x1.1400p-46,
- 0x1.c199bdd8552e0p-1, 0x1.be00p-47,
- 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,
- 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,
- 0x1.c544778fafd15p-1, 0x1.9660p-44,
- 0x1.c67f12e57d0cbp-1, -0x1.a100p-46,
- 0x1.c7ba88988c1b6p-1, -0x1.8458p-42,
- 0x1.c8f6d9406e733p-1, -0x1.a480p-46,
- 0x1.ca3405751c4dfp-1, 0x1.b000p-51,
- 0x1.cb720dcef9094p-1, 0x1.1400p-47,
- 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48,
- 0x1.cdf0b555dc412p-1, 0x1.3600p-48,
- 0x1.cf3155b5bab3bp-1, -0x1.6900p-47,
- 0x1.d072d4a0789bcp-1, 0x1.9a00p-47,
- 0x1.d1b532b08c8fap-1, -0x1.5e00p-46,
- 0x1.d2f87080d8a85p-1, 0x1.d280p-46,
- 0x1.d43c8eacaa203p-1, 0x1.1a00p-47,
- 0x1.d5818dcfba491p-1, 0x1.f000p-50,
- 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,
- 0x1.d80e316c9834ep-1, -0x1.cd80p-47,
- 0x1.d955d71ff6090p-1, 0x1.4c00p-48,
- 0x1.da9e603db32aep-1, 0x1.f900p-48,
- 0x1.dbe7cd63a8325p-1, 0x1.9800p-49,
- 0x1.dd321f301b445p-1, -0x1.5200p-48,
- 0x1.de7d5641c05bfp-1, -0x1.d700p-46,
- 0x1.dfc97337b9aecp-1, -0x1.6140p-46,
- 0x1.e11676b197d5ep-1, 0x1.b480p-47,
- 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43,
- 0x1.e3b333b16ee5cp-1, 0x1.c680p-47,
- 0x1.e502ee78b3fb4p-1, -0x1.9300p-47,
- 0x1.e653924676d68p-1, -0x1.5000p-49,
- 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,
- 0x1.e8f7977cdb726p-1, -0x1.3700p-48,
- 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49,
- 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46,
- 0x1.ecf482d8e680dp-1, 0x1.5500p-48,
- 0x1.ee4aaa2188514p-1, 0x1.6400p-51,
- 0x1.efa1bee615a13p-1, -0x1.e800p-49,
- 0x1.f0f9c1cb64106p-1, -0x1.a880p-48,
- 0x1.f252b376bb963p-1, -0x1.c900p-45,
- 0x1.f3ac948dd7275p-1, 0x1.a000p-53,
- 0x1.f50765b6e4524p-1, -0x1.4f00p-48,
- 0x1.f6632798844fdp-1, 0x1.a800p-51,
- 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48,
- 0x1.f91d802243c82p-1, -0x1.4600p-50,
- 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,
- 0x1.fbdba3692d511p-1, -0x1.0e00p-51,
- 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,
- 0x1.fe9d96b2a23eep-1, 0x1.e430p-49,
- 0x1.0000000000000p+0, 0x0.0000p+0,
- 0x1.00b1afa5abcbep+0, -0x1.3400p-52,
- 0x1.0163da9fb3303p+0, -0x1.2170p-46,
- 0x1.02168143b0282p+0, 0x1.a400p-52,
- 0x1.02c9a3e77806cp+0, 0x1.f980p-49,
- 0x1.037d42e11bbcap+0, -0x1.7400p-51,
- 0x1.04315e86e7f89p+0, 0x1.8300p-50,
- 0x1.04e5f72f65467p+0, -0x1.a3f0p-46,
- 0x1.059b0d315855ap+0, -0x1.2840p-47,
- 0x1.0650a0e3c1f95p+0, 0x1.1600p-48,
- 0x1.0706b29ddf71ap+0, 0x1.5240p-46,
- 0x1.07bd42b72a82dp+0, -0x1.9a00p-49,
- 0x1.0874518759bd0p+0, 0x1.6400p-49,
- 0x1.092bdf66607c8p+0, -0x1.0780p-47,
- 0x1.09e3ecac6f383p+0, -0x1.8000p-54,
- 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48,
- 0x1.0b5586cf988fcp+0, -0x1.ac80p-48,
- 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50,
- 0x1.0cc922b724816p+0, 0x1.5200p-47,
- 0x1.0d83b23395dd8p+0, -0x1.ad00p-48,
- 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46,
- 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,
- 0x1.0fb66affed2f0p+0, -0x1.d300p-47,
- 0x1.1073028d7234bp+0, 0x1.1500p-48,
- 0x1.11301d0125b5bp+0, 0x1.c000p-49,
- 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46,
- 0x1.12abdc06c31d5p+0, 0x1.8400p-49,
- 0x1.136a814f2047dp+0, -0x1.ed00p-47,
- 0x1.1429aaea92de9p+0, 0x1.8e00p-49,
- 0x1.14e95934f3138p+0, 0x1.b400p-49,
- 0x1.15a98c8a58e71p+0, 0x1.5300p-47,
- 0x1.166a45471c3dfp+0, 0x1.3380p-47,
- 0x1.172b83c7d5211p+0, 0x1.8d40p-45,
- 0x1.17ed48695bb9fp+0, -0x1.5d00p-47,
- 0x1.18af9388c8d93p+0, -0x1.c880p-46,
- 0x1.1972658375d66p+0, 0x1.1f00p-46,
- 0x1.1a35beb6fcba7p+0, 0x1.0480p-46,
- 0x1.1af99f81387e3p+0, -0x1.7390p-43,
- 0x1.1bbe084045d54p+0, 0x1.4e40p-45,
- 0x1.1c82f95281c43p+0, -0x1.a200p-47,
- 0x1.1d4873168b9b2p+0, 0x1.3800p-49,
- 0x1.1e0e75eb44031p+0, 0x1.ac00p-49,
- 0x1.1ed5022fcd938p+0, 0x1.1900p-47,
- 0x1.1f9c18438cdf7p+0, -0x1.b780p-46,
- 0x1.2063b88628d8fp+0, 0x1.d940p-45,
- 0x1.212be3578a81ep+0, 0x1.8000p-50,
- 0x1.21f49917ddd41p+0, 0x1.b340p-45,
- 0x1.22bdda2791323p+0, 0x1.9f80p-46,
- 0x1.2387a6e7561e7p+0, -0x1.9c80p-46,
- 0x1.2451ffb821427p+0, 0x1.2300p-47,
- 0x1.251ce4fb2a602p+0, -0x1.3480p-46,
- 0x1.25e85711eceb0p+0, 0x1.2700p-46,
- 0x1.26b4565e27d16p+0, 0x1.1d00p-46,
- 0x1.2780e341de00fp+0, 0x1.1ee0p-44,
- 0x1.284dfe1f5633ep+0, -0x1.4c00p-46,
- 0x1.291ba7591bb30p+0, -0x1.3d80p-46,
- 0x1.29e9df51fdf09p+0, 0x1.8b00p-47,
- 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,
- 0x1.2b87fd0dada3ap+0, 0x1.a340p-45,
- 0x1.2c57e39771af9p+0, -0x1.0800p-46,
- 0x1.2d285a6e402d9p+0, -0x1.ed00p-47,
- 0x1.2df961f641579p+0, -0x1.4200p-48,
- 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45,
- 0x1.2f9d24abd8822p+0, -0x1.6300p-46,
- 0x1.306fe0a31b625p+0, -0x1.2360p-44,
- 0x1.31432edeea50bp+0, -0x1.0df8p-40,
- 0x1.32170fc4cd7b8p+0, -0x1.2480p-45,
- 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,
- 0x1.33c08b2641766p+0, 0x1.ed00p-46,
- 0x1.3496266e3fa27p+0, -0x1.c000p-50,
- 0x1.356c55f929f0fp+0, -0x1.0d80p-44,
- 0x1.36431a2de88b9p+0, 0x1.2c80p-45,
- 0x1.371a7373aaa39p+0, 0x1.0600p-45,
- 0x1.37f26231e74fep+0, -0x1.6600p-46,
- 0x1.38cae6d05d838p+0, -0x1.ae00p-47,
- 0x1.39a401b713ec3p+0, -0x1.4720p-43,
- 0x1.3a7db34e5a020p+0, 0x1.8200p-47,
- 0x1.3b57fbfec6e95p+0, 0x1.e800p-44,
- 0x1.3c32dc313a8f2p+0, 0x1.f800p-49,
- 0x1.3d0e544ede122p+0, -0x1.7a00p-46,
- 0x1.3dea64c1234bbp+0, 0x1.6300p-45,
- 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,
- 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,
- 0x1.40822c367a0bbp+0, 0x1.5b80p-45,
- 0x1.4160a21f72e95p+0, 0x1.ec00p-46,
- 0x1.423fb27094646p+0, -0x1.3600p-46,
- 0x1.431f5d950a920p+0, 0x1.3980p-45,
- 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48,
- 0x1.44e0860618919p+0, -0x1.6c00p-48,
- 0x1.45c2042a7d201p+0, -0x1.bc00p-47,
- 0x1.46a41ed1d0016p+0, -0x1.2800p-46,
- 0x1.4786d668b3326p+0, 0x1.0e00p-44,
- 0x1.486a2b5c13c00p+0, -0x1.d400p-45,
- 0x1.494e1e192af04p+0, 0x1.c200p-47,
- 0x1.4a32af0d7d372p+0, -0x1.e500p-46,
- 0x1.4b17dea6db801p+0, 0x1.7800p-47,
- 0x1.4bfdad53629e1p+0, -0x1.3800p-46,
- 0x1.4ce41b817c132p+0, 0x1.0800p-47,
- 0x1.4dcb299fddddbp+0, 0x1.c700p-45,
- 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,
- 0x1.4f9b2769d2d02p+0, 0x1.9200p-46,
- 0x1.508417f4531c1p+0, -0x1.8c00p-47,
- 0x1.516daa2cf662ap+0, -0x1.a000p-48,
- 0x1.5257de83f51eap+0, 0x1.a080p-43,
- 0x1.5342b569d4edap+0, -0x1.6d80p-45,
- 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,
- 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43,
- 0x1.56070dde9116bp+0, 0x1.4b00p-45,
- 0x1.56f4736b529dep+0, 0x1.15a0p-43,
- 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,
- 0x1.58d12d497c76fp+0, -0x1.3080p-45,
- 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43,
- 0x1.5ab07dd485427p+0, -0x1.4000p-51,
- 0x1.5ba11fba87af4p+0, 0x1.0080p-44,
- 0x1.5c9268a59460bp+0, -0x1.6c80p-45,
- 0x1.5d84590998e3fp+0, 0x1.69a0p-43,
- 0x1.5e76f15ad20e1p+0, -0x1.b400p-46,
- 0x1.5f6a320dcebcap+0, 0x1.7700p-46,
- 0x1.605e1b976dcb8p+0, 0x1.6f80p-45,
- 0x1.6152ae6cdf715p+0, 0x1.1000p-47,
- 0x1.6247eb03a5531p+0, -0x1.5d00p-46,
- 0x1.633dd1d1929b5p+0, -0x1.2d00p-46,
- 0x1.6434634ccc313p+0, -0x1.a800p-49,
- 0x1.652b9febc8efap+0, -0x1.8600p-45,
- 0x1.6623882553397p+0, 0x1.1fe0p-40,
- 0x1.671c1c708328ep+0, -0x1.7200p-44,
- 0x1.68155d44ca97ep+0, 0x1.6800p-49,
- 0x1.690f4b19e9471p+0, -0x1.9780p-45,
-};
-
-/*
- * exp2(x): compute the base 2 exponential of x
- *
- * Accuracy: Peak error < 0.503 ulp for normalized results.
- *
- * Method: (accurate tables)
- *
- * Reduce x:
- * x = 2**k + y, for integer k and |y| <= 1/2.
- * Thus we have exp2(x) = 2**k * exp2(y).
- *
- * Reduce y:
- * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
- * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
- * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used.
- *
- * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
- * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61.
- * The values in exp2t[] and eps[] are chosen such that
- * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
- * that exp2t[i] is accurate to 2**-64.
- *
- * Note that the range of i is +-TBLSIZE/2, so we actually index the tables
- * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are
- * virtual tables, interleaved in the real table tbl[].
- *
- * This method is due to Gal, with many details due to Gal and Bachelis:
- *
- * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library
- * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991).
- */
-double
-exp2(double x)
-{
- double r, t, twopk, twopkp1000, z;
- uint32_t hx, ix, lx, i0;
- int k;
-
- /* Filter out exceptional cases. */
- GET_HIGH_WORD(hx,x);
- ix = hx & 0x7fffffff; /* high word of |x| */
- if(ix >= 0x40900000) { /* |x| >= 1024 */
- if(ix >= 0x7ff00000) {
- GET_LOW_WORD(lx,x);
- if(((ix & 0xfffff) | lx) != 0 || (hx & 0x80000000) == 0)
- return (x + x); /* x is NaN or +Inf */
- else
- return (0.0); /* x is -Inf */
- }
- if(x >= 0x1.0p10)
- return (huge * huge); /* overflow */
- if(x <= -0x1.0ccp10)
- return (twom1000 * twom1000); /* underflow */
- } else if (ix < 0x3c900000) { /* |x| < 0x1p-54 */
- return (1.0 + x);
- }
-
- /* Reduce x, computing z, i0, and k. */
- STRICT_ASSIGN(double, t, x + redux);
- GET_LOW_WORD(i0, t);
- i0 += TBLSIZE / 2;
- k = (i0 >> TBLBITS) << 20;
- i0 = (i0 & (TBLSIZE - 1)) << 1;
- t -= redux;
- z = x - t;
-
- /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
- t = tbl[i0]; /* exp2t[i0] */
- z -= tbl[i0 + 1]; /* eps[i0] */
- if (k >= -(1021 << 20))
- INSERT_WORDS(twopk, 0x3ff00000 + k, 0);
- else
- INSERT_WORDS(twopkp1000, 0x3ff00000 + k + (1000 << 20), 0);
- r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
-
- /* Scale by 2**(k>>20). */
- if(k >= -(1021 << 20)) {
- if (k == 1024 << 20)
- return (r * 2.0 * 0x1p1023);
- return (r * twopk);
- } else {
- return (r * twopkp1000 * twom1000);
- }
-}
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(exp2, exp2l);
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c b/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
deleted file mode 100644
index c5b4c8e..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-#define TBLBITS 4
-#define TBLSIZE (1 << TBLBITS)
-
-static const float
- redux = 0x1.8p23f / TBLSIZE,
- P1 = 0x1.62e430p-1f,
- P2 = 0x1.ebfbe0p-3f,
- P3 = 0x1.c6b348p-5f,
- P4 = 0x1.3b2c9cp-7f;
-
-static volatile float
- huge = 0x1p100f,
- twom100 = 0x1p-100f;
-
-static const double exp2ft[TBLSIZE] = {
- 0x1.6a09e667f3bcdp-1,
- 0x1.7a11473eb0187p-1,
- 0x1.8ace5422aa0dbp-1,
- 0x1.9c49182a3f090p-1,
- 0x1.ae89f995ad3adp-1,
- 0x1.c199bdd85529cp-1,
- 0x1.d5818dcfba487p-1,
- 0x1.ea4afa2a490dap-1,
- 0x1.0000000000000p+0,
- 0x1.0b5586cf9890fp+0,
- 0x1.172b83c7d517bp+0,
- 0x1.2387a6e756238p+0,
- 0x1.306fe0a31b715p+0,
- 0x1.3dea64c123422p+0,
- 0x1.4bfdad5362a27p+0,
- 0x1.5ab07dd485429p+0,
-};
-
-/*
- * exp2f(x): compute the base 2 exponential of x
- *
- * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927.
- *
- * Method: (equally-spaced tables)
- *
- * Reduce x:
- * x = 2**k + y, for integer k and |y| <= 1/2.
- * Thus we have exp2f(x) = 2**k * exp2(y).
- *
- * Reduce y:
- * y = i/TBLSIZE + z for integer i near y * TBLSIZE.
- * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
- * with |z| <= 2**-(TBLSIZE+1).
- *
- * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
- * degree-4 minimax polynomial with maximum error under 1.4 * 2**-33.
- * Using double precision for everything except the reduction makes
- * roundoff error insignificant and simplifies the scaling step.
- *
- * This method is due to Tang, but I do not use his suggested parameters:
- *
- * Tang, P. Table-driven Implementation of the Exponential Function
- * in IEEE Floating-Point Arithmetic. TOMS 15(2), 144-157 (1989).
- */
-float
-exp2f(float x)
-{
- double tv, twopk, u, z;
- float t;
- uint32_t hx, ix, i0;
- int32_t k;
-
- /* Filter out exceptional cases. */
- GET_FLOAT_WORD(hx, x);
- ix = hx & 0x7fffffff; /* high word of |x| */
- if(ix >= 0x43000000) { /* |x| >= 128 */
- if(ix >= 0x7f800000) {
- if ((ix & 0x7fffff) != 0 || (hx & 0x80000000) == 0)
- return (x + x); /* x is NaN or +Inf */
- else
- return (0.0); /* x is -Inf */
- }
- if(x >= 0x1.0p7f)
- return (huge * huge); /* overflow */
- if(x <= -0x1.2cp7f)
- return (twom100 * twom100); /* underflow */
- } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */
- return (1.0f + x);
- }
-
- /* Reduce x, computing z, i0, and k. */
- STRICT_ASSIGN(float, t, x + redux);
- GET_FLOAT_WORD(i0, t);
- i0 += TBLSIZE / 2;
- k = (i0 >> TBLBITS) << 20;
- i0 &= TBLSIZE - 1;
- t -= redux;
- z = x - t;
- INSERT_WORDS(twopk, 0x3ff00000 + k, 0);
-
- /* Compute r = exp2(y) = exp2ft[i0] * p(z). */
- tv = exp2ft[i0];
- u = tv * z;
- tv = tv + u * (P1 + z * P2) + u * (z * z) * (P3 + z * P4);
-
- /* Scale by 2**(k>>20). */
- return (tv * twopk);
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fabsl.c b/libm/upstream-freebsd/lib/msun/src/s_fabsl.c
deleted file mode 100644
index 5076d8a..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_fabsl.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 2003 Dag-Erling Smørgrav
- * 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
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#include <math.h>
-
-#include "fpmath.h"
-
-long double
-fabsl(long double x)
-{
- union IEEEl2bits u;
-
- u.e = x;
- u.bits.sign = 0;
- return (u.e);
-}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sincosf.c b/libm/upstream-freebsd/lib/msun/src/s_sincosf.c
deleted file mode 100644
index 755ff05..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_sincosf.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* s_sincosf.c -- float version of s_sincos.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- * Optimized by Bruce D. Evans.
- * Merged s_sinf.c and s_cosf.c by Steven G. Kargl.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#define INLINE_REM_PIO2F
-#include "math_private.h"
-#include "e_rem_pio2f.c"
-#include "k_sincosf.h"
-
-/* Small multiples of pi/2 rounded to double precision. */
-static const double
-p1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
-p2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
-p3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
-p4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
-
-void
-sincosf(float x, float *sn, float *cs)
-{
- float c, s;
- double y;
- int32_t n, hx, ix;
-
- GET_FLOAT_WORD(hx, x);
- ix = hx & 0x7fffffff;
-
- if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
- if (ix < 0x39800000) { /* |x| < 2**-12 */
- if ((int)x == 0) {
- *sn = x; /* x with inexact if x != 0 */
- *cs = 1;
- return;
- }
- }
- __kernel_sincosdf(x, sn, cs);
- return;
- }
-
- if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
- if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
- if (hx > 0) {
- __kernel_sincosdf(x - p1pio2, cs, sn);
- *cs = -*cs;
- } else {
- __kernel_sincosdf(x + p1pio2, cs, sn);
- *sn = -*sn;
- }
- } else {
- if (hx > 0)
- __kernel_sincosdf(x - p2pio2, sn, cs);
- else
- __kernel_sincosdf(x + p2pio2, sn, cs);
- *sn = -*sn;
- *cs = -*cs;
- }
- return;
- }
-
- if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
- if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
- if (hx > 0) {
- __kernel_sincosdf(x - p3pio2, cs, sn);
- *sn = -*sn;
- } else {
- __kernel_sincosdf(x + p3pio2, cs, sn);
- *cs = -*cs;
- }
- } else {
- if (hx > 0)
- __kernel_sincosdf(x - p4pio2, sn, cs);
- else
- __kernel_sincosdf(x + p4pio2, sn, cs);
- }
- return;
- }
-
- /* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
- if (ix >= 0x7f800000) {
- *sn = x - x;
- *cs = x - x;
- return;
- }
-
- /* Argument reduction. */
- n = __ieee754_rem_pio2f(x, &y);
- __kernel_sincosdf(y, &s, &c);
-
- switch(n & 3) {
- case 0:
- *sn = s;
- *cs = c;
- break;
- case 1:
- *sn = c;
- *cs = -s;
- break;
- case 2:
- *sn = -s;
- *cs = -c;
- break;
- default:
- *sn = -c;
- *cs = s;
- }
-}
-
-
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinf.c b/libm/upstream-freebsd/lib/msun/src/s_sinf.c
deleted file mode 100644
index 41b5dc1..0000000
--- a/libm/upstream-freebsd/lib/msun/src/s_sinf.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* s_sinf.c -- float version of s_sin.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- * Optimized by Bruce D. Evans.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#define INLINE_KERNEL_COSDF
-#define INLINE_KERNEL_SINDF
-#define INLINE_REM_PIO2F
-#include "math_private.h"
-#include "e_rem_pio2f.c"
-#include "k_cosf.c"
-#include "k_sinf.c"
-
-/* Small multiples of pi/2 rounded to double precision. */
-static const double
-s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
-s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
-s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
-s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
-
-float
-sinf(float x)
-{
- double y;
- int32_t n, hx, ix;
-
- GET_FLOAT_WORD(hx,x);
- ix = hx & 0x7fffffff;
-
- if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
- if(ix<0x39800000) /* |x| < 2**-12 */
- if(((int)x)==0) return x; /* x with inexact if x != 0 */
- return __kernel_sindf(x);
- }
- if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */
- if(ix<=0x4016cbe3) { /* |x| ~<= 3pi/4 */
- if(hx>0)
- return __kernel_cosdf(x - s1pio2);
- else
- return -__kernel_cosdf(x + s1pio2);
- } else
- return __kernel_sindf((hx > 0 ? s2pio2 : -s2pio2) - x);
- }
- if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */
- if(ix<=0x40afeddf) { /* |x| ~<= 7*pi/4 */
- if(hx>0)
- return -__kernel_cosdf(x - s3pio2);
- else
- return __kernel_cosdf(x + s3pio2);
- } else
- return __kernel_sindf(x + (hx > 0 ? -s4pio2 : s4pio2));
- }
-
- /* sin(Inf or NaN) is NaN */
- else if (ix>=0x7f800000) return x-x;
-
- /* general argument reduction needed */
- else {
- n = __ieee754_rem_pio2f(x,&y);
- switch(n&3) {
- case 0: return __kernel_sindf(y);
- case 1: return __kernel_cosdf(y);
- case 2: return __kernel_sindf(-y);
- default:
- return -__kernel_cosdf(y);
- }
- }
-}
diff --git a/linker/Android.bp b/linker/Android.bp
index 78109e8..143dbd5 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -1,14 +1,3 @@
-// ========================================================
-// linker_wrapper - Linux Bionic (on the host)
-// ========================================================
-
-// This is used for bionic on (host) Linux to bootstrap our linker embedded into
-// a binary.
-//
-// Host bionic binaries do not have a PT_INTERP section, instead this gets
-// embedded as the entry point, and the linker is embedded as ELF sections in
-// each binary. There's a linker script that sets all of that up (generated by
-// extract_linker), and defines the extern symbols used in this file.
package {
default_team: "trendy_team_native_tools_libraries",
default_applicable_licenses: ["bionic_linker_license"],
@@ -25,6 +14,17 @@
],
}
+// ========================================================
+// linker_wrapper - Linux Bionic (on the host)
+// ========================================================
+
+// This is used for bionic on (host) Linux to bootstrap our linker embedded into
+// a binary.
+//
+// Host bionic binaries do not have a PT_INTERP section, instead this gets
+// embedded as the entry point, and the linker is embedded as ELF sections in
+// each binary. There's a linker script that sets all of that up (generated by
+// extract_linker), and defines the extern symbols used in this file.
cc_object {
name: "linker_wrapper",
host_supported: true,
@@ -327,8 +327,10 @@
},
},
+ static_executable: true,
+
// -shared is used to overwrite the -Bstatic and -static flags triggered by enabling
- // static_executable. This dynamic linker is actually a shared object linked with static
+ // static_executable. The dynamic linker is actually a shared object linked with static
// libraries.
ldflags: [
"-shared",
@@ -344,50 +346,38 @@
"-Wl,--pack-dyn-relocs=relr",
],
- // we are going to link libc++_static manually because
- // when stl is not set to "none" build system adds libdl
- // to the list of static libraries which needs to be
- // avoided in the case of building loader.
+ // We link libc++_static manually because otherwise the build system will
+ // automatically add libdl to the list of static libraries.
stl: "none",
- // we don't want crtbegin.o (because we have begin.o), so unset it
- // just for this module
+ // We don't want crtbegin.o (because we have our own arch/*/begin.o),
+ // so unset it just for this module.
nocrt: true,
- static_executable: true,
-
// Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
// looking up symbols in the linker by mistake.
prefix_symbols: "__dl_",
sanitize: {
hwaddress: false,
+ memtag_stack: false,
},
static_libs: [
"liblinker_main",
"liblinker_malloc",
- // Use a version of libc++ built without exceptions, because accessing EH globals uses
- // ELF TLS, which is not supported in the loader.
+ // We use a version of libc++ built without exceptions,
+ // because accessing EH globals uses ELF TLS,
+ // which is not supported in the loader.
"libc++_static_noexcept",
+
"libc_nomalloc",
"libc_dynamic_dispatch",
"libm",
"libunwind",
],
- // Ensure that if the linker needs __gnu_Unwind_Find_exidx, then the linker will have a
- // definition of the symbol. The linker links against libgcc.a, whose arm32 unwinder has a weak
- // reference to __gnu_Unwind_Find_exidx, which isn't sufficient to pull in the strong definition
- // of __gnu_Unwind_Find_exidx from libc. An unresolved weak reference would create a
- // non-relative dynamic relocation in the linker binary, which complicates linker startup.
- //
- // This line should be unnecessary because the linker's dependency on libunwind_llvm.a should
- // override libgcc.a, but this line provides a simpler guarantee. It can be removed once the
- // linker stops linking against libgcc.a's arm32 unwinder.
- whole_static_libs: ["libc_unwind_static"],
-
system_shared_libs: [],
// Opt out of native_coverage when opting out of system_shared_libs
@@ -474,35 +464,6 @@
}
cc_library {
- // NOTE: --exclude-libs=libgcc.a makes sure that any symbols ld-android.so pulls from
- // libgcc.a are made static to ld-android.so. This in turn ensures that libraries that
- // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so
- // to provide those symbols, but will instead pull them from libgcc.a. Specifically,
- // we use this property to make sure libc.so has its own copy of the code from
- // libgcc.a it uses.
- //
- // DO NOT REMOVE --exclude-libs!
-
- ldflags: [
- "-Wl,--exclude-libs=libgcc.a",
- "-Wl,--exclude-libs=libgcc_stripped.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
- "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
- ],
-
- // for x86, exclude libgcc_eh.a for the same reasons as above
- arch: {
- x86: {
- ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
- },
- x86_64: {
- ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
- },
- },
-
srcs: ["ld_android.cpp"],
cflags: [
"-Wall",
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8b467a3..e13d37d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3595,7 +3595,7 @@
// 2. Initialize other namespaces
for (auto& ns_config : namespace_configs) {
- if (namespaces.find(ns_config->name()) != namespaces.end()) {
+ if (namespaces.contains(ns_config->name())) {
continue;
}
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index ad40c50..70430b8 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -304,7 +304,7 @@
}
if (result == ConfigParser::kPropertyAssign) {
- if (properties->find(name) != properties->end()) {
+ if (properties->contains(name)) {
DL_WARN("%s:%zd: warning: redefining property \"%s\" (overriding previous value)",
ld_config_file_path,
cp.lineno(),
@@ -313,7 +313,7 @@
(*properties)[name] = PropertyValue(std::move(value), cp.lineno());
} else if (result == ConfigParser::kPropertyAppend) {
- if (properties->find(name) == properties->end()) {
+ if (!properties->contains(name)) {
DL_WARN("%s:%zd: warning: appending to undefined property \"%s\" (treating as assignment)",
ld_config_file_path,
cp.lineno(),
@@ -526,7 +526,7 @@
properties.get_strings(property_name_prefix + ".links", &lineno);
for (const auto& linked_ns_name : linked_namespaces) {
- if (namespace_configs.find(linked_ns_name) == namespace_configs.end()) {
+ if (!namespace_configs.contains(linked_ns_name)) {
*error_msg = create_error_msg(ld_config_file_path,
lineno,
std::string("undefined namespace: ") + linked_ns_name);
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index 5182129..eb9dae9 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -100,7 +100,7 @@
// be searched.
if (allow_secondary) {
const android_namespace_list_t& secondary_namespaces = si->get_secondary_namespaces();
- if (secondary_namespaces.find(this) != secondary_namespaces.end()) {
+ if (secondary_namespaces.contains(this)) {
return true;
}
}
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 802c06a..d915503 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -887,7 +887,7 @@
handle_ = handle_ | 1;
} while (handle_ == reinterpret_cast<uintptr_t>(RTLD_DEFAULT) ||
handle_ == reinterpret_cast<uintptr_t>(RTLD_NEXT) ||
- g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());
+ g_soinfo_handles_map.contains(handle_));
g_soinfo_handles_map[handle_] = this;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 9aca488..ee34666 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -369,7 +369,10 @@
cc_test_library {
name: "libBionicStandardTests",
- defaults: ["bionic_tests_defaults"],
+ defaults: [
+ "bionic_tests_defaults",
+ "large_system_property_node_defaults",
+ ],
tidy_disabled_srcs: [
"malloc_test.cpp", // timed out with clang-tidy, and too many warnings
],
@@ -401,6 +404,7 @@
"_FILE_OFFSET_BITS_test.cpp",
"float_test.cpp",
"fnmatch_test.cpp",
+ "fts_test.cpp",
"ftw_test.cpp",
"getauxval_test.cpp",
"getcwd_test.cpp",
@@ -430,6 +434,7 @@
"netdb_test.cpp",
"net_if_test.cpp",
"netinet_ether_test.cpp",
+ "netinet_igmp_test.cpp",
"netinet_in_test.cpp",
"netinet_ip_icmp_test.cpp",
"netinet_udp_test.cpp",
@@ -474,6 +479,7 @@
"sys_cachectl_test.cpp",
"sys_epoll_test.cpp",
"sys_hwprobe_test.cpp",
+ "sys_io_test.cpp",
"sys_mman_test.cpp",
"sys_msg_test.cpp",
"sys_param_test.cpp",
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 4d21246..cde2d11 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -33,11 +33,11 @@
static void CheckProcSelf(std::set<std::string>& names) {
// We have a good idea of what should be in /proc/self.
- ASSERT_TRUE(names.find(".") != names.end());
- ASSERT_TRUE(names.find("..") != names.end());
- ASSERT_TRUE(names.find("cmdline") != names.end());
- ASSERT_TRUE(names.find("fd") != names.end());
- ASSERT_TRUE(names.find("stat") != names.end());
+ ASSERT_TRUE(names.contains("."));
+ ASSERT_TRUE(names.contains(".."));
+ ASSERT_TRUE(names.contains("cmdline"));
+ ASSERT_TRUE(names.contains("fd"));
+ ASSERT_TRUE(names.contains("stat"));
}
template <typename DirEntT>
diff --git a/tests/fts_test.cpp b/tests/fts_test.cpp
new file mode 100644
index 0000000..39e570b
--- /dev/null
+++ b/tests/fts_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#if !defined(__GLIBC__)
+#include <fts.h>
+#endif
+
+TEST(fts, smoke) {
+#if !defined(__GLIBC__)
+ char* const paths[] = { const_cast<char*>("."), NULL };
+ FTS* fts = fts_open(paths, FTS_PHYSICAL, NULL);
+ ASSERT_TRUE(fts != NULL);
+ FTSENT* e;
+ while ((e = fts_read(fts)) != NULL) {
+ ASSERT_EQ(0, fts_set(fts, e, FTS_SKIP));
+ }
+ ASSERT_EQ(0, fts_close(fts));
+#else
+ GTEST_SKIP() << "no _FILE_OFFSET_BITS=64 <fts.h> in our old glibc";
+#endif
+}
diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp
index b3ab94d..da64770 100644
--- a/tests/ifaddrs_test.cpp
+++ b/tests/ifaddrs_test.cpp
@@ -137,7 +137,7 @@
sockaddr_in* sock = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
in_addr_t addr = sock->sin_addr.s_addr;
- EXPECT_TRUE(addrs.find(addr) != addrs.end()) << if_name << ' ' << std::hex << ntohl(addr);
+ EXPECT_TRUE(addrs.contains(addr)) << if_name << ' ' << std::hex << ntohl(addr);
}
TEST(ifaddrs, getifaddrs_INET) {
diff --git a/tests/libs/testbinary_is_stack_mte.cpp b/tests/libs/testbinary_is_stack_mte.cpp
index d8074d5..0cdc466 100644
--- a/tests/libs/testbinary_is_stack_mte.cpp
+++ b/tests/libs/testbinary_is_stack_mte.cpp
@@ -36,7 +36,9 @@
#if defined(__BIONIC__) && defined(__aarch64__)
extern "C" int main(int, char**) {
- int ret = is_stack_mte_on() ? 0 : 1;
+ void* mte_tls_ptr = mte_tls();
+ *reinterpret_cast<uintptr_t*>(mte_tls_ptr) = 1;
+ int ret = is_stack_mte_on() && mte_tls_ptr != nullptr ? 0 : 1;
printf("RAN\n");
return ret;
}
diff --git a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
index 937ac4c..35af8f4 100644
--- a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
+++ b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
@@ -96,6 +96,7 @@
State state = kInit;
bool is_early_thread_mte_on = false;
+ void* early_thread_mte_tls = nullptr;
std::thread early_th([&] {
{
std::lock_guard lk(m);
@@ -107,6 +108,8 @@
cv.wait(lk, [&] { return state == kStackRemapped; });
}
is_early_thread_mte_on = is_stack_mte_on();
+ early_thread_mte_tls = mte_tls();
+ *reinterpret_cast<uintptr_t*>(early_thread_mte_tls) = 1;
});
{
std::unique_lock lk(m);
@@ -120,6 +123,7 @@
cv.notify_one();
CHECK(handle != nullptr);
CHECK(is_stack_mte_on());
+ CHECK(mte_tls() != nullptr);
bool new_stack_page_mte_on = false;
uintptr_t low;
@@ -129,11 +133,18 @@
CHECK(new_stack_page_mte_on);
bool is_late_thread_mte_on = false;
- std::thread late_th([&] { is_late_thread_mte_on = is_stack_mte_on(); });
+ void* late_thread_mte_tls = nullptr;
+ std::thread late_th([&] {
+ is_late_thread_mte_on = is_stack_mte_on();
+ late_thread_mte_tls = mte_tls();
+ *reinterpret_cast<uintptr_t*>(late_thread_mte_tls) = 1;
+ });
late_th.join();
early_th.join();
CHECK(is_late_thread_mte_on);
CHECK(is_early_thread_mte_on);
+ CHECK(late_thread_mte_tls != nullptr);
+ CHECK(early_thread_mte_tls != nullptr);
printf("RAN\n");
return 0;
}
diff --git a/tests/link_test.cpp b/tests/link_test.cpp
index 127a3d9..ae3a1cd 100644
--- a/tests/link_test.cpp
+++ b/tests/link_test.cpp
@@ -195,7 +195,7 @@
}
void AddModule(dl_phdr_info* info, size_t s) {
ASSERT_EQ(sizeof(dl_phdr_info), s);
- ASSERT_TRUE(dl_iter_mods.find(info->dlpi_addr) == dl_iter_mods.end());
+ ASSERT_FALSE(dl_iter_mods.contains(info->dlpi_addr));
ASSERT_TRUE(info->dlpi_name != nullptr);
dl_iter_mods[info->dlpi_addr] = {
.name = info->dlpi_name,
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 493f3af..273ef97 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -17,36 +17,37 @@
#define _GNU_SOURCE 1
#include <math.h>
-// This include (and the associated definition of __test_capture_signbit)
-// must be placed before any files that include <cmath> (gtest.h in this case).
+// <math.h> is required to define type-generic macros: fpclassify, signbit,
+// isfinite, isinf, isnan, isnormal, isgreater, isgreaterequal, isless,
+// islessequal, islessgreater, and isunordered.
//
-// <math.h> is required to define generic macros signbit, isfinite and
-// several other such functions.
+// <cmath> is required to #undef these macros and make equivalent sets of
+// _overloaded_ functions available in namespace std. So the isnan() macro,
+// for example, is replaced by std::isnan(float), std::isnan(double),
+// and std::isnan(long double).
//
-// <cmath> is required to undef declarations of these macros in the global
-// namespace and make equivalent functions available in namespace std. Our
-// stlport implementation does this only for signbit, isfinite, isinf and
-// isnan.
-//
-// NOTE: We don't write our test using std::signbit because we want to be
-// sure that we're testing the bionic version of signbit. The C++ libraries
-// are free to reimplement signbit or delegate to compiler builtins if they
-// please.
+// We're trying to test the bionic macros rather than whatever libc++'s
+// implementation happens to be, so we #include <math.h> and "capture" the
+// macros in our own _template_ functions in the global namespace before
+// we #include any files that include <cmath>, such as <gtest.h>.
-namespace {
-template<typename T> inline int test_capture_signbit(const T in) {
- return signbit(in);
-}
-template<typename T> inline int test_capture_isfinite(const T in) {
- return isfinite(in);
-}
-template<typename T> inline int test_capture_isnan(const T in) {
- return isnan(in);
-}
-template<typename T> inline int test_capture_isinf(const T in) {
- return isinf(in);
-}
-}
+#define capture_generic_macro(capture_function_name, generic_macro_name) \
+ template <typename T> inline int capture_function_name(const T in) { \
+ return generic_macro_name(in); \
+ }
+
+capture_generic_macro(test_capture_fpclassify, fpclassify)
+capture_generic_macro(test_capture_signbit, signbit)
+capture_generic_macro(test_capture_isfinite, isfinite)
+capture_generic_macro(test_capture_isinf, isinf)
+capture_generic_macro(test_capture_isnan, isnan)
+capture_generic_macro(test_capture_isnormal, isnormal)
+capture_generic_macro(test_capture_isgreater, isgreater)
+capture_generic_macro(test_capture_isgreaterequal, isgreaterequal)
+capture_generic_macro(test_capture_isless, isless)
+capture_generic_macro(test_capture_islessequal, islessequal)
+capture_generic_macro(test_capture_islessgreater, islessgreater)
+capture_generic_macro(test_capture_isunordered, isunordered)
#include "math_data_test.h"
@@ -60,6 +61,22 @@
#include <android-base/scopeguard.h>
+// Now we've included all the headers we need, we can redefine the generic
+// function-like macros to point to the bionic <math.h> versions we captured
+// earlier.
+#define fpclassify test_capture_fpclassify
+#define signbit test_capture_signbit
+#define isfinite test_capture_isfinite
+#define isinf test_capture_isinf
+#define isnan test_capture_isnan
+#define isnormal test_capture_isnormal
+#define isgreater test_capture_isgreater
+#define isgreaterequal test_capture_isgreaterequal
+#define isless test_capture_isless
+#define islessequal test_capture_islessequal
+#define islessgreater test_capture_islessgreater
+#define isunordered test_capture_isunordered
+
static float float_subnormal() {
union {
float f;
@@ -124,36 +141,36 @@
}
TEST(math_h, isfinite) {
- ASSERT_TRUE(test_capture_isfinite(123.0f));
- ASSERT_TRUE(test_capture_isfinite(123.0));
- ASSERT_TRUE(test_capture_isfinite(123.0L));
- ASSERT_FALSE(test_capture_isfinite(HUGE_VALF));
- ASSERT_FALSE(test_capture_isfinite(-HUGE_VALF));
- ASSERT_FALSE(test_capture_isfinite(HUGE_VAL));
- ASSERT_FALSE(test_capture_isfinite(-HUGE_VAL));
- ASSERT_FALSE(test_capture_isfinite(HUGE_VALL));
- ASSERT_FALSE(test_capture_isfinite(-HUGE_VALL));
+ ASSERT_TRUE(isfinite(123.0f));
+ ASSERT_TRUE(isfinite(123.0));
+ ASSERT_TRUE(isfinite(123.0L));
+ ASSERT_FALSE(isfinite(HUGE_VALF));
+ ASSERT_FALSE(isfinite(-HUGE_VALF));
+ ASSERT_FALSE(isfinite(HUGE_VAL));
+ ASSERT_FALSE(isfinite(-HUGE_VAL));
+ ASSERT_FALSE(isfinite(HUGE_VALL));
+ ASSERT_FALSE(isfinite(-HUGE_VALL));
}
TEST(math_h, isinf) {
- ASSERT_FALSE(test_capture_isinf(123.0f));
- ASSERT_FALSE(test_capture_isinf(123.0));
- ASSERT_FALSE(test_capture_isinf(123.0L));
- ASSERT_TRUE(test_capture_isinf(HUGE_VALF));
- ASSERT_TRUE(test_capture_isinf(-HUGE_VALF));
- ASSERT_TRUE(test_capture_isinf(HUGE_VAL));
- ASSERT_TRUE(test_capture_isinf(-HUGE_VAL));
- ASSERT_TRUE(test_capture_isinf(HUGE_VALL));
- ASSERT_TRUE(test_capture_isinf(-HUGE_VALL));
+ ASSERT_FALSE(isinf(123.0f));
+ ASSERT_FALSE(isinf(123.0));
+ ASSERT_FALSE(isinf(123.0L));
+ ASSERT_TRUE(isinf(HUGE_VALF));
+ ASSERT_TRUE(isinf(-HUGE_VALF));
+ ASSERT_TRUE(isinf(HUGE_VAL));
+ ASSERT_TRUE(isinf(-HUGE_VAL));
+ ASSERT_TRUE(isinf(HUGE_VALL));
+ ASSERT_TRUE(isinf(-HUGE_VALL));
}
TEST(math_h, isnan) {
- ASSERT_FALSE(test_capture_isnan(123.0f));
- ASSERT_FALSE(test_capture_isnan(123.0));
- ASSERT_FALSE(test_capture_isnan(123.0L));
- ASSERT_TRUE(test_capture_isnan(nanf("")));
- ASSERT_TRUE(test_capture_isnan(nan("")));
- ASSERT_TRUE(test_capture_isnan(nanl("")));
+ ASSERT_FALSE(isnan(123.0f));
+ ASSERT_FALSE(isnan(123.0));
+ ASSERT_FALSE(isnan(123.0L));
+ ASSERT_TRUE(isnan(nanf("")));
+ ASSERT_TRUE(isnan(nan("")));
+ ASSERT_TRUE(isnan(nanl("")));
}
TEST(math_h, isnormal) {
@@ -167,17 +184,17 @@
// TODO: isgreater, isgreaterequals, isless, islessequal, islessgreater, isunordered
TEST(math_h, signbit) {
- ASSERT_EQ(0, test_capture_signbit(0.0f));
- ASSERT_EQ(0, test_capture_signbit(0.0));
- ASSERT_EQ(0, test_capture_signbit(0.0L));
+ ASSERT_EQ(0, signbit(0.0f));
+ ASSERT_EQ(0, signbit(0.0));
+ ASSERT_EQ(0, signbit(0.0L));
- ASSERT_EQ(0, test_capture_signbit(1.0f));
- ASSERT_EQ(0, test_capture_signbit(1.0));
- ASSERT_EQ(0, test_capture_signbit(1.0L));
+ ASSERT_EQ(0, signbit(1.0f));
+ ASSERT_EQ(0, signbit(1.0));
+ ASSERT_EQ(0, signbit(1.0L));
- ASSERT_NE(0, test_capture_signbit(-1.0f));
- ASSERT_NE(0, test_capture_signbit(-1.0));
- ASSERT_NE(0, test_capture_signbit(-1.0L));
+ ASSERT_NE(0, signbit(-1.0f));
+ ASSERT_NE(0, signbit(-1.0));
+ ASSERT_NE(0, signbit(-1.0L));
}
// Historical BSD cruft that isn't exposed in <math.h> any more.
@@ -309,9 +326,7 @@
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isinf(double);
extern "C" int __isinff(float);
-extern "C" int isinff(float);
extern "C" int __isinfl(long double);
-extern "C" int isinfl(long double);
TEST(math_h, __isinf) {
#if defined(ANDROID_HOST_MUSL)
@@ -367,9 +382,7 @@
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isnan(double);
extern "C" int __isnanf(float);
-extern "C" int isnanf(float);
extern "C" int __isnanl(long double);
-extern "C" int isnanl(long double);
TEST(math_h, __isnan) {
#if defined(ANDROID_HOST_MUSL)
diff --git a/tests/mte_utils.h b/tests/mte_utils.h
index 6e8385c..020faec 100644
--- a/tests/mte_utils.h
+++ b/tests/mte_utils.h
@@ -40,4 +40,10 @@
return p == p_cpy;
}
+static void* mte_tls() {
+ void** dst;
+ __asm__("mrs %0, TPIDR_EL0" : "=r"(dst) :);
+ return dst[-3];
+}
+
#endif
diff --git a/tests/netinet_igmp_test.cpp b/tests/netinet_igmp_test.cpp
new file mode 100644
index 0000000..4cf7876
--- /dev/null
+++ b/tests/netinet_igmp_test.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <netinet/igmp.h>
+
+TEST(netinet_igmp, smoke) {
+ // Just check that the fields exist, so code is likely to compile.
+ struct igmp i;
+ i.igmp_type = IGMP_MEMBERSHIP_QUERY;
+ i.igmp_code = 0;
+ i.igmp_cksum = 0;
+ i.igmp_group.s_addr = htonl(INADDR_ANY);
+}
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index aea791c..5817a27 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -48,7 +48,7 @@
printf("[thread %d] TLS stack guard = %p\n", tid, guard);
// Duplicate tid. gettid(2) bug? Seeing this would be very upsetting.
- ASSERT_TRUE(tids.find(tid) == tids.end());
+ ASSERT_FALSE(tids.contains(tid));
// Uninitialized guard. Our bug. Note this is potentially flaky; we _could_
// get four random zero bytes, but it should be vanishingly unlikely.
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 0123ed9..1f04344 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -30,7 +30,7 @@
#define CHECK_OFFSET(name, field, offset) \
check_offset(#name, #field, offsetof(name, field), offset);
#ifdef __LP64__
- CHECK_SIZE(pthread_internal_t, 776);
+ CHECK_SIZE(pthread_internal_t, 816);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 8);
CHECK_OFFSET(pthread_internal_t, tid, 16);
@@ -55,6 +55,8 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 248);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 760);
CHECK_OFFSET(pthread_internal_t, errno_value, 768);
+ CHECK_OFFSET(pthread_internal_t, bionic_tcb, 776);
+ CHECK_OFFSET(pthread_internal_t, stack_mte_ringbuffer_vma_name_buffer, 784);
CHECK_SIZE(bionic_tls, 12200);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 2080);
@@ -72,7 +74,7 @@
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
CHECK_OFFSET(bionic_tls, padding, 12194);
#else
- CHECK_SIZE(pthread_internal_t, 668);
+ CHECK_SIZE(pthread_internal_t, 704);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 4);
CHECK_OFFSET(pthread_internal_t, tid, 8);
@@ -97,6 +99,8 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 148);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 660);
CHECK_OFFSET(pthread_internal_t, errno_value, 664);
+ CHECK_OFFSET(pthread_internal_t, bionic_tcb, 668);
+ CHECK_OFFSET(pthread_internal_t, stack_mte_ringbuffer_vma_name_buffer, 672);
CHECK_SIZE(bionic_tls, 11080);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 1040);
diff --git a/tests/sys_io_test.cpp b/tests/sys_io_test.cpp
new file mode 100644
index 0000000..293ceb2
--- /dev/null
+++ b/tests/sys_io_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <sys/io.h>
+
+#include "utils.h"
+
+TEST(sys_io, iopl) {
+#if defined(__i386__) || defined(__x86_64__)
+ errno = 0;
+ ASSERT_EQ(-1, iopl(4));
+ ASSERT_ERRNO(EINVAL);
+#else
+ GTEST_SKIP() << "iopl requires x86/x86-64";
+#endif
+}
+
+TEST(sys_io, ioperm) {
+#if defined(__i386__) || defined(__x86_64__)
+ errno = 0;
+ ASSERT_EQ(-1, ioperm(65535, 4, 0));
+ ASSERT_ERRNO(EINVAL);
+#else
+ GTEST_SKIP() << "ioperm requires x86/x86-64";
+#endif
+}
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index df13e07..40c85f2 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -243,6 +243,20 @@
ASSERT_EQ(0, munmap(map, kPageSize));
}
+TEST(sys_mman, mremap_MREMAP_FIXED) {
+ // We're not trying to test the kernel here; that's external/ltp's job.
+ // We just want to check that optional argument (mremap() is varargs)
+ // gets passed through in an MREMAP_FIXED call.
+ void* vma1 = mmap(NULL, getpagesize(), PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_NE(MAP_FAILED, vma1);
+
+ void* vma2 = mmap(NULL, getpagesize(), PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_NE(MAP_FAILED, vma2);
+
+ void* vma3 = mremap(vma1, getpagesize(), getpagesize(), MREMAP_FIXED | MREMAP_MAYMOVE, vma2);
+ ASSERT_EQ(vma2, vma3);
+}
+
TEST(sys_mman, mmap_bug_27265969) {
char* base = reinterpret_cast<char*>(
mmap(nullptr, kPageSize * 2, PROT_EXEC | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index 0b7f5ae..f11f509 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -593,7 +593,13 @@
ASSERT_TRUE(system_properties.valid());
auto name = "ro.super_long_property"s;
+
+#ifdef LARGE_SYSTEM_PROPERTY_NODE
+ auto value = std::string(1024 * 1024 + 1, 'x');
+#else
auto value = std::string(128 * 1024 + 1, 'x');
+#endif
+
ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
#else // __BIONIC__
diff --git a/tests/termios_test.cpp b/tests/termios_test.cpp
index 480f3af..19e9bfe 100644
--- a/tests/termios_test.cpp
+++ b/tests/termios_test.cpp
@@ -96,7 +96,7 @@
EXPECT_EQ(0U, (t.c_oflag & OPOST));
EXPECT_EQ(0U, (t.c_lflag & (ECHO|ECHONL|ICANON|ISIG|IEXTEN)));
EXPECT_EQ(0U, (t.c_cflag & PARENB));
- EXPECT_EQ(CS8, static_cast<int>(t.c_cflag & CSIZE));
+ EXPECT_EQ(static_cast<unsigned>(CS8), (t.c_cflag & CSIZE));
EXPECT_EQ(1, t.c_cc[VMIN]);
EXPECT_EQ(0, t.c_cc[VTIME]);
}
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 955cdcf..37c8bac 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -142,7 +142,7 @@
auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
for (const auto& it : ignored_headers) {
- if (it.second.find(arch) == it.second.end()) {
+ if (!it.second.contains(arch)) {
continue;
}