[automerger skipped] Merge "Move bionic test libraries to a default, for easy consumption in cts." into android14-tests-dev am: 430eb3e96b -s ours am: 741541d307 -s ours
am skip reason: Merged-In I271668e83aed239107b9129dfb707f03bae47cfa with SHA-1 f5c9a65046 is already in history
Original change: https://android-review.googlesource.com/c/platform/bionic/+/3394596
Change-Id: Ide47c37ac3f975db3ab2f81ba748e971568d7a9c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: NOTICE
-}
diff --git a/OWNERS b/OWNERS
index 3818b1d..7455fd7 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,3 +5,5 @@
danalbert@google.com
rprichard@google.com
yabinc@google.com
+
+per-file docs/mte.md=fmayer@google.com,pcc@google.com
diff --git a/README.md b/README.md
index 0f2c30f..953e983 100644
--- a/README.md
+++ b/README.md
@@ -177,7 +177,7 @@
library that would make more sense as the place to add the wrapper.
In all other cases, you should use
-[syscall(3)](http://man7.org/linux/man-pages/man2/syscall.2.html) instead.
+[syscall(3)](https://man7.org/linux/man-pages/man2/syscall.2.html) instead.
Adding a system call usually involves:
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 60a4f61..e98c2ff 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -88,6 +88,12 @@
},
{
"name": "toybox-tests"
+ },
+ {
+ "name": "hwasan_test"
+ },
+ {
+ "name": "hwasan_test_static"
}
],
"kernel-presubmit": [
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index e9cfbac..a96e105 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -47,10 +47,12 @@
dynamic linker's caching code cached failures too, so it was necessary
to topologically sort your libraries and load them in reverse order.
-If you need to support Android devices running OS versions older than
+This issue is no longer relevant to most developers,
+but if you need to support Android devices running OS versions older than
API level 23, you might want to consider
-[ReLinker](https://github.com/KeepSafe/ReLinker) which claims to solve
-these and other problems automatically.
+[ReLinker](https://github.com/KeepSafe/ReLinker) or
+[SoLoader](https://github.com/facebook/SoLoader),
+which claim to solve these problems automatically.
Alternatively, if you don't have too many dependencies, it can be easiest to
simply link all of your code into one big library and sidestep the details of
@@ -76,6 +78,17 @@
the local group. This allows ASAN, for example, to ensure that it can
intercept any symbol.
+This issue is no longer relevant to most developers,
+but if you need to support Android devices running OS versions older than
+API level 23, you might want to consider
+[ReLinker](https://github.com/KeepSafe/ReLinker) or
+[SoLoader](https://github.com/facebook/SoLoader),
+which claim to solve these problems automatically.
+
+Alternatively, if you don't have too many dependencies, it can be easiest to
+simply link all of your code into one big library and sidestep the details of
+library and symbol lookup changes on all past (and future) Android versions.
+
## LD_PRELOAD and 32/64 bit
diff --git a/benchmarks/README.md b/benchmarks/README.md
index 6b6c448..319db25 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -189,6 +189,5 @@
Some devices have a `perf-setup.sh` script that locks CPU and GPU frequencies. Some TradeFed
benchmarks appear to be using the script. For more information:
- * run `get_build_var BOARD_PERFSETUP_SCRIPT`
- * run `m perf-setup` to install the script into `${OUT}/data/local/tmp/perf-setup.sh`
+ * run `adb shell perf-setup.sh` to execute the script, it is already by default be installed on device for eng and userdebug build
* see: https://android.googlesource.com/platform/platform_testing/+/refs/heads/main/scripts/perf-setup/
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 1b4ba23..b356ab7 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -28,8 +28,7 @@
#if defined(__BIONIC__)
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
+#include <sys/system_properties.h>
#include <benchmark/benchmark.h>
#include <system_properties/system_properties.h>
diff --git a/cpu_target_features/Android.bp b/cpu_target_features/Android.bp
new file mode 100644
index 0000000..25f37d1
--- /dev/null
+++ b/cpu_target_features/Android.bp
@@ -0,0 +1,18 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "cpu-target-features",
+ srcs: [
+ "main.cpp",
+ ],
+ generated_headers: ["print_target_features.inc"],
+}
+
+genrule {
+ name: "print_target_features.inc",
+ out: ["print_target_features.inc"],
+ tool_files: ["generate_printer.py"],
+ cmd: "$(location generate_printer.py) $(out)",
+}
diff --git a/cpu_target_features/generate_printer.py b/cpu_target_features/generate_printer.py
new file mode 100755
index 0000000..dc56eb5
--- /dev/null
+++ b/cpu_target_features/generate_printer.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+
+"""Generate the compilation target feature printing source code.
+
+The source code for detecting target features is heavily redundant and
+copy-pasted, and is easier to maintain using a generative script.
+
+This script creates the source and the include files in its current
+directory.
+"""
+
+import argparse
+from pathlib import Path
+from typing import Dict, List, Iterable
+
+_CPP_BOILERPLATE: str = """\
+#include <stdio.h>
+
+#define TO_STRING_EXP(DEF) #DEF
+#define TO_STRING(DEF) TO_STRING_EXP(DEF)
+"""
+
+_FEATURES = {
+ "Aarch64": [
+ "__ARM_FEATURE_AES",
+ "__ARM_FEATURE_BTI",
+ "__ARM_FEATURE_CRC32",
+ "__ARM_FEATURE_CRYPTO",
+ "__ARM_FEATURE_PAC_DEFAULT",
+ "__ARM_FEATURE_SHA2",
+ "__ARM_FEATURE_SHA3",
+ "__ARM_FEATURE_SHA512",
+ ],
+ "Arm32": [
+ "__ARM_ARCH_ISA_THUMB",
+ "__ARM_FEATURE_AES",
+ "__ARM_FEATURE_BTI",
+ "__ARM_FEATURE_CRC32",
+ "__ARM_FEATURE_CRYPTO",
+ "__ARM_FEATURE_PAC_DEFAULT",
+ "__ARM_FEATURE_SHA2",
+ ],
+ "X86": [
+ "__AES__",
+ "__AVX__",
+ "__CRC32__",
+ "__POPCNT__",
+ "__SHA512__",
+ "__SHA__",
+ ],
+ "Riscv": [
+ "__riscv_vector",
+ ],
+}
+
+
+def _make_function_sig(name: str) -> str:
+ return f"void print{name}TargetFeatures()"
+
+
+def check_template(define: str) -> List[str]:
+ return [
+ f"#if defined({define})",
+ f' printf("%s=%s\\n", TO_STRING_EXP({define}), TO_STRING({define}));',
+ "#else",
+ f' printf("%s not defined\\n", TO_STRING_EXP({define}));',
+ "#endif",
+ ]
+
+
+def generate_cpp_file(define_mapping: Dict[str, List[str]]) -> List[str]:
+ out: List[str] = _CPP_BOILERPLATE.split("\n")
+ for target, defines in define_mapping.items():
+ out.append("")
+ out.extend(generate_print_function(target, defines))
+ return out
+
+
+def generate_print_function(name: str, defines: List[str]) -> List[str]:
+ """Generate a print<DEFINE>TargetFeatures function."""
+ function_body = [_make_function_sig(name) + " {"]
+ for d in defines:
+ function_body.extend(check_template(d))
+ function_body.append("}")
+ return function_body
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "cpp_in",
+ type=Path,
+ help="Output path to generate the cpp file.",
+ )
+ return parser.parse_args()
+
+
+def main() -> None:
+ args = parse_args()
+ printer_cpp_filepath = args.cpp_in
+ printer_cpp_filepath.write_text(
+ "\n".join(generate_cpp_file(_FEATURES)), encoding="utf-8"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/cpu_target_features/main.cpp b/cpu_target_features/main.cpp
new file mode 100644
index 0000000..61f3d25
--- /dev/null
+++ b/cpu_target_features/main.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#include "print_target_features.inc"
+
+int main() {
+#if defined(__aarch64__)
+ printAarch64TargetFeatures();
+ return 0;
+#elif defined(__arm__)
+ printArm32TargetFeatures();
+ return 0;
+#elif defined(__x86_64__) || defined(__i386__)
+ printX86TargetFeatures();
+ return 0;
+#elif defined(__riscv)
+ printRiscvTargetFeatures();
+ return 0;
+#else
+#error Unsupported arch. This binary only supports aarch64, arm, x86, x86-64, and risc-v
+#endif
+}
diff --git a/docs/README.md b/docs/README.md
index 2825eac..d66fa68 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,6 +17,7 @@
which detects use-after-close() bugs.
* [fdtrack](fdtrack.md) - bionic's file descriptor tracker,
which helps debug file descriptor leaks.
+* [C23](c23.md) - dealing with C23's breaking changes.
## Maintainer documentation
diff --git a/docs/c23.md b/docs/c23.md
new file mode 100644
index 0000000..9ed570d
--- /dev/null
+++ b/docs/c23.md
@@ -0,0 +1,97 @@
+# C23 language changes
+
+## Breaking changes
+
+### `void foo()` now means `void foo(void)`
+In C17 and earlier, `void foo()` means "I haven't yet told you how many
+arguments this function has". In C23, it's equivalent to C++ and means "this
+function has no arguments". This may surface as a function pointer type
+mismatch, because previously `()` matched functions taking any arguments,
+whereas in C23 it only matches functions taking no arguments.
+
+Fix: in cases where your function does have arguments, declare them.
+
+### Undeclared identifiers are now errors
+In C17 and earlier, calling `foo(123)` without a declaration for `foo()`
+produced a warning. In C23 this is an error instead. One common special case of
+this is code that's explicitly ignoring such warnings to call functions that are
+GNU extensions; such code should be fixed to ensure that `_GNU_SOURCE` is
+defined before any header is included instead (often by adding `-D_GNU_SOURCE`
+to the cflags in the build file).
+
+Fix: add the missing forward declaration or `#include` (or `-D_GNU_SOURCE`).
+
+### `bool`/`true`/`false` are now keywords
+In C17 and earlier, only code that included `<stdbool.h>` would have standard
+definitions for these (typically macros for `_Bool`/`1`/`0`). In C23 these are
+keywords and should no longer be defined in your code.
+
+Fix: delete any definitions of `bool`/`true`/`false` if you only need to build
+as C23, or switch to `#include <stdbool.h>` for compatibility back to C99.
+
+### `false` is no longer `0`
+In C17 and earlier, it was common for true and false to be defined as 1 and 0
+(either by `<stdbool.h>` or by user-provided `#define`/`enum`). This meant that
+`false` (as 0) could be implicitly converted to `NULL`. In C23, a function that
+returns (or takes) a pointer can no longer return `false` (or be passed
+`false`).
+
+Fix: return/pass `NULL` (or `nullptr` for C23-only code) instead of `false`
+in pointer contexts.
+
+### `unreachable()` is now a predefined function-like macro in `<stddef.h>`
+In C17 and earlier, `unreachable()` was available for your own macros/functions.
+In C23 there's a standard definition.
+
+Fix: delete your `unreachable()` if it was just equivalent to
+`__builtin_unreachable()` or rename it if it had different behavior.
+
+### K&R prototypes are no longer valid
+In C17 and earlier, K&R function prototypes were deprecated but still allowed.
+In C23 K&R prototypes are no longer allowed.
+
+Fix: rewrite any K&R prototypes as ANSI/ISO prototypes.
+
+
+## Non-breaking changes
+
+### Unused function parameters can now be anonymous
+In C17 and earlier you'd have to use `__attribute__((unused))` on an unused
+function parameter. In C23 you can just omit the parameter name instead,
+like `void* pthread_callback_fn(void*) {` (as in C++).
+
+### New standard attributes
+C23 adds `[[deprecated("reason")]]`, `[[fallthrough]]`, `[[nodiscard]]` (the
+equivalent of the clang attribute `warn_unused_result`),
+`[[maybe_unused]]` (the equivalent of the clang attribute `unused`),
+and `[[noreturn]]` (equivalent to C11 `_Noreturn`).
+Most of these have been available before via `__attribute__` or other syntax,
+but are now standard.
+
+### `#embed`
+You can now include binary data directly into an array or string: https://en.cppreference.com/w/c/preprocessor/embed
+
+### `void foo(...)` is now allowed
+In C17 and earlier, a varargs function needed a non-varargs argument.
+In C23 this is allowed (as in C++).
+
+### `enum` base types
+You can now say `enum E : long { ... }` to explicitly choose the base type of
+your enum (as in C++, and already supported by clang as an extension).
+
+### `nullptr` constant
+There is now a `nullptr` constant (as in C++),
+and a corresponding `nullptr_t` type for that constant.
+
+### `constexpr`
+There is now a limited form of `constexpr` for defining `const` variables
+(similar to, but much more limited than C++ constexpr).
+
+
+## Library changes
+
+Library changes are not covered here because bionic does not make library
+functionality available based on target C version, since the target API level
+distinctions are confusing enough already.
+
+See [status.md](status.md) for what functionality went into which API level.
diff --git a/docs/clang_fortify_anatomy.md b/docs/clang_fortify_anatomy.md
index 4b95fdc..46d3a71 100644
--- a/docs/clang_fortify_anatomy.md
+++ b/docs/clang_fortify_anatomy.md
@@ -147,8 +147,7 @@
void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
```
-Which is annotated with nothing special, except for Bionic's versioner, which
-is Android-specific (and orthogonal to FORTIFY anyway), so it will be ignored.
+Which is annotated with nothing special, so it will be ignored.
The [source for `mempcpy`] in Bionic's headers for is:
```c
diff --git a/docs/fdtrack.md b/docs/fdtrack.md
index 07c69b3..8928a5c 100644
--- a/docs/fdtrack.md
+++ b/docs/fdtrack.md
@@ -4,9 +4,11 @@
fdtrack is a file descriptor leak checker added to Android in API level 30.
-fdtrack consists of two parts: a set of hooks in bionic to register a callback
-that's invoked on file descriptor operations, and a library that implements a
-hook to perform and store backtraces for file descriptor creation.
+fdtrack consists of several parts: a set of hooks in bionic to register a
+callback that's invoked on file descriptor operations, a library that implements
+a hook to perform and store backtraces for file descriptor creation, and
+code in frameworks to automatically enable it (and deliberately crash a process
+that's leaking).
### bionic hooks
bionic provides a header in the `bionic_libc_platform_headers` header_lib at <[bionic/fdtrack.h](https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/platform/bionic/fdtrack.h)>.
@@ -21,6 +23,28 @@
[libfdtrack](https://android.googlesource.com/platform/bionic/+/refs/heads/main/libfdtrack)
implements a library that uses libunwindstack to unwind and store fd creation backtraces.
+### frameworks
+As the name implies, `spawnFdLeakCheckThread` in SystemServer spawns a thread
+to monitor the number of open file descriptors every so often.
+If that passes a certain threshold, fdtrack is enabled.
+If it passes another threshold, the process is aborted.
+These thresholds are configurable via system properties:
+```
+ // Number of open file descriptors before fdtrack starts; default 1600.
+ private static final String SYSPROP_FDTRACK_ENABLE_THRESHOLD =
+ "persist.sys.debug.fdtrack_enable_threshold";
+
+ // Number of open file descriptors before aborting; default 3000.
+ private static final String SYSPROP_FDTRACK_ABORT_THRESHOLD =
+ "persist.sys.debug.fdtrack_abort_threshold";
+
+ // Number of seconds between open fd count checks; default 120s.
+ private static final String SYSPROP_FDTRACK_INTERVAL =
+ "persist.sys.debug.fdtrack_interval";
+```
+Note that it's also possible to monitor the number of open file descriptors for
+a given process from the shell. `adb shell watch ls -l /proc/<pid>/fd` will show
+them (and you can choose your own update rate as an argument to `watch`).
#### Using libfdtrack
libfdtrack registers its hook upon being loaded, so to start capturing
diff --git a/docs/mte.md b/docs/mte.md
new file mode 100644
index 0000000..3034cc7
--- /dev/null
+++ b/docs/mte.md
@@ -0,0 +1,244 @@
+# Arm Memory Tagging Extension (MTE) implementation
+
+AOSP supports Arm MTE to detect invalid memory accesses. The implementation is
+spread across multiple components, both within and out of the AOSP tree. This
+document gives an overview and pointers about how the various MTE features are
+implemented.
+
+For documentation of the behavior rather than the implementation, see the
+[SAC page on MTE] instead. For MTE for apps, see the [NDK page on MTE].
+
+The relevant components are:
+
+* [LLVM Project] (out of AOSP tree)
+ * Stack tagging instrumentation pass
+ * Scudo memory allocator
+* bionic
+ * libc
+ * dynamic loader
+* Zygote
+* debuggerd
+* [NDK]
+
+## MTE enablement
+
+The way MTE is requested and enabled differs between native binaries and Java
+apps. This is necessarily so, because Java apps get forked from the Zygote,
+while native executables get inintialized by the linker.
+
+### Native binaries
+
+Both AOSP and the NDK allow you to compile C/C++ code that use MTE to detect
+memory safety issues. The [NDK legacy cmake toolchain] and the
+[NDK new cmake toolchain] both support "memtag" as an argument for
+`ANDROID_SANITIZE`. NDK make has no specific support for MTE, but the
+relevant flags can be passed directly as `CFLAGS` and `LDFLAGS`.
+
+For the OS itself, [Soong] supports "memtag_[heap|stack|globals]" as
+`SANITIZE_TARGET and as `sanitize:` attribute in Android.bp files;
+[Android make] supports the same environment variables as Soong. This passes
+the appropriate flags to the clang driver for both compile and link steps.
+
+#### Linker
+
+* For **dynamic executables** LLD has support to
+ [add appropriate dynamic sections] as defined in the [ELF standard]
+* For **static executables** and as a fallback for older devices, LLD
+ also supports [adding the Android-specific ELF note]
+
+Both of the above are controlled by the linker flag `--android-memtag-mode`
+which is [passed in by the clang driver] if
+`-fsanitize=memtag-[stack|heap|globals]` is [passed in].
+`-fsanitize=memtag` [enables all three] (even for API levels that don't
+implement the runtime for globals, which means builds from old versions
+of clang may no work with newer platform versions that support globals).
+`-fsanitize-memtag-mode` allows to choose between ASYNC and SYNC.
+
+This information can be queried using `llvm-readelf --memtag`.
+
+This information is [picked up by libc init] to decide whether to enable MTE.
+`-fsanitize-heap` controls both whether scudo tags allocations, and whether
+tag checking is enabled.
+
+#### Runtime environment (dynamic loader, libc)
+
+There are two different initialization sequences for libc, both of which end up
+calling `__libc_init_mte`.
+
+N.B. the linker has its own copy of libc, which is used when executing these
+functions. That is why we have to use `__libc_shared_globals` to communicate
+with the libc of the process we are starting.
+
+* **static executables** `__libc_init` is called from `crtbegin.c`, which calls
+ `__libc_init_mte`
+* **dynamic executables** the linker calls `__libc_init_mte`
+
+`__libc_init_mte` figures out the appropriate MTE level that is requested by
+the process, calls `prctl` to request this from the kernel, and stores data in
+`__libc_shared_globals` which gets picked up later to enable MTE in scudo.
+
+It also does work related to stack tagging and permissive mode, which will be
+detailed later.
+
+### Apps
+
+Apps can request MTE be enabled for their process via the manifest attribute
+`android:memtagMode`. This gets interpreted by Zygote, which always runs with
+`ASYNC` MTE enabled, because MTE for a process can only be disabled after
+it has been initialized (see [Native binaries](#native-binaries)), not enabled.
+
+[decideTaggingLevel] in the Zygote figures out whether to enable MTE for
+an app, and stores it in the `runtimeFlags`, which get picked up by
+[SpecializeCommon] after forking from the Zygote.
+
+## MTE implementation
+
+### Heap Tagging
+
+Heap tagging is implemented in the scudo allocator. On `malloc` and `free`,
+scudo will update the memory's tags to prevent use-after-free and buffer
+overflows.
+
+[scudo's memtag.h] contains helper functions to deal with MTE tag management,
+which are used in [combined.h] and [secondary.h].
+
+
+### Stack Tagging
+
+Stack tagging requires instrumenting function bodies. It is implemented as
+an instrumentation pass in LLVM called [AArch64StackTagging], which sets
+the tags according to the lifetime of stack objects.
+
+The instrumentation pass also supports recording stack history, consisting of:
+
+* PC
+* Frame pointer
+* Base tag
+
+This can be used to reconstruct which stack object was referred to in an
+invalid access. The logic to reconstruct this can be found in the
+[stack script].
+
+
+Stack tagging is enabled in one of two circumstances:
+* at process startup, if the main binary or any of its dependencies are
+ compiled with `memtag-stack`
+* library compiled with `memtag-stack` is `dlopen`ed later, either directly or
+ as a dependency of a `dlopen`ed library. In this case, the
+ [__pthread_internal_remap_stack_with_mte] function is used (called from
+ `memtag_stack_dlopen_callback`). Because `dlopen`
+ is handled by the linker, we have to [store a function pointer] to the
+ process's version of the function in `__libc_shared_globals`.
+
+Enabling stack MTE consists of two operations:
+* Remapping the stacks as `PROT_MTE`
+* Allocating a stack history buffer.
+
+The first operation is only necessary when the process is running with MTE
+enabled. The second operation is also necessary when the process is not running
+with MTE enabled, because the writes to the stack history buffer are
+unconditional.
+
+libc keeps track of this through two globals:
+
+* `__libc_memtag_stack`: 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_memtag_stack_abi`: whether the process contains any code that was
+ compiled with memtag-stack. This is true even if the process does not have
+ MTE enabled.
+
+### Globals Tagging
+
+TODO(fmayer): write once submitted
+
+### Crash reporting
+
+For MTE crashes, debuggerd serializes special information into the Tombstone
+proto:
+
+* Tags around fault address
+* Scudo allocation history
+
+This is done in [tombstone\_proto.cpp]. The information is converted to a text
+proto in [tombstone\_proto\_to\_text.cpp].
+
+## Bootloader control
+
+The bootloader API allows userspace to enable MTE on devices that do not ship
+with MTE enabled by default.
+
+See [SAC MTE bootloader support] for the API definition. In AOSP, this API is
+implemented in [system/extras/mtectrl]. mtectrl.rc handles the property
+changes and invokes mtectrl to update the misc partition to communicate
+with the bootloader.
+
+There is also an [API in Device Policy Manager] that allows the device admin
+to enable or disable MTE under certain circumstances.
+
+The device can opt in or out of these APIs by a set of system properties:
+
+* `ro.arm64.memtag.bootctl_supported`: the system property API is supported,
+ and an option is displayed in Developer Options.
+* `ro.arm64.memtag.bootctl_settings_toggle`: an option is displayed in the
+ normal settings. This requires `ro.arm64.memtag.bootctl_supported` to be
+ true. This implies `ro.arm64.memtag.bootctl_device_policy_manager`, if it
+ is not explicitely set.
+* `ro.arm64.memtag.bootctl_device_policy_manager`: the Device Policy Manager
+ API is supported.
+
+## Permissive MTE
+
+Permissive MTE refers to a mode which, instead of crashing the process on an
+MTE fault, records a tombstone but then continues execution of the process.
+An important caveat is that system calls with invalid pointers (where the
+pointer tag does not match the memory tag) still return an error code.
+
+This mode is only available for system services, not apps. It is implemented
+in the [debugger\_signal\_handler] by disabling MTE for the faulting thread.
+Optionally, the user can ask for MTE to be re-enabled after some time.
+This is achieved by arming a timer that calls [enable_mte_signal_handler]
+upon expiry.
+
+## MTE Mode Upgrade
+
+When a system service [crashes in ASYNC mode], we set an impossible signal
+as an exit code (because that signal is always gracefully handled by libc),
+and [in init] we set `BIONIC_MEMTAG_UPGRADE_SECS`, which gets handled by
+[libc startup].
+
+[SpecializeCommon]: https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp?q=f:frameworks%2Fbase%2Fcore%2Fjni%2Fcom_android_internal_os_Zygote.cpp%20%22%20mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL,%22&ss=android%2Fplatform%2Fsuperproject%2Fmain
+[LLVM Project]: https://github.com/llvm/llvm-project/
+[NDK]: https://android.googlesource.com/platform/ndk/
+[NDK legacy cmake toolchain]: https://android.googlesource.com/platform/ndk/+/refs/heads/main/build/cmake/android-legacy.toolchain.cmake#490
+[NDK new cmake toolchain]: https://android.googlesource.com/platform/ndk/+/refs/heads/main/build/cmake/flags.cmake#56
+[Soong]: https://cs.android.com/android/platform/superproject/main/+/main:build/soong/cc/sanitize.go?q=sanitize.go&ss=android%2Fplatform%2Fsuperproject%2Fmain
+[decideTaggingLevel]: https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/com/android/internal/os/Zygote.java?q=symbol:decideTaggingLevel
+[picked up by libc init]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/libc_init_mte.cpp?q=symbol:__get_tagging_level%20f:bionic
+[enables all three]: https://github.com/llvm/llvm-project/blob/e732d1ce86783b1d7fe30645fcb30434109505b9/clang/include/clang/Basic/Sanitizers.def#L62
+[passed in]: https://github.com/llvm/llvm-project/blob/ff2e619dfcd77328812a42d2ba2b11c3ff96f410/clang/lib/Driver/SanitizerArgs.cpp#L719
+[passed in by the clang driver]: https://github.com/llvm/llvm-project/blob/ff2e619dfcd77328812a42d2ba2b11c3ff96f410/clang/lib/Driver/ToolChains/CommonArgs.cpp#L1595
+[adding the Android-specific ELF note]: https://github.com/llvm/llvm-project/blob/435cb0dc5eca08cdd8d9ed0d887fa1693cc2bf33/lld/ELF/Driver.cpp#L1258
+[ELF standard]: https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#6dynamic-section
+[add appropriate dynamic sections]: https://github.com/llvm/llvm-project/blob/7022498ac2f236e411e8a0f9a48669e754000a4b/lld/ELF/SyntheticSections.cpp#L1473
+[storeTags]: https://cs.android.com/android/platform/superproject/main/+/main:external/scudo/standalone/memtag.h?q=f:scudo%20f:memtag.h%20function:storeTags
+[SAC page on MTE]: https://source.android.com/docs/security/test/memory-safety/arm-mte
+[NDK page on MTE]: https://developer.android.com/ndk/guides/arm-mte
+[AArch64StackTagging]: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
+[scudo's memtag.h]: https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/scudo/standalone/memtag.h
+[combined.h]: https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/scudo/standalone/combined.h
+[secondary.h]: https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/scudo/standalone/secondary.h
+[__pthread_internal_remap_stack_with_mte]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/pthread_internal.cpp?q=__pthread_internal_remap_stack_with_mte
+[stack script]: https://cs.android.com/android/platform/superproject/main/+/main:development/scripts/stack?q=stack
+[Android make]: https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/config_sanitizers.mk
+[store a function pointer]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/libc_init_dynamic.cpp;l=168?q=memtag_stack_dlopen_callback
+[tombstone\_proto.cpp]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/debuggerd/libdebuggerd/tombstone_proto.cpp?q=tombstone_proto.cpp
+[tombstone\_proto\_to\_text.cpp]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+[SAC MTE bootloader support]: https://source.android.com/docs/security/test/memory-safety/bootloader-support
+[system/extras/mtectrl]: https://cs.android.com/android/platform/superproject/main/+/main:system/extras/mtectrl/
+[API in Device Policy Manager]: https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/admin/DevicePolicyManager.java?q=symbol:setMtePolicy%20f:DevicePolicyManager.java
+[debuggerd\_signal_handler]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/debuggerd/handler/debuggerd_handler.cpp?q=f:debuggerd_handler.cpp%20symbol:debuggerd_signal_handler
+[enable_mte_signal_handler]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/libc_init_mte.cpp?q=symbol:__enable_mte_signal_handler
+[in init]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/init/service.cpp?q=f:system%2Fcore%2Finit%2Fservice.cpp%20should_upgrade_mte
+[crashes in ASYNC mode]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/debuggerd/handler/debuggerd_handler.cpp;l=799?q=BIONIC_SIGNAL_ART_PROFILER
+[libc startup]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/libc_init_mte.cpp?q=BIONIC_MEMTAG_UPGRADE_SECS
diff --git a/docs/status.md b/docs/status.md
index 7ebd195..e7111d9 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -32,10 +32,14 @@
* `ualarm`
Missing functionality:
- * `<aio.h>`
+ * `<aio.h>`. No particular reason not to have this other than that no-one's
+ needed it yet, and it's relatively complex. If/when llvm-libc adds this,
+ maybe we'll just reuse that.
* `<monetary.h>`. See
[discussion](https://github.com/android/ndk/issues/1182).
- * `<wordexp.h>`
+ * `<wordexp.h>`. Unsafe because it passes user input to the shell (!),
+ and often should just be a call to glob() anyway. See also
+ [OpenBSD's discussion about adding wordexp()](https://www.mail-archive.com/tech@openbsd.org/msg02325.html).
* Locales. Although bionic contains the various `_l()` functions, the only
locale supported is a UTF-8 C/POSIX locale. Most of the POSIX APIs are
insufficient to support the wide range of languages used by Android users,
@@ -55,6 +59,12 @@
Current libc symbols: https://android.googlesource.com/platform/bionic/+/main/libc/libc.map.txt
+New libc functions in API level 36:
+ * `qsort_r`, `sig2str`/`str2sig` (POSIX Issue 8 additions).
+ * GNU/BSD extension `lchmod`.
+ * GNU extensions `pthread_getaffinity_np`/`pthread_setaffinity_np`.
+ * New system call wrapper: `mseal` (`<sys/mman.h>`).
+
New libc functions in V (API level 35):
* New `android_crash_detail_register`, `android_crash_detail_unregister`,
`android_crash_detail_replace_name`, and `android_crash_detail_replace_data`
diff --git a/libc/Android.bp b/libc/Android.bp
index 7788a48..007dab0 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -264,6 +264,7 @@
name: "libc_init_static",
defaults: ["libc_defaults"],
srcs: [
+ "bionic/libc_init_mte.cpp",
"bionic/libc_init_static.cpp",
":elf_note_sources",
],
@@ -353,7 +354,6 @@
"-Wno-unused-parameter",
"-include netbsd-compat.h",
"-Wframe-larger-than=66000",
- "-include private/bsd_sys_param.h",
],
local_include_dirs: [
@@ -389,6 +389,7 @@
"upstream-freebsd/lib/libc/stdlib/hdestroy_r.c",
"upstream-freebsd/lib/libc/stdlib/hsearch_r.c",
"upstream-freebsd/lib/libc/stdlib/qsort.c",
+ "upstream-freebsd/lib/libc/stdlib/qsort_r.c",
"upstream-freebsd/lib/libc/stdlib/quick_exit.c",
"upstream-freebsd/lib/libc/string/wcpcpy.c",
"upstream-freebsd/lib/libc/string/wcpncpy.c",
@@ -417,20 +418,6 @@
"upstream-freebsd/lib/libc/string/wmemmove.c",
"upstream-freebsd/lib/libc/string/wmemset.c",
],
- arch: {
- x86: {
- exclude_srcs: [
- "upstream-freebsd/lib/libc/string/wcschr.c",
- "upstream-freebsd/lib/libc/string/wcscmp.c",
- "upstream-freebsd/lib/libc/string/wcslen.c",
- "upstream-freebsd/lib/libc/string/wcsrchr.c",
- "upstream-freebsd/lib/libc/string/wmemcmp.c",
- "upstream-freebsd/lib/libc/string/wcscat.c",
- "upstream-freebsd/lib/libc/string/wcscpy.c",
- "upstream-freebsd/lib/libc/string/wmemcmp.c",
- ],
- },
- },
cflags: [
"-Wno-sign-compare",
@@ -484,7 +471,6 @@
"upstream-netbsd/lib/libc/regex/regerror.c",
"upstream-netbsd/lib/libc/regex/regexec.c",
"upstream-netbsd/lib/libc/regex/regfree.c",
- "upstream-netbsd/lib/libc/stdlib/bsearch.c",
"upstream-netbsd/lib/libc/stdlib/drand48.c",
"upstream-netbsd/lib/libc/stdlib/erand48.c",
"upstream-netbsd/lib/libc/stdlib/jrand48.c",
@@ -570,7 +556,6 @@
"upstream-openbsd/lib/libc/stdio/fgetwc.c",
"upstream-openbsd/lib/libc/stdio/fgetws.c",
"upstream-openbsd/lib/libc/stdio/flags.c",
- "upstream-openbsd/lib/libc/stdio/fpurge.c",
"upstream-openbsd/lib/libc/stdio/fputwc.c",
"upstream-openbsd/lib/libc/stdio/fputws.c",
"upstream-openbsd/lib/libc/stdio/fvwrite.c",
@@ -624,10 +609,12 @@
"upstream-openbsd/lib/libc/string/wcslcpy.c",
"upstream-openbsd/lib/libc/string/wcswidth.c",
- // This file is originally from OpenBSD, and benefits from
- // being compiled with openbsd-compat.h.
- // TODO: clean this up instead.
+ // These files are originally from OpenBSD,
+ // and benefit from being compiled with openbsd-compat.h.
+ // TODO: clean them up instead.
"bionic/fts.c",
+ "stdio/vfprintf.cpp",
+ "stdio/vfwprintf.cpp",
],
// Each architecture has optimized versions of some routines,
@@ -635,11 +622,7 @@
arch: {
arm: {
srcs: [
- "upstream-openbsd/lib/libc/string/memchr.c",
- "upstream-openbsd/lib/libc/string/memrchr.c",
"upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strlcat.c",
- "upstream-openbsd/lib/libc/string/strlcpy.c",
"upstream-openbsd/lib/libc/string/strncat.c",
"upstream-openbsd/lib/libc/string/strncmp.c",
"upstream-openbsd/lib/libc/string/strncpy.c",
@@ -649,18 +632,13 @@
srcs: [
"upstream-openbsd/lib/libc/string/strcat.c",
"upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strlcat.c",
- "upstream-openbsd/lib/libc/string/strlcpy.c",
"upstream-openbsd/lib/libc/string/strncat.c",
"upstream-openbsd/lib/libc/string/strncpy.c",
],
},
riscv64: {
srcs: [
- "upstream-openbsd/lib/libc/string/memrchr.c",
"upstream-openbsd/lib/libc/string/stpncpy.c",
- "upstream-openbsd/lib/libc/string/strlcat.c",
- "upstream-openbsd/lib/libc/string/strlcpy.c",
],
},
x86: {
@@ -670,10 +648,7 @@
},
x86_64: {
srcs: [
- "upstream-openbsd/lib/libc/string/memchr.c",
- "upstream-openbsd/lib/libc/string/memrchr.c",
- "upstream-openbsd/lib/libc/string/strlcat.c",
- "upstream-openbsd/lib/libc/string/strlcpy.c",
+ // x86_64 has custom/llvm-libc implementations of all of these.
],
},
},
@@ -686,9 +661,11 @@
local_include_dirs: [
"private",
- "upstream-openbsd/android/include",
"stdio",
- "upstream-openbsd/lib/libc/include",
+ "upstream-openbsd/android/include/",
+ "upstream-openbsd/lib/libc/gdtoa/",
+ "upstream-openbsd/lib/libc/include/",
+ "upstream-openbsd/lib/libc/stdio/",
],
name: "libc_openbsd",
@@ -698,8 +675,6 @@
name: "libc_openbsd_large_stack",
defaults: ["libc_defaults"],
srcs: [
- "stdio/vfprintf.cpp",
- "stdio/vfwprintf.cpp",
"upstream-openbsd/lib/libc/string/memmem.c",
"upstream-openbsd/lib/libc/string/strstr.c",
],
@@ -710,11 +685,7 @@
],
local_include_dirs: [
- "private",
"upstream-openbsd/android/include/",
- "upstream-openbsd/lib/libc/gdtoa/",
- "upstream-openbsd/lib/libc/include/",
- "upstream-openbsd/lib/libc/stdio/",
],
}
@@ -915,6 +886,7 @@
"bionic/isatty.cpp",
"bionic/killpg.cpp",
"bionic/langinfo.cpp",
+ "bionic/lchmod.cpp",
"bionic/lchown.cpp",
"bionic/lfs64_support.cpp",
"bionic/libc_init_common.cpp",
@@ -956,6 +928,7 @@
"bionic/pthread_detach.cpp",
"bionic/pthread_equal.cpp",
"bionic/pthread_exit.cpp",
+ "bionic/pthread_getaffinity.cpp",
"bionic/pthread_getcpuclockid.cpp",
"bionic/pthread_getschedparam.cpp",
"bionic/pthread_gettid_np.cpp",
@@ -969,6 +942,7 @@
"bionic/pthread_sigqueue.cpp",
"bionic/pthread_self.cpp",
"bionic/pthread_setname_np.cpp",
+ "bionic/pthread_setaffinity.cpp",
"bionic/pthread_setschedparam.cpp",
"bionic/pthread_spinlock.cpp",
"bionic/ptrace.cpp",
@@ -1031,7 +1005,6 @@
"bionic/thread_private.cpp",
"bionic/threads.cpp",
"bionic/time.cpp",
- "bionic/time_l.cpp",
"bionic/tmpfile.cpp",
"bionic/umount.cpp",
"bionic/unlink.cpp",
@@ -1109,11 +1082,6 @@
"arch-arm/krait/bionic/memset.S",
"arch-arm/kryo/bionic/memcpy.S",
-
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.cpp",
- "bionic/strrchr.cpp",
],
},
arm64: {
@@ -1151,25 +1119,6 @@
"arch-riscv64/string/strncmp_v.S",
"arch-riscv64/string/strncpy_v.S",
"arch-riscv64/string/strnlen_v.S",
-
- "arch-riscv64/string/memchr.c",
- "arch-riscv64/string/memcmp.c",
- "arch-riscv64/string/memcpy.c",
- "arch-riscv64/string/memmove.c",
- "arch-riscv64/string/memset.c",
- "arch-riscv64/string/stpcpy.c",
- "arch-riscv64/string/strcat.c",
- "arch-riscv64/string/strchr.c",
- "arch-riscv64/string/strcmp.c",
- "arch-riscv64/string/strcpy.c",
- "arch-riscv64/string/strlen.c",
- "arch-riscv64/string/strncat.c",
- "arch-riscv64/string/strncmp.c",
- "arch-riscv64/string/strncpy.c",
- "arch-riscv64/string/strnlen.c",
-
- "bionic/strchrnul.cpp",
- "bionic/strrchr.cpp",
],
},
@@ -1183,55 +1132,21 @@
"arch-x86/bionic/vfork.S",
"arch-x86/bionic/__x86.get_pc_thunk.S",
- "arch-x86/generic/string/memcmp.S",
- "arch-x86/generic/string/strcmp.S",
- "arch-x86/generic/string/strncmp.S",
- "arch-x86/generic/string/strcat.S",
-
- "arch-x86/generic/string/strlcat.c",
- "arch-x86/generic/string/strlcpy.c",
- "arch-x86/generic/string/strncat.c",
- "arch-x86/generic/string/wcscat.c",
- "arch-x86/generic/string/wcscpy.c",
- "arch-x86/generic/string/wmemcmp.c",
-
- "arch-x86/string/sse2-memchr-atom.S",
"arch-x86/string/sse2-memmove-slm.S",
- "arch-x86/string/sse2-memrchr-atom.S",
- "arch-x86/string/sse2-memset-atom.S",
"arch-x86/string/sse2-memset-slm.S",
"arch-x86/string/sse2-stpcpy-slm.S",
"arch-x86/string/sse2-stpncpy-slm.S",
- "arch-x86/string/sse2-strchr-atom.S",
"arch-x86/string/sse2-strcpy-slm.S",
"arch-x86/string/sse2-strlen-slm.S",
"arch-x86/string/sse2-strncpy-slm.S",
- "arch-x86/string/sse2-strnlen-atom.S",
- "arch-x86/string/sse2-strrchr-atom.S",
- "arch-x86/string/sse2-wcschr-atom.S",
- "arch-x86/string/sse2-wcsrchr-atom.S",
- "arch-x86/string/sse2-wcslen-atom.S",
- "arch-x86/string/sse2-wcscmp-atom.S",
- "arch-x86/string/sse2-strlen-atom.S",
"arch-x86/string/ssse3-memcmp-atom.S",
- "arch-x86/string/ssse3-memmove-atom.S",
"arch-x86/string/ssse3-strcat-atom.S",
"arch-x86/string/ssse3-strcmp-atom.S",
- "arch-x86/string/ssse3-strcpy-atom.S",
- "arch-x86/string/ssse3-strlcat-atom.S",
- "arch-x86/string/ssse3-strlcpy-atom.S",
"arch-x86/string/ssse3-strncat-atom.S",
"arch-x86/string/ssse3-strncmp-atom.S",
- "arch-x86/string/ssse3-strncpy-atom.S",
- "arch-x86/string/ssse3-wcscat-atom.S",
- "arch-x86/string/ssse3-wcscpy-atom.S",
- "arch-x86/string/ssse3-wmemcmp-atom.S",
"arch-x86/string/sse4-memcmp-slm.S",
- "arch-x86/string/sse4-wmemcmp-slm.S",
-
- "bionic/strchrnul.cpp",
],
},
x86_64: {
@@ -1256,11 +1171,6 @@
"arch-x86_64/string/sse4-memcmp-slm.S",
"arch-x86_64/string/ssse3-strcmp-slm.S",
"arch-x86_64/string/ssse3-strncmp-slm.S",
-
- "bionic/strchr.cpp",
- "bionic/strchrnul.cpp",
- "bionic/strnlen.cpp",
- "bionic/strrchr.cpp",
],
},
},
@@ -1279,6 +1189,7 @@
generated_headers: ["generated_android_ids"],
whole_static_libs: [
+ "//external/llvm-libc:llvmlibc",
"libsystemproperties",
],
@@ -1415,43 +1326,13 @@
}
// ========================================================
-// libc_static_dispatch.a --- libc.a ifuncs
+// libc_static_dispatch.a/libc_dynamic_dispatch.a --- string/memory "ifuncs"
+// (Actually ifuncs for libc.so, but a home-grown alternative for libc.a.)
// ========================================================
-cc_library_static {
+
+cc_defaults {
+ name: "libc_dispatch_defaults",
defaults: ["libc_defaults"],
- name: "libc_static_dispatch",
-
- arch: {
- x86_64: {
- srcs: ["arch-x86_64/static_function_dispatch.S"],
- },
- x86: {
- srcs: ["arch-x86/static_function_dispatch.S"],
- },
- arm: {
- srcs: ["arch-arm/static_function_dispatch.S"],
- },
- arm64: {
- srcs: ["arch-arm64/static_function_dispatch.S"],
- },
- riscv64: {
- srcs: ["arch-riscv64/static_function_dispatch.S"],
- },
- },
-}
-
-// ========================================================
-// libc_dynamic_dispatch.a --- libc.so ifuncs
-// ========================================================
-cc_library_static {
- defaults: ["libc_defaults"],
- name: "libc_dynamic_dispatch",
-
- cflags: [
- "-ffreestanding",
- "-fno-stack-protector",
- "-fno-jump-tables",
- ],
arch: {
x86_64: {
srcs: ["arch-x86_64/dynamic_function_dispatch.cpp"],
@@ -1465,10 +1346,31 @@
arm64: {
srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
},
- riscv64: {
- srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"],
- },
},
+ // Prevent the compiler from inserting calls to libc/taking the address of
+ // a jump table from within an ifunc (or, in the static case, code that
+ // can be executed arbitrarily early).
+ cflags: [
+ "-ffreestanding",
+ "-fno-stack-protector",
+ "-fno-jump-tables",
+ ],
+}
+
+cc_library_static {
+ name: "libc_static_dispatch",
+ defaults: ["libc_dispatch_defaults"],
+ cflags: [
+ "-DBIONIC_STATIC_DISPATCH",
+ ],
+}
+
+cc_library_static {
+ name: "libc_dynamic_dispatch",
+ defaults: ["libc_dispatch_defaults"],
+ cflags: [
+ "-DBIONIC_DYNAMIC_DISPATCH",
+ ],
}
// ========================================================
@@ -1537,6 +1439,7 @@
srcs: [
"arch-common/bionic/crtbegin_so.c",
"arch-common/bionic/crtbrand.S",
+ "bionic/android_mallopt.cpp",
"bionic/gwp_asan_wrappers.cpp",
"bionic/heap_tagging.cpp",
"bionic/icu.cpp",
@@ -1555,6 +1458,7 @@
filegroup {
name: "libc_sources_static",
srcs: [
+ "bionic/android_mallopt.cpp",
"bionic/gwp_asan_wrappers.cpp",
"bionic/heap_tagging.cpp",
"bionic/icu_static.cpp",
@@ -1665,7 +1569,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
@@ -1695,8 +1598,7 @@
llndk: {
symbol_file: "libc.map.txt",
export_headers_as_system: true,
- export_preprocessed_headers: ["include"],
- export_llndk_headers: ["libc_llndk_headers"],
+ export_llndk_headers: ["libc_headers"],
},
}
@@ -1723,8 +1625,12 @@
},
native_bridge_supported: false,
// It is never correct to depend on this directly. This is only
- // needed for the runtime apex, and in base_system.mk.
- visibility: ["//bionic/apex"],
+ // needed for the runtime apex, and in base_system.mk, and system_image_defaults
+ // which is default module for soong-defined system image.
+ visibility: [
+ "//bionic/apex",
+ "//visibility:any_system_partition",
+ ],
}
genrule {
@@ -1807,9 +1713,10 @@
}
cc_library_headers {
- name: "libc_llndk_headers",
+ name: "libc_uapi_headers",
visibility: [
"//external/musl",
+ "//external/rust/crates/v4l2r/android",
],
llndk: {
llndk_headers: true,
@@ -1902,13 +1809,13 @@
target: {
android: {
export_system_include_dirs: ["include"],
- header_libs: ["libc_llndk_headers"],
- export_header_lib_headers: ["libc_llndk_headers"],
+ header_libs: ["libc_uapi_headers"],
+ export_header_lib_headers: ["libc_uapi_headers"],
},
linux_bionic: {
export_system_include_dirs: ["include"],
- header_libs: ["libc_llndk_headers"],
- export_header_lib_headers: ["libc_llndk_headers"],
+ header_libs: ["libc_uapi_headers"],
+ export_header_lib_headers: ["libc_uapi_headers"],
},
},
}
@@ -2045,15 +1952,6 @@
cc_defaults {
name: "crt_so_defaults",
defaults: ["crt_defaults"],
-
- arch: {
- x86: {
- cflags: ["-fPIC"],
- },
- x86_64: {
- cflags: ["-fPIC"],
- },
- },
stl: "none",
}
@@ -2193,6 +2091,7 @@
// async_safe_fatal_va_list
cc_library_static {
name: "librust_baremetal",
+ defaults: ["cc_baremetal_defaults"],
header_libs: ["libc_headers"],
include_dirs: [
"bionic/libc/async_safe/include",
@@ -2219,6 +2118,7 @@
},
},
whole_static_libs: [
+ "//external/llvm-libc:llvmlibc",
"libarm-optimized-routines-mem",
"libc_netbsd",
],
@@ -2226,19 +2126,31 @@
nocrt: true,
stl: "none",
visibility: [
- "//packages/modules/Virtualization/vmbase",
+ "//packages/modules/Virtualization/libs/libvmbase",
],
+
+ // b/358211032: This library gets linked into a rust rlib. Disable LTO
+ // until cross-language lto is supported.
+ lto: {
+ never: true,
+ },
}
// ========================================================
// NDK headers.
// ========================================================
-versioned_ndk_headers {
+ndk_headers {
name: "common_libc",
from: "include",
to: "",
+ srcs: ["include/**/*.h"],
license: "NOTICE",
+ // These don't pass the bad verification we do because many of them are
+ // arch-specific, and they aren't necessarily independently includable.
+ // That's not much of a problem though, since C-incompaitibilities in the
+ // UAPI headers should run into problems long before they reach us.
+ skip_verification: true,
}
ndk_headers {
@@ -2258,6 +2170,7 @@
"kernel/uapi/xen/**/*.h",
],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2274,6 +2187,7 @@
to: "scsi",
srcs: ["kernel/android/scsi/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2282,6 +2196,7 @@
to: "arm-linux-androideabi",
srcs: ["kernel/uapi/asm-arm/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2290,6 +2205,7 @@
to: "aarch64-linux-android",
srcs: ["kernel/uapi/asm-arm64/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2298,6 +2214,7 @@
to: "riscv64-linux-android",
srcs: ["kernel/uapi/asm-riscv/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2306,6 +2223,7 @@
to: "i686-linux-android",
srcs: ["kernel/uapi/asm-x86/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2314,23 +2232,13 @@
to: "x86_64-linux-android",
srcs: ["kernel/uapi/asm-x86/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_library {
name: "libc",
symbol_file: "libc.map.txt",
first_version: "9",
- export_header_libs: [
- "common_libc",
- "libc_uapi",
- "libc_kernel_android_uapi_linux",
- "libc_kernel_android_scsi",
- "libc_asm_arm",
- "libc_asm_arm64",
- "libc_asm_riscv64",
- "libc_asm_x86",
- "libc_asm_x86_64",
- ],
}
ndk_library {
@@ -2360,6 +2268,9 @@
"-E",
"-Wall",
"-Werror",
+ // Soong implicitly adds a -c argument that we override with -E.
+ // Suppress Clang's error about the unused -c argument.
+ "-Wno-unused-command-line-argument",
"-nostdinc",
],
}
@@ -2980,13 +2891,6 @@
},
}
-// headers that will be placed on the include path when running versioner in bazel
-// this module should be a no-op in soong
-filegroup {
- name: "versioner-dependencies",
- srcs: ["versioner-dependencies/**/*"],
-}
-
filegroup {
name: "linux_capability_header",
srcs: ["kernel/uapi/linux/capability.h"],
diff --git a/libc/NOTICE b/libc/NOTICE
index 1a84d3c..88d022f 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -3585,22 +3585,6 @@
-------------------------------------------------------------------
-Copyright (c) 2007 Todd C. Miller <millert@openbsd.org>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
Copyright (c) 2007-2008 Michael G Schwern
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
@@ -3862,36 +3846,6 @@
-------------------------------------------------------------------
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
Permission to use, copy, modify, and distribute this software for any
@@ -3937,36 +3891,6 @@
-------------------------------------------------------------------
-Copyright (c) 2011, 2012, 2013 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (c) 2011, Intel Corporation
All rights reserved.
@@ -4790,40 +4714,6 @@
SPDX-License-Identifier: BSD-3-Clause
-Copyright (c) 1990, 1993
- The Regents of the University of California. All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Mike Hibler and Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-SPDX-License-Identifier: BSD-3-Clause
-
Copyright (c) 1992, 1993
The Regents of the University of California. All rights reserved.
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index a8c70e5..8c5572e 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -65,7 +65,7 @@
int tgkill(pid_t tgid, pid_t tid, int sig) all
void* __brk:brk(void*) all
-int __execve:execve(const char*, char* const*, char* const*) all
+int execve(const char*, char* const*, char* const*) all
int __ptrace:ptrace(int request, int pid, void* addr, void* data) all
# <sys/resource.h>
@@ -88,7 +88,6 @@
int setregid:setregid(gid_t, gid_t) lp64
int chroot(const char*) all
int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long) all
-long __arch_prctl:arch_prctl(int, unsigned long) x86_64
int capget(cap_user_header_t header, cap_user_data_t data) all
int capset(cap_user_header_t header, const cap_user_data_t data) all
int sigaltstack(const stack_t*, stack_t*) all
@@ -126,6 +125,7 @@
int mlock2(const void* addr, size_t len, int flags) all
int munlock(const void* addr, size_t len) all
int mlockall(int flags) all
+int mseal(void*, size_t, unsigned long) lp64
int munlockall() all
int mincore(void* start, size_t length, unsigned char* vec) all
int __ioctl:ioctl(int, int, void*) all
@@ -330,7 +330,7 @@
int __eventfd:eventfd2(unsigned int, int) all
-void __exit_group:exit_group(int) all
+void _exit|_Exit:exit_group(int) all
void __exit:exit(int) all
int inotify_init1(int) all
@@ -350,7 +350,7 @@
int setdomainname(const char*, size_t) all
int sethostname(const char*, size_t) all
-int __sync_file_range:sync_file_range(int, off64_t, off64_t, unsigned int) x86,lp64
+int sync_file_range(int, off64_t, off64_t, unsigned int) x86,lp64
int __sync_file_range2:sync_file_range2(int, unsigned int, off64_t, off64_t) arm
pid_t wait4(pid_t, int*, int, struct rusage*) all
@@ -365,6 +365,7 @@
# x86-specific
int __set_thread_area:set_thread_area(void*) x86
+long arch_prctl(int, unsigned long) x86_64
# vdso stuff.
int __clock_getres:clock_getres(clockid_t, struct timespec*) all
diff --git a/libc/arch-arm/dynamic_function_dispatch.cpp b/libc/arch-arm/dynamic_function_dispatch.cpp
index 1d2f38f..f984421 100644
--- a/libc/arch-arm/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm/dynamic_function_dispatch.cpp
@@ -27,27 +27,26 @@
*/
#include <fcntl.h>
-#include <sys/syscall.h>
-
#include <private/bionic_ifuncs.h>
+#include <sys/syscall.h>
extern "C" {
enum CpuVariant {
- kUnknown = 0,
- kGeneric,
- kCortexA7,
- kCortexA9,
- kCortexA53,
- kCortexA55,
- kKrait,
- kKryo,
+ kUnknown = 0,
+ kGeneric,
+ kCortexA7,
+ kCortexA9,
+ kCortexA53,
+ kCortexA55,
+ kKrait,
+ kKryo,
};
static constexpr int MAX_CPU_NAME_LEN = 12;
struct CpuVariantNames {
- alignas(alignof(int)) char name[MAX_CPU_NAME_LEN];
- CpuVariant variant;
+ alignas(alignof(int)) char name[MAX_CPU_NAME_LEN];
+ CpuVariant variant;
};
static constexpr CpuVariantNames cpu_variant_names[] = {
@@ -66,227 +65,237 @@
};
static long ifunc_open(const char* pathname) {
- register long r0 __asm__("r0") = AT_FDCWD;
- register long r1 __asm__("r1") = reinterpret_cast<long>(pathname);
- register long r2 __asm__("r2") = O_RDONLY;
- register long r3 __asm__("r3") = 0;
- register long r7 __asm__("r7") = __NR_openat;
- __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r7));
- return r0;
+ register long r0 __asm__("r0") = AT_FDCWD;
+ register long r1 __asm__("r1") = reinterpret_cast<long>(pathname);
+ register long r2 __asm__("r2") = O_RDONLY;
+ register long r3 __asm__("r3") = 0;
+ register long r7 __asm__("r7") = __NR_openat;
+ __asm__ volatile("swi #0"
+ : "=r"(r0)
+ : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r7));
+ return r0;
}
static ssize_t ifunc_read(int fd, void* buf, size_t count) {
- register long r0 __asm__("r0") = fd;
- register long r1 __asm__("r1") = reinterpret_cast<long>(buf);
- register long r2 __asm__("r2") = count;
- register long r7 __asm__("r7") = __NR_read;
- __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r1), "r"(r2), "r"(r7) : "memory");
- return r0;
+ register long r0 __asm__("r0") = fd;
+ register long r1 __asm__("r1") = reinterpret_cast<long>(buf);
+ register long r2 __asm__("r2") = count;
+ register long r7 __asm__("r7") = __NR_read;
+ __asm__ volatile("swi #0"
+ : "=r"(r0)
+ : "r"(r0), "r"(r1), "r"(r2), "r"(r7)
+ : "memory");
+ return r0;
}
static int ifunc_close(int fd) {
- register long r0 __asm__("r0") = fd;
- register long r7 __asm__("r7") = __NR_close;
- __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r7));
- return r0;
+ register long r0 __asm__("r0") = fd;
+ register long r7 __asm__("r7") = __NR_close;
+ __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r7));
+ return r0;
}
static bool is_same_name(const char* a, const char* b) {
- static_assert(MAX_CPU_NAME_LEN % sizeof(int) == 0, "");
- const int* ia = reinterpret_cast<const int*>(a);
- const int* ib = reinterpret_cast<const int*>(b);
- for (size_t i = 0; i < MAX_CPU_NAME_LEN / sizeof(int); ++i) {
- if (ia[i] != ib[i]) {
- return false;
- }
+ static_assert(MAX_CPU_NAME_LEN % sizeof(int) == 0, "");
+ const int* ia = reinterpret_cast<const int*>(a);
+ const int* ib = reinterpret_cast<const int*>(b);
+ for (size_t i = 0; i < MAX_CPU_NAME_LEN / sizeof(int); ++i) {
+ if (ia[i] != ib[i]) {
+ return false;
}
- return true;
+ }
+ return true;
}
static CpuVariant init_cpu_variant() {
- int fd = ifunc_open("/dev/cpu_variant:arm");
- if (fd < 0) return kGeneric;
+ int fd = ifunc_open("/dev/cpu_variant:arm");
+ if (fd < 0) return kGeneric;
- alignas(alignof(int)) char name[MAX_CPU_NAME_LEN] = {};
+ alignas(alignof(int)) char name[MAX_CPU_NAME_LEN] = {};
- int bytes_read, total_read = 0;
- while (total_read < MAX_CPU_NAME_LEN - 1 &&
- (bytes_read = ifunc_read(fd, name + total_read,
- MAX_CPU_NAME_LEN - 1 - total_read)) > 0) {
- total_read += bytes_read;
- }
- ifunc_close(fd);
+ int bytes_read, total_read = 0;
+ while (total_read < MAX_CPU_NAME_LEN - 1 &&
+ (bytes_read = ifunc_read(fd, name + total_read,
+ MAX_CPU_NAME_LEN - 1 - total_read)) > 0) {
+ total_read += bytes_read;
+ }
+ ifunc_close(fd);
- if (bytes_read != 0) {
- // The file is too big. We haven't reach the end. Or maybe there is an
- // error when reading.
- return kGeneric;
- }
- name[total_read] = 0;
-
- const CpuVariantNames* cpu_variant = cpu_variant_names;
- while (cpu_variant->variant != kUnknown) {
- if (is_same_name(cpu_variant->name, name)) {
- return cpu_variant->variant;
- }
- cpu_variant++;
- }
+ if (bytes_read != 0) {
+ // The file is too big. We haven't reach the end. Or maybe there is an
+ // error when reading.
return kGeneric;
+ }
+ name[total_read] = 0;
+
+ const CpuVariantNames* cpu_variant = cpu_variant_names;
+ while (cpu_variant->variant != kUnknown) {
+ if (is_same_name(cpu_variant->name, name)) {
+ return cpu_variant->variant;
+ }
+ cpu_variant++;
+ }
+ return kGeneric;
}
static CpuVariant get_cpu_variant() {
- static CpuVariant cpu_variant = kUnknown;
- if (cpu_variant == kUnknown) {
- cpu_variant = init_cpu_variant();
- }
- return cpu_variant;
+ static CpuVariant cpu_variant = kUnknown;
+ if (cpu_variant == kUnknown) {
+ cpu_variant = init_cpu_variant();
+ }
+ return cpu_variant;
}
-typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
DEFINE_IFUNC_FOR(memmove) {
- RETURN_FUNC(memmove_func, memmove_a15);
+ RETURN_FUNC(memmove_func_t, memmove_a15);
}
+MEMMOVE_SHIM()
-typedef void* memcpy_func(void*, const void*, size_t);
DEFINE_IFUNC_FOR(memcpy) {
- return memmove_resolver(hwcap);
+ return memmove_resolver(hwcap);
}
+MEMCPY_SHIM()
-typedef void* __memcpy_func(void*, const void*, size_t);
+// On arm32, __memcpy() is not publicly exposed, but gets called by memmove()
+// in cases where the copy is known to be overlap-safe.
+typedef void* __memcpy_func_t(void*, const void*, size_t);
DEFINE_IFUNC_FOR(__memcpy) {
- switch(get_cpu_variant()) {
- case kCortexA7:
- RETURN_FUNC(__memcpy_func, __memcpy_a7);
- case kCortexA9:
- RETURN_FUNC(__memcpy_func, __memcpy_a9);
- case kKrait:
- RETURN_FUNC(__memcpy_func, __memcpy_krait);
- case kCortexA53:
- RETURN_FUNC(__memcpy_func, __memcpy_a53);
- case kCortexA55:
- RETURN_FUNC(__memcpy_func, __memcpy_a55);
- case kKryo:
- RETURN_FUNC(__memcpy_func, __memcpy_kryo);
- default:
- RETURN_FUNC(__memcpy_func, __memcpy_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA7:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_a7);
+ case kCortexA9:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_a9);
+ case kKrait:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_krait);
+ case kCortexA53:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_a53);
+ case kCortexA55:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_a55);
+ case kKryo:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_kryo);
+ default:
+ RETURN_FUNC(__memcpy_func_t, __memcpy_a15);
+ }
}
+DEFINE_STATIC_SHIM(void* __memcpy(void* dst, const void* src, size_t n) {
+ FORWARD(__memcpy)(dst, src, n);
+})
-typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
DEFINE_IFUNC_FOR(__memset_chk) {
- switch(get_cpu_variant()) {
- case kCortexA7:
- case kCortexA53:
- case kCortexA55:
- case kKryo:
- RETURN_FUNC(__memset_chk_func, __memset_chk_a7);
- case kCortexA9:
- RETURN_FUNC(__memset_chk_func, __memset_chk_a9);
- case kKrait:
- RETURN_FUNC(__memset_chk_func, __memset_chk_krait);
- default:
- RETURN_FUNC(__memset_chk_func, __memset_chk_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA7:
+ case kCortexA53:
+ case kCortexA55:
+ case kKryo:
+ RETURN_FUNC(__memset_chk_func_t, __memset_chk_a7);
+ case kCortexA9:
+ RETURN_FUNC(__memset_chk_func_t, __memset_chk_a9);
+ case kKrait:
+ RETURN_FUNC(__memset_chk_func_t, __memset_chk_krait);
+ default:
+ RETURN_FUNC(__memset_chk_func_t, __memset_chk_a15);
+ }
}
+__MEMSET_CHK_SHIM()
-typedef void* memset_func(void* __dst, int __ch, size_t __n);
DEFINE_IFUNC_FOR(memset) {
- switch(get_cpu_variant()) {
- case kCortexA7:
- case kCortexA53:
- case kCortexA55:
- case kKryo:
- RETURN_FUNC(memset_func, memset_a7);
- case kCortexA9:
- RETURN_FUNC(memset_func, memset_a9);
- case kKrait:
- RETURN_FUNC(memset_func, memset_krait);
- default:
- RETURN_FUNC(memset_func, memset_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA7:
+ case kCortexA53:
+ case kCortexA55:
+ case kKryo:
+ RETURN_FUNC(memset_func_t, memset_a7);
+ case kCortexA9:
+ RETURN_FUNC(memset_func_t, memset_a9);
+ case kKrait:
+ RETURN_FUNC(memset_func_t, memset_krait);
+ default:
+ RETURN_FUNC(memset_func_t, memset_a15);
+ }
}
+MEMSET_SHIM()
-typedef char* strcpy_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcpy) {
- switch(get_cpu_variant()) {
- case kCortexA9:
- RETURN_FUNC(strcpy_func, strcpy_a9);
- default:
- RETURN_FUNC(strcpy_func, strcpy_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strcpy_func_t, strcpy_a9);
+ default:
+ RETURN_FUNC(strcpy_func_t, strcpy_a15);
+ }
}
+STRCPY_SHIM()
-typedef char* __strcpy_chk_func(char* dst, const char* src, size_t dst_len);
DEFINE_IFUNC_FOR(__strcpy_chk) {
- switch(get_cpu_variant()) {
- case kCortexA7:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a7);
- case kCortexA9:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a9);
- case kKrait:
- case kKryo:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_krait);
- case kCortexA53:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a53);
- case kCortexA55:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a55);
- default:
- RETURN_FUNC(__strcpy_chk_func, __strcpy_chk_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA7:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_a7);
+ case kCortexA9:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_a9);
+ case kKrait:
+ case kKryo:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_krait);
+ case kCortexA53:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_a53);
+ case kCortexA55:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_a55);
+ default:
+ RETURN_FUNC(__strcpy_chk_func_t, __strcpy_chk_a15);
+ }
}
+__STRCPY_CHK_SHIM()
-typedef char* stpcpy_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(stpcpy) {
- switch(get_cpu_variant()) {
- case kCortexA9:
- RETURN_FUNC(stpcpy_func, stpcpy_a9);
- default:
- RETURN_FUNC(stpcpy_func, stpcpy_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(stpcpy_func_t, stpcpy_a9);
+ default:
+ RETURN_FUNC(stpcpy_func_t, stpcpy_a15);
+ }
}
+STPCPY_SHIM()
-typedef char* strcat_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcat) {
- switch(get_cpu_variant()) {
- case kCortexA9:
- RETURN_FUNC(strcat_func, strcat_a9);
- default:
- RETURN_FUNC(strcat_func, strcat_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strcat_func_t, strcat_a9);
+ default:
+ RETURN_FUNC(strcat_func_t, strcat_a15);
+ }
}
+STRCAT_SHIM()
-typedef char* __strcat_chk_func(char* dst, const char* src, size_t dst_buf_size);
DEFINE_IFUNC_FOR(__strcat_chk) {
- switch(get_cpu_variant()) {
- case kCortexA7:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_a7);
- case kCortexA9:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_a9);
- case kKrait:
- case kKryo:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_krait);
- case kCortexA53:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_a53);
- case kCortexA55:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_a55);
- default:
- RETURN_FUNC(__strcat_chk_func, __strcat_chk_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA7:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_a7);
+ case kCortexA9:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_a9);
+ case kKrait:
+ case kKryo:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_krait);
+ case kCortexA53:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_a53);
+ case kCortexA55:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_a55);
+ default:
+ RETURN_FUNC(__strcat_chk_func_t, __strcat_chk_a15);
+ }
}
+__STRCAT_CHK_SHIM()
-typedef int strcmp_func(const char* __lhs, const char* __rhs);
DEFINE_IFUNC_FOR(strcmp) {
- RETURN_FUNC(strcmp_func, strcmp_a15);
+ RETURN_FUNC(strcmp_func_t, strcmp_a15);
}
+STRCMP_SHIM()
-typedef size_t strlen_func(const char* __s);
DEFINE_IFUNC_FOR(strlen) {
- switch(get_cpu_variant()) {
- case kCortexA9:
- RETURN_FUNC(strlen_func, strlen_a9);
- default:
- RETURN_FUNC(strlen_func, strlen_a15);
- }
+ switch (get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strlen_func_t, strlen_a9);
+ default:
+ RETURN_FUNC(strlen_func_t, strlen_a15);
+ }
}
+STRLEN_SHIM()
} // extern "C"
diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp
index f9e4263..29e47b3 100644
--- a/libc/arch-arm64/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm64/dynamic_function_dispatch.cpp
@@ -28,148 +28,147 @@
#include <private/bionic_ifuncs.h>
#include <stddef.h>
-#include <sys/auxv.h>
static inline bool __bionic_is_oryon(unsigned long hwcap) {
- if (!(hwcap & HWCAP_CPUID)) return false;
+ if (!(hwcap & HWCAP_CPUID)) return false;
- // Extract the implementor and variant bits from MIDR_EL1.
- // https://www.kernel.org/doc/html/latest/arch/arm64/cpu-feature-registers.html#list-of-registers-with-visible-features
- unsigned long midr;
- __asm__ __volatile__("mrs %0, MIDR_EL1" : "=r"(midr));
- uint16_t cpu = (midr >> 20) & 0xfff;
+ // Extract the implementor and variant bits from MIDR_EL1.
+ // https://www.kernel.org/doc/html/latest/arch/arm64/cpu-feature-registers.html#list-of-registers-with-visible-features
+ unsigned long midr;
+ __asm__ __volatile__("mrs %0, MIDR_EL1" : "=r"(midr));
+ uint16_t cpu = (midr >> 20) & 0xfff;
- auto make_cpu = [](unsigned implementor, unsigned variant) {
- return (implementor << 4) | variant;
- };
+ auto make_cpu = [](unsigned implementor, unsigned variant) {
+ return (implementor << 4) | variant;
+ };
- // Check for implementor Qualcomm's variants 0x1..0x5 (Oryon).
- return cpu >= make_cpu('Q', 0x1) && cpu <= make_cpu('Q', 0x5);
+ // Check for implementor Qualcomm's variants 0x1..0x5 (Oryon).
+ return cpu >= make_cpu('Q', 0x1) && cpu <= make_cpu('Q', 0x5);
}
extern "C" {
-typedef void* memchr_func(const void*, int, size_t);
DEFINE_IFUNC_FOR(memchr) {
- if (arg->_hwcap2 & HWCAP2_MTE) {
- RETURN_FUNC(memchr_func, __memchr_aarch64_mte);
- } else {
- RETURN_FUNC(memchr_func, __memchr_aarch64);
- }
-}
-
-typedef int memcmp_func(const void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memcmp) {
- // TODO: enable the SVE version.
- RETURN_FUNC(memcmp_func, __memcmp_aarch64);
-}
-
-typedef void* memcpy_func(void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memcpy) {
- 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);
- } else {
- RETURN_FUNC(memcpy_func, __memcpy_aarch64);
- }
-}
-
-typedef void* memmove_func(void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memmove) {
- 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);
+ if (arg->_hwcap2 & HWCAP2_MTE) {
+ RETURN_FUNC(memchr_func_t, __memchr_aarch64_mte);
} else {
- RETURN_FUNC(memmove_func, __memmove_aarch64);
+ RETURN_FUNC(memchr_func_t, __memchr_aarch64);
}
}
+MEMCHR_SHIM()
-typedef int memrchr_func(const void*, int, size_t);
+DEFINE_IFUNC_FOR(memcmp) {
+ // TODO: enable the SVE version.
+ RETURN_FUNC(memcmp_func_t, __memcmp_aarch64);
+}
+MEMCMP_SHIM()
+
+DEFINE_IFUNC_FOR(memcpy) {
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memcpy_func_t, __memmove_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
+ RETURN_FUNC(memcpy_func_t, __memcpy_aarch64_nt);
+ } else if (arg->_hwcap & HWCAP_ASIMD) {
+ RETURN_FUNC(memcpy_func_t, __memcpy_aarch64_simd);
+ } else {
+ RETURN_FUNC(memcpy_func_t, __memcpy_aarch64);
+ }
+}
+MEMCPY_SHIM()
+
+DEFINE_IFUNC_FOR(memmove) {
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memmove_func_t, __memmove_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
+ RETURN_FUNC(memmove_func_t, __memmove_aarch64_nt);
+ } else if (arg->_hwcap & HWCAP_ASIMD) {
+ RETURN_FUNC(memmove_func_t, __memmove_aarch64_simd);
+ } else {
+ RETURN_FUNC(memmove_func_t, __memmove_aarch64);
+ }
+}
+MEMMOVE_SHIM()
+
DEFINE_IFUNC_FOR(memrchr) {
- RETURN_FUNC(memrchr_func, __memrchr_aarch64);
+ RETURN_FUNC(memrchr_func_t, __memrchr_aarch64);
}
+MEMRCHR_SHIM()
-typedef int memset_func(void*, int, size_t);
DEFINE_IFUNC_FOR(memset) {
- 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);
- }
+ if (arg->_hwcap2 & HWCAP2_MOPS) {
+ RETURN_FUNC(memset_func_t, __memset_aarch64_mops);
+ } else if (__bionic_is_oryon(arg->_hwcap)) {
+ RETURN_FUNC(memset_func_t, __memset_aarch64_nt);
+ } else {
+ RETURN_FUNC(memset_func_t, __memset_aarch64);
+ }
}
+MEMSET_SHIM()
-typedef char* stpcpy_func(char*, const char*, size_t);
DEFINE_IFUNC_FOR(stpcpy) {
- // TODO: enable the SVE version.
- RETURN_FUNC(stpcpy_func, __stpcpy_aarch64);
+ // TODO: enable the SVE version.
+ RETURN_FUNC(stpcpy_func_t, __stpcpy_aarch64);
}
+STPCPY_SHIM()
-typedef char* strchr_func(const char*, int);
DEFINE_IFUNC_FOR(strchr) {
- if (arg->_hwcap2 & HWCAP2_MTE) {
- RETURN_FUNC(strchr_func, __strchr_aarch64_mte);
- } else {
- RETURN_FUNC(strchr_func, __strchr_aarch64);
- }
+ if (arg->_hwcap2 & HWCAP2_MTE) {
+ RETURN_FUNC(strchr_func_t, __strchr_aarch64_mte);
+ } else {
+ RETURN_FUNC(strchr_func_t, __strchr_aarch64);
+ }
}
+STRCHR_SHIM()
-typedef char* strchrnul_func(const char*, int);
DEFINE_IFUNC_FOR(strchrnul) {
- if (arg->_hwcap2 & HWCAP2_MTE) {
- RETURN_FUNC(strchrnul_func, __strchrnul_aarch64_mte);
- } else {
- RETURN_FUNC(strchrnul_func, __strchrnul_aarch64);
- }
+ if (arg->_hwcap2 & HWCAP2_MTE) {
+ RETURN_FUNC(strchrnul_func_t, __strchrnul_aarch64_mte);
+ } else {
+ RETURN_FUNC(strchrnul_func_t, __strchrnul_aarch64);
+ }
}
+STRCHRNUL_SHIM()
-typedef int strcmp_func(const char*, const char*);
DEFINE_IFUNC_FOR(strcmp) {
- // TODO: enable the SVE version.
- RETURN_FUNC(strcmp_func, __strcmp_aarch64);
+ // TODO: enable the SVE version.
+ RETURN_FUNC(strcmp_func_t, __strcmp_aarch64);
}
+STRCMP_SHIM()
-typedef char* strcpy_func(char*, const char*);
DEFINE_IFUNC_FOR(strcpy) {
- // TODO: enable the SVE version.
- RETURN_FUNC(strcpy_func, __strcpy_aarch64);
+ // TODO: enable the SVE version.
+ RETURN_FUNC(strcpy_func_t, __strcpy_aarch64);
}
+STRCPY_SHIM()
-typedef size_t strlen_func(const char*);
DEFINE_IFUNC_FOR(strlen) {
- if (arg->_hwcap2 & HWCAP2_MTE) {
- RETURN_FUNC(strlen_func, __strlen_aarch64_mte);
- } else {
- RETURN_FUNC(strlen_func, __strlen_aarch64);
- }
+ if (arg->_hwcap2 & HWCAP2_MTE) {
+ RETURN_FUNC(strlen_func_t, __strlen_aarch64_mte);
+ } else {
+ RETURN_FUNC(strlen_func_t, __strlen_aarch64);
+ }
}
+STRLEN_SHIM()
-typedef int strncmp_func(const char*, const char*, size_t);
DEFINE_IFUNC_FOR(strncmp) {
- // TODO: enable the SVE version.
- RETURN_FUNC(strncmp_func, __strncmp_aarch64);
+ // TODO: enable the SVE version.
+ RETURN_FUNC(strncmp_func_t, __strncmp_aarch64);
}
+STRNCMP_SHIM()
-typedef size_t strnlen_func(const char*, size_t);
DEFINE_IFUNC_FOR(strnlen) {
- // TODO: enable the SVE version.
- RETURN_FUNC(strnlen_func, __strnlen_aarch64);
+ // TODO: enable the SVE version.
+ RETURN_FUNC(strnlen_func_t, __strnlen_aarch64);
}
+STRNLEN_SHIM()
-typedef char* strrchr_func(const char*, int);
DEFINE_IFUNC_FOR(strrchr) {
- if (arg->_hwcap2 & HWCAP2_MTE) {
- RETURN_FUNC(strrchr_func, __strrchr_aarch64_mte);
- } else {
- RETURN_FUNC(strrchr_func, __strrchr_aarch64);
- }
+ if (arg->_hwcap2 & HWCAP2_MTE) {
+ RETURN_FUNC(strrchr_func_t, __strrchr_aarch64_mte);
+ } else {
+ RETURN_FUNC(strrchr_func_t, __strrchr_aarch64);
+ }
}
+STRRCHR_SHIM()
} // extern "C"
diff --git a/libc/arch-arm64/static_function_dispatch.S b/libc/arch-arm64/static_function_dispatch.S
deleted file mode 100644
index 18c3783..0000000
--- a/libc/arch-arm64/static_function_dispatch.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-#define FUNCTION_DELEGATE(name, impl) \
-ENTRY(name); \
- b impl; \
-END(name)
-
-FUNCTION_DELEGATE(memchr, __memchr_aarch64_mte)
-FUNCTION_DELEGATE(memcmp, __memcmp_aarch64)
-FUNCTION_DELEGATE(memcpy, __memcpy_aarch64)
-FUNCTION_DELEGATE(memmove, __memmove_aarch64)
-FUNCTION_DELEGATE(memrchr, __memrchr_aarch64)
-FUNCTION_DELEGATE(memset, __memset_aarch64)
-FUNCTION_DELEGATE(stpcpy, __stpcpy_aarch64)
-FUNCTION_DELEGATE(strchr, __strchr_aarch64_mte)
-FUNCTION_DELEGATE(strchrnul, __strchrnul_aarch64_mte)
-FUNCTION_DELEGATE(strcmp, __strcmp_aarch64)
-FUNCTION_DELEGATE(strcpy, __strcpy_aarch64)
-FUNCTION_DELEGATE(strlen, __strlen_aarch64_mte)
-FUNCTION_DELEGATE(strrchr, __strrchr_aarch64_mte)
-FUNCTION_DELEGATE(strncmp, __strncmp_aarch64)
-FUNCTION_DELEGATE(strnlen, __strnlen_aarch64)
-
-NOTE_GNU_PROPERTY()
diff --git a/libc/arch-common/bionic/crt_pad_segment.S b/libc/arch-common/bionic/crt_pad_segment.S
index 86c730d..2fbe0b9 100644
--- a/libc/arch-common/bionic/crt_pad_segment.S
+++ b/libc/arch-common/bionic/crt_pad_segment.S
@@ -26,6 +26,12 @@
* SUCH DAMAGE.
*/
+#if defined(__aarch64__)
+#include <private/bionic_asm_arm64.h>
+
+__bionic_asm_custom_note_gnu_section()
+#endif
+
#include <private/bionic_asm_note.h>
.section ".note.android.pad_segment", "a", %note
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
deleted file mode 100644
index bb2ba51..0000000
--- a/libc/arch-riscv64/dynamic_function_dispatch.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <stddef.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-#include <private/bionic_ifuncs.h>
-
-extern "C" {
-
-static inline __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
- register long a0 __asm__("a0") = dir_fd;
- register long a1 __asm__("a1") = reinterpret_cast<long>(path);
- register long a2 __asm__("a2") = mode;
- register long a7 __asm__("a7") = __NR_faccessat;
- __asm__("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a7) : "memory");
- return a0;
-}
-
-static bool have_fast_v() {
- static bool result = []() {
- // We don't want to do a full "bogomips" test, so just check for the
- // presence of a file that would indicate that we're running in qemu.
- return ifunc_faccessat(AT_FDCWD, "/dev/hvc0", F_OK) != 0;
- }();
- return result;
-}
-
-typedef void* memchr_func(const void*, int, size_t);
-DEFINE_IFUNC_FOR(memchr) {
- if (have_fast_v()) RETURN_FUNC(memchr_func, memchr_v);
- RETURN_FUNC(memchr_func, memchr_gc);
-}
-
-typedef int memcmp_func(const void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memcmp) {
- if (have_fast_v()) RETURN_FUNC(memcmp_func, memcmp_v);
- RETURN_FUNC(memcmp_func, memcmp_gc);
-}
-
-typedef void* memcpy_func(void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memcpy) {
- if (have_fast_v()) RETURN_FUNC(memcpy_func, memcpy_v);
- RETURN_FUNC(memcpy_func, memcpy_gc);
-}
-
-typedef void* memmove_func(void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memmove) {
- if (have_fast_v()) RETURN_FUNC(memmove_func, memmove_v);
- RETURN_FUNC(memmove_func, memmove_gc);
-}
-
-typedef void* memset_func(void*, int, size_t);
-DEFINE_IFUNC_FOR(memset) {
- if (have_fast_v()) RETURN_FUNC(memset_func, memset_v);
- RETURN_FUNC(memset_func, memset_gc);
-}
-
-typedef char* stpcpy_func(char*, const char*);
-DEFINE_IFUNC_FOR(stpcpy) {
- if (have_fast_v()) RETURN_FUNC(stpcpy_func, stpcpy_v);
- RETURN_FUNC(stpcpy_func, stpcpy_gc);
-}
-
-typedef char* strcat_func(char*, const char*);
-DEFINE_IFUNC_FOR(strcat) {
- if (have_fast_v()) RETURN_FUNC(strcat_func, strcat_v);
- RETURN_FUNC(strcat_func, strcat_gc);
-}
-
-typedef char* strchr_func(const char*, int);
-DEFINE_IFUNC_FOR(strchr) {
- if (have_fast_v()) RETURN_FUNC(strchr_func, strchr_v);
- RETURN_FUNC(strchr_func, strchr_gc);
-}
-
-typedef int strcmp_func(const char*, const char*);
-DEFINE_IFUNC_FOR(strcmp) {
- if (have_fast_v()) RETURN_FUNC(strcmp_func, strcmp_v);
- RETURN_FUNC(strcmp_func, strcmp_gc);
-}
-
-typedef char* strcpy_func(char*, const char*);
-DEFINE_IFUNC_FOR(strcpy) {
- if (have_fast_v()) RETURN_FUNC(strcpy_func, strcpy_v);
- RETURN_FUNC(strcpy_func, strcpy_gc);
-}
-
-typedef size_t strlen_func(const char*);
-DEFINE_IFUNC_FOR(strlen) {
- if (have_fast_v()) RETURN_FUNC(strlen_func, strlen_v);
- RETURN_FUNC(strlen_func, strlen_gc);
-}
-
-typedef char* strncat_func(char*, const char*, size_t);
-DEFINE_IFUNC_FOR(strncat) {
- if (have_fast_v()) RETURN_FUNC(strncat_func, strncat_v);
- RETURN_FUNC(strncat_func, strncat_gc);
-}
-
-typedef int strncmp_func(const char*, const char*, size_t);
-DEFINE_IFUNC_FOR(strncmp) {
- if (have_fast_v()) RETURN_FUNC(strncmp_func, strncmp_v);
- RETURN_FUNC(strncmp_func, strncmp_gc);
-}
-
-typedef char* strncpy_func(char*, const char*, size_t);
-DEFINE_IFUNC_FOR(strncpy) {
- if (have_fast_v()) RETURN_FUNC(strncpy_func, strncpy_v);
- RETURN_FUNC(strncpy_func, strncpy_gc);
-}
-
-typedef size_t strnlen_func(const char*, size_t);
-DEFINE_IFUNC_FOR(strnlen) {
- if (have_fast_v()) RETURN_FUNC(strnlen_func, strnlen_v);
- RETURN_FUNC(strnlen_func, strnlen_gc);
-}
-
-} // extern "C"
diff --git a/libc/arch-riscv64/static_function_dispatch.S b/libc/arch-riscv64/static_function_dispatch.S
deleted file mode 100644
index accfec8..0000000
--- a/libc/arch-riscv64/static_function_dispatch.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-#define FUNCTION_DELEGATE(name, impl) \
-ENTRY(name); \
- j impl; \
-END(name)
-
-// TODO: switch to the V variants when qemu is fixed.
-FUNCTION_DELEGATE(memchr, memchr_gc)
-FUNCTION_DELEGATE(memcmp, memcmp_gc)
-FUNCTION_DELEGATE(memcpy, memcpy_gc)
-FUNCTION_DELEGATE(memmove, memmove_gc)
-FUNCTION_DELEGATE(memset, memset_gc)
-FUNCTION_DELEGATE(stpcpy, stpcpy_gc)
-FUNCTION_DELEGATE(strcat, strcat_gc)
-FUNCTION_DELEGATE(strchr, strchr_gc)
-FUNCTION_DELEGATE(strcmp, strcmp_gc)
-FUNCTION_DELEGATE(strcpy, strcpy_gc)
-FUNCTION_DELEGATE(strlen, strlen_gc)
-FUNCTION_DELEGATE(strncat, strncat_gc)
-FUNCTION_DELEGATE(strncmp, strncmp_gc)
-FUNCTION_DELEGATE(strncpy, strncpy_gc)
-FUNCTION_DELEGATE(strnlen, strnlen_gc)
diff --git a/libc/arch-riscv64/string/memchr.c b/libc/arch-riscv64/string/memchr.c
deleted file mode 100644
index 34eb6d7..0000000
--- a/libc/arch-riscv64/string/memchr.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define memchr memchr_gc
-#include <upstream-openbsd/lib/libc/string/memchr.c>
diff --git a/libc/arch-riscv64/string/memchr_v.S b/libc/arch-riscv64/string/memchr_v.S
index d4999c3..8833436 100644
--- a/libc/arch-riscv64/string/memchr_v.S
+++ b/libc/arch-riscv64/string/memchr_v.S
@@ -68,7 +68,7 @@
#define vData v0
#define vMask v8
-ENTRY(memchr_v)
+ENTRY(memchr)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -93,4 +93,4 @@
add iResult, pSrc, iTemp
ret
-END(memchr_v)
+END(memchr)
diff --git a/libc/arch-riscv64/string/memcmp.c b/libc/arch-riscv64/string/memcmp.c
deleted file mode 100644
index 2d7335a..0000000
--- a/libc/arch-riscv64/string/memcmp.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-/*
- * Compare memory regions.
- */
-int
-memcmp_gc(const void *s1, const void *s2, size_t n)
-{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
-}
diff --git a/libc/arch-riscv64/string/memcmp_v.S b/libc/arch-riscv64/string/memcmp_v.S
index 55e08db..9c1ecdc 100644
--- a/libc/arch-riscv64/string/memcmp_v.S
+++ b/libc/arch-riscv64/string/memcmp_v.S
@@ -71,7 +71,7 @@
#define vData2 v8
#define vMask v16
-ENTRY(memcmp_v)
+ENTRY(memcmp)
L(loop):
vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -103,4 +103,4 @@
sub iResult, iTemp1, iTemp2
ret
-END(memcmp_v)
+END(memcmp)
diff --git a/libc/arch-riscv64/string/memcpy.c b/libc/arch-riscv64/string/memcpy.c
deleted file mode 100644
index ee11504..0000000
--- a/libc/arch-riscv64/string/memcpy.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define MEMCOPY
-#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memcpy_v.S b/libc/arch-riscv64/string/memcpy_v.S
index 93ec60f..def1d9b 100644
--- a/libc/arch-riscv64/string/memcpy_v.S
+++ b/libc/arch-riscv64/string/memcpy_v.S
@@ -65,7 +65,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memcpy_v)
+ENTRY(memcpy)
mv pDstPtr, pDst
@@ -82,4 +82,4 @@
ret
-END(memcpy_v)
+END(memcpy)
diff --git a/libc/arch-riscv64/string/memmove.c b/libc/arch-riscv64/string/memmove.c
deleted file mode 100644
index e9bb2c2..0000000
--- a/libc/arch-riscv64/string/memmove.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define MEMMOVE
-#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memmove_v.S b/libc/arch-riscv64/string/memmove_v.S
index cad2b05..fa70f76 100644
--- a/libc/arch-riscv64/string/memmove_v.S
+++ b/libc/arch-riscv64/string/memmove_v.S
@@ -67,7 +67,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memmove_v)
+ENTRY(memmove)
mv pDstPtr, pDst
@@ -99,4 +99,4 @@
bnez iNum, L(backward_copy_loop)
ret
-END(memmove_v)
+END(memmove)
diff --git a/libc/arch-riscv64/string/memset.c b/libc/arch-riscv64/string/memset.c
deleted file mode 100644
index d51cbf9..0000000
--- a/libc/arch-riscv64/string/memset.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Hibler and Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-#define wsize sizeof(u_long)
-#define wmask (wsize - 1)
-
-#include <string.h>
-
-#define RETURN return (dst0)
-#define VAL c0
-#define WIDEVAL c
-
-void *
-memset_gc(void *dst0, int c0, size_t length)
-{
- size_t t;
- u_long c;
- u_char *dst;
-
- dst = dst0;
- /*
- * If not enough words, just fill bytes. A length >= 2 words
- * guarantees that at least one of them is `complete' after
- * any necessary alignment. For instance:
- *
- * |-----------|-----------|-----------|
- * |00|01|02|03|04|05|06|07|08|09|0A|00|
- * ^---------------------^
- * dst dst+length-1
- *
- * but we use a minimum of 3 here since the overhead of the code
- * to do word writes is substantial.
- *
- * TODO: This threshold might not be sensible for 64-bit u_long.
- * We should benchmark and revisit this decision.
- */
- if (length < 3 * wsize) {
- while (length != 0) {
- *dst++ = VAL;
- --length;
- }
- RETURN;
- }
-
- if ((c = (u_char)c0) != 0) { /* Fill the word. */
- c = (c << 8) | c; /* u_long is 16 bits. */
- c = (c << 16) | c; /* u_long is 32 bits. */
- c = (c << 32) | c; /* u_long is 64 bits. */
- }
- /* Align destination by filling in bytes. */
- if ((t = (long)dst & wmask) != 0) {
- t = wsize - t;
- length -= t;
- do {
- *dst++ = VAL;
- } while (--t != 0);
- }
-
- /* Fill words. Length was >= 2*words so we know t >= 1 here. */
- t = length / wsize;
- do {
- *(u_long *)(void *)dst = WIDEVAL;
- dst += wsize;
- } while (--t != 0);
-
- /* Mop up trailing bytes, if any. */
- t = length & wmask;
- if (t != 0)
- do {
- *dst++ = VAL;
- } while (--t != 0);
- RETURN;
-}
diff --git a/libc/arch-riscv64/string/memset_v.S b/libc/arch-riscv64/string/memset_v.S
index 06a2c6a..5aa525e 100644
--- a/libc/arch-riscv64/string/memset_v.S
+++ b/libc/arch-riscv64/string/memset_v.S
@@ -66,7 +66,7 @@
#define ELEM_LMUL_SETTING m8
#define vData v0
-ENTRY(memset_v)
+ENTRY(memset)
mv pDstPtr, pDst
@@ -82,4 +82,4 @@
ret
-END(memset_v)
+END(memset)
diff --git a/libc/arch-riscv64/string/stpcpy.c b/libc/arch-riscv64/string/stpcpy.c
deleted file mode 100644
index 2afcf99..0000000
--- a/libc/arch-riscv64/string/stpcpy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define stpcpy stpcpy_gc
-#include <upstream-openbsd/lib/libc/string/stpcpy.c>
diff --git a/libc/arch-riscv64/string/stpcpy_v.S b/libc/arch-riscv64/string/stpcpy_v.S
index 6a853ec..c5d0945 100644
--- a/libc/arch-riscv64/string/stpcpy_v.S
+++ b/libc/arch-riscv64/string/stpcpy_v.S
@@ -68,7 +68,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(stpcpy_v)
+ENTRY(stpcpy)
L(stpcpy_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
vle8ff.v vStr1, (pSrc)
@@ -85,4 +85,4 @@
sub pDstPtr, pDstPtr, iCurrentVL
add pDstPtr, pDstPtr, iActiveElemPos
ret
-END(stpcpy_v)
+END(stpcpy)
diff --git a/libc/arch-riscv64/string/strcat.c b/libc/arch-riscv64/string/strcat.c
deleted file mode 100644
index 5fb1621..0000000
--- a/libc/arch-riscv64/string/strcat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strcat strcat_gc
-#include <upstream-openbsd/lib/libc/string/strcat.c>
diff --git a/libc/arch-riscv64/string/strcat_v.S b/libc/arch-riscv64/string/strcat_v.S
index 3d348e7..5abf295 100644
--- a/libc/arch-riscv64/string/strcat_v.S
+++ b/libc/arch-riscv64/string/strcat_v.S
@@ -69,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcat_v)
+ENTRY(strcat)
mv pDstPtr, pDst
@@ -104,4 +104,4 @@
ret
-END(strcat_v)
+END(strcat)
diff --git a/libc/arch-riscv64/string/strchr.c b/libc/arch-riscv64/string/strchr.c
deleted file mode 100644
index dc07766..0000000
--- a/libc/arch-riscv64/string/strchr.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $OpenBSD: strchr.c,v 1.4 2018/10/01 06:37:37 martijn Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char *
-strchr_gc(const char *p, int ch)
-{
- for (;; ++p) {
- if (*p == (char) ch)
- return((char *)p);
- if (!*p)
- return((char *)NULL);
- }
- /* NOTREACHED */
-}
diff --git a/libc/arch-riscv64/string/strchr_v.S b/libc/arch-riscv64/string/strchr_v.S
index bc7b58a..ea13c5d 100644
--- a/libc/arch-riscv64/string/strchr_v.S
+++ b/libc/arch-riscv64/string/strchr_v.S
@@ -69,7 +69,7 @@
#define vMaskEnd v8
#define vMaskCh v9
-ENTRY(strchr_v)
+ENTRY(strchr)
L(strchr_loop):
vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
@@ -91,4 +91,4 @@
add pStr, pStr, iChOffset
ret
-END(strchr_v)
+END(strchr)
diff --git a/libc/arch-riscv64/string/strcmp.c b/libc/arch-riscv64/string/strcmp.c
deleted file mode 100644
index 7a1fefe..0000000
--- a/libc/arch-riscv64/string/strcmp.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $OpenBSD: strcmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-/*
- * Compare strings.
- */
-int
-strcmp_gc(const char *s1, const char *s2)
-{
- while (*s1 == *s2++)
- if (*s1++ == 0)
- return (0);
- return (*(unsigned char *)s1 - *(unsigned char *)--s2);
-}
diff --git a/libc/arch-riscv64/string/strcmp_v.S b/libc/arch-riscv64/string/strcmp_v.S
index 01e72b1..3332c83 100644
--- a/libc/arch-riscv64/string/strcmp_v.S
+++ b/libc/arch-riscv64/string/strcmp_v.S
@@ -74,7 +74,7 @@
#define vMask1 v16
#define vMask2 v17
-ENTRY(strcmp_v)
+ENTRY(strcmp)
# increase the lmul using the following sequences:
# 1/2, 1/2, 1, 2, 4, 4, 4, ...
@@ -166,4 +166,4 @@
sub iResult, iTemp1, iTemp2
ret
-END(strcmp_v)
+END(strcmp)
diff --git a/libc/arch-riscv64/string/strcpy.c b/libc/arch-riscv64/string/strcpy.c
deleted file mode 100644
index a624541..0000000
--- a/libc/arch-riscv64/string/strcpy.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $OpenBSD: strcpy.c,v 1.10 2017/11/28 06:55:49 tb Exp $ */
-
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char *
-strcpy_gc(char *to, const char *from)
-{
- char *save = to;
-
- for (; (*to = *from) != '\0'; ++from, ++to);
- return(save);
-}
diff --git a/libc/arch-riscv64/string/strcpy_v.S b/libc/arch-riscv64/string/strcpy_v.S
index 084b3a5..b89b1a8 100644
--- a/libc/arch-riscv64/string/strcpy_v.S
+++ b/libc/arch-riscv64/string/strcpy_v.S
@@ -69,7 +69,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strcpy_v)
+ENTRY(strcpy)
mv pDstPtr, pDst
@@ -88,4 +88,4 @@
ret
-END(strcpy_v)
+END(strcpy)
diff --git a/libc/arch-riscv64/string/strlen.c b/libc/arch-riscv64/string/strlen.c
deleted file mode 100644
index ac8d27f..0000000
--- a/libc/arch-riscv64/string/strlen.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $OpenBSD: strlen.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-size_t
-strlen_gc(const char *str)
-{
- const char *s;
-
- for (s = str; *s; ++s)
- ;
- return (s - str);
-}
diff --git a/libc/arch-riscv64/string/strlen_v.S b/libc/arch-riscv64/string/strlen_v.S
index c284021..7f7d2dd 100644
--- a/libc/arch-riscv64/string/strlen_v.S
+++ b/libc/arch-riscv64/string/strlen_v.S
@@ -66,7 +66,7 @@
#define vStr v0
#define vMaskEnd v2
-ENTRY(strlen_v)
+ENTRY(strlen)
mv pCopyStr, pStr
L(loop):
@@ -84,4 +84,4 @@
ret
-END(strlen_v)
+END(strlen)
diff --git a/libc/arch-riscv64/string/strncat.c b/libc/arch-riscv64/string/strncat.c
deleted file mode 100644
index 8c26b95..0000000
--- a/libc/arch-riscv64/string/strncat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncat strncat_gc
-#include <upstream-openbsd/lib/libc/string/strncat.c>
diff --git a/libc/arch-riscv64/string/strncat_v.S b/libc/arch-riscv64/string/strncat_v.S
index adc768d..01cb14f 100644
--- a/libc/arch-riscv64/string/strncat_v.S
+++ b/libc/arch-riscv64/string/strncat_v.S
@@ -70,7 +70,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncat_v)
+ENTRY(strncat)
mv pDstPtr, pDst
@@ -114,4 +114,4 @@
L(fill_zero_end):
ret
-END(strncat_v)
+END(strncat)
diff --git a/libc/arch-riscv64/string/strncmp.c b/libc/arch-riscv64/string/strncmp.c
deleted file mode 100644
index ebc5357..0000000
--- a/libc/arch-riscv64/string/strncmp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncmp strncmp_gc
-#include <upstream-openbsd/lib/libc/string/strncmp.c>
diff --git a/libc/arch-riscv64/string/strncmp_v.S b/libc/arch-riscv64/string/strncmp_v.S
index 1ce4817..b9e6ee2 100644
--- a/libc/arch-riscv64/string/strncmp_v.S
+++ b/libc/arch-riscv64/string/strncmp_v.S
@@ -71,7 +71,7 @@
#define vMask1 v8
#define vMask2 v9
-ENTRY(strncmp_v)
+ENTRY(strncmp)
beqz iLength, L(zero_length)
@@ -116,4 +116,4 @@
li iResult, 0
ret
-END(strncmp_v)
+END(strncmp)
diff --git a/libc/arch-riscv64/string/strncpy.c b/libc/arch-riscv64/string/strncpy.c
deleted file mode 100644
index bbd1bd7..0000000
--- a/libc/arch-riscv64/string/strncpy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncpy strncpy_gc
-#include <upstream-openbsd/lib/libc/string/strncpy.c>
diff --git a/libc/arch-riscv64/string/strncpy_v.S b/libc/arch-riscv64/string/strncpy_v.S
index f133f28..651a064 100644
--- a/libc/arch-riscv64/string/strncpy_v.S
+++ b/libc/arch-riscv64/string/strncpy_v.S
@@ -71,7 +71,7 @@
#define vStr1 v8
#define vStr2 v16
-ENTRY(strncpy_v)
+ENTRY(strncpy)
mv pDstPtr, pDst
@@ -111,4 +111,4 @@
ret
-END(strncpy_v)
+END(strncpy)
diff --git a/libc/arch-riscv64/string/strnlen.c b/libc/arch-riscv64/string/strnlen.c
deleted file mode 100644
index 0e31c3b..0000000
--- a/libc/arch-riscv64/string/strnlen.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* $OpenBSD: strnlen.c,v 1.9 2019/01/25 00:19:25 millert Exp $ */
-
-/*
- * Copyright (c) 2010 Todd C. Miller <millert@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <string.h>
-
-size_t
-strnlen_gc(const char *str, size_t maxlen)
-{
- const char *cp;
-
- for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
- ;
-
- return (size_t)(cp - str);
-}
diff --git a/libc/arch-riscv64/string/strnlen_v.S b/libc/arch-riscv64/string/strnlen_v.S
index bd1bb9a..66366f0 100644
--- a/libc/arch-riscv64/string/strnlen_v.S
+++ b/libc/arch-riscv64/string/strnlen_v.S
@@ -66,7 +66,7 @@
#define vStr v0
#define vMaskEnd v8
-ENTRY(strnlen_v)
+ENTRY(strnlen)
mv pCopyStr, pStr
mv iRetValue, iMaxlen
@@ -86,4 +86,4 @@
L(end_strnlen_loop):
ret
-END(strnlen_v)
+END(strnlen)
diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index 38d8a0a..240fcdf 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -26,129 +26,16 @@
* SUCH DAMAGE.
*/
-#include <stddef.h>
-
#include <private/bionic_ifuncs.h>
+#include <stddef.h>
extern "C" {
-typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n);
DEFINE_IFUNC_FOR(memcmp) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(memcmp_func, memcmp_atom);
- if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(memcmp_func, memcmp_sse4);
- RETURN_FUNC(memcmp_func, memcmp_generic);
+ __builtin_cpu_init();
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(memcmp_func_t, memcmp_sse4);
+ RETURN_FUNC(memcmp_func_t, memcmp_atom);
}
-
-typedef void* memset_func(void* __dst, int __ch, size_t __n);
-DEFINE_IFUNC_FOR(memset) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(memset_func, memset_atom);
- RETURN_FUNC(memset_func, memset_generic);
-}
-
-typedef void* __memset_chk_func(void *s, int c, size_t n, size_t n2);
-DEFINE_IFUNC_FOR(__memset_chk) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(__memset_chk_func, __memset_chk_atom);
- RETURN_FUNC(__memset_chk_func, __memset_chk_generic);
-}
-
-typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
-DEFINE_IFUNC_FOR(memmove) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(memmove_func, memmove_atom);
- RETURN_FUNC(memmove_func, memmove_generic);
-}
-
-typedef void* memcpy_func(void*, const void*, size_t);
-DEFINE_IFUNC_FOR(memcpy) {
- return memmove_resolver();
-}
-
-typedef char* strcpy_func(char* __dst, const char* __src);
-DEFINE_IFUNC_FOR(strcpy) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(strcpy_func, strcpy_atom);
- RETURN_FUNC(strcpy_func, strcpy_generic);
-}
-
-typedef char* strncpy_func(char* __dst, const char* __src, size_t __n);
-DEFINE_IFUNC_FOR(strncpy) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(strncpy_func, strncpy_atom);
- RETURN_FUNC(strncpy_func, strncpy_generic);
-}
-
-typedef size_t strlen_func(const char* __s);
-DEFINE_IFUNC_FOR(strlen) {
- __builtin_cpu_init();
- if (__builtin_cpu_is("atom")) RETURN_FUNC(strlen_func, strlen_atom);
- RETURN_FUNC(strlen_func, strlen_generic);
-}
-
-typedef int wmemcmp_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-DEFINE_IFUNC_FOR(wmemcmp) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(wmemcmp_func, wmemcmp_sse4);
- if (__builtin_cpu_is("atom")) RETURN_FUNC(wmemcmp_func, wmemcmp_atom);
- RETURN_FUNC(wmemcmp_func, wmemcmp_freebsd);
-}
-
-typedef int strcmp_func(const char* __lhs, const char* __rhs);
-DEFINE_IFUNC_FOR(strcmp) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcmp_func, strcmp_ssse3);
- RETURN_FUNC(strcmp_func, strcmp_generic);
-}
-
-typedef int strncmp_func(const char* __lhs, const char* __rhs, size_t __n);
-DEFINE_IFUNC_FOR(strncmp) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncmp_func, strncmp_ssse3);
- RETURN_FUNC(strncmp_func, strncmp_generic);
-}
-
-typedef char* strcat_func(char* __dst, const char* __src);
-DEFINE_IFUNC_FOR(strcat) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcat_func, strcat_ssse3);
- RETURN_FUNC(strcat_func, strcat_generic);
-}
-
-typedef char* strncat_func(char* __dst, const char* __src, size_t __n);
-DEFINE_IFUNC_FOR(strncat) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncat_func, strncat_ssse3);
- RETURN_FUNC(strncat_func, strncat_openbsd);
-}
-
-typedef size_t strlcat_func(char *dst, const char *src, size_t dsize);
-DEFINE_IFUNC_FOR(strlcat) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcat_func, strlcat_ssse3);
- RETURN_FUNC(strlcat_func, strlcat_openbsd);
-}
-
-typedef size_t strlcpy_func(char *dst, const char *src, size_t dsize);
-DEFINE_IFUNC_FOR(strlcpy) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcpy_func, strlcpy_ssse3);
- RETURN_FUNC(strlcpy_func, strlcpy_openbsd);
-}
-
-typedef wchar_t* wcscat_func(wchar_t *s1, const wchar_t *s2);
-DEFINE_IFUNC_FOR(wcscat) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscat_func, wcscat_ssse3);
- RETURN_FUNC(wcscat_func, wcscat_freebsd);
-}
-
-typedef wchar_t* wcscpy_func(wchar_t *s1, const wchar_t *s2);
-DEFINE_IFUNC_FOR(wcscpy) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscpy_func, wcscpy_ssse3);
- RETURN_FUNC(wcscpy_func, wcscpy_freebsd);
-}
+MEMCMP_SHIM()
} // extern "C"
diff --git a/libc/arch-x86/generic/string/memcmp.S b/libc/arch-x86/generic/string/memcmp.S
deleted file mode 100644
index 1d327c7..0000000
--- a/libc/arch-x86/generic/string/memcmp.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $OpenBSD: memcmp.S,v 1.4 2005/08/07 11:30:38 espie Exp $ */
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(memcmp_generic)
- pushl %edi
- pushl %esi
- movl 12(%esp),%edi
- movl 16(%esp),%esi
- cld /* set compare direction forward */
-
- movl 20(%esp),%ecx /* compare by words */
- shrl $2,%ecx
- repe
- cmpsl
- jne L5 /* do we match so far? */
-
- movl 20(%esp),%ecx /* compare remainder by bytes */
- andl $3,%ecx
- repe
- cmpsb
- jne L6 /* do we match? */
-
- xorl %eax,%eax /* we match, return zero */
- popl %esi
- popl %edi
- ret
-
-L5: movl $4,%ecx /* We know that one of the next */
- subl %ecx,%edi /* four pairs of bytes do not */
- subl %ecx,%esi /* match. */
- repe
- cmpsb
-L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */
- movzbl -1(%esi),%edx
- subl %edx,%eax
- popl %esi
- popl %edi
- ret
-END(memcmp_generic)
diff --git a/libc/arch-x86/generic/string/strcat.S b/libc/arch-x86/generic/string/strcat.S
deleted file mode 100644
index e2e9623..0000000
--- a/libc/arch-x86/generic/string/strcat.S
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $OpenBSD: strcat.S,v 1.8 2005/08/07 11:30:38 espie Exp $ */
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <private/bionic_asm.h>
-
-#if defined(APIWARN)
-#APP
- .section .gnu.warning.strcat
- .ascii "warning: strcat() is almost always misused, please use strlcat()"
-#NO_APP
-#endif
-
-/*
- * NOTE: I've unrolled the loop eight times: large enough to make a
- * significant difference, and small enough not to totally trash the
- * cache.
- */
-
-ENTRY(strcat_generic)
- pushl %edi /* save edi */
- movl 8(%esp),%edi /* dst address */
- movl 12(%esp),%edx /* src address */
- pushl %edi /* push destination address */
-
- cld /* set search forward */
- xorl %eax,%eax /* set search for null terminator */
- movl $-1,%ecx /* set search for lots of characters */
- repne /* search! */
- scasb
-
- leal -1(%edi),%ecx /* correct dst address */
-
- .align 2,0x90
-L1: movb (%edx),%al /* unroll loop, but not too much */
- movb %al,(%ecx)
- testb %al,%al
- jz L2
- movb 1(%edx),%al
- movb %al,1(%ecx)
- testb %al,%al
- jz L2
- movb 2(%edx),%al
- movb %al,2(%ecx)
- testb %al,%al
- jz L2
- movb 3(%edx),%al
- movb %al,3(%ecx)
- testb %al,%al
- jz L2
- movb 4(%edx),%al
- movb %al,4(%ecx)
- testb %al,%al
- jz L2
- movb 5(%edx),%al
- movb %al,5(%ecx)
- testb %al,%al
- jz L2
- movb 6(%edx),%al
- movb %al,6(%ecx)
- testb %al,%al
- jz L2
- movb 7(%edx),%al
- movb %al,7(%ecx)
- addl $8,%edx
- addl $8,%ecx
- testb %al,%al
- jnz L1
-L2: popl %eax /* pop destination address */
- popl %edi /* restore edi */
- ret
-END(strcat_generic)
diff --git a/libc/arch-x86/generic/string/strcmp.S b/libc/arch-x86/generic/string/strcmp.S
deleted file mode 100644
index 7b003e8..0000000
--- a/libc/arch-x86/generic/string/strcmp.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $OpenBSD: strcmp.S,v 1.3 2005/08/07 11:30:38 espie Exp $ */
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <private/bionic_asm.h>
-
-/*
- * NOTE: I've unrolled the loop eight times: large enough to make a
- * significant difference, and small enough not to totally trash the
- * cache.
- */
-
-ENTRY(strcmp_generic)
- movl 0x04(%esp),%eax
- movl 0x08(%esp),%edx
- jmp L2 /* Jump into the loop! */
-
- .align 2,0x90
-L1: incl %eax
- incl %edx
-L2: movb (%eax),%cl
- testb %cl,%cl /* null terminator??? */
- jz L3
- cmpb %cl,(%edx) /* chars match??? */
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- jne L3
- incl %eax
- incl %edx
- movb (%eax),%cl
- testb %cl,%cl
- jz L3
- cmpb %cl,(%edx)
- je L1
- .align 2, 0x90
-L3: movzbl (%eax),%eax /* unsigned comparison */
- movzbl (%edx),%edx
- subl %edx,%eax
- ret
-END(strcmp_generic)
diff --git a/libc/arch-x86/generic/string/strlcat.c b/libc/arch-x86/generic/string/strlcat.c
deleted file mode 100644
index 95c34a3..0000000
--- a/libc/arch-x86/generic/string/strlcat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strlcat strlcat_openbsd
-#include <upstream-openbsd/lib/libc/string/strlcat.c>
diff --git a/libc/arch-x86/generic/string/strlcpy.c b/libc/arch-x86/generic/string/strlcpy.c
deleted file mode 100644
index 8d4047c..0000000
--- a/libc/arch-x86/generic/string/strlcpy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strlcpy strlcpy_openbsd
-#include <upstream-openbsd/lib/libc/string/strlcpy.c>
diff --git a/libc/arch-x86/generic/string/strncat.c b/libc/arch-x86/generic/string/strncat.c
deleted file mode 100644
index 687e560..0000000
--- a/libc/arch-x86/generic/string/strncat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncat strncat_openbsd
-#include <upstream-openbsd/lib/libc/string/strncat.c>
diff --git a/libc/arch-x86/generic/string/strncmp.S b/libc/arch-x86/generic/string/strncmp.S
deleted file mode 100644
index 6d9f23c..0000000
--- a/libc/arch-x86/generic/string/strncmp.S
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $OpenBSD: strncmp.S,v 1.3 2005/08/07 11:30:38 espie Exp $ */
-/*
- * Written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <private/bionic_asm.h>
-
-/*
- * NOTE: I've unrolled the loop eight times: large enough to make a
- * significant difference, and small enough not to totally trash the
- * cache.
- */
-
-ENTRY(strncmp_generic)
- pushl %ebx
- movl 8(%esp),%eax
- movl 12(%esp),%ecx
- movl 16(%esp),%edx
- testl %edx,%edx
- jmp L2 /* Jump into the loop! */
-
- .align 2,0x90
-L1: incl %eax
- incl %ecx
- decl %edx
-L2: jz L4 /* strings are equal */
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- jne L3
-
- incl %eax
- incl %ecx
- decl %edx
- jz L4
- movb (%eax),%bl
- testb %bl,%bl
- jz L3
- cmpb %bl,(%ecx)
- je L1
-
- .align 2,0x90
-L3: movzbl (%eax),%eax /* unsigned comparision */
- movzbl (%ecx),%ecx
- subl %ecx,%eax
- popl %ebx
- ret
- .align 2,0x90
-L4: xorl %eax,%eax
- popl %ebx
- ret
-END(strncmp_generic)
diff --git a/libc/arch-x86/generic/string/wcscat.c b/libc/arch-x86/generic/string/wcscat.c
deleted file mode 100644
index a102551..0000000
--- a/libc/arch-x86/generic/string/wcscat.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define wcscat wcscat_freebsd
-#include <upstream-freebsd/lib/libc/string/wcscat.c>
diff --git a/libc/arch-x86/generic/string/wcscpy.c b/libc/arch-x86/generic/string/wcscpy.c
deleted file mode 100644
index 10fb66d..0000000
--- a/libc/arch-x86/generic/string/wcscpy.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define wcscpy wcscpy_freebsd
-#include <upstream-freebsd/lib/libc/string/wcscpy.c>
diff --git a/libc/arch-x86/generic/string/wmemcmp.c b/libc/arch-x86/generic/string/wmemcmp.c
deleted file mode 100644
index 9d5e929..0000000
--- a/libc/arch-x86/generic/string/wmemcmp.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define wmemcmp wmemcmp_freebsd
-#include <upstream-freebsd/lib/libc/string/wmemcmp.c>
diff --git a/libc/arch-x86/static_function_dispatch.S b/libc/arch-x86/static_function_dispatch.S
deleted file mode 100644
index 7e8e63d..0000000
--- a/libc/arch-x86/static_function_dispatch.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-#define FUNCTION_DELEGATE(name, impl) \
-ENTRY(name); \
- jmp impl; \
-END(name)
-
-FUNCTION_DELEGATE(memcmp, memcmp_generic)
-FUNCTION_DELEGATE(memset, memset_generic)
-FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic)
-FUNCTION_DELEGATE(memcpy, memmove_generic)
-FUNCTION_DELEGATE(memmove, memmove_generic)
-FUNCTION_DELEGATE(strcpy, strcpy_generic)
-FUNCTION_DELEGATE(strncpy, strncpy_generic)
-FUNCTION_DELEGATE(strlen, strlen_generic)
-FUNCTION_DELEGATE(strcmp, strcmp_generic)
-FUNCTION_DELEGATE(strncmp, strncmp_generic)
-FUNCTION_DELEGATE(strcat, strcat_generic)
-FUNCTION_DELEGATE(wmemcmp, wmemcmp_freebsd)
-FUNCTION_DELEGATE(wcscat, wcscat_freebsd)
-FUNCTION_DELEGATE(strncat, strncat_openbsd)
-FUNCTION_DELEGATE(strlcat, strlcat_openbsd)
-FUNCTION_DELEGATE(strlcpy, strlcpy_openbsd)
-FUNCTION_DELEGATE(wcscpy, wcscpy_freebsd)
diff --git a/libc/arch-x86/string/cache.h b/libc/arch-x86/string/cache.h
deleted file mode 100644
index 33719a0..0000000
--- a/libc/arch-x86/string/cache.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifdef FOR_ATOM
-#define SHARED_CACHE_SIZE (512 * 1024) /* Atom L2 Cache */
-#endif
-#ifdef FOR_SILVERMONT
-#define SHARED_CACHE_SIZE (1024 * 1024) /* Silvermont L2 Cache */
-#endif
-
-#define DATA_CACHE_SIZE (24 * 1024) /* Atom and Silvermont L1 Data Cache */
-
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86/string/sse2-memchr-atom.S b/libc/arch-x86/string/sse2-memchr-atom.S
deleted file mode 100644
index 013af9b..0000000
--- a/libc/arch-x86/string/sse2-memchr-atom.S
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define ENTRANCE PUSH (%edi);
-#define PARMS 8
-#define RETURN POP (%edi); ret; CFI_PUSH (%edi);
-
-#define STR1 PARMS
-#define STR2 STR1+4
-#define LEN STR2+4
-
- .text
-ENTRY (memchr)
- ENTRANCE
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
- mov LEN(%esp), %edx
- test %edx, %edx
- jz L(return_null)
-
- punpcklbw %xmm1, %xmm1
- mov %ecx, %edi
- punpcklbw %xmm1, %xmm1
-
- and $63, %ecx
- pshufd $0, %xmm1, %xmm1
- cmp $48, %ecx
- ja L(crosscache)
-
- movdqu (%edi), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(match_case2_prolog)
-
- sub $16, %edx
- jbe L(return_null)
- lea 16(%edi), %edi
- and $15, %ecx
- and $-16, %edi
- add %ecx, %edx
- sub $64, %edx
- jbe L(exit_loop)
- jmp L(loop_prolog)
-
- .p2align 4
-L(crosscache):
- and $15, %ecx
- and $-16, %edi
- movdqa (%edi), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- sar %cl, %eax
- test %eax, %eax
-
- jnz L(match_case2_prolog1)
- lea -16(%edx), %edx
- add %ecx, %edx
- jle L(return_null)
- lea 16(%edi), %edi
- sub $64, %edx
- jbe L(exit_loop)
-
- .p2align 4
-L(loop_prolog):
- movdqa (%edi), %xmm0
- pcmpeqb %xmm1, %xmm0
- xor %ecx, %ecx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 16(%edi), %xmm2
- pcmpeqb %xmm1, %xmm2
- lea 16(%ecx), %ecx
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 32(%edi), %xmm3
- pcmpeqb %xmm1, %xmm3
- lea 16(%ecx), %ecx
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 48(%edi), %xmm4
- pcmpeqb %xmm1, %xmm4
- lea 16(%ecx), %ecx
- pmovmskb %xmm4, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- lea 64(%edi), %edi
- sub $64, %edx
- jbe L(exit_loop)
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm1, %xmm0
- xor %ecx, %ecx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 16(%edi), %xmm2
- pcmpeqb %xmm1, %xmm2
- lea 16(%ecx), %ecx
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 32(%edi), %xmm3
- pcmpeqb %xmm1, %xmm3
- lea 16(%ecx), %ecx
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 48(%edi), %xmm4
- pcmpeqb %xmm1, %xmm4
- lea 16(%ecx), %ecx
- pmovmskb %xmm4, %eax
- test %eax, %eax
- jnz L(match_case1)
-
- lea 64(%edi), %edi
- mov %edi, %ecx
- and $-64, %edi
- and $63, %ecx
- add %ecx, %edx
-
- .p2align 4
-L(align64_loop):
- sub $64, %edx
- jbe L(exit_loop)
- movdqa (%edi), %xmm0
- movdqa 16(%edi), %xmm2
- movdqa 32(%edi), %xmm3
- movdqa 48(%edi), %xmm4
- pcmpeqb %xmm1, %xmm0
- pcmpeqb %xmm1, %xmm2
- pcmpeqb %xmm1, %xmm3
- pcmpeqb %xmm1, %xmm4
-
- pmaxub %xmm0, %xmm3
- pmaxub %xmm2, %xmm4
- pmaxub %xmm3, %xmm4
- add $64, %edi
- pmovmskb %xmm4, %eax
-
- test %eax, %eax
- jz L(align64_loop)
-
- sub $64, %edi
-
- pmovmskb %xmm0, %eax
- xor %ecx, %ecx
- test %eax, %eax
- jnz L(match_case1)
-
- pmovmskb %xmm2, %eax
- lea 16(%ecx), %ecx
- test %eax, %eax
- jnz L(match_case1)
-
- movdqa 32(%edi), %xmm3
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %eax
- lea 16(%ecx), %ecx
- test %eax, %eax
- jnz L(match_case1)
-
- pcmpeqb 48(%edi), %xmm1
- pmovmskb %xmm1, %eax
- lea 16(%ecx), %ecx
-
- .p2align 4
-L(match_case1):
- add %ecx, %edi
- test %al, %al
- jz L(match_case1_high)
- mov %al, %cl
- and $15, %cl
- jz L(match_case1_8)
- test $0x01, %al
- jnz L(exit_case1_1)
- test $0x02, %al
- jnz L(exit_case1_2)
- test $0x04, %al
- jnz L(exit_case1_3)
- lea 3(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_8):
- test $0x10, %al
- jnz L(exit_case1_5)
- test $0x20, %al
- jnz L(exit_case1_6)
- test $0x40, %al
- jnz L(exit_case1_7)
- lea 7(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_high):
- mov %ah, %ch
- and $15, %ch
- jz L(match_case1_high_8)
- test $0x01, %ah
- jnz L(exit_case1_9)
- test $0x02, %ah
- jnz L(exit_case1_10)
- test $0x04, %ah
- jnz L(exit_case1_11)
- lea 11(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_high_8):
- test $0x10, %ah
- jnz L(exit_case1_13)
- test $0x20, %ah
- jnz L(exit_case1_14)
- test $0x40, %ah
- jnz L(exit_case1_15)
- lea 15(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_loop):
- add $64, %edx
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm1, %xmm0
- xor %ecx, %ecx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(match_case2)
- cmp $16, %edx
- jbe L(return_null)
-
- movdqa 16(%edi), %xmm2
- pcmpeqb %xmm1, %xmm2
- lea 16(%ecx), %ecx
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(match_case2)
- cmp $32, %edx
- jbe L(return_null)
-
- movdqa 32(%edi), %xmm3
- pcmpeqb %xmm1, %xmm3
- lea 16(%ecx), %ecx
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(match_case2)
- cmp $48, %edx
- jbe L(return_null)
-
- pcmpeqb 48(%edi), %xmm1
- lea 16(%ecx), %ecx
- pmovmskb %xmm1, %eax
- test %eax, %eax
- jnz L(match_case2)
-
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(exit_case1_1):
- mov %edi, %eax
- RETURN
-
- .p2align 4
-L(exit_case1_2):
- lea 1(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_3):
- lea 2(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_5):
- lea 4(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_6):
- lea 5(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_7):
- lea 6(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_9):
- lea 8(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_10):
- lea 9(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_11):
- lea 10(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_13):
- lea 12(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_14):
- lea 13(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case1_15):
- lea 14(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2):
- sub %ecx, %edx
-L(match_case2_prolog1):
- add %ecx, %edi
-L(match_case2_prolog):
- test %al, %al
- jz L(match_case2_high)
- mov %al, %cl
- and $15, %cl
- jz L(match_case2_8)
- test $0x01, %al
- jnz L(exit_case2_1)
- test $0x02, %al
- jnz L(exit_case2_2)
- test $0x04, %al
- jnz L(exit_case2_3)
- sub $4, %edx
- jb L(return_null)
- lea 3(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2_8):
- test $0x10, %al
- jnz L(exit_case2_5)
- test $0x20, %al
- jnz L(exit_case2_6)
- test $0x40, %al
- jnz L(exit_case2_7)
- sub $8, %edx
- jb L(return_null)
- lea 7(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2_high):
- mov %ah, %ch
- and $15, %ch
- jz L(match_case2_high_8)
- test $0x01, %ah
- jnz L(exit_case2_9)
- test $0x02, %ah
- jnz L(exit_case2_10)
- test $0x04, %ah
- jnz L(exit_case2_11)
- sub $12, %edx
- jb L(return_null)
- lea 11(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2_high_8):
- test $0x10, %ah
- jnz L(exit_case2_13)
- test $0x20, %ah
- jnz L(exit_case2_14)
- test $0x40, %ah
- jnz L(exit_case2_15)
- sub $16, %edx
- jb L(return_null)
- lea 15(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_1):
- mov %edi, %eax
- RETURN
-
- .p2align 4
-L(exit_case2_2):
- sub $2, %edx
- jb L(return_null)
- lea 1(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_3):
- sub $3, %edx
- jb L(return_null)
- lea 2(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_5):
- sub $5, %edx
- jb L(return_null)
- lea 4(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_6):
- sub $6, %edx
- jb L(return_null)
- lea 5(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_7):
- sub $7, %edx
- jb L(return_null)
- lea 6(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_9):
- sub $9, %edx
- jb L(return_null)
- lea 8(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_10):
- sub $10, %edx
- jb L(return_null)
- lea 9(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_11):
- sub $11, %edx
- jb L(return_null)
- lea 10(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_13):
- sub $13, %edx
- jb L(return_null)
- lea 12(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_14):
- sub $14, %edx
- jb L(return_null)
- lea 13(%edi), %eax
- RETURN
-
- .p2align 4
-L(exit_case2_15):
- sub $15, %edx
- jb L(return_null)
- lea 14(%edi), %eax
- RETURN
- .p2align 4
-L(return_null):
- xor %eax, %eax
- RETURN
-END (memchr)
diff --git a/libc/arch-x86/string/sse2-memmove-slm.S b/libc/arch-x86/string/sse2-memmove-slm.S
index 79b5d1b..2ed4e7b 100644
--- a/libc/arch-x86/string/sse2-memmove-slm.S
+++ b/libc/arch-x86/string/sse2-memmove-slm.S
@@ -29,10 +29,9 @@
*/
#define FOR_SILVERMONT
-#include "cache.h"
#ifndef MEMMOVE
-# define MEMMOVE memmove_generic
+# define MEMMOVE memmove
#endif
#ifndef L
@@ -94,6 +93,8 @@
#define RETURN_END POP (%ebx); ret
#define RETURN RETURN_END; CFI_PUSH (%ebx)
+#define SETUP_PIC_REG(x) call __x86.get_pc_thunk.x
+
.section .text.sse2,"ax",@progbits
ENTRY (MEMMOVE)
ENTRANCE
@@ -193,7 +194,13 @@
cmp %edi, %ebx
jbe L(mm_copy_remaining_forward)
- cmp $SHARED_CACHE_SIZE_HALF, %ecx
+ PUSH(%ebx)
+ SETUP_PIC_REG(bx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+ cmp __x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
+ /* Restore ebx. We can place a pop before jump as it doesn't affect any flags. */
+ POP(%ebx)
+
jae L(mm_large_page_loop_forward)
.p2align 4
@@ -424,7 +431,13 @@
cmp %edi, %ebx
jae L(mm_main_loop_backward_end)
- cmp $SHARED_CACHE_SIZE_HALF, %ecx
+ PUSH(%ebx)
+ SETUP_PIC_REG(bx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+ cmp __x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
+ /* Restore ebx. We can place a pop before jump as it doesn't affect any flags. */
+ POP(%ebx)
+
jae L(mm_large_page_loop_backward)
.p2align 4
@@ -538,3 +551,9 @@
jmp L(mm_recalc_len)
END (MEMMOVE)
+
+// N.B., `private/bionic_asm.h` provides ALIAS_SYMBOL, but that file provides
+// conflicting definitions for some macros in this file. Since ALIAS_SYMBOL is
+// small, inline it here.
+.globl memcpy;
+.equ memcpy, MEMMOVE
diff --git a/libc/arch-x86/string/sse2-memrchr-atom.S b/libc/arch-x86/string/sse2-memrchr-atom.S
deleted file mode 100644
index 1aa1a1a..0000000
--- a/libc/arch-x86/string/sse2-memrchr-atom.S
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 4
-#define STR1 PARMS
-#define STR2 STR1+4
-#define LEN STR2+4
-
- .text
-ENTRY (memrchr)
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
- mov LEN(%esp), %edx
-
- test %edx, %edx
- jz L(return_null)
- sub $16, %edx
- jbe L(length_less16)
-
- punpcklbw %xmm1, %xmm1
- add %edx, %ecx
- punpcklbw %xmm1, %xmm1
-
- movdqu (%ecx), %xmm0
- pshufd $0, %xmm1, %xmm1
- pcmpeqb %xmm1, %xmm0
-
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(exit_dispatch)
-
- sub $64, %ecx
- mov %ecx, %eax
- and $15, %eax
- jz L(loop_prolog)
-
- add $16, %ecx
- add $16, %edx
- and $-16, %ecx
- sub %eax, %edx
-
- .p2align 4
-/* Loop start on aligned string. */
-L(loop_prolog):
- sub $64, %edx
- jbe L(exit_loop)
-
- movdqa 48(%ecx), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches48)
-
- movdqa 32(%ecx), %xmm2
- pcmpeqb %xmm1, %xmm2
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(matches32)
-
- movdqa 16(%ecx), %xmm3
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(matches16)
-
- movdqa (%ecx), %xmm4
- pcmpeqb %xmm1, %xmm4
- pmovmskb %xmm4, %eax
- test %eax, %eax
- jnz L(exit_dispatch)
-
- sub $64, %ecx
- sub $64, %edx
- jbe L(exit_loop)
-
- movdqa 48(%ecx), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches48)
-
- movdqa 32(%ecx), %xmm2
- pcmpeqb %xmm1, %xmm2
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(matches32)
-
- movdqa 16(%ecx), %xmm3
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(matches16)
-
- movdqa (%ecx), %xmm3
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(exit_dispatch)
-
- mov %ecx, %eax
- and $63, %eax
- test %eax, %eax
- jz L(align64_loop)
-
- add $64, %ecx
- add $64, %edx
- and $-64, %ecx
- sub %eax, %edx
-
- .p2align 4
-L(align64_loop):
- sub $64, %ecx
- sub $64, %edx
- jbe L(exit_loop)
-
- movdqa (%ecx), %xmm0
- movdqa 16(%ecx), %xmm2
- movdqa 32(%ecx), %xmm3
- movdqa 48(%ecx), %xmm4
-
- pcmpeqb %xmm1, %xmm0
- pcmpeqb %xmm1, %xmm2
- pcmpeqb %xmm1, %xmm3
- pcmpeqb %xmm1, %xmm4
-
- pmaxub %xmm3, %xmm0
- pmaxub %xmm4, %xmm2
- pmaxub %xmm0, %xmm2
- pmovmskb %xmm2, %eax
-
- test %eax, %eax
- jz L(align64_loop)
-
- pmovmskb %xmm4, %eax
- test %eax, %eax
- jnz L(matches48)
-
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(matches32)
-
- movdqa 16(%ecx), %xmm2
-
- pcmpeqb %xmm1, %xmm2
- pcmpeqb (%ecx), %xmm1
-
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(matches16)
-
- pmovmskb %xmm1, %eax
- test %ah, %ah
- jnz L(exit_dispatch_high)
- mov %al, %dl
- and $15 << 4, %dl
- jnz L(exit_dispatch_8)
- test $0x08, %al
- jnz L(exit_4)
- test $0x04, %al
- jnz L(exit_3)
- test $0x02, %al
- jnz L(exit_2)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(exit_loop):
- add $64, %edx
- cmp $32, %edx
- jbe L(exit_loop_32)
-
- movdqa 48(%ecx), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches48)
-
- movdqa 32(%ecx), %xmm2
- pcmpeqb %xmm1, %xmm2
- pmovmskb %xmm2, %eax
- test %eax, %eax
- jnz L(matches32)
-
- movdqa 16(%ecx), %xmm3
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %eax
- test %eax, %eax
- jnz L(matches16_1)
- cmp $48, %edx
- jbe L(return_null)
-
- pcmpeqb (%ecx), %xmm1
- pmovmskb %xmm1, %eax
- test %eax, %eax
- jnz L(matches0_1)
- xor %eax, %eax
- ret
-
- .p2align 4
-L(exit_loop_32):
- movdqa 48(%ecx), %xmm0
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches48_1)
- cmp $16, %edx
- jbe L(return_null)
-
- pcmpeqb 32(%ecx), %xmm1
- pmovmskb %xmm1, %eax
- test %eax, %eax
- jnz L(matches32_1)
- xor %eax, %eax
- ret
-
- .p2align 4
-L(matches16):
- lea 16(%ecx), %ecx
- test %ah, %ah
- jnz L(exit_dispatch_high)
- mov %al, %dl
- and $15 << 4, %dl
- jnz L(exit_dispatch_8)
- test $0x08, %al
- jnz L(exit_4)
- test $0x04, %al
- jnz L(exit_3)
- test $0x02, %al
- jnz L(exit_2)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(matches32):
- lea 32(%ecx), %ecx
- test %ah, %ah
- jnz L(exit_dispatch_high)
- mov %al, %dl
- and $15 << 4, %dl
- jnz L(exit_dispatch_8)
- test $0x08, %al
- jnz L(exit_4)
- test $0x04, %al
- jnz L(exit_3)
- test $0x02, %al
- jnz L(exit_2)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(matches48):
- lea 48(%ecx), %ecx
-
- .p2align 4
-L(exit_dispatch):
- test %ah, %ah
- jnz L(exit_dispatch_high)
- mov %al, %dl
- and $15 << 4, %dl
- jnz L(exit_dispatch_8)
- test $0x08, %al
- jnz L(exit_4)
- test $0x04, %al
- jnz L(exit_3)
- test $0x02, %al
- jnz L(exit_2)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(exit_dispatch_8):
- test $0x80, %al
- jnz L(exit_8)
- test $0x40, %al
- jnz L(exit_7)
- test $0x20, %al
- jnz L(exit_6)
- lea 4(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_dispatch_high):
- mov %ah, %dh
- and $15 << 4, %dh
- jnz L(exit_dispatch_high_8)
- test $0x08, %ah
- jnz L(exit_12)
- test $0x04, %ah
- jnz L(exit_11)
- test $0x02, %ah
- jnz L(exit_10)
- lea 8(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_dispatch_high_8):
- test $0x80, %ah
- jnz L(exit_16)
- test $0x40, %ah
- jnz L(exit_15)
- test $0x20, %ah
- jnz L(exit_14)
- lea 12(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_2):
- lea 1(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_3):
- lea 2(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_4):
- lea 3(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_6):
- lea 5(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_7):
- lea 6(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_8):
- lea 7(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_10):
- lea 9(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_11):
- lea 10(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_12):
- lea 11(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_14):
- lea 13(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_15):
- lea 14(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_16):
- lea 15(%ecx), %eax
- ret
-
- .p2align 4
-L(matches0_1):
- lea -64(%edx), %edx
-
- test %ah, %ah
- jnz L(exit_dispatch_1_high)
- mov %al, %ah
- and $15 << 4, %ah
- jnz L(exit_dispatch_1_8)
- test $0x08, %al
- jnz L(exit_1_4)
- test $0x04, %al
- jnz L(exit_1_3)
- test $0x02, %al
- jnz L(exit_1_2)
-
- add $0, %edx
- jl L(return_null)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(matches16_1):
- lea -48(%edx), %edx
- lea 16(%ecx), %ecx
-
- test %ah, %ah
- jnz L(exit_dispatch_1_high)
- mov %al, %ah
- and $15 << 4, %ah
- jnz L(exit_dispatch_1_8)
- test $0x08, %al
- jnz L(exit_1_4)
- test $0x04, %al
- jnz L(exit_1_3)
- test $0x02, %al
- jnz L(exit_1_2)
-
- add $0, %edx
- jl L(return_null)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(matches32_1):
- lea -32(%edx), %edx
- lea 32(%ecx), %ecx
-
- test %ah, %ah
- jnz L(exit_dispatch_1_high)
- mov %al, %ah
- and $15 << 4, %ah
- jnz L(exit_dispatch_1_8)
- test $0x08, %al
- jnz L(exit_1_4)
- test $0x04, %al
- jnz L(exit_1_3)
- test $0x02, %al
- jnz L(exit_1_2)
-
- add $0, %edx
- jl L(return_null)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(matches48_1):
- lea -16(%edx), %edx
- lea 48(%ecx), %ecx
-
- .p2align 4
-L(exit_dispatch_1):
- test %ah, %ah
- jnz L(exit_dispatch_1_high)
- mov %al, %ah
- and $15 << 4, %ah
- jnz L(exit_dispatch_1_8)
- test $0x08, %al
- jnz L(exit_1_4)
- test $0x04, %al
- jnz L(exit_1_3)
- test $0x02, %al
- jnz L(exit_1_2)
-
- add $0, %edx
- jl L(return_null)
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(exit_dispatch_1_8):
- test $0x80, %al
- jnz L(exit_1_8)
- test $0x40, %al
- jnz L(exit_1_7)
- test $0x20, %al
- jnz L(exit_1_6)
-
- add $4, %edx
- jl L(return_null)
- lea 4(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_dispatch_1_high):
- mov %ah, %al
- and $15 << 4, %al
- jnz L(exit_dispatch_1_high_8)
- test $0x08, %ah
- jnz L(exit_1_12)
- test $0x04, %ah
- jnz L(exit_1_11)
- test $0x02, %ah
- jnz L(exit_1_10)
-
- add $8, %edx
- jl L(return_null)
- lea 8(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_dispatch_1_high_8):
- test $0x80, %ah
- jnz L(exit_1_16)
- test $0x40, %ah
- jnz L(exit_1_15)
- test $0x20, %ah
- jnz L(exit_1_14)
-
- add $12, %edx
- jl L(return_null)
- lea 12(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_2):
- add $1, %edx
- jl L(return_null)
- lea 1(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_3):
- add $2, %edx
- jl L(return_null)
- lea 2(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_4):
- add $3, %edx
- jl L(return_null)
- lea 3(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_6):
- add $5, %edx
- jl L(return_null)
- lea 5(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_7):
- add $6, %edx
- jl L(return_null)
- lea 6(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_8):
- add $7, %edx
- jl L(return_null)
- lea 7(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_10):
- add $9, %edx
- jl L(return_null)
- lea 9(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_11):
- add $10, %edx
- jl L(return_null)
- lea 10(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_12):
- add $11, %edx
- jl L(return_null)
- lea 11(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_14):
- add $13, %edx
- jl L(return_null)
- lea 13(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_15):
- add $14, %edx
- jl L(return_null)
- lea 14(%ecx), %eax
- ret
-
- .p2align 4
-L(exit_1_16):
- add $15, %edx
- jl L(return_null)
- lea 15(%ecx), %eax
- ret
-
- .p2align 4
-L(return_null):
- xor %eax, %eax
- ret
-
- .p2align 4
-L(length_less16_offset0):
- mov %dl, %cl
- pcmpeqb (%eax), %xmm1
-
- mov $1, %edx
- sal %cl, %edx
- sub $1, %edx
-
- mov %eax, %ecx
- pmovmskb %xmm1, %eax
-
- and %edx, %eax
- test %eax, %eax
- jnz L(exit_dispatch)
-
- xor %eax, %eax
- ret
-
- .p2align 4
-L(length_less16):
- punpcklbw %xmm1, %xmm1
- add $16, %edx
- punpcklbw %xmm1, %xmm1
-
- mov %ecx, %eax
- pshufd $0, %xmm1, %xmm1
-
- and $15, %ecx
- jz L(length_less16_offset0)
-
- PUSH (%edi)
-
- mov %cl, %dh
- add %dl, %dh
- and $-16, %eax
-
- sub $16, %dh
- ja L(length_less16_part2)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edi
-
- sar %cl, %edi
- add %ecx, %eax
- mov %dl, %cl
-
- mov $1, %edx
- sal %cl, %edx
- sub $1, %edx
-
- and %edx, %edi
- test %edi, %edi
- jz L(ret_null)
-
- bsr %edi, %edi
- add %edi, %eax
- POP (%edi)
- ret
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(length_less16_part2):
- movdqa 16(%eax), %xmm2
- pcmpeqb %xmm1, %xmm2
- pmovmskb %xmm2, %edi
-
- mov %cl, %ch
-
- mov %dh, %cl
- mov $1, %edx
- sal %cl, %edx
- sub $1, %edx
-
- and %edx, %edi
-
- test %edi, %edi
- jnz L(length_less16_part2_return)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edi
-
- mov %ch, %cl
- sar %cl, %edi
- test %edi, %edi
- jz L(ret_null)
-
- bsr %edi, %edi
- add %edi, %eax
- xor %ch, %ch
- add %ecx, %eax
- POP (%edi)
- ret
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(length_less16_part2_return):
- bsr %edi, %edi
- lea 16(%eax, %edi), %eax
- POP (%edi)
- ret
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ret_null):
- xor %eax, %eax
- POP (%edi)
- ret
-
-END (memrchr)
diff --git a/libc/arch-x86/string/sse2-memset-atom.S b/libc/arch-x86/string/sse2-memset-atom.S
deleted file mode 100644
index 320afec..0000000
--- a/libc/arch-x86/string/sse2-memset-atom.S
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-#define FOR_ATOM
-#include "cache.h"
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef ALIGN
-# define ALIGN(n) .p2align n
-#endif
-
-#define CFI_PUSH(REG) \
- .cfi_adjust_cfa_offset 4; \
- .cfi_rel_offset REG, 0
-
-#define CFI_POP(REG) \
- .cfi_adjust_cfa_offset -4; \
- .cfi_restore REG
-
-#define PUSH(REG) pushl REG; CFI_PUSH(REG)
-#define POP(REG) popl REG; CFI_POP(REG)
-
-#define PARMS 8 /* Preserve EBX. */
-#define DST PARMS
-#define CHR (DST+4)
-#define LEN (CHR+4)
-#define CHK_DST_LEN (LEN+4)
-#define SETRTNVAL movl DST(%esp), %eax
-
-#define ENTRANCE PUSH(%ebx);
-#define RETURN_END POP(%ebx); ret
-#define RETURN RETURN_END; CFI_PUSH(%ebx)
-#define JMPTBL(I, B) I - B
-
-/* Load an entry in a jump table into EBX and branch to it. TABLE is a
- jump table with relative offsets. */
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE) \
- /* We first load PC into EBX. */ \
- call __x86.get_pc_thunk.bx; \
- /* Get the address of the jump table. */ \
- add $(TABLE - .), %ebx; \
- /* Get the entry and convert the relative offset to the \
- absolute address. */ \
- add (%ebx,%ecx,4), %ebx; \
- add %ecx, %edx; \
- /* We loaded the jump table and adjusted EDX. Go. */ \
- jmp *%ebx
-
-ENTRY(__memset_chk_atom)
- ENTRANCE
-
- movl LEN(%esp), %ecx
- cmpl CHK_DST_LEN(%esp), %ecx
- jna L(memset_length_loaded)
-
- POP(%ebx) // Undo ENTRANCE without returning.
- jmp __memset_chk_fail
-END(__memset_chk_atom)
-
- .section .text.sse2,"ax",@progbits
- ALIGN(4)
-ENTRY(memset_atom)
- ENTRANCE
-
- movl LEN(%esp), %ecx
-L(memset_length_loaded):
- movzbl CHR(%esp), %eax
- movb %al, %ah
- /* Fill the whole EAX with pattern. */
- movl %eax, %edx
- shl $16, %eax
- or %edx, %eax
- movl DST(%esp), %edx
- cmp $32, %ecx
- jae L(32bytesormore)
-
-L(write_less32bytes):
- BRANCH_TO_JMPTBL_ENTRY(L(table_less_32bytes))
-
-
- .pushsection .rodata.sse2,"a",@progbits
- ALIGN(2)
-L(table_less_32bytes):
- .int JMPTBL(L(write_0bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_1bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_2bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_3bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_4bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_5bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_6bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_7bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_8bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_9bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_10bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_11bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_12bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_13bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_14bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_15bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_16bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_17bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_18bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_19bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_20bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_21bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_22bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_23bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_24bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_25bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_26bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_27bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_28bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_29bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_30bytes), L(table_less_32bytes))
- .int JMPTBL(L(write_31bytes), L(table_less_32bytes))
- .popsection
-
- ALIGN(4)
-L(write_28bytes):
- movl %eax, -28(%edx)
-L(write_24bytes):
- movl %eax, -24(%edx)
-L(write_20bytes):
- movl %eax, -20(%edx)
-L(write_16bytes):
- movl %eax, -16(%edx)
-L(write_12bytes):
- movl %eax, -12(%edx)
-L(write_8bytes):
- movl %eax, -8(%edx)
-L(write_4bytes):
- movl %eax, -4(%edx)
-L(write_0bytes):
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(write_29bytes):
- movl %eax, -29(%edx)
-L(write_25bytes):
- movl %eax, -25(%edx)
-L(write_21bytes):
- movl %eax, -21(%edx)
-L(write_17bytes):
- movl %eax, -17(%edx)
-L(write_13bytes):
- movl %eax, -13(%edx)
-L(write_9bytes):
- movl %eax, -9(%edx)
-L(write_5bytes):
- movl %eax, -5(%edx)
-L(write_1bytes):
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(write_30bytes):
- movl %eax, -30(%edx)
-L(write_26bytes):
- movl %eax, -26(%edx)
-L(write_22bytes):
- movl %eax, -22(%edx)
-L(write_18bytes):
- movl %eax, -18(%edx)
-L(write_14bytes):
- movl %eax, -14(%edx)
-L(write_10bytes):
- movl %eax, -10(%edx)
-L(write_6bytes):
- movl %eax, -6(%edx)
-L(write_2bytes):
- movw %ax, -2(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(write_31bytes):
- movl %eax, -31(%edx)
-L(write_27bytes):
- movl %eax, -27(%edx)
-L(write_23bytes):
- movl %eax, -23(%edx)
-L(write_19bytes):
- movl %eax, -19(%edx)
-L(write_15bytes):
- movl %eax, -15(%edx)
-L(write_11bytes):
- movl %eax, -11(%edx)
-L(write_7bytes):
- movl %eax, -7(%edx)
-L(write_3bytes):
- movw %ax, -3(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-/* ECX > 32 and EDX is 4 byte aligned. */
-L(32bytesormore):
- /* Fill xmm0 with the pattern. */
- movd %eax, %xmm0
- pshufd $0, %xmm0, %xmm0
- testl $0xf, %edx
- jz L(aligned_16)
-/* ECX > 32 and EDX is not 16 byte aligned. */
-L(not_aligned_16):
- movdqu %xmm0, (%edx)
- movl %edx, %eax
- and $-16, %edx
- add $16, %edx
- sub %edx, %eax
- add %eax, %ecx
- movd %xmm0, %eax
-
- ALIGN(4)
-L(aligned_16):
- cmp $128, %ecx
- jae L(128bytesormore)
-
-L(aligned_16_less128bytes):
- BRANCH_TO_JMPTBL_ENTRY(L(table_16_128bytes))
-
- ALIGN(4)
-L(128bytesormore):
- PUSH(%ebx)
- mov $SHARED_CACHE_SIZE, %ebx
- cmp %ebx, %ecx
- jae L(128bytesormore_nt_start)
-
-
- POP(%ebx)
-# define RESTORE_EBX_STATE CFI_PUSH(%ebx)
- cmp $DATA_CACHE_SIZE, %ecx
-
- jae L(128bytes_L2_normal)
- subl $128, %ecx
-L(128bytesormore_normal):
- sub $128, %ecx
- movdqa %xmm0, (%edx)
- movdqa %xmm0, 0x10(%edx)
- movdqa %xmm0, 0x20(%edx)
- movdqa %xmm0, 0x30(%edx)
- movdqa %xmm0, 0x40(%edx)
- movdqa %xmm0, 0x50(%edx)
- movdqa %xmm0, 0x60(%edx)
- movdqa %xmm0, 0x70(%edx)
- lea 128(%edx), %edx
- jb L(128bytesless_normal)
-
-
- sub $128, %ecx
- movdqa %xmm0, (%edx)
- movdqa %xmm0, 0x10(%edx)
- movdqa %xmm0, 0x20(%edx)
- movdqa %xmm0, 0x30(%edx)
- movdqa %xmm0, 0x40(%edx)
- movdqa %xmm0, 0x50(%edx)
- movdqa %xmm0, 0x60(%edx)
- movdqa %xmm0, 0x70(%edx)
- lea 128(%edx), %edx
- jae L(128bytesormore_normal)
-
-L(128bytesless_normal):
- add $128, %ecx
- BRANCH_TO_JMPTBL_ENTRY(L(table_16_128bytes))
-
- ALIGN(4)
-L(128bytes_L2_normal):
- prefetcht0 0x380(%edx)
- prefetcht0 0x3c0(%edx)
- sub $128, %ecx
- movdqa %xmm0, (%edx)
- movaps %xmm0, 0x10(%edx)
- movaps %xmm0, 0x20(%edx)
- movaps %xmm0, 0x30(%edx)
- movaps %xmm0, 0x40(%edx)
- movaps %xmm0, 0x50(%edx)
- movaps %xmm0, 0x60(%edx)
- movaps %xmm0, 0x70(%edx)
- add $128, %edx
- cmp $128, %ecx
- jae L(128bytes_L2_normal)
-
-L(128bytesless_L2_normal):
- BRANCH_TO_JMPTBL_ENTRY(L(table_16_128bytes))
-
- RESTORE_EBX_STATE
-L(128bytesormore_nt_start):
- sub %ebx, %ecx
- mov %ebx, %eax
- and $0x7f, %eax
- add %eax, %ecx
- movd %xmm0, %eax
- ALIGN(4)
-L(128bytesormore_shared_cache_loop):
- prefetcht0 0x3c0(%edx)
- prefetcht0 0x380(%edx)
- sub $0x80, %ebx
- movdqa %xmm0, (%edx)
- movdqa %xmm0, 0x10(%edx)
- movdqa %xmm0, 0x20(%edx)
- movdqa %xmm0, 0x30(%edx)
- movdqa %xmm0, 0x40(%edx)
- movdqa %xmm0, 0x50(%edx)
- movdqa %xmm0, 0x60(%edx)
- movdqa %xmm0, 0x70(%edx)
- add $0x80, %edx
- cmp $0x80, %ebx
- jae L(128bytesormore_shared_cache_loop)
- cmp $0x80, %ecx
- jb L(shared_cache_loop_end)
- ALIGN(4)
-L(128bytesormore_nt):
- sub $0x80, %ecx
- movntdq %xmm0, (%edx)
- movntdq %xmm0, 0x10(%edx)
- movntdq %xmm0, 0x20(%edx)
- movntdq %xmm0, 0x30(%edx)
- movntdq %xmm0, 0x40(%edx)
- movntdq %xmm0, 0x50(%edx)
- movntdq %xmm0, 0x60(%edx)
- movntdq %xmm0, 0x70(%edx)
- add $0x80, %edx
- cmp $0x80, %ecx
- jae L(128bytesormore_nt)
- sfence
-L(shared_cache_loop_end):
- POP(%ebx)
- BRANCH_TO_JMPTBL_ENTRY(L(table_16_128bytes))
-
-
- .pushsection .rodata.sse2,"a",@progbits
- ALIGN(2)
-L(table_16_128bytes):
- .int JMPTBL(L(aligned_16_0bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_1bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_2bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_3bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_4bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_5bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_6bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_7bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_8bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_9bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_10bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_11bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_12bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_13bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_14bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_15bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_16bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_17bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_18bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_19bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_20bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_21bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_22bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_23bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_24bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_25bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_26bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_27bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_28bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_29bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_30bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_31bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_32bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_33bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_34bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_35bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_36bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_37bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_38bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_39bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_40bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_41bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_42bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_43bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_44bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_45bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_46bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_47bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_48bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_49bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_50bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_51bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_52bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_53bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_54bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_55bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_56bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_57bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_58bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_59bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_60bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_61bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_62bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_63bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_64bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_65bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_66bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_67bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_68bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_69bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_70bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_71bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_72bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_73bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_74bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_75bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_76bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_77bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_78bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_79bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_80bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_81bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_82bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_83bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_84bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_85bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_86bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_87bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_88bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_89bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_90bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_91bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_92bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_93bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_94bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_95bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_96bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_97bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_98bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_99bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_100bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_101bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_102bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_103bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_104bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_105bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_106bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_107bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_108bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_109bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_110bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_111bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_112bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_113bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_114bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_115bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_116bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_117bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_118bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_119bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_120bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_121bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_122bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_123bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_124bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_125bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_126bytes), L(table_16_128bytes))
- .int JMPTBL(L(aligned_16_127bytes), L(table_16_128bytes))
- .popsection
-
- ALIGN(4)
-L(aligned_16_112bytes):
- movdqa %xmm0, -112(%edx)
-L(aligned_16_96bytes):
- movdqa %xmm0, -96(%edx)
-L(aligned_16_80bytes):
- movdqa %xmm0, -80(%edx)
-L(aligned_16_64bytes):
- movdqa %xmm0, -64(%edx)
-L(aligned_16_48bytes):
- movdqa %xmm0, -48(%edx)
-L(aligned_16_32bytes):
- movdqa %xmm0, -32(%edx)
-L(aligned_16_16bytes):
- movdqa %xmm0, -16(%edx)
-L(aligned_16_0bytes):
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_113bytes):
- movdqa %xmm0, -113(%edx)
-L(aligned_16_97bytes):
- movdqa %xmm0, -97(%edx)
-L(aligned_16_81bytes):
- movdqa %xmm0, -81(%edx)
-L(aligned_16_65bytes):
- movdqa %xmm0, -65(%edx)
-L(aligned_16_49bytes):
- movdqa %xmm0, -49(%edx)
-L(aligned_16_33bytes):
- movdqa %xmm0, -33(%edx)
-L(aligned_16_17bytes):
- movdqa %xmm0, -17(%edx)
-L(aligned_16_1bytes):
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_114bytes):
- movdqa %xmm0, -114(%edx)
-L(aligned_16_98bytes):
- movdqa %xmm0, -98(%edx)
-L(aligned_16_82bytes):
- movdqa %xmm0, -82(%edx)
-L(aligned_16_66bytes):
- movdqa %xmm0, -66(%edx)
-L(aligned_16_50bytes):
- movdqa %xmm0, -50(%edx)
-L(aligned_16_34bytes):
- movdqa %xmm0, -34(%edx)
-L(aligned_16_18bytes):
- movdqa %xmm0, -18(%edx)
-L(aligned_16_2bytes):
- movw %ax, -2(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_115bytes):
- movdqa %xmm0, -115(%edx)
-L(aligned_16_99bytes):
- movdqa %xmm0, -99(%edx)
-L(aligned_16_83bytes):
- movdqa %xmm0, -83(%edx)
-L(aligned_16_67bytes):
- movdqa %xmm0, -67(%edx)
-L(aligned_16_51bytes):
- movdqa %xmm0, -51(%edx)
-L(aligned_16_35bytes):
- movdqa %xmm0, -35(%edx)
-L(aligned_16_19bytes):
- movdqa %xmm0, -19(%edx)
-L(aligned_16_3bytes):
- movw %ax, -3(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_116bytes):
- movdqa %xmm0, -116(%edx)
-L(aligned_16_100bytes):
- movdqa %xmm0, -100(%edx)
-L(aligned_16_84bytes):
- movdqa %xmm0, -84(%edx)
-L(aligned_16_68bytes):
- movdqa %xmm0, -68(%edx)
-L(aligned_16_52bytes):
- movdqa %xmm0, -52(%edx)
-L(aligned_16_36bytes):
- movdqa %xmm0, -36(%edx)
-L(aligned_16_20bytes):
- movdqa %xmm0, -20(%edx)
-L(aligned_16_4bytes):
- movl %eax, -4(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_117bytes):
- movdqa %xmm0, -117(%edx)
-L(aligned_16_101bytes):
- movdqa %xmm0, -101(%edx)
-L(aligned_16_85bytes):
- movdqa %xmm0, -85(%edx)
-L(aligned_16_69bytes):
- movdqa %xmm0, -69(%edx)
-L(aligned_16_53bytes):
- movdqa %xmm0, -53(%edx)
-L(aligned_16_37bytes):
- movdqa %xmm0, -37(%edx)
-L(aligned_16_21bytes):
- movdqa %xmm0, -21(%edx)
-L(aligned_16_5bytes):
- movl %eax, -5(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_118bytes):
- movdqa %xmm0, -118(%edx)
-L(aligned_16_102bytes):
- movdqa %xmm0, -102(%edx)
-L(aligned_16_86bytes):
- movdqa %xmm0, -86(%edx)
-L(aligned_16_70bytes):
- movdqa %xmm0, -70(%edx)
-L(aligned_16_54bytes):
- movdqa %xmm0, -54(%edx)
-L(aligned_16_38bytes):
- movdqa %xmm0, -38(%edx)
-L(aligned_16_22bytes):
- movdqa %xmm0, -22(%edx)
-L(aligned_16_6bytes):
- movl %eax, -6(%edx)
- movw %ax, -2(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_119bytes):
- movdqa %xmm0, -119(%edx)
-L(aligned_16_103bytes):
- movdqa %xmm0, -103(%edx)
-L(aligned_16_87bytes):
- movdqa %xmm0, -87(%edx)
-L(aligned_16_71bytes):
- movdqa %xmm0, -71(%edx)
-L(aligned_16_55bytes):
- movdqa %xmm0, -55(%edx)
-L(aligned_16_39bytes):
- movdqa %xmm0, -39(%edx)
-L(aligned_16_23bytes):
- movdqa %xmm0, -23(%edx)
-L(aligned_16_7bytes):
- movl %eax, -7(%edx)
- movw %ax, -3(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_120bytes):
- movdqa %xmm0, -120(%edx)
-L(aligned_16_104bytes):
- movdqa %xmm0, -104(%edx)
-L(aligned_16_88bytes):
- movdqa %xmm0, -88(%edx)
-L(aligned_16_72bytes):
- movdqa %xmm0, -72(%edx)
-L(aligned_16_56bytes):
- movdqa %xmm0, -56(%edx)
-L(aligned_16_40bytes):
- movdqa %xmm0, -40(%edx)
-L(aligned_16_24bytes):
- movdqa %xmm0, -24(%edx)
-L(aligned_16_8bytes):
- movq %xmm0, -8(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_121bytes):
- movdqa %xmm0, -121(%edx)
-L(aligned_16_105bytes):
- movdqa %xmm0, -105(%edx)
-L(aligned_16_89bytes):
- movdqa %xmm0, -89(%edx)
-L(aligned_16_73bytes):
- movdqa %xmm0, -73(%edx)
-L(aligned_16_57bytes):
- movdqa %xmm0, -57(%edx)
-L(aligned_16_41bytes):
- movdqa %xmm0, -41(%edx)
-L(aligned_16_25bytes):
- movdqa %xmm0, -25(%edx)
-L(aligned_16_9bytes):
- movq %xmm0, -9(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_122bytes):
- movdqa %xmm0, -122(%edx)
-L(aligned_16_106bytes):
- movdqa %xmm0, -106(%edx)
-L(aligned_16_90bytes):
- movdqa %xmm0, -90(%edx)
-L(aligned_16_74bytes):
- movdqa %xmm0, -74(%edx)
-L(aligned_16_58bytes):
- movdqa %xmm0, -58(%edx)
-L(aligned_16_42bytes):
- movdqa %xmm0, -42(%edx)
-L(aligned_16_26bytes):
- movdqa %xmm0, -26(%edx)
-L(aligned_16_10bytes):
- movq %xmm0, -10(%edx)
- movw %ax, -2(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_123bytes):
- movdqa %xmm0, -123(%edx)
-L(aligned_16_107bytes):
- movdqa %xmm0, -107(%edx)
-L(aligned_16_91bytes):
- movdqa %xmm0, -91(%edx)
-L(aligned_16_75bytes):
- movdqa %xmm0, -75(%edx)
-L(aligned_16_59bytes):
- movdqa %xmm0, -59(%edx)
-L(aligned_16_43bytes):
- movdqa %xmm0, -43(%edx)
-L(aligned_16_27bytes):
- movdqa %xmm0, -27(%edx)
-L(aligned_16_11bytes):
- movq %xmm0, -11(%edx)
- movw %ax, -3(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_124bytes):
- movdqa %xmm0, -124(%edx)
-L(aligned_16_108bytes):
- movdqa %xmm0, -108(%edx)
-L(aligned_16_92bytes):
- movdqa %xmm0, -92(%edx)
-L(aligned_16_76bytes):
- movdqa %xmm0, -76(%edx)
-L(aligned_16_60bytes):
- movdqa %xmm0, -60(%edx)
-L(aligned_16_44bytes):
- movdqa %xmm0, -44(%edx)
-L(aligned_16_28bytes):
- movdqa %xmm0, -28(%edx)
-L(aligned_16_12bytes):
- movq %xmm0, -12(%edx)
- movl %eax, -4(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_125bytes):
- movdqa %xmm0, -125(%edx)
-L(aligned_16_109bytes):
- movdqa %xmm0, -109(%edx)
-L(aligned_16_93bytes):
- movdqa %xmm0, -93(%edx)
-L(aligned_16_77bytes):
- movdqa %xmm0, -77(%edx)
-L(aligned_16_61bytes):
- movdqa %xmm0, -61(%edx)
-L(aligned_16_45bytes):
- movdqa %xmm0, -45(%edx)
-L(aligned_16_29bytes):
- movdqa %xmm0, -29(%edx)
-L(aligned_16_13bytes):
- movq %xmm0, -13(%edx)
- movl %eax, -5(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_126bytes):
- movdqa %xmm0, -126(%edx)
-L(aligned_16_110bytes):
- movdqa %xmm0, -110(%edx)
-L(aligned_16_94bytes):
- movdqa %xmm0, -94(%edx)
-L(aligned_16_78bytes):
- movdqa %xmm0, -78(%edx)
-L(aligned_16_62bytes):
- movdqa %xmm0, -62(%edx)
-L(aligned_16_46bytes):
- movdqa %xmm0, -46(%edx)
-L(aligned_16_30bytes):
- movdqa %xmm0, -30(%edx)
-L(aligned_16_14bytes):
- movq %xmm0, -14(%edx)
- movl %eax, -6(%edx)
- movw %ax, -2(%edx)
- SETRTNVAL
- RETURN
-
- ALIGN(4)
-L(aligned_16_127bytes):
- movdqa %xmm0, -127(%edx)
-L(aligned_16_111bytes):
- movdqa %xmm0, -111(%edx)
-L(aligned_16_95bytes):
- movdqa %xmm0, -95(%edx)
-L(aligned_16_79bytes):
- movdqa %xmm0, -79(%edx)
-L(aligned_16_63bytes):
- movdqa %xmm0, -63(%edx)
-L(aligned_16_47bytes):
- movdqa %xmm0, -47(%edx)
-L(aligned_16_31bytes):
- movdqa %xmm0, -31(%edx)
-L(aligned_16_15bytes):
- movq %xmm0, -15(%edx)
- movl %eax, -7(%edx)
- movw %ax, -3(%edx)
- movb %al, -1(%edx)
- SETRTNVAL
- RETURN_END
-
-END(memset_atom)
diff --git a/libc/arch-x86/string/sse2-memset-slm.S b/libc/arch-x86/string/sse2-memset-slm.S
index 5cff141..ec2ee52 100644
--- a/libc/arch-x86/string/sse2-memset-slm.S
+++ b/libc/arch-x86/string/sse2-memset-slm.S
@@ -31,7 +31,6 @@
#include <private/bionic_asm.h>
#define FOR_SILVERMONT
-#include "cache.h"
#ifndef L
# define L(label) .L##label
@@ -64,6 +63,8 @@
# define RETURN RETURN_END; CFI_PUSH(%ebx)
# define JMPTBL(I, B) I - B
+#define SETUP_PIC_REG(x) call __x86.get_pc_thunk.x
+
/* Load an entry in a jump table into EBX and branch to it. TABLE is a
jump table with relative offsets. */
# define BRANCH_TO_JMPTBL_ENTRY(TABLE) \
@@ -78,7 +79,7 @@
/* We loaded the jump table and adjusted EDX. Go. */ \
jmp *%ebx
-ENTRY(__memset_chk_generic)
+ENTRY(__memset_chk)
ENTRANCE
movl LEN(%esp), %ecx
@@ -87,11 +88,11 @@
POP(%ebx) // Undo ENTRANCE without returning.
jmp __memset_chk_fail
-END(__memset_chk_generic)
+END(__memset_chk)
.section .text.sse2,"ax",@progbits
ALIGN(4)
-ENTRY(memset_generic)
+ENTRY(memset)
ENTRANCE
movl LEN(%esp), %ecx
@@ -177,14 +178,18 @@
ALIGN(4)
L(128bytesormore):
PUSH(%ebx)
- mov $SHARED_CACHE_SIZE, %ebx
+ SETUP_PIC_REG(bx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+ mov __x86_shared_cache_size@GOTOFF(%ebx), %ebx
cmp %ebx, %ecx
jae L(128bytesormore_nt_start)
POP(%ebx)
PUSH(%ebx)
- mov $DATA_CACHE_SIZE, %ebx
+ SETUP_PIC_REG(bx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+ mov __x86_data_cache_size@GOTOFF(%ebx), %ebx
cmp %ebx, %ecx
jae L(128bytes_L2_normal)
@@ -750,4 +755,4 @@
SETRTNVAL
RETURN_END
-END(memset_generic)
+END(memset)
diff --git a/libc/arch-x86/string/sse2-stpcpy-slm.S b/libc/arch-x86/string/sse2-stpcpy-slm.S
old mode 100755
new mode 100644
diff --git a/libc/arch-x86/string/sse2-strchr-atom.S b/libc/arch-x86/string/sse2-strchr-atom.S
deleted file mode 100644
index e325181..0000000
--- a/libc/arch-x86/string/sse2-strchr-atom.S
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 8
-#define ENTRANCE PUSH(%edi)
-#define RETURN POP (%edi); ret; CFI_PUSH (%edi);
-
-
-#define STR1 PARMS
-#define STR2 STR1+4
-
- .text
-ENTRY (strchr)
-
- ENTRANCE
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
-
- pxor %xmm2, %xmm2
- mov %ecx, %edi
- punpcklbw %xmm1, %xmm1
- punpcklbw %xmm1, %xmm1
- /* ECX has OFFSET. */
- and $15, %ecx
- pshufd $0, %xmm1, %xmm1
- je L(loop)
-
-/* Handle unaligned string. */
- and $-16, %edi
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- /* Find where NULL is. */
- pmovmskb %xmm2, %edx
- /* Check if there is a match. */
- pmovmskb %xmm0, %eax
- /* Remove the leading bytes. */
- sarl %cl, %edx
- sarl %cl, %eax
- test %eax, %eax
- jz L(unaligned_no_match)
- add %ecx, %edi
- test %edx, %edx
- jz L(match_case1)
- jmp L(match_case2)
-
- .p2align 4
-L(unaligned_no_match):
- test %edx, %edx
- jne L(return_null)
-
- pxor %xmm2, %xmm2
- add $16, %edi
-
- .p2align 4
-/* Loop start on aligned string. */
-L(loop):
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches)
- test %edx, %edx
- jnz L(return_null)
- add $16, %edi
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches)
- test %edx, %edx
- jnz L(return_null)
- add $16, %edi
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches)
- test %edx, %edx
- jnz L(return_null)
- add $16, %edi
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(matches)
- test %edx, %edx
- jnz L(return_null)
- add $16, %edi
- jmp L(loop)
-
-L(matches):
- /* There is a match. First find where NULL is. */
- test %edx, %edx
- jz L(match_case1)
-
- .p2align 4
-L(match_case2):
- test %al, %al
- jz L(match_higth_case2)
-
- mov %al, %cl
- and $15, %cl
- jnz L(match_case2_4)
-
- mov %dl, %ch
- and $15, %ch
- jnz L(return_null)
-
- test $0x10, %al
- jnz L(Exit5)
- test $0x10, %dl
- jnz L(return_null)
- test $0x20, %al
- jnz L(Exit6)
- test $0x20, %dl
- jnz L(return_null)
- test $0x40, %al
- jnz L(Exit7)
- test $0x40, %dl
- jnz L(return_null)
- lea 7(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2_4):
- test $0x01, %al
- jnz L(Exit1)
- test $0x01, %dl
- jnz L(return_null)
- test $0x02, %al
- jnz L(Exit2)
- test $0x02, %dl
- jnz L(return_null)
- test $0x04, %al
- jnz L(Exit3)
- test $0x04, %dl
- jnz L(return_null)
- lea 3(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_higth_case2):
- test %dl, %dl
- jnz L(return_null)
-
- mov %ah, %cl
- and $15, %cl
- jnz L(match_case2_12)
-
- mov %dh, %ch
- and $15, %ch
- jnz L(return_null)
-
- test $0x10, %ah
- jnz L(Exit13)
- test $0x10, %dh
- jnz L(return_null)
- test $0x20, %ah
- jnz L(Exit14)
- test $0x20, %dh
- jnz L(return_null)
- test $0x40, %ah
- jnz L(Exit15)
- test $0x40, %dh
- jnz L(return_null)
- lea 15(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case2_12):
- test $0x01, %ah
- jnz L(Exit9)
- test $0x01, %dh
- jnz L(return_null)
- test $0x02, %ah
- jnz L(Exit10)
- test $0x02, %dh
- jnz L(return_null)
- test $0x04, %ah
- jnz L(Exit11)
- test $0x04, %dh
- jnz L(return_null)
- lea 11(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1):
- test %al, %al
- jz L(match_higth_case1)
-
- test $0x01, %al
- jnz L(Exit1)
- test $0x02, %al
- jnz L(Exit2)
- test $0x04, %al
- jnz L(Exit3)
- test $0x08, %al
- jnz L(Exit4)
- test $0x10, %al
- jnz L(Exit5)
- test $0x20, %al
- jnz L(Exit6)
- test $0x40, %al
- jnz L(Exit7)
- lea 7(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_higth_case1):
- test $0x01, %ah
- jnz L(Exit9)
- test $0x02, %ah
- jnz L(Exit10)
- test $0x04, %ah
- jnz L(Exit11)
- test $0x08, %ah
- jnz L(Exit12)
- test $0x10, %ah
- jnz L(Exit13)
- test $0x20, %ah
- jnz L(Exit14)
- test $0x40, %ah
- jnz L(Exit15)
- lea 15(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit1):
- lea (%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit2):
- lea 1(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit3):
- lea 2(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit4):
- lea 3(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit5):
- lea 4(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit6):
- lea 5(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit7):
- lea 6(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit9):
- lea 8(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit10):
- lea 9(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit11):
- lea 10(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit12):
- lea 11(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit13):
- lea 12(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit14):
- lea 13(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit15):
- lea 14(%edi), %eax
- RETURN
-
- .p2align 4
-L(return_null):
- xor %eax, %eax
- RETURN
-
-END (strchr)
diff --git a/libc/arch-x86/string/sse2-strcpy-slm.S b/libc/arch-x86/string/sse2-strcpy-slm.S
old mode 100755
new mode 100644
index 22ceeab..b5d84b5
--- a/libc/arch-x86/string/sse2-strcpy-slm.S
+++ b/libc/arch-x86/string/sse2-strcpy-slm.S
@@ -79,7 +79,7 @@
#define POP(REG) popl REG; CFI_POP (REG)
#ifndef STRCPY
-# define STRCPY strcpy_generic
+# define STRCPY strcpy
#endif
#ifdef USE_AS_STPNCPY
diff --git a/libc/arch-x86/string/sse2-strlen-slm.S b/libc/arch-x86/string/sse2-strlen-slm.S
old mode 100755
new mode 100644
index b805ad6..27cc025
--- a/libc/arch-x86/string/sse2-strlen-slm.S
+++ b/libc/arch-x86/string/sse2-strlen-slm.S
@@ -29,7 +29,7 @@
*/
#ifndef STRLEN
-# define STRLEN strlen_generic
+# define STRLEN strlen
#endif
#ifndef L
diff --git a/libc/arch-x86/string/sse2-strncpy-slm.S b/libc/arch-x86/string/sse2-strncpy-slm.S
old mode 100755
new mode 100644
index aff7fb9..591419f
--- a/libc/arch-x86/string/sse2-strncpy-slm.S
+++ b/libc/arch-x86/string/sse2-strncpy-slm.S
@@ -29,5 +29,5 @@
*/
#define USE_AS_STRNCPY
-#define STRCPY strncpy_generic
+#define STRCPY strncpy
#include "sse2-strcpy-slm.S"
diff --git a/libc/arch-x86/string/sse2-strnlen-atom.S b/libc/arch-x86/string/sse2-strnlen-atom.S
deleted file mode 100644
index 1f89b4e..0000000
--- a/libc/arch-x86/string/sse2-strnlen-atom.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define USE_AS_STRNLEN 1
-#define STRLEN strnlen
-#include "sse2-strlen-atom.S"
diff --git a/libc/arch-x86/string/sse2-strrchr-atom.S b/libc/arch-x86/string/sse2-strrchr-atom.S
deleted file mode 100644
index e916bc1..0000000
--- a/libc/arch-x86/string/sse2-strrchr-atom.S
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 8
-#define ENTRANCE PUSH(%edi);
-#define RETURN POP (%edi); ret; CFI_PUSH (%edi);
-
-#define STR1 PARMS
-#define STR2 STR1+4
-
- .text
-ENTRY (strrchr)
-
- ENTRANCE
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
-
- pxor %xmm2, %xmm2
- mov %ecx, %edi
- punpcklbw %xmm1, %xmm1
- punpcklbw %xmm1, %xmm1
- /* ECX has OFFSET. */
- and $63, %ecx
- pshufd $0, %xmm1, %xmm1
- cmp $48, %ecx
- ja L(crosscache)
-
-/* unaligned string. */
- movdqu (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- pcmpeqb %xmm1, %xmm0
- /* Find where NULL is. */
- pmovmskb %xmm2, %ecx
- /* Check if there is a match. */
- pmovmskb %xmm0, %eax
- add $16, %edi
-
- test %eax, %eax
- jnz L(unaligned_match1)
-
- test %ecx, %ecx
- jnz L(return_null)
-
- and $-16, %edi
-
- PUSH (%esi)
- PUSH (%ebx)
-
- xor %ebx, %ebx
- jmp L(loop)
-
- CFI_POP (%esi)
- CFI_POP (%ebx)
-
- .p2align 4
-L(unaligned_match1):
- test %ecx, %ecx
- jnz L(prolog_find_zero_1)
-
- PUSH (%esi)
- PUSH (%ebx)
-
- mov %eax, %ebx
- mov %edi, %esi
- and $-16, %edi
- jmp L(loop)
-
- CFI_POP (%esi)
- CFI_POP (%ebx)
-
- .p2align 4
-L(crosscache):
-/* Hancle unaligned string. */
- and $15, %ecx
- and $-16, %edi
- pxor %xmm3, %xmm3
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm3
- pcmpeqb %xmm1, %xmm0
- /* Find where NULL is. */
- pmovmskb %xmm3, %edx
- /* Check if there is a match. */
- pmovmskb %xmm0, %eax
- /* Remove the leading bytes. */
- shr %cl, %edx
- shr %cl, %eax
- add $16, %edi
-
- test %eax, %eax
- jnz L(unaligned_match)
-
- test %edx, %edx
- jnz L(return_null)
-
- PUSH (%esi)
- PUSH (%ebx)
-
- xor %ebx, %ebx
- jmp L(loop)
-
- CFI_POP (%esi)
- CFI_POP (%ebx)
-
- .p2align 4
-L(unaligned_match):
- test %edx, %edx
- jnz L(prolog_find_zero)
-
- PUSH (%esi)
- PUSH (%ebx)
-
- mov %eax, %ebx
- lea (%edi, %ecx), %esi
-
-/* Loop start on aligned string. */
- .p2align 4
-L(loop):
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- add $16, %edi
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm0, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- add $16, %edi
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm0, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- add $16, %edi
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm0, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm0
- pcmpeqb %xmm0, %xmm2
- add $16, %edi
- pcmpeqb %xmm1, %xmm0
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm0, %eax
- or %eax, %ecx
- jz L(loop)
-
-L(matches):
- test %eax, %eax
- jnz L(match)
-L(return_value):
- test %ebx, %ebx
- jz L(return_null_1)
- mov %ebx, %eax
- mov %esi, %edi
-
- POP (%ebx)
- POP (%esi)
-
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(return_null_1):
- POP (%ebx)
- POP (%esi)
-
- xor %eax, %eax
- RETURN
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(match):
- pmovmskb %xmm2, %ecx
- test %ecx, %ecx
- jnz L(find_zero)
- mov %eax, %ebx
- mov %edi, %esi
- jmp L(loop)
-
- .p2align 4
-L(find_zero):
- test %cl, %cl
- jz L(find_zero_high)
- mov %cl, %dl
- and $15, %dl
- jz L(find_zero_8)
- test $0x01, %cl
- jnz L(FindZeroExit1)
- test $0x02, %cl
- jnz L(FindZeroExit2)
- test $0x04, %cl
- jnz L(FindZeroExit3)
- and $(1 << 4) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_8):
- test $0x10, %cl
- jnz L(FindZeroExit5)
- test $0x20, %cl
- jnz L(FindZeroExit6)
- test $0x40, %cl
- jnz L(FindZeroExit7)
- and $(1 << 8) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_high):
- mov %ch, %dh
- and $15, %dh
- jz L(find_zero_high_8)
- test $0x01, %ch
- jnz L(FindZeroExit9)
- test $0x02, %ch
- jnz L(FindZeroExit10)
- test $0x04, %ch
- jnz L(FindZeroExit11)
- and $(1 << 12) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_high_8):
- test $0x10, %ch
- jnz L(FindZeroExit13)
- test $0x20, %ch
- jnz L(FindZeroExit14)
- test $0x40, %ch
- jnz L(FindZeroExit15)
- and $(1 << 16) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit1):
- and $1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit2):
- and $(1 << 2) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit3):
- and $(1 << 3) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit5):
- and $(1 << 5) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit6):
- and $(1 << 6) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit7):
- and $(1 << 7) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit9):
- and $(1 << 9) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit10):
- and $(1 << 10) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit11):
- and $(1 << 11) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit13):
- and $(1 << 13) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit14):
- and $(1 << 14) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
- jmp L(match_case1)
-
- CFI_PUSH (%ebx)
- CFI_PUSH (%esi)
-
- .p2align 4
-L(FindZeroExit15):
- and $(1 << 15) - 1, %eax
- jz L(return_value)
-
- POP (%ebx)
- POP (%esi)
-
- .p2align 4
-L(match_case1):
- test %ah, %ah
- jnz L(match_case1_high)
- mov %al, %dl
- and $15 << 4, %dl
- jnz L(match_case1_8)
- test $0x08, %al
- jnz L(Exit4)
- test $0x04, %al
- jnz L(Exit3)
- test $0x02, %al
- jnz L(Exit2)
- lea -16(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_8):
- test $0x80, %al
- jnz L(Exit8)
- test $0x40, %al
- jnz L(Exit7)
- test $0x20, %al
- jnz L(Exit6)
- lea -12(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_high):
- mov %ah, %dh
- and $15 << 4, %dh
- jnz L(match_case1_high_8)
- test $0x08, %ah
- jnz L(Exit12)
- test $0x04, %ah
- jnz L(Exit11)
- test $0x02, %ah
- jnz L(Exit10)
- lea -8(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_case1_high_8):
- test $0x80, %ah
- jnz L(Exit16)
- test $0x40, %ah
- jnz L(Exit15)
- test $0x20, %ah
- jnz L(Exit14)
- lea -4(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit2):
- lea -15(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit3):
- lea -14(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit4):
- lea -13(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit6):
- lea -11(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit7):
- lea -10(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit8):
- lea -9(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit10):
- lea -7(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit11):
- lea -6(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit12):
- lea -5(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit14):
- lea -3(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit15):
- lea -2(%edi), %eax
- RETURN
-
- .p2align 4
-L(Exit16):
- lea -1(%edi), %eax
- RETURN
-
-/* Return NULL. */
- .p2align 4
-L(return_null):
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero):
- add %ecx, %edi
- mov %edx, %ecx
-L(prolog_find_zero_1):
- test %cl, %cl
- jz L(prolog_find_zero_high)
- mov %cl, %dl
- and $15, %dl
- jz L(prolog_find_zero_8)
- test $0x01, %cl
- jnz L(PrologFindZeroExit1)
- test $0x02, %cl
- jnz L(PrologFindZeroExit2)
- test $0x04, %cl
- jnz L(PrologFindZeroExit3)
- and $(1 << 4) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_8):
- test $0x10, %cl
- jnz L(PrologFindZeroExit5)
- test $0x20, %cl
- jnz L(PrologFindZeroExit6)
- test $0x40, %cl
- jnz L(PrologFindZeroExit7)
- and $(1 << 8) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_high):
- mov %ch, %dh
- and $15, %dh
- jz L(prolog_find_zero_high_8)
- test $0x01, %ch
- jnz L(PrologFindZeroExit9)
- test $0x02, %ch
- jnz L(PrologFindZeroExit10)
- test $0x04, %ch
- jnz L(PrologFindZeroExit11)
- and $(1 << 12) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_high_8):
- test $0x10, %ch
- jnz L(PrologFindZeroExit13)
- test $0x20, %ch
- jnz L(PrologFindZeroExit14)
- test $0x40, %ch
- jnz L(PrologFindZeroExit15)
- and $(1 << 16) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit1):
- and $1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit2):
- and $(1 << 2) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit3):
- and $(1 << 3) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit5):
- and $(1 << 5) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit6):
- and $(1 << 6) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit7):
- and $(1 << 7) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit9):
- and $(1 << 9) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit10):
- and $(1 << 10) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit11):
- and $(1 << 11) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit13):
- and $(1 << 13) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit14):
- and $(1 << 14) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(PrologFindZeroExit15):
- and $(1 << 15) - 1, %eax
- jnz L(match_case1)
- xor %eax, %eax
- RETURN
-
-END (strrchr)
diff --git a/libc/arch-x86/string/sse2-wcschr-atom.S b/libc/arch-x86/string/sse2-wcschr-atom.S
deleted file mode 100644
index 729302b..0000000
--- a/libc/arch-x86/string/sse2-wcschr-atom.S
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 4
-
-
-#define STR1 PARMS
-#define STR2 STR1+4
-
- .text
-ENTRY (wcschr)
-
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
-
- mov %ecx, %eax
- punpckldq %xmm1, %xmm1
- pxor %xmm2, %xmm2
- punpckldq %xmm1, %xmm1
-
- and $63, %eax
- cmp $48, %eax
- ja L(cross_cache)
-
- movdqu (%ecx), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- or %eax, %edx
- jnz L(matches)
- and $-16, %ecx
- jmp L(loop)
-
- .p2align 4
-L(cross_cache):
- PUSH (%edi)
- mov %ecx, %edi
- mov %eax, %ecx
- and $-16, %edi
- and $15, %ecx
- movdqa (%edi), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
-
- sarl %cl, %edx
- sarl %cl, %eax
- test %eax, %eax
- jz L(unaligned_no_match)
-
- add %edi, %ecx
- POP (%edi)
-
- test %edx, %edx
- jz L(match_case1)
- test %al, %al
- jz L(match_higth_case2)
- test $15, %al
- jnz L(match_case2_4)
- test $15, %dl
- jnz L(return_null)
- lea 4(%ecx), %eax
- ret
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(unaligned_no_match):
- mov %edi, %ecx
- POP (%edi)
-
- test %edx, %edx
- jnz L(return_null)
-
- pxor %xmm2, %xmm2
-
-/* Loop start on aligned string. */
- .p2align 4
-L(loop):
- add $16, %ecx
- movdqa (%ecx), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- or %eax, %edx
- jnz L(matches)
- add $16, %ecx
-
- movdqa (%ecx), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- or %eax, %edx
- jnz L(matches)
- add $16, %ecx
-
- movdqa (%ecx), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- or %eax, %edx
- jnz L(matches)
- add $16, %ecx
-
- movdqa (%ecx), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %edx
- pmovmskb %xmm0, %eax
- or %eax, %edx
- jz L(loop)
-
- .p2align 4
-L(matches):
- pmovmskb %xmm2, %edx
- test %eax, %eax
- jz L(return_null)
- test %edx, %edx
- jz L(match_case1)
-
- .p2align 4
-L(match_case2):
- test %al, %al
- jz L(match_higth_case2)
- test $15, %al
- jnz L(match_case2_4)
- test $15, %dl
- jnz L(return_null)
- lea 4(%ecx), %eax
- ret
-
- .p2align 4
-L(match_case2_4):
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(match_higth_case2):
- test %dl, %dl
- jnz L(return_null)
- test $15, %ah
- jnz L(match_case2_12)
- test $15, %dh
- jnz L(return_null)
- lea 12(%ecx), %eax
- ret
-
- .p2align 4
-L(match_case2_12):
- lea 8(%ecx), %eax
- ret
-
- .p2align 4
-L(match_case1):
- test %al, %al
- jz L(match_higth_case1)
-
- test $0x01, %al
- jnz L(exit0)
- lea 4(%ecx), %eax
- ret
-
- .p2align 4
-L(match_higth_case1):
- test $0x01, %ah
- jnz L(exit3)
- lea 12(%ecx), %eax
- ret
-
- .p2align 4
-L(exit0):
- mov %ecx, %eax
- ret
-
- .p2align 4
-L(exit3):
- lea 8(%ecx), %eax
- ret
-
- .p2align 4
-L(return_null):
- xor %eax, %eax
- ret
-
-END (wcschr)
diff --git a/libc/arch-x86/string/sse2-wcscmp-atom.S b/libc/arch-x86/string/sse2-wcscmp-atom.S
deleted file mode 100644
index 8867d28..0000000
--- a/libc/arch-x86/string/sse2-wcscmp-atom.S
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define ENTRANCE PUSH(%esi); PUSH(%edi)
-#define RETURN POP(%edi); POP(%esi); ret; CFI_PUSH(%esi); CFI_PUSH(%edi);
-#define PARMS 4
-#define STR1 PARMS
-#define STR2 STR1+4
-
- .text
-ENTRY (wcscmp)
-/*
- * This implementation uses SSE to compare up to 16 bytes at a time.
-*/
- mov STR1(%esp), %edx
- mov STR2(%esp), %eax
-
- mov (%eax), %ecx
- cmp %ecx, (%edx)
- jne L(neq)
- test %ecx, %ecx
- jz L(eq)
-
- mov 4(%eax), %ecx
- cmp %ecx, 4(%edx)
- jne L(neq)
- test %ecx, %ecx
- jz L(eq)
-
- mov 8(%eax), %ecx
- cmp %ecx, 8(%edx)
- jne L(neq)
- test %ecx, %ecx
- jz L(eq)
-
- mov 12(%eax), %ecx
- cmp %ecx, 12(%edx)
- jne L(neq)
- test %ecx, %ecx
- jz L(eq)
-
- ENTRANCE
- add $16, %eax
- add $16, %edx
-
- mov %eax, %esi
- mov %edx, %edi
- pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */
- mov %al, %ch
- mov %dl, %cl
- and $63, %eax /* esi alignment in cache line */
- and $63, %edx /* edi alignment in cache line */
- and $15, %cl
- jz L(continue_00)
- cmp $16, %edx
- jb L(continue_0)
- cmp $32, %edx
- jb L(continue_16)
- cmp $48, %edx
- jb L(continue_32)
-
-L(continue_48):
- and $15, %ch
- jz L(continue_48_00)
- cmp $16, %eax
- jb L(continue_0_48)
- cmp $32, %eax
- jb L(continue_16_48)
- cmp $48, %eax
- jb L(continue_32_48)
-
- .p2align 4
-L(continue_48_48):
- mov (%esi), %ecx
- cmp %ecx, (%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- movdqu 16(%edi), %xmm1
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%edi), %xmm1
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- movdqu 48(%edi), %xmm1
- movdqu 48(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_48_48)
-
-L(continue_0):
- and $15, %ch
- jz L(continue_0_00)
- cmp $16, %eax
- jb L(continue_0_0)
- cmp $32, %eax
- jb L(continue_0_16)
- cmp $48, %eax
- jb L(continue_0_32)
-
- .p2align 4
-L(continue_0_48):
- mov (%esi), %ecx
- cmp %ecx, (%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- movdqu 16(%edi), %xmm1
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%edi), %xmm1
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- mov 48(%esi), %ecx
- cmp %ecx, 48(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 52(%esi), %ecx
- cmp %ecx, 52(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 56(%esi), %ecx
- cmp %ecx, 56(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 60(%esi), %ecx
- cmp %ecx, 60(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_0_48)
-
- .p2align 4
-L(continue_00):
- and $15, %ch
- jz L(continue_00_00)
- cmp $16, %eax
- jb L(continue_00_0)
- cmp $32, %eax
- jb L(continue_00_16)
- cmp $48, %eax
- jb L(continue_00_32)
-
- .p2align 4
-L(continue_00_48):
- pcmpeqd (%edi), %xmm0
- mov (%edi), %eax
- pmovmskb %xmm0, %ecx
- test %ecx, %ecx
- jnz L(less4_double_words1)
-
- cmp (%esi), %eax
- jne L(nequal)
-
- mov 4(%edi), %eax
- cmp 4(%esi), %eax
- jne L(nequal)
-
- mov 8(%edi), %eax
- cmp 8(%esi), %eax
- jne L(nequal)
-
- mov 12(%edi), %eax
- cmp 12(%esi), %eax
- jne L(nequal)
-
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 32(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- movdqu 48(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 48(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_00_48)
-
- .p2align 4
-L(continue_32):
- and $15, %ch
- jz L(continue_32_00)
- cmp $16, %eax
- jb L(continue_0_32)
- cmp $32, %eax
- jb L(continue_16_32)
- cmp $48, %eax
- jb L(continue_32_32)
-
- .p2align 4
-L(continue_32_48):
- mov (%esi), %ecx
- cmp %ecx, (%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 16(%esi), %ecx
- cmp %ecx, 16(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 20(%esi), %ecx
- cmp %ecx, 20(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 24(%esi), %ecx
- cmp %ecx, 24(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 28(%esi), %ecx
- cmp %ecx, 28(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- movdqu 32(%edi), %xmm1
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- movdqu 48(%edi), %xmm1
- movdqu 48(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_32_48)
-
- .p2align 4
-L(continue_16):
- and $15, %ch
- jz L(continue_16_00)
- cmp $16, %eax
- jb L(continue_0_16)
- cmp $32, %eax
- jb L(continue_16_16)
- cmp $48, %eax
- jb L(continue_16_32)
-
- .p2align 4
-L(continue_16_48):
- mov (%esi), %ecx
- cmp %ecx, (%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- movdqu 16(%edi), %xmm1
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- mov 32(%esi), %ecx
- cmp %ecx, 32(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 36(%esi), %ecx
- cmp %ecx, 36(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 40(%esi), %ecx
- cmp %ecx, 40(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 44(%esi), %ecx
- cmp %ecx, 44(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- movdqu 48(%edi), %xmm1
- movdqu 48(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_16_48)
-
- .p2align 4
-L(continue_00_00):
- movdqa (%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd (%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqa 16(%edi), %xmm3
- pcmpeqd %xmm3, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%esi), %xmm3 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm3 /* packed sub of comparison results*/
- pmovmskb %xmm3, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqa 32(%edi), %xmm5
- pcmpeqd %xmm5, %xmm0 /* Any null double_word? */
- pcmpeqd 32(%esi), %xmm5 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm5 /* packed sub of comparison results*/
- pmovmskb %xmm5, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- movdqa 48(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 48(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_00_00)
-
- .p2align 4
-L(continue_00_32):
- movdqu (%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd (%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- add $16, %esi
- add $16, %edi
- jmp L(continue_00_48)
-
- .p2align 4
-L(continue_00_16):
- movdqu (%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd (%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- add $32, %esi
- add $32, %edi
- jmp L(continue_00_48)
-
- .p2align 4
-L(continue_00_0):
- movdqu (%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd (%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm2, %xmm0 /* Any null double_word? */
- pcmpeqd 32(%edi), %xmm2 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm2 /* packed sub of comparison results*/
- pmovmskb %xmm2, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- add $48, %esi
- add $48, %edi
- jmp L(continue_00_48)
-
- .p2align 4
-L(continue_48_00):
- pcmpeqd (%esi), %xmm0
- mov (%edi), %eax
- pmovmskb %xmm0, %ecx
- test %ecx, %ecx
- jnz L(less4_double_words1)
-
- cmp (%esi), %eax
- jne L(nequal)
-
- mov 4(%edi), %eax
- cmp 4(%esi), %eax
- jne L(nequal)
-
- mov 8(%edi), %eax
- cmp 8(%esi), %eax
- jne L(nequal)
-
- mov 12(%edi), %eax
- cmp 12(%esi), %eax
- jne L(nequal)
-
- movdqu 16(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 32(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- movdqu 48(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 48(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_48)
-
- add $64, %esi
- add $64, %edi
- jmp L(continue_48_00)
-
- .p2align 4
-L(continue_32_00):
- movdqu (%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd (%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- add $16, %esi
- add $16, %edi
- jmp L(continue_48_00)
-
- .p2align 4
-L(continue_16_00):
- movdqu (%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd (%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- add $32, %esi
- add $32, %edi
- jmp L(continue_48_00)
-
- .p2align 4
-L(continue_0_00):
- movdqu (%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd (%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 16(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%edi), %xmm1
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd 32(%esi), %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- add $48, %esi
- add $48, %edi
- jmp L(continue_48_00)
-
- .p2align 4
-L(continue_32_32):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- add $16, %esi
- add $16, %edi
- jmp L(continue_48_48)
-
- .p2align 4
-L(continue_16_16):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%edi), %xmm3
- movdqu 16(%esi), %xmm4
- pcmpeqd %xmm3, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm4, %xmm3 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm3 /* packed sub of comparison results*/
- pmovmskb %xmm3, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- add $32, %esi
- add $32, %edi
- jmp L(continue_48_48)
-
- .p2align 4
-L(continue_0_0):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%edi), %xmm3
- movdqu 16(%esi), %xmm4
- pcmpeqd %xmm3, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm4, %xmm3 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm3 /* packed sub of comparison results*/
- pmovmskb %xmm3, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- movdqu 32(%edi), %xmm1
- movdqu 32(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_32)
-
- add $48, %esi
- add $48, %edi
- jmp L(continue_48_48)
-
- .p2align 4
-L(continue_0_16):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- movdqu 16(%edi), %xmm1
- movdqu 16(%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words_16)
-
- add $32, %esi
- add $32, %edi
- jmp L(continue_32_48)
-
- .p2align 4
-L(continue_0_32):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- add $16, %esi
- add $16, %edi
- jmp L(continue_16_48)
-
- .p2align 4
-L(continue_16_32):
- movdqu (%edi), %xmm1
- movdqu (%esi), %xmm2
- pcmpeqd %xmm1, %xmm0 /* Any null double_word? */
- pcmpeqd %xmm2, %xmm1 /* compare first 4 double_words for equality */
- psubb %xmm0, %xmm1 /* packed sub of comparison results*/
- pmovmskb %xmm1, %edx
- sub $0xffff, %edx /* if first 4 double_words are same, edx == 0xffff */
- jnz L(less4_double_words)
-
- add $16, %esi
- add $16, %edi
- jmp L(continue_32_48)
-
- .p2align 4
-L(less4_double_words1):
- cmp (%esi), %eax
- jne L(nequal)
- test %eax, %eax
- jz L(equal)
-
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- test %ecx, %ecx
- jz L(equal)
-
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(less4_double_words):
- xor %eax, %eax
- test %dl, %dl
- jz L(next_two_double_words)
- and $15, %dl
- jz L(second_double_word)
- mov (%esi), %ecx
- cmp %ecx, (%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(second_double_word):
- mov 4(%esi), %ecx
- cmp %ecx, 4(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(next_two_double_words):
- and $15, %dh
- jz L(fourth_double_word)
- mov 8(%esi), %ecx
- cmp %ecx, 8(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(fourth_double_word):
- mov 12(%esi), %ecx
- cmp %ecx, 12(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(less4_double_words_16):
- xor %eax, %eax
- test %dl, %dl
- jz L(next_two_double_words_16)
- and $15, %dl
- jz L(second_double_word_16)
- mov 16(%esi), %ecx
- cmp %ecx, 16(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(second_double_word_16):
- mov 20(%esi), %ecx
- cmp %ecx, 20(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(next_two_double_words_16):
- and $15, %dh
- jz L(fourth_double_word_16)
- mov 24(%esi), %ecx
- cmp %ecx, 24(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(fourth_double_word_16):
- mov 28(%esi), %ecx
- cmp %ecx, 28(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(less4_double_words_32):
- xor %eax, %eax
- test %dl, %dl
- jz L(next_two_double_words_32)
- and $15, %dl
- jz L(second_double_word_32)
- mov 32(%esi), %ecx
- cmp %ecx, 32(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(second_double_word_32):
- mov 36(%esi), %ecx
- cmp %ecx, 36(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(next_two_double_words_32):
- and $15, %dh
- jz L(fourth_double_word_32)
- mov 40(%esi), %ecx
- cmp %ecx, 40(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(fourth_double_word_32):
- mov 44(%esi), %ecx
- cmp %ecx, 44(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(less4_double_words_48):
- xor %eax, %eax
- test %dl, %dl
- jz L(next_two_double_words_48)
- and $15, %dl
- jz L(second_double_word_48)
- mov 48(%esi), %ecx
- cmp %ecx, 48(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(second_double_word_48):
- mov 52(%esi), %ecx
- cmp %ecx, 52(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(next_two_double_words_48):
- and $15, %dh
- jz L(fourth_double_word_48)
- mov 56(%esi), %ecx
- cmp %ecx, 56(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(fourth_double_word_48):
- mov 60(%esi), %ecx
- cmp %ecx, 60(%edi)
- jne L(nequal)
- RETURN
-
- .p2align 4
-L(nequal):
- mov $1, %eax
- jg L(return)
- neg %eax
- RETURN
-
- .p2align 4
-L(return):
- RETURN
-
- .p2align 4
-L(equal):
- xorl %eax, %eax
- RETURN
-
- CFI_POP (%edi)
- CFI_POP (%esi)
-
- .p2align 4
-L(neq):
- mov $1, %eax
- jg L(neq_bigger)
- neg %eax
-
-L(neq_bigger):
- ret
-
- .p2align 4
-L(eq):
- xorl %eax, %eax
- ret
-
-END (wcscmp)
-
diff --git a/libc/arch-x86/string/sse2-wcslen-atom.S b/libc/arch-x86/string/sse2-wcslen-atom.S
deleted file mode 100644
index 2f10db4..0000000
--- a/libc/arch-x86/string/sse2-wcslen-atom.S
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef USE_AS_WCSCAT
-
-# ifndef L
-# define L(label) .L##label
-# endif
-
-# ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-# endif
-
-# ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-# endif
-
-# ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-# endif
-
-# ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-# endif
-
-# define PARMS 4
-# define STR PARMS
-# define RETURN ret
-
- .text
-ENTRY (wcslen)
- mov STR(%esp), %edx
-#endif
- cmpl $0, (%edx)
- jz L(exit_tail0)
- cmpl $0, 4(%edx)
- jz L(exit_tail1)
- cmpl $0, 8(%edx)
- jz L(exit_tail2)
- cmpl $0, 12(%edx)
- jz L(exit_tail3)
- cmpl $0, 16(%edx)
- jz L(exit_tail4)
- cmpl $0, 20(%edx)
- jz L(exit_tail5)
- cmpl $0, 24(%edx)
- jz L(exit_tail6)
- cmpl $0, 28(%edx)
- jz L(exit_tail7)
-
- pxor %xmm0, %xmm0
-
- lea 32(%edx), %eax
- lea -16(%eax), %ecx
- and $-16, %eax
-
- pcmpeqd (%eax), %xmm0
- pmovmskb %xmm0, %edx
- pxor %xmm1, %xmm1
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm1
- pmovmskb %xmm1, %edx
- pxor %xmm2, %xmm2
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm2
- pmovmskb %xmm2, %edx
- pxor %xmm3, %xmm3
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- and $-0x40, %eax
-
- .p2align 4
-L(aligned_64_loop):
- movaps (%eax), %xmm0
- movaps 16(%eax), %xmm1
- movaps 32(%eax), %xmm2
- movaps 48(%eax), %xmm6
-
- pminub %xmm1, %xmm0
- pminub %xmm6, %xmm2
- pminub %xmm0, %xmm2
- pcmpeqd %xmm3, %xmm2
- pmovmskb %xmm2, %edx
- lea 64(%eax), %eax
- test %edx, %edx
- jz L(aligned_64_loop)
-
- pcmpeqd -64(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 48(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd %xmm1, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd -32(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqd %xmm6, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- jmp L(aligned_64_loop)
-
- .p2align 4
-L(exit):
- sub %ecx, %eax
- shr $2, %eax
- test %dl, %dl
- jz L(exit_high)
-
- mov %dl, %cl
- and $15, %cl
- jz L(exit_1)
- RETURN
-
- .p2align 4
-L(exit_high):
- mov %dh, %ch
- and $15, %ch
- jz L(exit_3)
- add $2, %eax
- RETURN
-
- .p2align 4
-L(exit_1):
- add $1, %eax
- RETURN
-
- .p2align 4
-L(exit_3):
- add $3, %eax
- RETURN
-
- .p2align 4
-L(exit_tail0):
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(exit_tail1):
- mov $1, %eax
- RETURN
-
- .p2align 4
-L(exit_tail2):
- mov $2, %eax
- RETURN
-
- .p2align 4
-L(exit_tail3):
- mov $3, %eax
- RETURN
-
- .p2align 4
-L(exit_tail4):
- mov $4, %eax
- RETURN
-
- .p2align 4
-L(exit_tail5):
- mov $5, %eax
- RETURN
-
- .p2align 4
-L(exit_tail6):
- mov $6, %eax
- RETURN
-
- .p2align 4
-L(exit_tail7):
- mov $7, %eax
-#ifndef USE_AS_WCSCAT
- RETURN
-
-END (wcslen)
-#endif
diff --git a/libc/arch-x86/string/sse2-wcsrchr-atom.S b/libc/arch-x86/string/sse2-wcsrchr-atom.S
deleted file mode 100644
index 1a55df2..0000000
--- a/libc/arch-x86/string/sse2-wcsrchr-atom.S
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 8
-#define ENTRANCE PUSH(%edi);
-#define RETURN POP(%edi); ret; CFI_PUSH(%edi);
-
-#define STR1 PARMS
-#define STR2 STR1+4
-
- .text
-ENTRY (wcsrchr)
-
- ENTRANCE
- mov STR1(%esp), %ecx
- movd STR2(%esp), %xmm1
-
- mov %ecx, %edi
- punpckldq %xmm1, %xmm1
- pxor %xmm2, %xmm2
- punpckldq %xmm1, %xmm1
-
-/* ECX has OFFSET. */
- and $63, %ecx
- cmp $48, %ecx
- ja L(crosscache)
-
-/* unaligned string. */
- movdqu (%edi), %xmm0
- pcmpeqd %xmm0, %xmm2
- pcmpeqd %xmm1, %xmm0
-/* Find where NULL is. */
- pmovmskb %xmm2, %ecx
-/* Check if there is a match. */
- pmovmskb %xmm0, %eax
- add $16, %edi
-
- test %eax, %eax
- jnz L(unaligned_match1)
-
- test %ecx, %ecx
- jnz L(return_null)
-
- and $-16, %edi
-
- PUSH (%esi)
-
- xor %edx, %edx
- jmp L(loop)
-
- CFI_POP (%esi)
-
- .p2align 4
-L(unaligned_match1):
- test %ecx, %ecx
- jnz L(prolog_find_zero_1)
-
- PUSH (%esi)
-
-/* Save current match */
- mov %eax, %edx
- mov %edi, %esi
- and $-16, %edi
- jmp L(loop)
-
- CFI_POP (%esi)
-
- .p2align 4
-L(crosscache):
-/* Hancle unaligned string. */
- and $15, %ecx
- and $-16, %edi
- pxor %xmm3, %xmm3
- movdqa (%edi), %xmm0
- pcmpeqd %xmm0, %xmm3
- pcmpeqd %xmm1, %xmm0
-/* Find where NULL is. */
- pmovmskb %xmm3, %edx
-/* Check if there is a match. */
- pmovmskb %xmm0, %eax
-/* Remove the leading bytes. */
- shr %cl, %edx
- shr %cl, %eax
- add $16, %edi
-
- test %eax, %eax
- jnz L(unaligned_match)
-
- test %edx, %edx
- jnz L(return_null)
-
- PUSH (%esi)
-
- xor %edx, %edx
- jmp L(loop)
-
- CFI_POP (%esi)
-
- .p2align 4
-L(unaligned_match):
- test %edx, %edx
- jnz L(prolog_find_zero)
-
- PUSH (%esi)
-
- mov %eax, %edx
- lea (%edi, %ecx), %esi
-
-/* Loop start on aligned string. */
- .p2align 4
-L(loop):
- movdqa (%edi), %xmm0
- pcmpeqd %xmm0, %xmm2
- add $16, %edi
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm0, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm3
- pcmpeqd %xmm3, %xmm2
- add $16, %edi
- pcmpeqd %xmm1, %xmm3
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm3, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm4
- pcmpeqd %xmm4, %xmm2
- add $16, %edi
- pcmpeqd %xmm1, %xmm4
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm4, %eax
- or %eax, %ecx
- jnz L(matches)
-
- movdqa (%edi), %xmm5
- pcmpeqd %xmm5, %xmm2
- add $16, %edi
- pcmpeqd %xmm1, %xmm5
- pmovmskb %xmm2, %ecx
- pmovmskb %xmm5, %eax
- or %eax, %ecx
- jz L(loop)
-
- .p2align 4
-L(matches):
- test %eax, %eax
- jnz L(match)
-L(return_value):
- test %edx, %edx
- jz L(return_null_1)
- mov %edx, %eax
- mov %esi, %edi
-
- POP (%esi)
-
- test %ah, %ah
- jnz L(match_third_or_fourth_wchar)
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(return_null_1):
- POP (%esi)
-
- xor %eax, %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(match):
- pmovmskb %xmm2, %ecx
- test %ecx, %ecx
- jnz L(find_zero)
-/* save match info */
- mov %eax, %edx
- mov %edi, %esi
- jmp L(loop)
-
- .p2align 4
-L(find_zero):
- test %cl, %cl
- jz L(find_zero_in_third_or_fourth_wchar)
- test $15, %cl
- jz L(find_zero_in_second_wchar)
- and $1, %eax
- jz L(return_value)
-
- POP (%esi)
-
- lea -16(%edi), %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_in_second_wchar):
- and $(1 << 5) - 1, %eax
- jz L(return_value)
-
- POP (%esi)
-
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_in_third_or_fourth_wchar):
- test $15, %ch
- jz L(find_zero_in_fourth_wchar)
- and $(1 << 9) - 1, %eax
- jz L(return_value)
-
- POP (%esi)
-
- test %ah, %ah
- jnz L(match_third_wchar)
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(find_zero_in_fourth_wchar):
-
- POP (%esi)
-
- test %ah, %ah
- jnz L(match_third_or_fourth_wchar)
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(match_second_wchar):
- lea -12(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_third_or_fourth_wchar):
- test $15 << 4, %ah
- jnz L(match_fourth_wchar)
- lea -8(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_third_wchar):
- lea -8(%edi), %eax
- RETURN
-
- .p2align 4
-L(match_fourth_wchar):
- lea -4(%edi), %eax
- RETURN
-
- .p2align 4
-L(return_null):
- xor %eax, %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero):
- add %ecx, %edi
- mov %edx, %ecx
-L(prolog_find_zero_1):
- test %cl, %cl
- jz L(prolog_find_zero_in_third_or_fourth_wchar)
- test $15, %cl
- jz L(prolog_find_zero_in_second_wchar)
- and $1, %eax
- jz L(return_null)
-
- lea -16(%edi), %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_in_second_wchar):
- and $(1 << 5) - 1, %eax
- jz L(return_null)
-
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_in_third_or_fourth_wchar):
- test $15, %ch
- jz L(prolog_find_zero_in_fourth_wchar)
- and $(1 << 9) - 1, %eax
- jz L(return_null)
-
- test %ah, %ah
- jnz L(match_third_wchar)
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
- .p2align 4
-L(prolog_find_zero_in_fourth_wchar):
- test %ah, %ah
- jnz L(match_third_or_fourth_wchar)
- test $15 << 4, %al
- jnz L(match_second_wchar)
- lea -16(%edi), %eax
- RETURN
-
-END (wcsrchr)
diff --git a/libc/arch-x86/string/sse4-memcmp-slm.S b/libc/arch-x86/string/sse4-memcmp-slm.S
old mode 100755
new mode 100644
diff --git a/libc/arch-x86/string/sse4-wmemcmp-slm.S b/libc/arch-x86/string/sse4-wmemcmp-slm.S
deleted file mode 100755
index 2bf92f5..0000000
--- a/libc/arch-x86/string/sse4-wmemcmp-slm.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define USE_AS_WMEMCMP
-#define MEMCMP wmemcmp_sse4
-#include "sse4-memcmp-slm.S"
diff --git a/libc/arch-x86/string/ssse3-memcpy-atom.S b/libc/arch-x86/string/ssse3-memcpy-atom.S
deleted file mode 100644
index fe3082e..0000000
--- a/libc/arch-x86/string/ssse3-memcpy-atom.S
+++ /dev/null
@@ -1,3125 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define FOR_ATOM
-#include "cache.h"
-
-#ifndef MEMCPY
-# define MEMCPY memcpy_atom
-#endif
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define DEST PARMS
-#define SRC DEST+4
-#define LEN SRC+4
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#if (defined SHARED || defined __PIC__)
-# define PARMS 8 /* Preserve EBX. */
-# define ENTRANCE PUSH (%ebx);
-# define RETURN_END POP (%ebx); ret
-# define RETURN RETURN_END; CFI_PUSH (%ebx)
-# define JMPTBL(I, B) I - B
-
-# define SETUP_PIC_REG(x) call __x86.get_pc_thunk.x
-
-/* Load an entry in a jump table into EBX and branch to it. TABLE is a
- jump table with relative offsets. INDEX is a register contains the
- index into the jump table. SCALE is the scale of INDEX. */
-
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
- /* We first load PC into EBX. */ \
- SETUP_PIC_REG(bx); \
- /* Get the address of the jump table. */ \
- addl $(TABLE - .), %ebx; \
- /* Get the entry and convert the relative offset to the \
- absolute address. */ \
- addl (%ebx, INDEX, SCALE), %ebx; \
- /* We loaded the jump table. Go. */ \
- jmp *%ebx
-#else
-
-# define PARMS 4
-# define ENTRANCE
-# define RETURN_END ret
-# define RETURN RETURN_END
-# define JMPTBL(I, B) I
-
-/* Branch to an entry in a jump table. TABLE is a jump table with
- absolute offsets. INDEX is a register contains the index into the
- jump table. SCALE is the scale of INDEX. */
-
-# define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
- jmp *TABLE(, INDEX, SCALE)
-#endif
-
- .section .text.ssse3,"ax",@progbits
-ENTRY (MEMCPY)
- ENTRANCE
- movl LEN(%esp), %ecx
- movl SRC(%esp), %eax
- movl DEST(%esp), %edx
-
-#ifdef USE_AS_MEMMOVE
- cmp %eax, %edx
- jb L(copy_forward)
- je L(fwd_write_0bytes)
- cmp $32, %ecx
- jae L(memmove_bwd)
- jmp L(bk_write_less32bytes_2)
-
- .p2align 4
-L(memmove_bwd):
- add %ecx, %eax
- cmp %eax, %edx
- movl SRC(%esp), %eax
- jb L(copy_backward)
-
-L(copy_forward):
-#endif
- cmp $48, %ecx
- jae L(48bytesormore)
-
-L(fwd_write_less32bytes):
-#ifndef USE_AS_MEMMOVE
- cmp %dl, %al
- jb L(bk_write)
-#endif
- add %ecx, %edx
- add %ecx, %eax
- BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd), %ecx, 4)
-#ifndef USE_AS_MEMMOVE
- .p2align 4
-L(bk_write):
- BRANCH_TO_JMPTBL_ENTRY (L(table_48_bytes_bwd), %ecx, 4)
-#endif
-
- .p2align 4
-L(48bytesormore):
-#ifndef USE_AS_MEMMOVE
- movlpd (%eax), %xmm0
- movlpd 8(%eax), %xmm1
- movlpd %xmm0, (%edx)
- movlpd %xmm1, 8(%edx)
-#else
- movdqu (%eax), %xmm0
-#endif
- PUSH (%edi)
- movl %edx, %edi
- and $-16, %edx
- add $16, %edx
- sub %edx, %edi
- add %edi, %ecx
- sub %edi, %eax
-
-#ifdef SHARED_CACHE_SIZE_HALF
- cmp $SHARED_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_shared_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_shared_cache_size_half, %ecx
-# endif
-#endif
-
- mov %eax, %edi
- jae L(large_page)
- and $0xf, %edi
- jz L(shl_0)
- BRANCH_TO_JMPTBL_ENTRY (L(shl_table), %edi, 4)
-
- .p2align 4
-L(shl_0):
-#ifdef USE_AS_MEMMOVE
- movl DEST+4(%esp), %edi
- movdqu %xmm0, (%edi)
-#endif
- xor %edi, %edi
- cmp $127, %ecx
- ja L(shl_0_gobble)
- lea -32(%ecx), %ecx
-
- .p2align 4
-L(shl_0_loop):
- movdqa (%eax, %edi), %xmm0
- movdqa 16(%eax, %edi), %xmm1
- sub $32, %ecx
- movdqa %xmm0, (%edx, %edi)
- movdqa %xmm1, 16(%edx, %edi)
- lea 32(%edi), %edi
- jb L(shl_0_end)
-
- movdqa (%eax, %edi), %xmm0
- movdqa 16(%eax, %edi), %xmm1
- sub $32, %ecx
- movdqa %xmm0, (%edx, %edi)
- movdqa %xmm1, 16(%edx, %edi)
- lea 32(%edi), %edi
- jb L(shl_0_end)
-
- movdqa (%eax, %edi), %xmm0
- movdqa 16(%eax, %edi), %xmm1
- sub $32, %ecx
- movdqa %xmm0, (%edx, %edi)
- movdqa %xmm1, 16(%edx, %edi)
- lea 32(%edi), %edi
- jb L(shl_0_end)
-
- movdqa (%eax, %edi), %xmm0
- movdqa 16(%eax, %edi), %xmm1
- sub $32, %ecx
- movdqa %xmm0, (%edx, %edi)
- movdqa %xmm1, 16(%edx, %edi)
- lea 32(%edi), %edi
-
-L(shl_0_end):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- add %edi, %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd_align), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_0_gobble):
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- POP (%edi)
- lea -128(%ecx), %ecx
- jae L(shl_0_gobble_mem_loop)
-
- .p2align 4
-L(shl_0_gobble_cache_loop):
- movdqa (%eax), %xmm0
- movdqa 0x10(%eax), %xmm1
- movdqa 0x20(%eax), %xmm2
- movdqa 0x30(%eax), %xmm3
- movdqa 0x40(%eax), %xmm4
- movdqa 0x50(%eax), %xmm5
- movdqa 0x60(%eax), %xmm6
- movdqa 0x70(%eax), %xmm7
- lea 0x80(%eax), %eax
- sub $128, %ecx
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
- movdqa %xmm2, 0x20(%edx)
- movdqa %xmm3, 0x30(%edx)
- movdqa %xmm4, 0x40(%edx)
- movdqa %xmm5, 0x50(%edx)
- movdqa %xmm6, 0x60(%edx)
- movdqa %xmm7, 0x70(%edx)
- lea 0x80(%edx), %edx
-
- jae L(shl_0_gobble_cache_loop)
- cmp $-0x40, %ecx
- lea 0x80(%ecx), %ecx
- jl L(shl_0_cache_less_64bytes)
-
- movdqa (%eax), %xmm0
- sub $0x40, %ecx
- movdqa 0x10(%eax), %xmm1
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
- movdqa 0x20(%eax), %xmm0
- movdqa 0x30(%eax), %xmm1
- add $0x40, %eax
- movdqa %xmm0, 0x20(%edx)
- movdqa %xmm1, 0x30(%edx)
- add $0x40, %edx
-
-L(shl_0_cache_less_64bytes):
- cmp $0x20, %ecx
- jb L(shl_0_cache_less_32bytes)
- movdqa (%eax), %xmm0
- sub $0x20, %ecx
- movdqa 0x10(%eax), %xmm1
- add $0x20, %eax
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
- add $0x20, %edx
-
-L(shl_0_cache_less_32bytes):
- cmp $0x10, %ecx
- jb L(shl_0_cache_less_16bytes)
- sub $0x10, %ecx
- movdqa (%eax), %xmm0
- add $0x10, %eax
- movdqa %xmm0, (%edx)
- add $0x10, %edx
-
-L(shl_0_cache_less_16bytes):
- add %ecx, %edx
- add %ecx, %eax
- BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd), %ecx, 4)
-
- .p2align 4
-L(shl_0_gobble_mem_loop):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x280(%eax)
- prefetcht0 0x1c0(%edx)
-
- movdqa (%eax), %xmm0
- movdqa 0x10(%eax), %xmm1
- movdqa 0x20(%eax), %xmm2
- movdqa 0x30(%eax), %xmm3
- movdqa 0x40(%eax), %xmm4
- movdqa 0x50(%eax), %xmm5
- movdqa 0x60(%eax), %xmm6
- movdqa 0x70(%eax), %xmm7
- lea 0x80(%eax), %eax
- sub $0x80, %ecx
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
- movdqa %xmm2, 0x20(%edx)
- movdqa %xmm3, 0x30(%edx)
- movdqa %xmm4, 0x40(%edx)
- movdqa %xmm5, 0x50(%edx)
- movdqa %xmm6, 0x60(%edx)
- movdqa %xmm7, 0x70(%edx)
- lea 0x80(%edx), %edx
-
- jae L(shl_0_gobble_mem_loop)
- cmp $-0x40, %ecx
- lea 0x80(%ecx), %ecx
- jl L(shl_0_mem_less_64bytes)
-
- movdqa (%eax), %xmm0
- sub $0x40, %ecx
- movdqa 0x10(%eax), %xmm1
-
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
-
- movdqa 0x20(%eax), %xmm0
- movdqa 0x30(%eax), %xmm1
- add $0x40, %eax
-
- movdqa %xmm0, 0x20(%edx)
- movdqa %xmm1, 0x30(%edx)
- add $0x40, %edx
-
-L(shl_0_mem_less_64bytes):
- cmp $0x20, %ecx
- jb L(shl_0_mem_less_32bytes)
- movdqa (%eax), %xmm0
- sub $0x20, %ecx
- movdqa 0x10(%eax), %xmm1
- add $0x20, %eax
- movdqa %xmm0, (%edx)
- movdqa %xmm1, 0x10(%edx)
- add $0x20, %edx
-
-L(shl_0_mem_less_32bytes):
- cmp $0x10, %ecx
- jb L(shl_0_mem_less_16bytes)
- sub $0x10, %ecx
- movdqa (%eax), %xmm0
- add $0x10, %eax
- movdqa %xmm0, (%edx)
- add $0x10, %edx
-
-L(shl_0_mem_less_16bytes):
- add %ecx, %edx
- add %ecx, %eax
- BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd_align), %ecx, 4)
-
- .p2align 4
-L(shl_1):
-#ifndef USE_AS_MEMMOVE
- movaps -1(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -1(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_1_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl1LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 15(%eax), %xmm2
- movaps 31(%eax), %xmm3
- movaps 47(%eax), %xmm4
- movaps 63(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $1, %xmm4, %xmm5
- palignr $1, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $1, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $1, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl1LoopStart)
-
-L(Shl1LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 15(%eax), %xmm2
- movaps 31(%eax), %xmm3
- palignr $1, %xmm2, %xmm3
- palignr $1, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_1_no_prefetch):
- lea -32(%ecx), %ecx
- lea -1(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_1_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $1, %xmm2, %xmm3
- palignr $1, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_1_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $1, %xmm2, %xmm3
- palignr $1, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_1_no_prefetch_loop)
-
-L(sh_1_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 1(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_2):
-#ifndef USE_AS_MEMMOVE
- movaps -2(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -2(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_2_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl2LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 14(%eax), %xmm2
- movaps 30(%eax), %xmm3
- movaps 46(%eax), %xmm4
- movaps 62(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $2, %xmm4, %xmm5
- palignr $2, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $2, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $2, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl2LoopStart)
-
-L(Shl2LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 14(%eax), %xmm2
- movaps 30(%eax), %xmm3
- palignr $2, %xmm2, %xmm3
- palignr $2, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_2_no_prefetch):
- lea -32(%ecx), %ecx
- lea -2(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_2_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $2, %xmm2, %xmm3
- palignr $2, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_2_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $2, %xmm2, %xmm3
- palignr $2, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_2_no_prefetch_loop)
-
-L(sh_2_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 2(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_3):
-#ifndef USE_AS_MEMMOVE
- movaps -3(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -3(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_3_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl3LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 13(%eax), %xmm2
- movaps 29(%eax), %xmm3
- movaps 45(%eax), %xmm4
- movaps 61(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $3, %xmm4, %xmm5
- palignr $3, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $3, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $3, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl3LoopStart)
-
-L(Shl3LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 13(%eax), %xmm2
- movaps 29(%eax), %xmm3
- palignr $3, %xmm2, %xmm3
- palignr $3, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_3_no_prefetch):
- lea -32(%ecx), %ecx
- lea -3(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_3_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $3, %xmm2, %xmm3
- palignr $3, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jb L(sh_3_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $3, %xmm2, %xmm3
- palignr $3, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jae L(sh_3_no_prefetch_loop)
-
-L(sh_3_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 3(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_4):
-#ifndef USE_AS_MEMMOVE
- movaps -4(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -4(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_4_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl4LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 12(%eax), %xmm2
- movaps 28(%eax), %xmm3
- movaps 44(%eax), %xmm4
- movaps 60(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $4, %xmm4, %xmm5
- palignr $4, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $4, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $4, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl4LoopStart)
-
-L(Shl4LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 12(%eax), %xmm2
- movaps 28(%eax), %xmm3
- palignr $4, %xmm2, %xmm3
- palignr $4, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_4_no_prefetch):
- lea -32(%ecx), %ecx
- lea -4(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_4_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $4, %xmm2, %xmm3
- palignr $4, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jb L(sh_4_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $4, %xmm2, %xmm3
- palignr $4, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jae L(sh_4_no_prefetch_loop)
-
-L(sh_4_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 4(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_5):
-#ifndef USE_AS_MEMMOVE
- movaps -5(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -5(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_5_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl5LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 11(%eax), %xmm2
- movaps 27(%eax), %xmm3
- movaps 43(%eax), %xmm4
- movaps 59(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $5, %xmm4, %xmm5
- palignr $5, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $5, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $5, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl5LoopStart)
-
-L(Shl5LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 11(%eax), %xmm2
- movaps 27(%eax), %xmm3
- palignr $5, %xmm2, %xmm3
- palignr $5, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_5_no_prefetch):
- lea -32(%ecx), %ecx
- lea -5(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_5_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $5, %xmm2, %xmm3
- palignr $5, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jb L(sh_5_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $5, %xmm2, %xmm3
- palignr $5, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jae L(sh_5_no_prefetch_loop)
-
-L(sh_5_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 5(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_6):
-#ifndef USE_AS_MEMMOVE
- movaps -6(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -6(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_6_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl6LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 10(%eax), %xmm2
- movaps 26(%eax), %xmm3
- movaps 42(%eax), %xmm4
- movaps 58(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $6, %xmm4, %xmm5
- palignr $6, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $6, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $6, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl6LoopStart)
-
-L(Shl6LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 10(%eax), %xmm2
- movaps 26(%eax), %xmm3
- palignr $6, %xmm2, %xmm3
- palignr $6, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_6_no_prefetch):
- lea -32(%ecx), %ecx
- lea -6(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_6_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $6, %xmm2, %xmm3
- palignr $6, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jb L(sh_6_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $6, %xmm2, %xmm3
- palignr $6, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
-
- jae L(sh_6_no_prefetch_loop)
-
-L(sh_6_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 6(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_7):
-#ifndef USE_AS_MEMMOVE
- movaps -7(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -7(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_7_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl7LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 9(%eax), %xmm2
- movaps 25(%eax), %xmm3
- movaps 41(%eax), %xmm4
- movaps 57(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $7, %xmm4, %xmm5
- palignr $7, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $7, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $7, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl7LoopStart)
-
-L(Shl7LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 9(%eax), %xmm2
- movaps 25(%eax), %xmm3
- palignr $7, %xmm2, %xmm3
- palignr $7, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_7_no_prefetch):
- lea -32(%ecx), %ecx
- lea -7(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_7_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $7, %xmm2, %xmm3
- palignr $7, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_7_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $7, %xmm2, %xmm3
- palignr $7, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_7_no_prefetch_loop)
-
-L(sh_7_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 7(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_8):
-#ifndef USE_AS_MEMMOVE
- movaps -8(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -8(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_8_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl8LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 8(%eax), %xmm2
- movaps 24(%eax), %xmm3
- movaps 40(%eax), %xmm4
- movaps 56(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $8, %xmm4, %xmm5
- palignr $8, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $8, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $8, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl8LoopStart)
-
-L(LoopLeave8):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 8(%eax), %xmm2
- movaps 24(%eax), %xmm3
- palignr $8, %xmm2, %xmm3
- palignr $8, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_8_no_prefetch):
- lea -32(%ecx), %ecx
- lea -8(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_8_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $8, %xmm2, %xmm3
- palignr $8, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_8_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $8, %xmm2, %xmm3
- palignr $8, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_8_no_prefetch_loop)
-
-L(sh_8_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 8(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_9):
-#ifndef USE_AS_MEMMOVE
- movaps -9(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -9(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_9_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl9LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 7(%eax), %xmm2
- movaps 23(%eax), %xmm3
- movaps 39(%eax), %xmm4
- movaps 55(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $9, %xmm4, %xmm5
- palignr $9, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $9, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $9, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl9LoopStart)
-
-L(Shl9LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 7(%eax), %xmm2
- movaps 23(%eax), %xmm3
- palignr $9, %xmm2, %xmm3
- palignr $9, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_9_no_prefetch):
- lea -32(%ecx), %ecx
- lea -9(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_9_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $9, %xmm2, %xmm3
- palignr $9, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_9_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $9, %xmm2, %xmm3
- palignr $9, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_9_no_prefetch_loop)
-
-L(sh_9_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 9(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_10):
-#ifndef USE_AS_MEMMOVE
- movaps -10(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -10(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_10_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl10LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 6(%eax), %xmm2
- movaps 22(%eax), %xmm3
- movaps 38(%eax), %xmm4
- movaps 54(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $10, %xmm4, %xmm5
- palignr $10, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $10, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $10, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl10LoopStart)
-
-L(Shl10LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 6(%eax), %xmm2
- movaps 22(%eax), %xmm3
- palignr $10, %xmm2, %xmm3
- palignr $10, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_10_no_prefetch):
- lea -32(%ecx), %ecx
- lea -10(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_10_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $10, %xmm2, %xmm3
- palignr $10, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_10_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $10, %xmm2, %xmm3
- palignr $10, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_10_no_prefetch_loop)
-
-L(sh_10_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 10(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_11):
-#ifndef USE_AS_MEMMOVE
- movaps -11(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -11(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_11_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl11LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 5(%eax), %xmm2
- movaps 21(%eax), %xmm3
- movaps 37(%eax), %xmm4
- movaps 53(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $11, %xmm4, %xmm5
- palignr $11, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $11, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $11, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl11LoopStart)
-
-L(Shl11LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 5(%eax), %xmm2
- movaps 21(%eax), %xmm3
- palignr $11, %xmm2, %xmm3
- palignr $11, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_11_no_prefetch):
- lea -32(%ecx), %ecx
- lea -11(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_11_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $11, %xmm2, %xmm3
- palignr $11, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_11_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $11, %xmm2, %xmm3
- palignr $11, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_11_no_prefetch_loop)
-
-L(sh_11_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 11(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_12):
-#ifndef USE_AS_MEMMOVE
- movaps -12(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -12(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_12_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl12LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 4(%eax), %xmm2
- movaps 20(%eax), %xmm3
- movaps 36(%eax), %xmm4
- movaps 52(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $12, %xmm4, %xmm5
- palignr $12, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $12, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $12, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl12LoopStart)
-
-L(Shl12LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 4(%eax), %xmm2
- movaps 20(%eax), %xmm3
- palignr $12, %xmm2, %xmm3
- palignr $12, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_12_no_prefetch):
- lea -32(%ecx), %ecx
- lea -12(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_12_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $12, %xmm2, %xmm3
- palignr $12, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_12_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $12, %xmm2, %xmm3
- palignr $12, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_12_no_prefetch_loop)
-
-L(sh_12_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 12(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_13):
-#ifndef USE_AS_MEMMOVE
- movaps -13(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -13(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_13_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl13LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 3(%eax), %xmm2
- movaps 19(%eax), %xmm3
- movaps 35(%eax), %xmm4
- movaps 51(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $13, %xmm4, %xmm5
- palignr $13, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $13, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $13, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl13LoopStart)
-
-L(Shl13LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 3(%eax), %xmm2
- movaps 19(%eax), %xmm3
- palignr $13, %xmm2, %xmm3
- palignr $13, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_13_no_prefetch):
- lea -32(%ecx), %ecx
- lea -13(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_13_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $13, %xmm2, %xmm3
- palignr $13, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_13_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $13, %xmm2, %xmm3
- palignr $13, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_13_no_prefetch_loop)
-
-L(sh_13_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 13(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_14):
-#ifndef USE_AS_MEMMOVE
- movaps -14(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -14(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_14_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl14LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 2(%eax), %xmm2
- movaps 18(%eax), %xmm3
- movaps 34(%eax), %xmm4
- movaps 50(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $14, %xmm4, %xmm5
- palignr $14, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $14, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $14, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl14LoopStart)
-
-L(Shl14LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 2(%eax), %xmm2
- movaps 18(%eax), %xmm3
- palignr $14, %xmm2, %xmm3
- palignr $14, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_14_no_prefetch):
- lea -32(%ecx), %ecx
- lea -14(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_14_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $14, %xmm2, %xmm3
- palignr $14, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_14_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $14, %xmm2, %xmm3
- palignr $14, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_14_no_prefetch_loop)
-
-L(sh_14_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 14(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_15):
-#ifndef USE_AS_MEMMOVE
- movaps -15(%eax), %xmm1
-#else
- movl DEST+4(%esp), %edi
- movaps -15(%eax), %xmm1
- movdqu %xmm0, (%edi)
-#endif
-#ifdef DATA_CACHE_SIZE_HALF
- cmp $DATA_CACHE_SIZE_HALF, %ecx
-#else
-# if (defined SHARED || defined __PIC__)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size_half@GOTOFF(%ebx), %ecx
-# else
- cmp __x86_data_cache_size_half, %ecx
-# endif
-#endif
- jb L(sh_15_no_prefetch)
-
- lea -64(%ecx), %ecx
-
- .p2align 4
-L(Shl15LoopStart):
- prefetcht0 0x1c0(%eax)
- prefetcht0 0x1c0(%edx)
- movaps 1(%eax), %xmm2
- movaps 17(%eax), %xmm3
- movaps 33(%eax), %xmm4
- movaps 49(%eax), %xmm5
- movaps %xmm5, %xmm7
- palignr $15, %xmm4, %xmm5
- palignr $15, %xmm3, %xmm4
- movaps %xmm5, 48(%edx)
- palignr $15, %xmm2, %xmm3
- lea 64(%eax), %eax
- palignr $15, %xmm1, %xmm2
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm7, %xmm1
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- sub $64, %ecx
- ja L(Shl15LoopStart)
-
-L(Shl15LoopLeave):
- add $32, %ecx
- jle L(shl_end_0)
-
- movaps 1(%eax), %xmm2
- movaps 17(%eax), %xmm3
- palignr $15, %xmm2, %xmm3
- palignr $15, %xmm1, %xmm2
-
- movaps %xmm2, (%edx)
- movaps %xmm3, 16(%edx)
- lea 32(%edx, %ecx), %edx
- lea 32(%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(sh_15_no_prefetch):
- lea -32(%ecx), %ecx
- lea -15(%eax), %eax
- xor %edi, %edi
-
- .p2align 4
-L(sh_15_no_prefetch_loop):
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm4
- palignr $15, %xmm2, %xmm3
- palignr $15, %xmm1, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jb L(sh_15_end_no_prefetch_loop)
-
- movdqa 16(%eax, %edi), %xmm2
- sub $32, %ecx
- movdqa 32(%eax, %edi), %xmm3
- movdqa %xmm3, %xmm1
- palignr $15, %xmm2, %xmm3
- palignr $15, %xmm4, %xmm2
- lea 32(%edi), %edi
- movdqa %xmm2, -32(%edx, %edi)
- movdqa %xmm3, -16(%edx, %edi)
- jae L(sh_15_no_prefetch_loop)
-
-L(sh_15_end_no_prefetch_loop):
- lea 32(%ecx), %ecx
- add %ecx, %edi
- add %edi, %edx
- lea 15(%edi, %eax), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(shl_end_0):
- lea 32(%ecx), %ecx
- lea (%edx, %ecx), %edx
- lea (%eax, %ecx), %eax
- POP (%edi)
- BRANCH_TO_JMPTBL_ENTRY(L(table_48bytes_fwd), %ecx, 4)
-
- .p2align 4
-L(fwd_write_44bytes):
- movq -44(%eax), %xmm0
- movq %xmm0, -44(%edx)
-L(fwd_write_36bytes):
- movq -36(%eax), %xmm0
- movq %xmm0, -36(%edx)
-L(fwd_write_28bytes):
- movq -28(%eax), %xmm0
- movq %xmm0, -28(%edx)
-L(fwd_write_20bytes):
- movq -20(%eax), %xmm0
- movq %xmm0, -20(%edx)
-L(fwd_write_12bytes):
- movq -12(%eax), %xmm0
- movq %xmm0, -12(%edx)
-L(fwd_write_4bytes):
- movl -4(%eax), %ecx
- movl %ecx, -4(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_40bytes):
- movq -40(%eax), %xmm0
- movq %xmm0, -40(%edx)
-L(fwd_write_32bytes):
- movq -32(%eax), %xmm0
- movq %xmm0, -32(%edx)
-L(fwd_write_24bytes):
- movq -24(%eax), %xmm0
- movq %xmm0, -24(%edx)
-L(fwd_write_16bytes):
- movq -16(%eax), %xmm0
- movq %xmm0, -16(%edx)
-L(fwd_write_8bytes):
- movq -8(%eax), %xmm0
- movq %xmm0, -8(%edx)
-L(fwd_write_0bytes):
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_5bytes):
- movl -5(%eax), %ecx
- movl -4(%eax), %eax
- movl %ecx, -5(%edx)
- movl %eax, -4(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_45bytes):
- movq -45(%eax), %xmm0
- movq %xmm0, -45(%edx)
-L(fwd_write_37bytes):
- movq -37(%eax), %xmm0
- movq %xmm0, -37(%edx)
-L(fwd_write_29bytes):
- movq -29(%eax), %xmm0
- movq %xmm0, -29(%edx)
-L(fwd_write_21bytes):
- movq -21(%eax), %xmm0
- movq %xmm0, -21(%edx)
-L(fwd_write_13bytes):
- movq -13(%eax), %xmm0
- movq %xmm0, -13(%edx)
- movl -5(%eax), %ecx
- movl %ecx, -5(%edx)
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_41bytes):
- movq -41(%eax), %xmm0
- movq %xmm0, -41(%edx)
-L(fwd_write_33bytes):
- movq -33(%eax), %xmm0
- movq %xmm0, -33(%edx)
-L(fwd_write_25bytes):
- movq -25(%eax), %xmm0
- movq %xmm0, -25(%edx)
-L(fwd_write_17bytes):
- movq -17(%eax), %xmm0
- movq %xmm0, -17(%edx)
-L(fwd_write_9bytes):
- movq -9(%eax), %xmm0
- movq %xmm0, -9(%edx)
-L(fwd_write_1bytes):
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_46bytes):
- movq -46(%eax), %xmm0
- movq %xmm0, -46(%edx)
-L(fwd_write_38bytes):
- movq -38(%eax), %xmm0
- movq %xmm0, -38(%edx)
-L(fwd_write_30bytes):
- movq -30(%eax), %xmm0
- movq %xmm0, -30(%edx)
-L(fwd_write_22bytes):
- movq -22(%eax), %xmm0
- movq %xmm0, -22(%edx)
-L(fwd_write_14bytes):
- movq -14(%eax), %xmm0
- movq %xmm0, -14(%edx)
-L(fwd_write_6bytes):
- movl -6(%eax), %ecx
- movl %ecx, -6(%edx)
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_42bytes):
- movq -42(%eax), %xmm0
- movq %xmm0, -42(%edx)
-L(fwd_write_34bytes):
- movq -34(%eax), %xmm0
- movq %xmm0, -34(%edx)
-L(fwd_write_26bytes):
- movq -26(%eax), %xmm0
- movq %xmm0, -26(%edx)
-L(fwd_write_18bytes):
- movq -18(%eax), %xmm0
- movq %xmm0, -18(%edx)
-L(fwd_write_10bytes):
- movq -10(%eax), %xmm0
- movq %xmm0, -10(%edx)
-L(fwd_write_2bytes):
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_47bytes):
- movq -47(%eax), %xmm0
- movq %xmm0, -47(%edx)
-L(fwd_write_39bytes):
- movq -39(%eax), %xmm0
- movq %xmm0, -39(%edx)
-L(fwd_write_31bytes):
- movq -31(%eax), %xmm0
- movq %xmm0, -31(%edx)
-L(fwd_write_23bytes):
- movq -23(%eax), %xmm0
- movq %xmm0, -23(%edx)
-L(fwd_write_15bytes):
- movq -15(%eax), %xmm0
- movq %xmm0, -15(%edx)
-L(fwd_write_7bytes):
- movl -7(%eax), %ecx
- movl %ecx, -7(%edx)
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_43bytes):
- movq -43(%eax), %xmm0
- movq %xmm0, -43(%edx)
-L(fwd_write_35bytes):
- movq -35(%eax), %xmm0
- movq %xmm0, -35(%edx)
-L(fwd_write_27bytes):
- movq -27(%eax), %xmm0
- movq %xmm0, -27(%edx)
-L(fwd_write_19bytes):
- movq -19(%eax), %xmm0
- movq %xmm0, -19(%edx)
-L(fwd_write_11bytes):
- movq -11(%eax), %xmm0
- movq %xmm0, -11(%edx)
-L(fwd_write_3bytes):
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_40bytes_align):
- movdqa -40(%eax), %xmm0
- movdqa %xmm0, -40(%edx)
-L(fwd_write_24bytes_align):
- movdqa -24(%eax), %xmm0
- movdqa %xmm0, -24(%edx)
-L(fwd_write_8bytes_align):
- movq -8(%eax), %xmm0
- movq %xmm0, -8(%edx)
-L(fwd_write_0bytes_align):
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_32bytes_align):
- movdqa -32(%eax), %xmm0
- movdqa %xmm0, -32(%edx)
-L(fwd_write_16bytes_align):
- movdqa -16(%eax), %xmm0
- movdqa %xmm0, -16(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_5bytes_align):
- movl -5(%eax), %ecx
- movl -4(%eax), %eax
- movl %ecx, -5(%edx)
- movl %eax, -4(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_45bytes_align):
- movdqa -45(%eax), %xmm0
- movdqa %xmm0, -45(%edx)
-L(fwd_write_29bytes_align):
- movdqa -29(%eax), %xmm0
- movdqa %xmm0, -29(%edx)
-L(fwd_write_13bytes_align):
- movq -13(%eax), %xmm0
- movq %xmm0, -13(%edx)
- movl -5(%eax), %ecx
- movl %ecx, -5(%edx)
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_37bytes_align):
- movdqa -37(%eax), %xmm0
- movdqa %xmm0, -37(%edx)
-L(fwd_write_21bytes_align):
- movdqa -21(%eax), %xmm0
- movdqa %xmm0, -21(%edx)
- movl -5(%eax), %ecx
- movl %ecx, -5(%edx)
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_41bytes_align):
- movdqa -41(%eax), %xmm0
- movdqa %xmm0, -41(%edx)
-L(fwd_write_25bytes_align):
- movdqa -25(%eax), %xmm0
- movdqa %xmm0, -25(%edx)
-L(fwd_write_9bytes_align):
- movq -9(%eax), %xmm0
- movq %xmm0, -9(%edx)
-L(fwd_write_1bytes_align):
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_33bytes_align):
- movdqa -33(%eax), %xmm0
- movdqa %xmm0, -33(%edx)
-L(fwd_write_17bytes_align):
- movdqa -17(%eax), %xmm0
- movdqa %xmm0, -17(%edx)
- movzbl -1(%eax), %ecx
- movb %cl, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_46bytes_align):
- movdqa -46(%eax), %xmm0
- movdqa %xmm0, -46(%edx)
-L(fwd_write_30bytes_align):
- movdqa -30(%eax), %xmm0
- movdqa %xmm0, -30(%edx)
-L(fwd_write_14bytes_align):
- movq -14(%eax), %xmm0
- movq %xmm0, -14(%edx)
-L(fwd_write_6bytes_align):
- movl -6(%eax), %ecx
- movl %ecx, -6(%edx)
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_38bytes_align):
- movdqa -38(%eax), %xmm0
- movdqa %xmm0, -38(%edx)
-L(fwd_write_22bytes_align):
- movdqa -22(%eax), %xmm0
- movdqa %xmm0, -22(%edx)
- movl -6(%eax), %ecx
- movl %ecx, -6(%edx)
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_42bytes_align):
- movdqa -42(%eax), %xmm0
- movdqa %xmm0, -42(%edx)
-L(fwd_write_26bytes_align):
- movdqa -26(%eax), %xmm0
- movdqa %xmm0, -26(%edx)
-L(fwd_write_10bytes_align):
- movq -10(%eax), %xmm0
- movq %xmm0, -10(%edx)
-L(fwd_write_2bytes_align):
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_34bytes_align):
- movdqa -34(%eax), %xmm0
- movdqa %xmm0, -34(%edx)
-L(fwd_write_18bytes_align):
- movdqa -18(%eax), %xmm0
- movdqa %xmm0, -18(%edx)
- movzwl -2(%eax), %ecx
- movw %cx, -2(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_47bytes_align):
- movdqa -47(%eax), %xmm0
- movdqa %xmm0, -47(%edx)
-L(fwd_write_31bytes_align):
- movdqa -31(%eax), %xmm0
- movdqa %xmm0, -31(%edx)
-L(fwd_write_15bytes_align):
- movq -15(%eax), %xmm0
- movq %xmm0, -15(%edx)
-L(fwd_write_7bytes_align):
- movl -7(%eax), %ecx
- movl %ecx, -7(%edx)
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_39bytes_align):
- movdqa -39(%eax), %xmm0
- movdqa %xmm0, -39(%edx)
-L(fwd_write_23bytes_align):
- movdqa -23(%eax), %xmm0
- movdqa %xmm0, -23(%edx)
- movl -7(%eax), %ecx
- movl %ecx, -7(%edx)
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_43bytes_align):
- movdqa -43(%eax), %xmm0
- movdqa %xmm0, -43(%edx)
-L(fwd_write_27bytes_align):
- movdqa -27(%eax), %xmm0
- movdqa %xmm0, -27(%edx)
-L(fwd_write_11bytes_align):
- movq -11(%eax), %xmm0
- movq %xmm0, -11(%edx)
-L(fwd_write_3bytes_align):
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_35bytes_align):
- movdqa -35(%eax), %xmm0
- movdqa %xmm0, -35(%edx)
-L(fwd_write_19bytes_align):
- movdqa -19(%eax), %xmm0
- movdqa %xmm0, -19(%edx)
- movzwl -3(%eax), %ecx
- movzbl -1(%eax), %eax
- movw %cx, -3(%edx)
- movb %al, -1(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_44bytes_align):
- movdqa -44(%eax), %xmm0
- movdqa %xmm0, -44(%edx)
-L(fwd_write_28bytes_align):
- movdqa -28(%eax), %xmm0
- movdqa %xmm0, -28(%edx)
-L(fwd_write_12bytes_align):
- movq -12(%eax), %xmm0
- movq %xmm0, -12(%edx)
-L(fwd_write_4bytes_align):
- movl -4(%eax), %ecx
- movl %ecx, -4(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN
-
- .p2align 4
-L(fwd_write_36bytes_align):
- movdqa -36(%eax), %xmm0
- movdqa %xmm0, -36(%edx)
-L(fwd_write_20bytes_align):
- movdqa -20(%eax), %xmm0
- movdqa %xmm0, -20(%edx)
- movl -4(%eax), %ecx
- movl %ecx, -4(%edx)
-#ifdef USE_AS_MEMPCPY
- movl %edx, %eax
-#else
- movl DEST(%esp), %eax
-#endif
- RETURN_END
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(large_page):
- movdqu (%eax), %xmm1
-#ifdef USE_AS_MEMMOVE
- movl DEST+4(%esp), %edi
- movdqu %xmm0, (%edi)
-#endif
- lea 16(%eax), %eax
- movntdq %xmm1, (%edx)
- lea 16(%edx), %edx
- lea -0x90(%ecx), %ecx
- POP (%edi)
-
- .p2align 4
-L(large_page_loop):
- movdqu (%eax), %xmm0
- movdqu 0x10(%eax), %xmm1
- movdqu 0x20(%eax), %xmm2
- movdqu 0x30(%eax), %xmm3
- movdqu 0x40(%eax), %xmm4
- movdqu 0x50(%eax), %xmm5
- movdqu 0x60(%eax), %xmm6
- movdqu 0x70(%eax), %xmm7
- lea 0x80(%eax), %eax
-
- sub $0x80, %ecx
- movntdq %xmm0, (%edx)
- movntdq %xmm1, 0x10(%edx)
- movntdq %xmm2, 0x20(%edx)
- movntdq %xmm3, 0x30(%edx)
- movntdq %xmm4, 0x40(%edx)
- movntdq %xmm5, 0x50(%edx)
- movntdq %xmm6, 0x60(%edx)
- movntdq %xmm7, 0x70(%edx)
- lea 0x80(%edx), %edx
- jae L(large_page_loop)
- cmp $-0x40, %ecx
- lea 0x80(%ecx), %ecx
- jl L(large_page_less_64bytes)
-
- movdqu (%eax), %xmm0
- movdqu 0x10(%eax), %xmm1
- movdqu 0x20(%eax), %xmm2
- movdqu 0x30(%eax), %xmm3
- lea 0x40(%eax), %eax
-
- movntdq %xmm0, (%edx)
- movntdq %xmm1, 0x10(%edx)
- movntdq %xmm2, 0x20(%edx)
- movntdq %xmm3, 0x30(%edx)
- lea 0x40(%edx), %edx
- sub $0x40, %ecx
-L(large_page_less_64bytes):
- cmp $32, %ecx
- jb L(large_page_less_32bytes)
- movdqu (%eax), %xmm0
- movdqu 0x10(%eax), %xmm1
- lea 0x20(%eax), %eax
- movntdq %xmm0, (%edx)
- movntdq %xmm1, 0x10(%edx)
- lea 0x20(%edx), %edx
- sub $0x20, %ecx
-L(large_page_less_32bytes):
- add %ecx, %edx
- add %ecx, %eax
- sfence
- BRANCH_TO_JMPTBL_ENTRY (L(table_48bytes_fwd), %ecx, 4)
-
- .p2align 4
-L(bk_write_44bytes):
- movq 36(%eax), %xmm0
- movq %xmm0, 36(%edx)
-L(bk_write_36bytes):
- movq 28(%eax), %xmm0
- movq %xmm0, 28(%edx)
-L(bk_write_28bytes):
- movq 20(%eax), %xmm0
- movq %xmm0, 20(%edx)
-L(bk_write_20bytes):
- movq 12(%eax), %xmm0
- movq %xmm0, 12(%edx)
-L(bk_write_12bytes):
- movq 4(%eax), %xmm0
- movq %xmm0, 4(%edx)
-L(bk_write_4bytes):
- movl (%eax), %ecx
- movl %ecx, (%edx)
-L(bk_write_0bytes):
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_40bytes):
- movq 32(%eax), %xmm0
- movq %xmm0, 32(%edx)
-L(bk_write_32bytes):
- movq 24(%eax), %xmm0
- movq %xmm0, 24(%edx)
-L(bk_write_24bytes):
- movq 16(%eax), %xmm0
- movq %xmm0, 16(%edx)
-L(bk_write_16bytes):
- movq 8(%eax), %xmm0
- movq %xmm0, 8(%edx)
-L(bk_write_8bytes):
- movq (%eax), %xmm0
- movq %xmm0, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_45bytes):
- movq 37(%eax), %xmm0
- movq %xmm0, 37(%edx)
-L(bk_write_37bytes):
- movq 29(%eax), %xmm0
- movq %xmm0, 29(%edx)
-L(bk_write_29bytes):
- movq 21(%eax), %xmm0
- movq %xmm0, 21(%edx)
-L(bk_write_21bytes):
- movq 13(%eax), %xmm0
- movq %xmm0, 13(%edx)
-L(bk_write_13bytes):
- movq 5(%eax), %xmm0
- movq %xmm0, 5(%edx)
-L(bk_write_5bytes):
- movl 1(%eax), %ecx
- movl %ecx, 1(%edx)
-L(bk_write_1bytes):
- movzbl (%eax), %ecx
- movb %cl, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_41bytes):
- movq 33(%eax), %xmm0
- movq %xmm0, 33(%edx)
-L(bk_write_33bytes):
- movq 25(%eax), %xmm0
- movq %xmm0, 25(%edx)
-L(bk_write_25bytes):
- movq 17(%eax), %xmm0
- movq %xmm0, 17(%edx)
-L(bk_write_17bytes):
- movq 9(%eax), %xmm0
- movq %xmm0, 9(%edx)
-L(bk_write_9bytes):
- movq 1(%eax), %xmm0
- movq %xmm0, 1(%edx)
- movzbl (%eax), %ecx
- movb %cl, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_46bytes):
- movq 38(%eax), %xmm0
- movq %xmm0, 38(%edx)
-L(bk_write_38bytes):
- movq 30(%eax), %xmm0
- movq %xmm0, 30(%edx)
-L(bk_write_30bytes):
- movq 22(%eax), %xmm0
- movq %xmm0, 22(%edx)
-L(bk_write_22bytes):
- movq 14(%eax), %xmm0
- movq %xmm0, 14(%edx)
-L(bk_write_14bytes):
- movq 6(%eax), %xmm0
- movq %xmm0, 6(%edx)
-L(bk_write_6bytes):
- movl 2(%eax), %ecx
- movl %ecx, 2(%edx)
- movzwl (%eax), %ecx
- movw %cx, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_42bytes):
- movq 34(%eax), %xmm0
- movq %xmm0, 34(%edx)
-L(bk_write_34bytes):
- movq 26(%eax), %xmm0
- movq %xmm0, 26(%edx)
-L(bk_write_26bytes):
- movq 18(%eax), %xmm0
- movq %xmm0, 18(%edx)
-L(bk_write_18bytes):
- movq 10(%eax), %xmm0
- movq %xmm0, 10(%edx)
-L(bk_write_10bytes):
- movq 2(%eax), %xmm0
- movq %xmm0, 2(%edx)
-L(bk_write_2bytes):
- movzwl (%eax), %ecx
- movw %cx, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_47bytes):
- movq 39(%eax), %xmm0
- movq %xmm0, 39(%edx)
-L(bk_write_39bytes):
- movq 31(%eax), %xmm0
- movq %xmm0, 31(%edx)
-L(bk_write_31bytes):
- movq 23(%eax), %xmm0
- movq %xmm0, 23(%edx)
-L(bk_write_23bytes):
- movq 15(%eax), %xmm0
- movq %xmm0, 15(%edx)
-L(bk_write_15bytes):
- movq 7(%eax), %xmm0
- movq %xmm0, 7(%edx)
-L(bk_write_7bytes):
- movl 3(%eax), %ecx
- movl %ecx, 3(%edx)
- movzwl 1(%eax), %ecx
- movw %cx, 1(%edx)
- movzbl (%eax), %eax
- movb %al, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN
-
- .p2align 4
-L(bk_write_43bytes):
- movq 35(%eax), %xmm0
- movq %xmm0, 35(%edx)
-L(bk_write_35bytes):
- movq 27(%eax), %xmm0
- movq %xmm0, 27(%edx)
-L(bk_write_27bytes):
- movq 19(%eax), %xmm0
- movq %xmm0, 19(%edx)
-L(bk_write_19bytes):
- movq 11(%eax), %xmm0
- movq %xmm0, 11(%edx)
-L(bk_write_11bytes):
- movq 3(%eax), %xmm0
- movq %xmm0, 3(%edx)
-L(bk_write_3bytes):
- movzwl 1(%eax), %ecx
- movw %cx, 1(%edx)
- movzbl (%eax), %eax
- movb %al, (%edx)
- movl DEST(%esp), %eax
-#ifdef USE_AS_MEMPCPY
- movl LEN(%esp), %ecx
- add %ecx, %eax
-#endif
- RETURN_END
-
-
- .pushsection .rodata.ssse3,"a",@progbits
- .p2align 2
-L(table_48bytes_fwd):
- .int JMPTBL (L(fwd_write_0bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_1bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_2bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_3bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_4bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_5bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_6bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_7bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_8bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_9bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_10bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_11bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_12bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_13bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_14bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_15bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_16bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_17bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_18bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_19bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_20bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_21bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_22bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_23bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_24bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_25bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_26bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_27bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_28bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_29bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_30bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_31bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_32bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_33bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_34bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_35bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_36bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_37bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_38bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_39bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_40bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_41bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_42bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_43bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_44bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_45bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_46bytes), L(table_48bytes_fwd))
- .int JMPTBL (L(fwd_write_47bytes), L(table_48bytes_fwd))
-
- .p2align 2
-L(table_48bytes_fwd_align):
- .int JMPTBL (L(fwd_write_0bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_1bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_2bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_3bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_4bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_5bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_6bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_7bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_8bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_9bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_10bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_11bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_12bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_13bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_14bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_15bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_16bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_17bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_18bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_19bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_20bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_21bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_22bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_23bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_24bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_25bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_26bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_27bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_28bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_29bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_30bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_31bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_32bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_33bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_34bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_35bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_36bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_37bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_38bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_39bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_40bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_41bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_42bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_43bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_44bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_45bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_46bytes_align), L(table_48bytes_fwd_align))
- .int JMPTBL (L(fwd_write_47bytes_align), L(table_48bytes_fwd_align))
-
- .p2align 2
-L(shl_table):
- .int JMPTBL (L(shl_0), L(shl_table))
- .int JMPTBL (L(shl_1), L(shl_table))
- .int JMPTBL (L(shl_2), L(shl_table))
- .int JMPTBL (L(shl_3), L(shl_table))
- .int JMPTBL (L(shl_4), L(shl_table))
- .int JMPTBL (L(shl_5), L(shl_table))
- .int JMPTBL (L(shl_6), L(shl_table))
- .int JMPTBL (L(shl_7), L(shl_table))
- .int JMPTBL (L(shl_8), L(shl_table))
- .int JMPTBL (L(shl_9), L(shl_table))
- .int JMPTBL (L(shl_10), L(shl_table))
- .int JMPTBL (L(shl_11), L(shl_table))
- .int JMPTBL (L(shl_12), L(shl_table))
- .int JMPTBL (L(shl_13), L(shl_table))
- .int JMPTBL (L(shl_14), L(shl_table))
- .int JMPTBL (L(shl_15), L(shl_table))
-
- .p2align 2
-L(table_48_bytes_bwd):
- .int JMPTBL (L(bk_write_0bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_1bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_2bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_3bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_4bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_5bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_6bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_7bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_8bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_9bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_10bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_11bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_12bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_13bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_14bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_15bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_16bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_17bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_18bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_19bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_20bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_21bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_22bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_23bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_24bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_25bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_26bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_27bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_28bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_29bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_30bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_31bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_32bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_33bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_34bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_35bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_36bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_37bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_38bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_39bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_40bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_41bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_42bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_43bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_44bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_45bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_46bytes), L(table_48_bytes_bwd))
- .int JMPTBL (L(bk_write_47bytes), L(table_48_bytes_bwd))
-
- .popsection
-
-#ifdef USE_AS_MEMMOVE
- .p2align 4
-L(copy_backward):
- PUSH (%edi)
- movl %eax, %edi
- lea (%ecx,%edx,1),%edx
- lea (%ecx,%edi,1),%edi
- testl $0x3, %edx
- jnz L(bk_align)
-
-L(bk_aligned_4):
- cmp $64, %ecx
- jae L(bk_write_more64bytes)
-
-L(bk_write_64bytesless):
- cmp $32, %ecx
- jb L(bk_write_less32bytes)
-
-L(bk_write_more32bytes):
- /* Copy 32 bytes at a time. */
- sub $32, %ecx
- movq -8(%edi), %xmm0
- movq %xmm0, -8(%edx)
- movq -16(%edi), %xmm0
- movq %xmm0, -16(%edx)
- movq -24(%edi), %xmm0
- movq %xmm0, -24(%edx)
- movq -32(%edi), %xmm0
- movq %xmm0, -32(%edx)
- sub $32, %edx
- sub $32, %edi
-
-L(bk_write_less32bytes):
- movl %edi, %eax
- sub %ecx, %edx
- sub %ecx, %eax
- POP (%edi)
-L(bk_write_less32bytes_2):
- BRANCH_TO_JMPTBL_ENTRY (L(table_48_bytes_bwd), %ecx, 4)
-
- CFI_PUSH (%edi)
-
- .p2align 4
-L(bk_align):
- cmp $8, %ecx
- jbe L(bk_write_less32bytes)
- testl $1, %edx
- /* We get here only if (EDX & 3 ) != 0 so if (EDX & 1) ==0,
- then (EDX & 2) must be != 0. */
- jz L(bk_got2)
- sub $1, %edi
- sub $1, %ecx
- sub $1, %edx
- movzbl (%edi), %eax
- movb %al, (%edx)
-
- testl $2, %edx
- jz L(bk_aligned_4)
-
-L(bk_got2):
- sub $2, %edi
- sub $2, %ecx
- sub $2, %edx
- movzwl (%edi), %eax
- movw %ax, (%edx)
- jmp L(bk_aligned_4)
-
- .p2align 4
-L(bk_write_more64bytes):
- /* Check alignment of last byte. */
- testl $15, %edx
- jz L(bk_ssse3_cpy_pre)
-
-/* EDX is aligned 4 bytes, but not 16 bytes. */
-L(bk_ssse3_align):
- sub $4, %edi
- sub $4, %ecx
- sub $4, %edx
- movl (%edi), %eax
- movl %eax, (%edx)
-
- testl $15, %edx
- jz L(bk_ssse3_cpy_pre)
-
- sub $4, %edi
- sub $4, %ecx
- sub $4, %edx
- movl (%edi), %eax
- movl %eax, (%edx)
-
- testl $15, %edx
- jz L(bk_ssse3_cpy_pre)
-
- sub $4, %edi
- sub $4, %ecx
- sub $4, %edx
- movl (%edi), %eax
- movl %eax, (%edx)
-
-L(bk_ssse3_cpy_pre):
- cmp $64, %ecx
- jb L(bk_write_more32bytes)
-
- .p2align 4
-L(bk_ssse3_cpy):
- sub $64, %edi
- sub $64, %ecx
- sub $64, %edx
- movdqu 0x30(%edi), %xmm3
- movdqa %xmm3, 0x30(%edx)
- movdqu 0x20(%edi), %xmm2
- movdqa %xmm2, 0x20(%edx)
- movdqu 0x10(%edi), %xmm1
- movdqa %xmm1, 0x10(%edx)
- movdqu (%edi), %xmm0
- movdqa %xmm0, (%edx)
- cmp $64, %ecx
- jae L(bk_ssse3_cpy)
- jmp L(bk_write_64bytesless)
-
-#endif
-
-END (MEMCPY)
diff --git a/libc/arch-x86/string/ssse3-memmove-atom.S b/libc/arch-x86/string/ssse3-memmove-atom.S
deleted file mode 100644
index 3572eac..0000000
--- a/libc/arch-x86/string/ssse3-memmove-atom.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-
-#define MEMCPY memmove_atom
-#define USE_AS_MEMMOVE
-#include "ssse3-memcpy-atom.S"
diff --git a/libc/arch-x86/string/ssse3-strcat-atom.S b/libc/arch-x86/string/ssse3-strcat-atom.S
index 8d8e89d..b851d9e 100644
--- a/libc/arch-x86/string/ssse3-strcat-atom.S
+++ b/libc/arch-x86/string/ssse3-strcat-atom.S
@@ -87,7 +87,7 @@
#define POP(REG) popl REG; CFI_POP (REG)
#ifndef STRCAT
-# define STRCAT strcat_ssse3
+# define STRCAT strcat
#endif
#define PARMS 4
diff --git a/libc/arch-x86/string/ssse3-strcmp-atom.S b/libc/arch-x86/string/ssse3-strcmp-atom.S
index 08f6d4a..ee253b9 100644
--- a/libc/arch-x86/string/ssse3-strcmp-atom.S
+++ b/libc/arch-x86/string/ssse3-strcmp-atom.S
@@ -108,7 +108,7 @@
#endif
#ifndef STRCMP
-# define STRCMP strcmp_ssse3
+# define STRCMP strcmp
#endif
.section .text.ssse3,"ax",@progbits
diff --git a/libc/arch-x86/string/ssse3-strlcat-atom.S b/libc/arch-x86/string/ssse3-strlcat-atom.S
deleted file mode 100644
index 055b489..0000000
--- a/libc/arch-x86/string/ssse3-strlcat-atom.S
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-/* Optimized strlcat with SSSE3 */
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-#define L(label) .L##Prolog_##label
-
-#define DST 4
-#define SRC DST+8
-#define LEN SRC+4
-
- .text
-ENTRY (strlcat_ssse3)
- mov DST(%esp), %edx
- PUSH (%ebx)
- mov LEN(%esp), %ebx
- sub $4, %ebx
- jbe L(len_less4_prolog)
-
-#define RETURN jmp L(StrcpyStep)
-#define edi ebx
-
-#define USE_AS_STRNLEN
-#define USE_AS_STRCAT
-#define USE_AS_STRLCAT
-
-#include "sse2-strlen-atom.S"
-
- .p2align 4
-L(StrcpyStep):
-
-#undef edi
-#undef L
-#define L(label) .L##label
-#undef RETURN
-#define RETURN POP (%ebx); ret; CFI_PUSH (%ebx);
-#define RETURN1 POP (%edi); POP (%ebx); ret; CFI_PUSH (%ebx); CFI_PUSH (%edi)
-
- movl SRC(%esp), %ecx
- movl LEN(%esp), %ebx
-
- cmp %eax, %ebx
- je L(CalculateLengthOfSrcProlog)
- sub %eax, %ebx
-
- test %ebx, %ebx
- jz L(CalculateLengthOfSrcProlog)
-
- mov DST + 4(%esp), %edx
-
- PUSH (%edi)
- add %eax, %edx
- mov %ecx, %edi
- sub %eax, %edi
-
- cmp $8, %ebx
- jbe L(StrncpyExit8Bytes)
-
- cmpb $0, (%ecx)
- jz L(Exit1)
- cmpb $0, 1(%ecx)
- jz L(Exit2)
- cmpb $0, 2(%ecx)
- jz L(Exit3)
- cmpb $0, 3(%ecx)
- jz L(Exit4)
- cmpb $0, 4(%ecx)
- jz L(Exit5)
- cmpb $0, 5(%ecx)
- jz L(Exit6)
- cmpb $0, 6(%ecx)
- jz L(Exit7)
- cmpb $0, 7(%ecx)
- jz L(Exit8)
- cmp $16, %ebx
- jb L(StrncpyExit15Bytes)
- cmpb $0, 8(%ecx)
- jz L(Exit9)
- cmpb $0, 9(%ecx)
- jz L(Exit10)
- cmpb $0, 10(%ecx)
- jz L(Exit11)
- cmpb $0, 11(%ecx)
- jz L(Exit12)
- cmpb $0, 12(%ecx)
- jz L(Exit13)
- cmpb $0, 13(%ecx)
- jz L(Exit14)
- cmpb $0, 14(%ecx)
- jz L(Exit15)
- cmpb $0, 15(%ecx)
- jz L(Exit16)
- cmp $16, %ebx
- je L(StrlcpyExit16)
-
-#define USE_AS_STRNCPY
-#include "ssse3-strcpy-atom.S"
-
- .p2align 4
-L(CopyFrom1To16Bytes):
- add %esi, %edx
- add %esi, %ecx
-
- POP (%esi)
- test %al, %al
- jz L(ExitHigh8)
-
-L(CopyFrom1To16BytesLess8):
- mov %al, %ah
- and $15, %ah
- jz L(ExitHigh4)
-
- test $0x01, %al
- jnz L(Exit1)
- test $0x02, %al
- jnz L(Exit2)
- test $0x04, %al
- jnz L(Exit3)
-L(Exit4):
- movl (%ecx), %eax
- movl %eax, (%edx)
-
- lea 3(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh4):
- test $0x10, %al
- jnz L(Exit5)
- test $0x20, %al
- jnz L(Exit6)
- test $0x40, %al
- jnz L(Exit7)
-L(Exit8):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- lea 7(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh8):
- mov %ah, %al
- and $15, %al
- jz L(ExitHigh12)
-
- test $0x01, %ah
- jnz L(Exit9)
- test $0x02, %ah
- jnz L(Exit10)
- test $0x04, %ah
- jnz L(Exit11)
-L(Exit12):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- lea 11(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh12):
- test $0x10, %ah
- jnz L(Exit13)
- test $0x20, %ah
- jnz L(Exit14)
- test $0x40, %ah
- jnz L(Exit15)
-L(Exit16):
- movlpd (%ecx), %xmm0
- movlpd 8(%ecx), %xmm1
- movlpd %xmm0, (%edx)
- movlpd %xmm1, 8(%edx)
-
- lea 15(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- CFI_PUSH(%esi)
-
- .p2align 4
-L(CopyFrom1To16BytesCase2):
- add $16, %ebx
- add %esi, %ecx
- add %esi, %edx
-
- POP (%esi)
-
- test %al, %al
- jz L(ExitHighCase2)
-
- cmp $8, %ebx
- ja L(CopyFrom1To16BytesLess8)
-
- test $0x01, %al
- jnz L(Exit1)
- cmp $1, %ebx
- je L(StrlcpyExit1)
- test $0x02, %al
- jnz L(Exit2)
- cmp $2, %ebx
- je L(StrlcpyExit2)
- test $0x04, %al
- jnz L(Exit3)
- cmp $3, %ebx
- je L(StrlcpyExit3)
- test $0x08, %al
- jnz L(Exit4)
- cmp $4, %ebx
- je L(StrlcpyExit4)
- test $0x10, %al
- jnz L(Exit5)
- cmp $5, %ebx
- je L(StrlcpyExit5)
- test $0x20, %al
- jnz L(Exit6)
- cmp $6, %ebx
- je L(StrlcpyExit6)
- test $0x40, %al
- jnz L(Exit7)
- cmp $7, %ebx
- je L(StrlcpyExit7)
- test $0x80, %al
- jnz L(Exit8)
- jmp L(StrlcpyExit8)
-
- .p2align 4
-L(ExitHighCase2):
- cmp $8, %ebx
- jbe L(CopyFrom1To16BytesLess8Case3)
-
- test $0x01, %ah
- jnz L(Exit9)
- cmp $9, %ebx
- je L(StrlcpyExit9)
- test $0x02, %ah
- jnz L(Exit10)
- cmp $10, %ebx
- je L(StrlcpyExit10)
- test $0x04, %ah
- jnz L(Exit11)
- cmp $11, %ebx
- je L(StrlcpyExit11)
- test $0x8, %ah
- jnz L(Exit12)
- cmp $12, %ebx
- je L(StrlcpyExit12)
- test $0x10, %ah
- jnz L(Exit13)
- cmp $13, %ebx
- je L(StrlcpyExit13)
- test $0x20, %ah
- jnz L(Exit14)
- cmp $14, %ebx
- je L(StrlcpyExit14)
- test $0x40, %ah
- jnz L(Exit15)
- cmp $15, %ebx
- je L(StrlcpyExit15)
- test $0x80, %ah
- jnz L(Exit16)
- jmp L(StrlcpyExit16)
-
- CFI_PUSH(%esi)
-
- .p2align 4
-L(CopyFrom1To16BytesCase2OrCase3):
- test %eax, %eax
- jnz L(CopyFrom1To16BytesCase2)
-
- .p2align 4
-L(CopyFrom1To16BytesCase3):
- add $16, %ebx
- add %esi, %edx
- add %esi, %ecx
-
- POP (%esi)
-
- cmp $8, %ebx
- ja L(ExitHigh8Case3)
-
-L(CopyFrom1To16BytesLess8Case3):
- cmp $4, %ebx
- ja L(ExitHigh4Case3)
-
- cmp $1, %ebx
- je L(StrlcpyExit1)
- cmp $2, %ebx
- je L(StrlcpyExit2)
- cmp $3, %ebx
- je L(StrlcpyExit3)
-L(StrlcpyExit4):
- movb %bh, 3(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- lea 4(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh4Case3):
- cmp $5, %ebx
- je L(StrlcpyExit5)
- cmp $6, %ebx
- je L(StrlcpyExit6)
- cmp $7, %ebx
- je L(StrlcpyExit7)
-L(StrlcpyExit8):
- movb %bh, 7(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- lea 8(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh8Case3):
- cmp $12, %ebx
- ja L(ExitHigh12Case3)
-
- cmp $9, %ebx
- je L(StrlcpyExit9)
- cmp $10, %ebx
- je L(StrlcpyExit10)
- cmp $11, %ebx
- je L(StrlcpyExit11)
-L(StrlcpyExit12):
- movb %bh, 11(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- lea 12(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh12Case3):
- cmp $13, %ebx
- je L(StrlcpyExit13)
- cmp $14, %ebx
- je L(StrlcpyExit14)
- cmp $15, %ebx
- je L(StrlcpyExit15)
-L(StrlcpyExit16):
- movb %bh, 15(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- lea 16(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(StrlcpyExit1):
- movb %bh, (%edx)
-
- lea 1(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit1):
- movb (%ecx), %al
- movb %al, (%edx)
-
- mov %ecx, %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit2):
- movb %bh, 1(%edx)
- movb (%ecx), %al
- movb %al, (%edx)
-
- lea 2(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit2):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movl %edi, %eax
-
- lea 1(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit3):
- movb %bh, 2(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
-
- lea 3(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit3):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- lea 2(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit5):
- movb %bh, 4(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl %edi, %eax
-
- lea 5(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit5):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- lea 4(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit6):
- movb %bh, 5(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- lea 6(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit6):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- lea 5(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit7):
- movb %bh, 6(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- lea 7(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit7):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- lea 6(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit9):
- movb %bh, 8(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- lea 9(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit9):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- lea 8(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit10):
- movb %bh, 9(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- lea 10(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit10):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- lea 9(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit11):
- movb %bh, 10(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- lea 11(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit11):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- lea 10(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit13):
- movb %bh, 12(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- lea 13(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit13):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- lea 12(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit14):
- movb %bh, 13(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- lea 14(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit14):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- lea 13(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit15):
- movb %bh, 14(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- lea 15(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit15):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- lea 14(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrncpyExit15Bytes):
- cmp $12, %ebx
- ja L(StrncpyExit15Bytes1)
-
- cmpb $0, 8(%ecx)
- jz L(Exit9)
- cmp $9, %ebx
- je L(StrlcpyExit9)
-
- cmpb $0, 9(%ecx)
- jz L(Exit10)
- cmp $10, %ebx
- je L(StrlcpyExit10)
-
- cmpb $0, 10(%ecx)
- jz L(Exit11)
- cmp $11, %ebx
- je L(StrlcpyExit11)
-
- cmpb $0, 11(%ecx)
- jz L(Exit12)
- jmp L(StrlcpyExit12)
-
- .p2align 4
-L(StrncpyExit15Bytes1):
- cmpb $0, 8(%ecx)
- jz L(Exit9)
- cmpb $0, 9(%ecx)
- jz L(Exit10)
- cmpb $0, 10(%ecx)
- jz L(Exit11)
- cmpb $0, 11(%ecx)
- jz L(Exit12)
-
- cmpb $0, 12(%ecx)
- jz L(Exit13)
- cmp $13, %ebx
- je L(StrlcpyExit13)
-
- cmpb $0, 13(%ecx)
- jz L(Exit14)
- cmp $14, %ebx
- je L(StrlcpyExit14)
-
- cmpb $0, 14(%ecx)
- jz L(Exit15)
- jmp L(StrlcpyExit15)
-
- .p2align 4
-L(StrncpyExit8Bytes):
- cmp $4, %ebx
- ja L(StrncpyExit8Bytes1)
-
- cmpb $0, (%ecx)
- jz L(Exit1)
- cmp $1, %ebx
- je L(StrlcpyExit1)
-
- cmpb $0, 1(%ecx)
- jz L(Exit2)
- cmp $2, %ebx
- je L(StrlcpyExit2)
-
- cmpb $0, 2(%ecx)
- jz L(Exit3)
- cmp $3, %ebx
- je L(StrlcpyExit3)
-
- cmpb $0, 3(%ecx)
- jz L(Exit4)
- jmp L(StrlcpyExit4)
-
- .p2align 4
-L(StrncpyExit8Bytes1):
- cmpb $0, (%ecx)
- jz L(Exit1)
- cmpb $0, 1(%ecx)
- jz L(Exit2)
- cmpb $0, 2(%ecx)
- jz L(Exit3)
- cmpb $0, 3(%ecx)
- jz L(Exit4)
-
- cmpb $0, 4(%ecx)
- jz L(Exit5)
- cmp $5, %ebx
- je L(StrlcpyExit5)
-
- cmpb $0, 5(%ecx)
- jz L(Exit6)
- cmp $6, %ebx
- je L(StrlcpyExit6)
-
- cmpb $0, 6(%ecx)
- jz L(Exit7)
- cmp $7, %ebx
- je L(StrlcpyExit7)
-
- cmpb $0, 7(%ecx)
- jz L(Exit8)
- jmp L(StrlcpyExit8)
-
- CFI_POP (%edi)
-
-
- .p2align 4
-L(Prolog_return_start_len):
- movl LEN(%esp), %ebx
- movl SRC(%esp), %ecx
-L(CalculateLengthOfSrcProlog):
- mov %ecx, %edx
- sub %ebx, %ecx
-
- .p2align 4
-L(CalculateLengthOfSrc):
- cmpb $0, (%edx)
- jz L(exit_tail0)
- cmpb $0, 1(%edx)
- jz L(exit_tail1)
- cmpb $0, 2(%edx)
- jz L(exit_tail2)
- cmpb $0, 3(%edx)
- jz L(exit_tail3)
-
- cmpb $0, 4(%edx)
- jz L(exit_tail4)
- cmpb $0, 5(%edx)
- jz L(exit_tail5)
- cmpb $0, 6(%edx)
- jz L(exit_tail6)
- cmpb $0, 7(%edx)
- jz L(exit_tail7)
-
- cmpb $0, 8(%edx)
- jz L(exit_tail8)
- cmpb $0, 9(%edx)
- jz L(exit_tail9)
- cmpb $0, 10(%edx)
- jz L(exit_tail10)
- cmpb $0, 11(%edx)
- jz L(exit_tail11)
-
- cmpb $0, 12(%edx)
- jz L(exit_tail12)
- cmpb $0, 13(%edx)
- jz L(exit_tail13)
- cmpb $0, 14(%edx)
- jz L(exit_tail14)
- cmpb $0, 15(%edx)
- jz L(exit_tail15)
-
- pxor %xmm0, %xmm0
- lea 16(%edx), %eax
- add $16, %ecx
- and $-16, %eax
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- pxor %xmm1, %xmm1
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- pxor %xmm2, %xmm2
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- pxor %xmm3, %xmm3
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- and $-0x40, %eax
-
- .p2align 4
-L(aligned_64_loop):
- movaps (%eax), %xmm0
- movaps 16(%eax), %xmm1
- movaps 32(%eax), %xmm2
- movaps 48(%eax), %xmm6
- pminub %xmm1, %xmm0
- pminub %xmm6, %xmm2
- pminub %xmm0, %xmm2
- pcmpeqb %xmm3, %xmm2
- pmovmskb %xmm2, %edx
- lea 64(%eax), %eax
- test %edx, %edx
- jz L(aligned_64_loop)
-
- pcmpeqb -64(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 48(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb -32(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb %xmm6, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
-
- .p2align 4
-L(exit):
- sub %ecx, %eax
- test %dl, %dl
- jz L(exit_more_8)
-
- mov %dl, %cl
- and $15, %cl
- jz L(exit_more_4)
- test $0x01, %dl
- jnz L(exit_0)
- test $0x02, %dl
- jnz L(exit_1)
- test $0x04, %dl
- jnz L(exit_2)
- add $3, %eax
- RETURN
-
- .p2align 4
-L(exit_more_4):
- test $0x10, %dl
- jnz L(exit_4)
- test $0x20, %dl
- jnz L(exit_5)
- test $0x40, %dl
- jnz L(exit_6)
- add $7, %eax
- RETURN
-
- .p2align 4
-L(exit_more_8):
- mov %dh, %ch
- and $15, %ch
- jz L(exit_more_12)
- test $0x01, %dh
- jnz L(exit_8)
- test $0x02, %dh
- jnz L(exit_9)
- test $0x04, %dh
- jnz L(exit_10)
- add $11, %eax
- RETURN
-
- .p2align 4
-L(exit_more_12):
- test $0x10, %dh
- jnz L(exit_12)
- test $0x20, %dh
- jnz L(exit_13)
- test $0x40, %dh
- jnz L(exit_14)
- add $15, %eax
-L(exit_0):
- RETURN
-
- .p2align 4
-L(exit_1):
- add $1, %eax
- RETURN
-
-L(exit_2):
- add $2, %eax
- RETURN
-
-L(exit_3):
- add $3, %eax
- RETURN
-
-L(exit_4):
- add $4, %eax
- RETURN
-
-L(exit_5):
- add $5, %eax
- RETURN
-
-L(exit_6):
- add $6, %eax
- RETURN
-
-L(exit_7):
- add $7, %eax
- RETURN
-
-L(exit_8):
- add $8, %eax
- RETURN
-
-L(exit_9):
- add $9, %eax
- RETURN
-
-L(exit_10):
- add $10, %eax
- RETURN
-
-L(exit_11):
- add $11, %eax
- RETURN
-
-L(exit_12):
- add $12, %eax
- RETURN
-
-L(exit_13):
- add $13, %eax
- RETURN
-
-L(exit_14):
- add $14, %eax
- RETURN
-
-L(exit_15):
- add $15, %eax
- RETURN
-
-L(exit_tail0):
- mov %edx, %eax
- sub %ecx, %eax
- RETURN
-
- .p2align 4
-L(exit_tail1):
- lea 1(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail2):
- lea 2(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail3):
- lea 3(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail4):
- lea 4(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail5):
- lea 5(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail6):
- lea 6(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail7):
- lea 7(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail8):
- lea 8(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail9):
- lea 9(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail10):
- lea 10(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail11):
- lea 11(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail12):
- lea 12(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail13):
- lea 13(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail14):
- lea 14(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail15):
- lea 15(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-END (strlcat)
diff --git a/libc/arch-x86/string/ssse3-strlcpy-atom.S b/libc/arch-x86/string/ssse3-strlcpy-atom.S
deleted file mode 100644
index 1671da6..0000000
--- a/libc/arch-x86/string/ssse3-strlcpy-atom.S
+++ /dev/null
@@ -1,1403 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define USE_AS_STRNCPY
-#define STRCPY strlcpy_ssse3
-#define STRLEN strlcpy_ssse3
-#define USE_AS_STRLCPY
-#include "ssse3-strcpy-atom.S"
-
- .p2align 4
-L(CopyFrom1To16Bytes):
- add %esi, %edx
- add %esi, %ecx
-
- POP (%esi)
- test %al, %al
- jz L(ExitHigh8)
-
-L(CopyFrom1To16BytesLess8):
- mov %al, %ah
- and $15, %ah
- jz L(ExitHigh4)
-
- test $0x01, %al
- jnz L(Exit1)
- test $0x02, %al
- jnz L(Exit2)
- test $0x04, %al
- jnz L(Exit3)
-L(Exit4):
- movl (%ecx), %eax
- movl %eax, (%edx)
-
- lea 3(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh4):
- test $0x10, %al
- jnz L(Exit5)
- test $0x20, %al
- jnz L(Exit6)
- test $0x40, %al
- jnz L(Exit7)
-L(Exit8):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- lea 7(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh8):
- mov %ah, %al
- and $15, %al
- jz L(ExitHigh12)
-
- test $0x01, %ah
- jnz L(Exit9)
- test $0x02, %ah
- jnz L(Exit10)
- test $0x04, %ah
- jnz L(Exit11)
-L(Exit12):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- lea 11(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(ExitHigh12):
- test $0x10, %ah
- jnz L(Exit13)
- test $0x20, %ah
- jnz L(Exit14)
- test $0x40, %ah
- jnz L(Exit15)
-L(Exit16):
- movlpd (%ecx), %xmm0
- movlpd 8(%ecx), %xmm1
- movlpd %xmm0, (%edx)
- movlpd %xmm1, 8(%edx)
-
- lea 15(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- CFI_PUSH(%esi)
-
- .p2align 4
-L(CopyFrom1To16BytesCase2):
- add $16, %ebx
- add %esi, %ecx
- add %esi, %edx
-
- POP (%esi)
-
- test %al, %al
- jz L(ExitHighCase2)
-
- cmp $8, %ebx
- ja L(CopyFrom1To16BytesLess8)
-
- test $0x01, %al
- jnz L(Exit1)
- cmp $1, %ebx
- je L(StrlcpyExit1)
- test $0x02, %al
- jnz L(Exit2)
- cmp $2, %ebx
- je L(StrlcpyExit2)
- test $0x04, %al
- jnz L(Exit3)
- cmp $3, %ebx
- je L(StrlcpyExit3)
- test $0x08, %al
- jnz L(Exit4)
- cmp $4, %ebx
- je L(StrlcpyExit4)
- test $0x10, %al
- jnz L(Exit5)
- cmp $5, %ebx
- je L(StrlcpyExit5)
- test $0x20, %al
- jnz L(Exit6)
- cmp $6, %ebx
- je L(StrlcpyExit6)
- test $0x40, %al
- jnz L(Exit7)
- cmp $7, %ebx
- je L(StrlcpyExit7)
- test $0x80, %al
- jnz L(Exit8)
- jmp L(StrlcpyExit8)
-
- .p2align 4
-L(ExitHighCase2):
- cmp $8, %ebx
- jbe L(CopyFrom1To16BytesLess8Case3)
-
- test $0x01, %ah
- jnz L(Exit9)
- cmp $9, %ebx
- je L(StrlcpyExit9)
- test $0x02, %ah
- jnz L(Exit10)
- cmp $10, %ebx
- je L(StrlcpyExit10)
- test $0x04, %ah
- jnz L(Exit11)
- cmp $11, %ebx
- je L(StrlcpyExit11)
- test $0x8, %ah
- jnz L(Exit12)
- cmp $12, %ebx
- je L(StrlcpyExit12)
- test $0x10, %ah
- jnz L(Exit13)
- cmp $13, %ebx
- je L(StrlcpyExit13)
- test $0x20, %ah
- jnz L(Exit14)
- cmp $14, %ebx
- je L(StrlcpyExit14)
- test $0x40, %ah
- jnz L(Exit15)
- cmp $15, %ebx
- je L(StrlcpyExit15)
- test $0x80, %ah
- jnz L(Exit16)
- jmp L(StrlcpyExit16)
-
- CFI_PUSH(%esi)
-
- .p2align 4
-L(CopyFrom1To16BytesCase2OrCase3):
- test %eax, %eax
- jnz L(CopyFrom1To16BytesCase2)
-
- .p2align 4
-L(CopyFrom1To16BytesCase3):
- add $16, %ebx
- add %esi, %edx
- add %esi, %ecx
-
- POP (%esi)
-
- cmp $8, %ebx
- ja L(ExitHigh8Case3)
-
-L(CopyFrom1To16BytesLess8Case3):
- cmp $4, %ebx
- ja L(ExitHigh4Case3)
-
- cmp $1, %ebx
- je L(StrlcpyExit1)
- cmp $2, %ebx
- je L(StrlcpyExit2)
- cmp $3, %ebx
- je L(StrlcpyExit3)
-L(StrlcpyExit4):
- movb %bh, 3(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- lea 4(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh4Case3):
- cmp $5, %ebx
- je L(StrlcpyExit5)
- cmp $6, %ebx
- je L(StrlcpyExit6)
- cmp $7, %ebx
- je L(StrlcpyExit7)
-L(StrlcpyExit8):
- movb %bh, 7(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- lea 8(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh8Case3):
- cmp $12, %ebx
- ja L(ExitHigh12Case3)
-
- cmp $9, %ebx
- je L(StrlcpyExit9)
- cmp $10, %ebx
- je L(StrlcpyExit10)
- cmp $11, %ebx
- je L(StrlcpyExit11)
-L(StrlcpyExit12):
- movb %bh, 11(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- lea 12(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(ExitHigh12Case3):
- cmp $13, %ebx
- je L(StrlcpyExit13)
- cmp $14, %ebx
- je L(StrlcpyExit14)
- cmp $15, %ebx
- je L(StrlcpyExit15)
-L(StrlcpyExit16):
- movb %bh, 15(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- lea 16(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(StrlcpyExit1):
- movb %bh, (%edx)
-
- lea 1(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit1):
- movb (%ecx), %al
- movb %al, (%edx)
-
- mov %ecx, %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit2):
- movb %bh, 1(%edx)
- movb (%ecx), %al
- movb %al, (%edx)
-
- lea 2(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit2):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movl %edi, %eax
-
- lea 1(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit3):
- movb %bh, 2(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
-
- lea 3(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit3):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- lea 2(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit5):
- movb %bh, 4(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl %edi, %eax
-
- lea 5(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit5):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- lea 4(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit6):
- movb %bh, 5(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- lea 6(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit6):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- lea 5(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit7):
- movb %bh, 6(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- lea 7(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit7):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- lea 6(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit9):
- movb %bh, 8(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- lea 9(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit9):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- lea 8(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit10):
- movb %bh, 9(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- lea 10(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit10):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- lea 9(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit11):
- movb %bh, 10(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- lea 11(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit11):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- lea 10(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit13):
- movb %bh, 12(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- lea 13(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit13):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- lea 12(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit14):
- movb %bh, 13(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- lea 14(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit14):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- lea 13(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- .p2align 4
-L(StrlcpyExit15):
- movb %bh, 14(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- lea 15(%ecx), %edx
- mov %edi, %ecx
- POP (%edi)
- jmp L(CalculateLengthOfSrc)
- CFI_PUSH (%edi)
-
- .p2align 4
-L(Exit15):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- lea 14(%ecx), %eax
- sub %edi, %eax
- RETURN1
-
- CFI_POP (%edi)
-
- .p2align 4
-L(StrlcpyExit0):
- movl $0, %eax
- RETURN
-
- .p2align 4
-L(StrncpyExit15Bytes):
- cmp $12, %ebx
- ja L(StrncpyExit15Bytes1)
-
- cmpb $0, 8(%ecx)
- jz L(ExitTail9)
- cmp $9, %ebx
- je L(StrlcpyExitTail9)
-
- cmpb $0, 9(%ecx)
- jz L(ExitTail10)
- cmp $10, %ebx
- je L(StrlcpyExitTail10)
-
- cmpb $0, 10(%ecx)
- jz L(ExitTail11)
- cmp $11, %ebx
- je L(StrlcpyExitTail11)
-
- cmpb $0, 11(%ecx)
- jz L(ExitTail12)
-
- movb %bh, 11(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- lea 12(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(StrncpyExit15Bytes1):
- cmpb $0, 8(%ecx)
- jz L(ExitTail9)
- cmpb $0, 9(%ecx)
- jz L(ExitTail10)
- cmpb $0, 10(%ecx)
- jz L(ExitTail11)
- cmpb $0, 11(%ecx)
- jz L(ExitTail12)
-
- cmpb $0, 12(%ecx)
- jz L(ExitTail13)
- cmp $13, %ebx
- je L(StrlcpyExitTail13)
-
- cmpb $0, 13(%ecx)
- jz L(ExitTail14)
- cmp $14, %ebx
- je L(StrlcpyExitTail14)
-
- cmpb $0, 14(%ecx)
- jz L(ExitTail15)
-
- movb %bh, 14(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- lea 15(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(StrncpyExit8Bytes):
- cmp $4, %ebx
- ja L(StrncpyExit8Bytes1)
-
- test %ebx, %ebx
- jz L(StrlcpyExitTail0)
-
- cmpb $0, (%ecx)
- jz L(ExitTail1)
- cmp $1, %ebx
- je L(StrlcpyExitTail1)
-
- cmpb $0, 1(%ecx)
- jz L(ExitTail2)
- cmp $2, %ebx
- je L(StrlcpyExitTail2)
-
- cmpb $0, 2(%ecx)
- jz L(ExitTail3)
- cmp $3, %ebx
- je L(StrlcpyExitTail3)
-
- cmpb $0, 3(%ecx)
- jz L(ExitTail4)
-
- movb %bh, 3(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- lea 4(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(StrncpyExit8Bytes1):
- cmpb $0, (%ecx)
- jz L(ExitTail1)
- cmpb $0, 1(%ecx)
- jz L(ExitTail2)
- cmpb $0, 2(%ecx)
- jz L(ExitTail3)
- cmpb $0, 3(%ecx)
- jz L(ExitTail4)
-
- cmpb $0, 4(%ecx)
- jz L(ExitTail5)
- cmp $5, %ebx
- je L(StrlcpyExitTail5)
-
- cmpb $0, 5(%ecx)
- jz L(ExitTail6)
- cmp $6, %ebx
- je L(StrlcpyExitTail6)
-
- cmpb $0, 6(%ecx)
- jz L(ExitTail7)
- cmp $7, %ebx
- je L(StrlcpyExitTail7)
-
- cmpb $0, 7(%ecx)
- jz L(ExitTail8)
-
- movb %bh, 7(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- lea 8(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(StrlcpyExitTail0):
- mov %ecx, %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(StrlcpyExitTail1):
- movb %bh, (%edx)
-
- lea 1(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail1):
- movb (%ecx), %al
- movb %al, (%edx)
-
- mov $0, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail2):
- movb %bh, 1(%edx)
- movb (%ecx), %al
- movb %al, (%edx)
-
- lea 2(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail2):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movl %edx, %eax
-
- mov $1, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail3):
- movb %bh, 2(%edx)
- movw (%ecx), %ax
- movw %ax, (%edx)
-
- lea 3(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail3):
- movw (%ecx), %ax
- movw %ax, (%edx)
- movb 2(%ecx), %al
- movb %al, 2(%edx)
-
- mov $2, %eax
- RETURN
-
- .p2align 4
-L(ExitTail4):
- movl (%ecx), %eax
- movl %eax, (%edx)
-
- mov $3, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail5):
- movb %bh, 4(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl %edx, %eax
-
- lea 5(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail5):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- mov $4, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail6):
- movb %bh, 5(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movb 4(%ecx), %al
- movb %al, 4(%edx)
-
- lea 6(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail6):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- mov $5, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail7):
- movb %bh, 6(%edx)
- movl (%ecx), %eax
- movl %eax, (%edx)
- movw 4(%ecx), %ax
- movw %ax, 4(%edx)
-
- lea 7(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail7):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl 3(%ecx), %eax
- movl %eax, 3(%edx)
-
- mov $6, %eax
- RETURN
-
- .p2align 4
-L(ExitTail8):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- mov $7, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail9):
- movb %bh, 8(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
-
- lea 9(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail9):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- mov $8, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail10):
- movb %bh, 9(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movb 8(%ecx), %al
- movb %al, 8(%edx)
-
- lea 10(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail10):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- mov $9, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail11):
- movb %bh, 10(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movw 8(%ecx), %ax
- movw %ax, 8(%edx)
-
- lea 11(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail11):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 7(%ecx), %eax
- movl %eax, 7(%edx)
-
- mov $10, %eax
- RETURN
-
- .p2align 4
-L(ExitTail12):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- mov $11, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail13):
- movb %bh, 12(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
-
- lea 13(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail13):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- mov $12, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail14):
- movb %bh, 13(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 5(%ecx), %xmm0
- movlpd %xmm0, 5(%edx)
-
- lea 14(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail14):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 6(%ecx), %xmm0
- movlpd %xmm0, 6(%edx)
-
- mov $13, %eax
- RETURN
-
- .p2align 4
-L(ExitTail15):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- mov $14, %eax
- RETURN
-
- .p2align 4
-L(StrlcpyExitTail16):
- movb %bh, 15(%edx)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movlpd 7(%ecx), %xmm0
- movlpd %xmm0, 7(%edx)
-
- lea 16(%ecx), %edx
- jmp L(CalculateLengthOfSrc)
-
- .p2align 4
-L(ExitTail16):
- movlpd (%ecx), %xmm0
- movlpd 8(%ecx), %xmm1
- movlpd %xmm0, (%edx)
- movlpd %xmm1, 8(%edx)
-
- mov $15, %eax
- RETURN
-
- .p2align 4
-L(CalculateLengthOfSrc):
- xor %eax, %eax
- cmpb $0, (%edx)
- jz L(exit_tail0)
- cmpb $0, 1(%edx)
- jz L(exit_tail1)
- cmpb $0, 2(%edx)
- jz L(exit_tail2)
- cmpb $0, 3(%edx)
- jz L(exit_tail3)
-
- cmpb $0, 4(%edx)
- jz L(exit_tail4)
- cmpb $0, 5(%edx)
- jz L(exit_tail5)
- cmpb $0, 6(%edx)
- jz L(exit_tail6)
- cmpb $0, 7(%edx)
- jz L(exit_tail7)
-
- cmpb $0, 8(%edx)
- jz L(exit_tail8)
- cmpb $0, 9(%edx)
- jz L(exit_tail9)
- cmpb $0, 10(%edx)
- jz L(exit_tail10)
- cmpb $0, 11(%edx)
- jz L(exit_tail11)
-
- cmpb $0, 12(%edx)
- jz L(exit_tail12)
- cmpb $0, 13(%edx)
- jz L(exit_tail13)
- cmpb $0, 14(%edx)
- jz L(exit_tail14)
- cmpb $0, 15(%edx)
- jz L(exit_tail15)
-
- pxor %xmm0, %xmm0
- lea 16(%edx), %eax
- add $16, %ecx
- and $-16, %eax
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- pxor %xmm1, %xmm1
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- pxor %xmm2, %xmm2
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- pxor %xmm3, %xmm3
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm0
- pmovmskb %xmm0, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm1
- pmovmskb %xmm1, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm2
- pmovmskb %xmm2, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb (%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 16(%eax), %eax
- test %edx, %edx
- jnz L(exit)
-
- and $-0x40, %eax
-
- .p2align 4
-L(aligned_64_loop):
- movaps (%eax), %xmm0
- movaps 16(%eax), %xmm1
- movaps 32(%eax), %xmm2
- movaps 48(%eax), %xmm6
- pminub %xmm1, %xmm0
- pminub %xmm6, %xmm2
- pminub %xmm0, %xmm2
- pcmpeqb %xmm3, %xmm2
- pmovmskb %xmm2, %edx
- lea 64(%eax), %eax
- test %edx, %edx
- jz L(aligned_64_loop)
-
- pcmpeqb -64(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea 48(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb %xmm1, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb -32(%eax), %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
- test %edx, %edx
- jnz L(exit)
-
- pcmpeqb %xmm6, %xmm3
- pmovmskb %xmm3, %edx
- lea -16(%ecx), %ecx
-
- .p2align 4
-L(exit):
- sub %ecx, %eax
- test %dl, %dl
- jz L(exit_more_8)
-
- mov %dl, %cl
- and $15, %cl
- jz L(exit_more_4)
- test $0x01, %dl
- jnz L(exit_0)
- test $0x02, %dl
- jnz L(exit_1)
- test $0x04, %dl
- jnz L(exit_2)
- add $3, %eax
- RETURN
-
- .p2align 4
-L(exit_more_4):
- test $0x10, %dl
- jnz L(exit_4)
- test $0x20, %dl
- jnz L(exit_5)
- test $0x40, %dl
- jnz L(exit_6)
- add $7, %eax
- RETURN
-
- .p2align 4
-L(exit_more_8):
- mov %dh, %ch
- and $15, %ch
- jz L(exit_more_12)
- test $0x01, %dh
- jnz L(exit_8)
- test $0x02, %dh
- jnz L(exit_9)
- test $0x04, %dh
- jnz L(exit_10)
- add $11, %eax
- RETURN
-
- .p2align 4
-L(exit_more_12):
- test $0x10, %dh
- jnz L(exit_12)
- test $0x20, %dh
- jnz L(exit_13)
- test $0x40, %dh
- jnz L(exit_14)
- add $15, %eax
-L(exit_0):
- RETURN
-
- .p2align 4
-L(exit_1):
- add $1, %eax
- RETURN
-
-L(exit_2):
- add $2, %eax
- RETURN
-
-L(exit_3):
- add $3, %eax
- RETURN
-
-L(exit_4):
- add $4, %eax
- RETURN
-
-L(exit_5):
- add $5, %eax
- RETURN
-
-L(exit_6):
- add $6, %eax
- RETURN
-
-L(exit_7):
- add $7, %eax
- RETURN
-
-L(exit_8):
- add $8, %eax
- RETURN
-
-L(exit_9):
- add $9, %eax
- RETURN
-
-L(exit_10):
- add $10, %eax
- RETURN
-
-L(exit_11):
- add $11, %eax
- RETURN
-
-L(exit_12):
- add $12, %eax
- RETURN
-
-L(exit_13):
- add $13, %eax
- RETURN
-
-L(exit_14):
- add $14, %eax
- RETURN
-
-L(exit_15):
- add $15, %eax
- RETURN
-
-L(exit_tail0):
- mov %edx, %eax
- sub %ecx, %eax
- RETURN
-
- .p2align 4
-L(exit_tail1):
- lea 1(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail2):
- lea 2(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail3):
- lea 3(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail4):
- lea 4(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail5):
- lea 5(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail6):
- lea 6(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail7):
- lea 7(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail8):
- lea 8(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail9):
- lea 9(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail10):
- lea 10(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail11):
- lea 11(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail12):
- lea 12(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail13):
- lea 13(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail14):
- lea 14(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-L(exit_tail15):
- lea 15(%edx), %eax
- sub %ecx, %eax
- RETURN
-
-END (STRCPY)
-
diff --git a/libc/arch-x86/string/ssse3-strncat-atom.S b/libc/arch-x86/string/ssse3-strncat-atom.S
index ccb08a7..5618771 100644
--- a/libc/arch-x86/string/ssse3-strncat-atom.S
+++ b/libc/arch-x86/string/ssse3-strncat-atom.S
@@ -28,7 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define STRCAT strncat_ssse3
+#define STRCAT strncat
#define USE_AS_STRNCAT
#include "ssse3-strcat-atom.S"
diff --git a/libc/arch-x86/string/ssse3-strncmp-atom.S b/libc/arch-x86/string/ssse3-strncmp-atom.S
index 2bf5002..234f728 100644
--- a/libc/arch-x86/string/ssse3-strncmp-atom.S
+++ b/libc/arch-x86/string/ssse3-strncmp-atom.S
@@ -30,6 +30,5 @@
#define USE_AS_STRNCMP
-#define STRCMP strncmp_ssse3
+#define STRCMP strncmp
#include "ssse3-strcmp-atom.S"
-
diff --git a/libc/arch-x86/string/ssse3-strncpy-atom.S b/libc/arch-x86/string/ssse3-strncpy-atom.S
deleted file mode 100644
index 0c27ffe..0000000
--- a/libc/arch-x86/string/ssse3-strncpy-atom.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define USE_AS_STRNCPY
-#define STRCPY strncpy_atom
-#include "ssse3-strcpy-atom.S"
diff --git a/libc/arch-x86/string/ssse3-wcscat-atom.S b/libc/arch-x86/string/ssse3-wcscat-atom.S
deleted file mode 100644
index a307983..0000000
--- a/libc/arch-x86/string/ssse3-wcscat-atom.S
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-Copyright (c) 2011 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef L
-# define L(label) .L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-#endif
-
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
-
-#define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define PARMS 4
-#define STR1 PARMS+4
-#define STR2 STR1+4
-
-#define USE_AS_WCSCAT
-
-.text
-ENTRY (wcscat_ssse3)
- PUSH (%edi)
- mov STR1(%esp), %edi
- mov %edi, %edx
-
-#define RETURN jmp L(WcscpyAtom)
-#include "sse2-wcslen-atom.S"
-
-L(WcscpyAtom):
- shl $2, %eax
- mov STR2(%esp), %ecx
- lea (%edi, %eax), %edx
-
- cmpl $0, (%ecx)
- jz L(Exit4)
- cmpl $0, 4(%ecx)
- jz L(Exit8)
- cmpl $0, 8(%ecx)
- jz L(Exit12)
- cmpl $0, 12(%ecx)
- jz L(Exit16)
-
-#undef RETURN
-#define RETURN POP(%edi); ret; CFI_PUSH(%edi)
-#include "ssse3-wcscpy-atom.S"
-
-END (wcscat_ssse3)
diff --git a/libc/arch-x86/string/ssse3-wcscpy-atom.S b/libc/arch-x86/string/ssse3-wcscpy-atom.S
deleted file mode 100644
index 80aa15f..0000000
--- a/libc/arch-x86/string/ssse3-wcscpy-atom.S
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#ifndef USE_AS_WCSCAT
-
-# ifndef L
-# define L(label) .L##label
-# endif
-
-# ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-# endif
-
-# ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-# endif
-
-# ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
-# endif
-
-# ifndef cfi_restore
-# define cfi_restore(reg) .cfi_restore reg
-# endif
-
-# ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
-# endif
-
-# ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
- .p2align 4; \
-name: \
- cfi_startproc
-# endif
-
-# ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-# endif
-
-# define CFI_PUSH(REG) \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (REG, 0)
-
-# define CFI_POP(REG) \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (REG)
-
-# define PUSH(REG) pushl REG; CFI_PUSH (REG)
-# define POP(REG) popl REG; CFI_POP (REG)
-
-# define PARMS 4
-# define RETURN POP (%edi); ret; CFI_PUSH (%edi)
-
-# define STR1 PARMS
-# define STR2 STR1+4
-# define LEN STR2+4
-
-.text
-ENTRY (wcscpy_ssse3)
- mov STR1(%esp), %edx
- mov STR2(%esp), %ecx
-
- cmpl $0, (%ecx)
- jz L(ExitTail4)
- cmpl $0, 4(%ecx)
- jz L(ExitTail8)
- cmpl $0, 8(%ecx)
- jz L(ExitTail12)
- cmpl $0, 12(%ecx)
- jz L(ExitTail16)
-
- PUSH (%edi)
- mov %edx, %edi
-#endif
- PUSH (%esi)
- lea 16(%ecx), %esi
-
- and $-16, %esi
-
- pxor %xmm0, %xmm0
- pcmpeqd (%esi), %xmm0
- movdqu (%ecx), %xmm1
- movdqu %xmm1, (%edx)
-
- pmovmskb %xmm0, %eax
- sub %ecx, %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- mov %edx, %eax
- lea 16(%edx), %edx
- and $-16, %edx
- sub %edx, %eax
-
- sub %eax, %ecx
- mov %ecx, %eax
- and $0xf, %eax
- mov $0, %esi
-
- jz L(Align16Both)
- cmp $4, %eax
- je L(Shl4)
- cmp $8, %eax
- je L(Shl8)
- jmp L(Shl12)
-
-L(Align16Both):
- movaps (%ecx), %xmm1
- movaps 16(%ecx), %xmm2
- movaps %xmm1, (%edx)
- pcmpeqd %xmm2, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps 16(%ecx, %esi), %xmm3
- movaps %xmm2, (%edx, %esi)
- pcmpeqd %xmm3, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps 16(%ecx, %esi), %xmm4
- movaps %xmm3, (%edx, %esi)
- pcmpeqd %xmm4, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps 16(%ecx, %esi), %xmm1
- movaps %xmm4, (%edx, %esi)
- pcmpeqd %xmm1, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps 16(%ecx, %esi), %xmm2
- movaps %xmm1, (%edx, %esi)
- pcmpeqd %xmm2, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps 16(%ecx, %esi), %xmm3
- movaps %xmm2, (%edx, %esi)
- pcmpeqd %xmm3, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
-
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps %xmm3, (%edx, %esi)
- mov %ecx, %eax
- lea 16(%ecx, %esi), %ecx
- and $-0x40, %ecx
- sub %ecx, %eax
- sub %eax, %edx
-
- mov $-0x40, %esi
-
-L(Aligned64Loop):
- movaps (%ecx), %xmm2
- movaps 32(%ecx), %xmm3
- movaps %xmm2, %xmm4
- movaps 16(%ecx), %xmm5
- movaps %xmm3, %xmm6
- movaps 48(%ecx), %xmm7
- pminub %xmm5, %xmm2
- pminub %xmm7, %xmm3
- pminub %xmm2, %xmm3
- lea 64(%edx), %edx
- pcmpeqd %xmm0, %xmm3
- lea 64(%ecx), %ecx
- pmovmskb %xmm3, %eax
-
- test %eax, %eax
- jnz L(Aligned64Leave)
- movaps %xmm4, -64(%edx)
- movaps %xmm5, -48(%edx)
- movaps %xmm6, -32(%edx)
- movaps %xmm7, -16(%edx)
- jmp L(Aligned64Loop)
-
-L(Aligned64Leave):
- pcmpeqd %xmm4, %xmm0
- pmovmskb %xmm0, %eax
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- pcmpeqd %xmm5, %xmm0
- pmovmskb %xmm0, %eax
- movaps %xmm4, -64(%edx)
- lea 16(%esi), %esi
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- pcmpeqd %xmm6, %xmm0
- pmovmskb %xmm0, %eax
- movaps %xmm5, -48(%edx)
- lea 16(%esi), %esi
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- movaps %xmm6, -32(%edx)
- pcmpeqd %xmm7, %xmm0
- pmovmskb %xmm0, %eax
- lea 16(%esi), %esi
- test %eax, %eax
- jnz L(CopyFrom1To16Bytes)
-
- mov $-0x40, %esi
- movaps %xmm7, -16(%edx)
- jmp L(Aligned64Loop)
-
- .p2align 4
-L(Shl4):
- movaps -4(%ecx), %xmm1
- movaps 12(%ecx), %xmm2
-L(Shl4Start):
- pcmpeqd %xmm2, %xmm0
- pmovmskb %xmm0, %eax
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl4LoopExit)
-
- palignr $4, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 28(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm1
-
- test %eax, %eax
- jnz L(Shl4LoopExit)
-
- palignr $4, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- movaps 28(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl4LoopExit)
-
- palignr $4, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 28(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
-
- test %eax, %eax
- jnz L(Shl4LoopExit)
-
- palignr $4, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- lea 28(%ecx), %ecx
- lea 16(%edx), %edx
-
- mov %ecx, %eax
- and $-0x40, %ecx
- sub %ecx, %eax
- lea -12(%ecx), %ecx
- sub %eax, %edx
-
- movaps -4(%ecx), %xmm1
-
-L(Shl4LoopStart):
- movaps 12(%ecx), %xmm2
- movaps 28(%ecx), %xmm3
- movaps %xmm3, %xmm6
- movaps 44(%ecx), %xmm4
- movaps %xmm4, %xmm7
- movaps 60(%ecx), %xmm5
- pminub %xmm2, %xmm6
- pminub %xmm5, %xmm7
- pminub %xmm6, %xmm7
- pcmpeqd %xmm0, %xmm7
- pmovmskb %xmm7, %eax
- movaps %xmm5, %xmm7
- palignr $4, %xmm4, %xmm5
- palignr $4, %xmm3, %xmm4
- test %eax, %eax
- jnz L(Shl4Start)
-
- palignr $4, %xmm2, %xmm3
- lea 64(%ecx), %ecx
- palignr $4, %xmm1, %xmm2
- movaps %xmm7, %xmm1
- movaps %xmm5, 48(%edx)
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- jmp L(Shl4LoopStart)
-
-L(Shl4LoopExit):
- movlpd (%ecx), %xmm0
- movl 8(%ecx), %esi
- movlpd %xmm0, (%edx)
- movl %esi, 8(%edx)
- POP (%esi)
- add $12, %edx
- add $12, %ecx
- test %al, %al
- jz L(ExitHigh)
- test $0x01, %al
- jnz L(Exit4)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl %edi, %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(Shl8):
- movaps -8(%ecx), %xmm1
- movaps 8(%ecx), %xmm2
-L(Shl8Start):
- pcmpeqd %xmm2, %xmm0
- pmovmskb %xmm0, %eax
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl8LoopExit)
-
- palignr $8, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 24(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm1
-
- test %eax, %eax
- jnz L(Shl8LoopExit)
-
- palignr $8, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- movaps 24(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl8LoopExit)
-
- palignr $8, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 24(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
-
- test %eax, %eax
- jnz L(Shl8LoopExit)
-
- palignr $8, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- lea 24(%ecx), %ecx
- lea 16(%edx), %edx
-
- mov %ecx, %eax
- and $-0x40, %ecx
- sub %ecx, %eax
- lea -8(%ecx), %ecx
- sub %eax, %edx
-
- movaps -8(%ecx), %xmm1
-
-L(Shl8LoopStart):
- movaps 8(%ecx), %xmm2
- movaps 24(%ecx), %xmm3
- movaps %xmm3, %xmm6
- movaps 40(%ecx), %xmm4
- movaps %xmm4, %xmm7
- movaps 56(%ecx), %xmm5
- pminub %xmm2, %xmm6
- pminub %xmm5, %xmm7
- pminub %xmm6, %xmm7
- pcmpeqd %xmm0, %xmm7
- pmovmskb %xmm7, %eax
- movaps %xmm5, %xmm7
- palignr $8, %xmm4, %xmm5
- palignr $8, %xmm3, %xmm4
- test %eax, %eax
- jnz L(Shl8Start)
-
- palignr $8, %xmm2, %xmm3
- lea 64(%ecx), %ecx
- palignr $8, %xmm1, %xmm2
- movaps %xmm7, %xmm1
- movaps %xmm5, 48(%edx)
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- jmp L(Shl8LoopStart)
-
-L(Shl8LoopExit):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- POP (%esi)
- add $8, %edx
- add $8, %ecx
- test %al, %al
- jz L(ExitHigh)
- test $0x01, %al
- jnz L(Exit4)
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl %edi, %eax
- RETURN
-
- CFI_PUSH (%esi)
-
- .p2align 4
-L(Shl12):
- movaps -12(%ecx), %xmm1
- movaps 4(%ecx), %xmm2
-L(Shl12Start):
- pcmpeqd %xmm2, %xmm0
- pmovmskb %xmm0, %eax
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl12LoopExit)
-
- palignr $12, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 20(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm1
-
- test %eax, %eax
- jnz L(Shl12LoopExit)
-
- palignr $12, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- movaps 20(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
- movaps %xmm2, %xmm3
-
- test %eax, %eax
- jnz L(Shl12LoopExit)
-
- palignr $12, %xmm1, %xmm2
- movaps %xmm2, (%edx)
- movaps 20(%ecx), %xmm2
-
- pcmpeqd %xmm2, %xmm0
- lea 16(%edx), %edx
- pmovmskb %xmm0, %eax
- lea 16(%ecx), %ecx
-
- test %eax, %eax
- jnz L(Shl12LoopExit)
-
- palignr $12, %xmm3, %xmm2
- movaps %xmm2, (%edx)
- lea 20(%ecx), %ecx
- lea 16(%edx), %edx
-
- mov %ecx, %eax
- and $-0x40, %ecx
- sub %ecx, %eax
- lea -4(%ecx), %ecx
- sub %eax, %edx
-
- movaps -12(%ecx), %xmm1
-
-L(Shl12LoopStart):
- movaps 4(%ecx), %xmm2
- movaps 20(%ecx), %xmm3
- movaps %xmm3, %xmm6
- movaps 36(%ecx), %xmm4
- movaps %xmm4, %xmm7
- movaps 52(%ecx), %xmm5
- pminub %xmm2, %xmm6
- pminub %xmm5, %xmm7
- pminub %xmm6, %xmm7
- pcmpeqd %xmm0, %xmm7
- pmovmskb %xmm7, %eax
- movaps %xmm5, %xmm7
- palignr $12, %xmm4, %xmm5
- palignr $12, %xmm3, %xmm4
- test %eax, %eax
- jnz L(Shl12Start)
-
- palignr $12, %xmm2, %xmm3
- lea 64(%ecx), %ecx
- palignr $12, %xmm1, %xmm2
- movaps %xmm7, %xmm1
- movaps %xmm5, 48(%edx)
- movaps %xmm4, 32(%edx)
- movaps %xmm3, 16(%edx)
- movaps %xmm2, (%edx)
- lea 64(%edx), %edx
- jmp L(Shl12LoopStart)
-
-L(Shl12LoopExit):
- movl (%ecx), %esi
- movl %esi, (%edx)
- mov $4, %esi
-
- .p2align 4
-L(CopyFrom1To16Bytes):
- add %esi, %edx
- add %esi, %ecx
-
- POP (%esi)
- test %al, %al
- jz L(ExitHigh)
- test $0x01, %al
- jnz L(Exit4)
-L(Exit8):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl %edi, %eax
- RETURN
-
- .p2align 4
-L(ExitHigh):
- test $0x01, %ah
- jnz L(Exit12)
-L(Exit16):
- movdqu (%ecx), %xmm0
- movdqu %xmm0, (%edx)
- movl %edi, %eax
- RETURN
-
- .p2align 4
-L(Exit4):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl %edi, %eax
- RETURN
-
- .p2align 4
-L(Exit12):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
- movl %edi, %eax
- RETURN
-
-CFI_POP (%edi)
-
- .p2align 4
-L(ExitTail4):
- movl (%ecx), %eax
- movl %eax, (%edx)
- movl %edx, %eax
- ret
-
- .p2align 4
-L(ExitTail8):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl %edx, %eax
- ret
-
- .p2align 4
-L(ExitTail12):
- movlpd (%ecx), %xmm0
- movlpd %xmm0, (%edx)
- movl 8(%ecx), %eax
- movl %eax, 8(%edx)
- movl %edx, %eax
- ret
-
- .p2align 4
-L(ExitTail16):
- movdqu (%ecx), %xmm0
- movdqu %xmm0, (%edx)
- movl %edx, %eax
- ret
-
-#ifndef USE_AS_WCSCAT
-END (wcscpy_ssse3)
-#endif
diff --git a/libc/arch-x86/string/ssse3-wmemcmp-atom.S b/libc/arch-x86/string/ssse3-wmemcmp-atom.S
deleted file mode 100644
index a81b78b..0000000
--- a/libc/arch-x86/string/ssse3-wmemcmp-atom.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-Copyright (c) 2011, 2012, 2013 Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define MEMCMP wmemcmp_atom
-
-#define USE_WCHAR
-#define USE_AS_WMEMCMP 1
-#include "ssse3-memcmp-atom.S"
diff --git a/libc/arch-x86_64/bionic/__set_tls.c b/libc/arch-x86_64/bionic/__set_tls.c
index 10fd36f..9460a03 100644
--- a/libc/arch-x86_64/bionic/__set_tls.c
+++ b/libc/arch-x86_64/bionic/__set_tls.c
@@ -27,11 +27,12 @@
*/
#include <sys/cdefs.h>
-#include <asm/prctl.h>
-#include <stdint.h>
-extern int __arch_prctl(int, unsigned long);
+// ARCH_SET_FS is not exposed via <sys/prctl.h> or <linux/prctl.h>.
+#include <asm/prctl.h>
+
+extern int arch_prctl(int, unsigned long);
__LIBC_HIDDEN__ int __set_tls(void* ptr) {
- return __arch_prctl(ARCH_SET_FS, (uintptr_t) ptr);
+ return arch_prctl(ARCH_SET_FS, (unsigned long) ptr);
}
diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp b/libc/arch-x86_64/dynamic_function_dispatch.cpp
index c846ded..cbe68a3 100644
--- a/libc/arch-x86_64/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp
@@ -32,18 +32,18 @@
extern "C" {
-typedef int memset_func(void* __dst, int __ch, size_t __n);
DEFINE_IFUNC_FOR(memset) {
__builtin_cpu_init();
- if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memset_func, memset_avx2);
- RETURN_FUNC(memset_func, memset_generic);
+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memset_func_t, memset_avx2);
+ RETURN_FUNC(memset_func_t, memset_generic);
}
+MEMSET_SHIM()
-typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
DEFINE_IFUNC_FOR(__memset_chk) {
__builtin_cpu_init();
- if (__builtin_cpu_supports("avx2")) RETURN_FUNC(__memset_chk_func, __memset_chk_avx2);
- RETURN_FUNC(__memset_chk_func, __memset_chk_generic);
+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(__memset_chk_func_t, __memset_chk_avx2);
+ RETURN_FUNC(__memset_chk_func_t, __memset_chk_generic);
}
+__MEMSET_CHK_SHIM()
} // extern "C"
diff --git a/libc/arch-x86_64/static_function_dispatch.S b/libc/arch-x86_64/static_function_dispatch.S
deleted file mode 100644
index 93ff5f2..0000000
--- a/libc/arch-x86_64/static_function_dispatch.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-#define FUNCTION_DELEGATE(name, impl) \
-ENTRY(name); \
- jmp impl; \
-END(name)
-
-FUNCTION_DELEGATE(memset, memset_generic)
-FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic)
diff --git a/libc/arch-x86_64/string/avx2-memset-kbl.S b/libc/arch-x86_64/string/avx2-memset-kbl.S
index ca62a9f..35d682a 100644
--- a/libc/arch-x86_64/string/avx2-memset-kbl.S
+++ b/libc/arch-x86_64/string/avx2-memset-kbl.S
@@ -30,7 +30,6 @@
#include <private/bionic_asm.h>
-#include "cache.h"
#ifndef L
# define L(label) .L##label
@@ -117,11 +116,8 @@
cmpq %rcx, %rdx
je L(done)
-#ifdef SHARED_CACHE_SIZE
- cmp $SHARED_CACHE_SIZE, %r8
-#else
- cmp __x86_64_shared_cache_size(%rip), %r8
-#endif
+ cmp __x86_shared_cache_size(%rip), %r8
+
ja L(non_temporal_loop)
ALIGN (4)
diff --git a/libc/arch-x86_64/string/cache.h b/libc/arch-x86_64/string/cache.h
deleted file mode 100644
index 4131509..0000000
--- a/libc/arch-x86_64/string/cache.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-/* Values are optimized for Core Architecture */
-#define SHARED_CACHE_SIZE (4096*1024) /* Core Architecture L2 Cache */
-#define DATA_CACHE_SIZE (24*1024) /* Core Architecture L1 Data Cache */
-
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86_64/string/sse2-memmove-slm.S b/libc/arch-x86_64/string/sse2-memmove-slm.S
index 7395028..8b32680 100644
--- a/libc/arch-x86_64/string/sse2-memmove-slm.S
+++ b/libc/arch-x86_64/string/sse2-memmove-slm.S
@@ -28,7 +28,6 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "cache.h"
#ifndef MEMMOVE
# define MEMMOVE memmove
@@ -189,8 +188,9 @@
cmp %r8, %rbx
jbe L(mm_copy_remaining_forward)
- cmp $SHARED_CACHE_SIZE_HALF, %rdx
- jae L(mm_large_page_loop_forward)
+ cmp __x86_shared_cache_size_half(%rip), %rdx
+
+ ja L(mm_overlapping_check_forward)
.p2align 4
L(mm_main_loop_forward):
@@ -414,8 +414,9 @@
cmp %r9, %rbx
jae L(mm_recalc_len)
- cmp $SHARED_CACHE_SIZE_HALF, %rdx
- jae L(mm_large_page_loop_backward)
+ cmp __x86_shared_cache_size_half(%rip), %rdx
+
+ ja L(mm_overlapping_check_backward)
.p2align 4
L(mm_main_loop_backward):
@@ -481,6 +482,13 @@
/* Big length copy forward part. */
.p2align 4
+
+L(mm_overlapping_check_forward):
+ mov %rsi, %r9
+ add %rdx, %r9
+ cmp __x86_shared_cache_size(%rip), %r9
+ jbe L(mm_main_loop_forward)
+
L(mm_large_page_loop_forward):
movdqu (%r8, %rsi), %xmm0
movdqu 16(%r8, %rsi), %xmm1
@@ -498,6 +506,14 @@
/* Big length copy backward part. */
.p2align 4
+
+L(mm_overlapping_check_backward):
+ mov %rdi, %r11
+ sub %rsi, %r11 /* r11 = dst - src, diff */
+ add %rdx, %r11
+ cmp __x86_shared_cache_size(%rip), %r11
+ jbe L(mm_main_loop_backward)
+
L(mm_large_page_loop_backward):
movdqu -64(%r9, %r8), %xmm0
movdqu -48(%r9, %r8), %xmm1
diff --git a/libc/arch-x86_64/string/sse2-memset-slm.S b/libc/arch-x86_64/string/sse2-memset-slm.S
index cceadd2..84ab327 100644
--- a/libc/arch-x86_64/string/sse2-memset-slm.S
+++ b/libc/arch-x86_64/string/sse2-memset-slm.S
@@ -30,7 +30,6 @@
#include <private/bionic_asm.h>
-#include "cache.h"
#ifndef L
# define L(label) .L##label
@@ -116,11 +115,8 @@
cmpq %rcx, %rdx
je L(return)
-#ifdef SHARED_CACHE_SIZE
- cmp $SHARED_CACHE_SIZE, %r8
-#else
- cmp __x86_64_shared_cache_size(%rip), %r8
-#endif
+ cmp __x86_shared_cache_size(%rip), %r8
+
ja L(128bytesmore_nt)
ALIGN (4)
diff --git a/libc/arch-x86_64/string/sse4-memcmp-slm.S b/libc/arch-x86_64/string/sse4-memcmp-slm.S
index 8a8b180..46ad78d 100644
--- a/libc/arch-x86_64/string/sse4-memcmp-slm.S
+++ b/libc/arch-x86_64/string/sse4-memcmp-slm.S
@@ -28,7 +28,6 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "cache.h"
#ifndef MEMCMP
# define MEMCMP memcmp
@@ -353,11 +352,7 @@
ALIGN (4)
L(512bytesormore):
-#ifdef DATA_CACHE_SIZE_HALF
- mov $DATA_CACHE_SIZE_HALF, %r8
-#else
- mov __x86_64_data_cache_size_half(%rip), %r8
-#endif
+ mov __x86_data_cache_size_half(%rip), %r8
mov %r8, %r9
shr $1, %r8
add %r9, %r8
@@ -669,11 +664,7 @@
ALIGN (4)
L(512bytesormorein2aligned):
-#ifdef DATA_CACHE_SIZE_HALF
- mov $DATA_CACHE_SIZE_HALF, %r8
-#else
- mov __x86_64_data_cache_size_half(%rip), %r8
-#endif
+ mov __x86_data_cache_size_half(%rip), %r8
mov %r8, %r9
shr $1, %r8
add %r9, %r8
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 1b539f2..0d557f1 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -44,7 +44,7 @@
// Declared in "private/bionic_ssp.h".
uintptr_t __stack_chk_guard = 0;
-static pthread_internal_t main_thread;
+BIONIC_USED_BEFORE_LINKER_RELOCATES static pthread_internal_t main_thread;
// Setup for the main thread. For dynamic executables, this is called by the
// linker _before_ libc is mapped in memory. This means that all writes to
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index c8bba01..1b7a5e6 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -29,27 +29,27 @@
#include <signal.h>
#include <stdlib.h>
-#include <sys/syscall.h>
#include <unistd.h>
#include "private/bionic_inline_raise.h"
void abort() {
- // Don't block SIGABRT to give any signal handler a chance; we ignore
- // any errors -- X311J doesn't allow abort to return anyway.
- sigset64_t mask;
- sigfillset64(&mask);
- sigdelset64(&mask, SIGABRT);
+ // Since abort() must not return, there's no error checking in this function:
+ // there's no way to report an error anyway.
- sigprocmask64(SIG_SETMASK, &mask, nullptr);
+ // Unblock SIGABRT to give any signal handler a chance.
+ sigset64_t mask;
+ sigemptyset64(&mask);
+ sigaddset64(&mask, SIGABRT);
+ sigprocmask64(SIG_UNBLOCK, &mask, nullptr);
+
+ // Use inline_raise() to raise SIGABRT without adding an uninteresting
+ // stack frame that anyone investigating the crash would have to ignore.
inline_raise(SIGABRT);
- // If SIGABRT is ignored or it's caught and the handler returns,
- // remove the SIGABRT signal handler and raise SIGABRT again.
- struct sigaction64 sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART };
- sigaction64(SIGABRT, &sa, nullptr);
-
- sigprocmask64(SIG_SETMASK, &mask, nullptr);
+ // If that signal was ignored or was caught and the handler returned,
+ // remove the signal handler and raise SIGABRT again.
+ signal(SIGABRT, SIG_DFL);
inline_raise(SIGABRT);
// If we get this far, just exit.
diff --git a/libc/bionic/android_mallopt.cpp b/libc/bionic/android_mallopt.cpp
new file mode 100644
index 0000000..79e4072
--- /dev/null
+++ b/libc/bionic/android_mallopt.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009 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 <stdatomic.h>
+
+#include <platform/bionic/malloc.h>
+#include <private/bionic_globals.h>
+
+#include "gwp_asan_wrappers.h"
+#include "malloc_limit.h"
+
+#if !defined(LIBC_STATIC)
+#include <stdio.h>
+
+#include <private/bionic_defs.h>
+
+#include "malloc_heapprofd.h"
+
+extern bool gZygoteChild;
+extern _Atomic bool gZygoteChildProfileable;
+
+bool WriteMallocLeakInfo(FILE* fp);
+bool GetMallocLeakInfo(android_mallopt_leak_info_t* leak_info);
+bool FreeMallocLeakInfo(android_mallopt_leak_info_t* leak_info);
+#endif
+
+// =============================================================================
+// Platform-internal mallopt variant.
+// =============================================================================
+#if !defined(LIBC_STATIC)
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+#endif
+extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
+ // Functionality available in both static and dynamic libc.
+ if (opcode == M_GET_DECAY_TIME_ENABLED) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->decay_time_enabled);
+ return true;
+ }
+ if (opcode == M_INITIALIZE_GWP_ASAN) {
+ if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) {
+ errno = EINVAL;
+ return false;
+ }
+
+ return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
+ }
+ if (opcode == M_MEMTAG_STACK_IS_ON) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_memtag_stack);
+ return true;
+ }
+ if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
+ return LimitEnable(arg, arg_size);
+ }
+
+#if defined(LIBC_STATIC)
+ errno = ENOTSUP;
+ return false;
+#else
+ if (opcode == M_SET_ZYGOTE_CHILD) {
+ if (arg != nullptr || arg_size != 0) {
+ errno = EINVAL;
+ return false;
+ }
+ gZygoteChild = true;
+ return true;
+ }
+ if (opcode == M_INIT_ZYGOTE_CHILD_PROFILING) {
+ if (arg != nullptr || arg_size != 0) {
+ errno = EINVAL;
+ return false;
+ }
+ atomic_store_explicit(&gZygoteChildProfileable, true, memory_order_release);
+ // Also check if heapprofd should start profiling from app startup.
+ HeapprofdInitZygoteChildProfiling();
+ return true;
+ }
+ if (opcode == M_GET_PROCESS_PROFILEABLE) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ // Native processes are considered profileable. Zygote children are considered
+ // profileable only when appropriately tagged.
+ *reinterpret_cast<bool*>(arg) =
+ !gZygoteChild || atomic_load_explicit(&gZygoteChildProfileable, memory_order_acquire);
+ return true;
+ }
+ if (opcode == M_WRITE_MALLOC_LEAK_INFO_TO_FILE) {
+ if (arg == nullptr || arg_size != sizeof(FILE*)) {
+ errno = EINVAL;
+ return false;
+ }
+ return WriteMallocLeakInfo(reinterpret_cast<FILE*>(arg));
+ }
+ if (opcode == M_GET_MALLOC_LEAK_INFO) {
+ if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
+ errno = EINVAL;
+ return false;
+ }
+ return GetMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
+ }
+ if (opcode == M_FREE_MALLOC_LEAK_INFO) {
+ if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
+ errno = EINVAL;
+ return false;
+ }
+ return FreeMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
+ }
+ // Try heapprofd's mallopt, as it handles options not covered here.
+ return HeapprofdMallopt(opcode, arg, arg_size);
+#endif
+}
diff --git a/libc/bionic/bionic_call_ifunc_resolver.cpp b/libc/bionic/bionic_call_ifunc_resolver.cpp
index e44d998..d5a812c 100644
--- a/libc/bionic/bionic_call_ifunc_resolver.cpp
+++ b/libc/bionic/bionic_call_ifunc_resolver.cpp
@@ -31,6 +31,7 @@
#include <sys/hwprobe.h>
#include <sys/ifunc.h>
+#include "bionic/macros.h"
#include "private/bionic_auxv.h"
// This code is called in the linker before it has been relocated, so minimize calls into other
@@ -40,8 +41,8 @@
ElfW(Addr) __bionic_call_ifunc_resolver(ElfW(Addr) resolver_addr) {
#if defined(__aarch64__)
typedef ElfW(Addr) (*ifunc_resolver_t)(uint64_t, __ifunc_arg_t*);
- static __ifunc_arg_t arg;
- static bool initialized = false;
+ BIONIC_USED_BEFORE_LINKER_RELOCATES static __ifunc_arg_t arg;
+ BIONIC_USED_BEFORE_LINKER_RELOCATES static bool initialized = false;
if (!initialized) {
initialized = true;
arg._size = sizeof(__ifunc_arg_t);
diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp
index 31e6c3c..45d29b7 100644
--- a/libc/bionic/clock.cpp
+++ b/libc/bionic/clock.cpp
@@ -32,7 +32,7 @@
#include "private/bionic_constants.h"
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/clock.html
clock_t clock() {
timespec ts;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
diff --git a/libc/bionic/elf_note.cpp b/libc/bionic/elf_note.cpp
index d5cd5de..efe3844 100644
--- a/libc/bionic/elf_note.cpp
+++ b/libc/bionic/elf_note.cpp
@@ -38,31 +38,34 @@
return false;
}
+ size_t note_name_len = strlen(note_name) + 1;
+
ElfW(Addr) p = note_addr;
ElfW(Addr) note_end = p + phdr_note->p_memsz;
-
while (p + sizeof(ElfW(Nhdr)) <= note_end) {
+ // Parse the note and check it's structurally valid.
const ElfW(Nhdr)* note = reinterpret_cast<const ElfW(Nhdr)*>(p);
p += sizeof(ElfW(Nhdr));
const char* name = reinterpret_cast<const char*>(p);
- p += align_up(note->n_namesz, 4);
+ if (__builtin_add_overflow(p, __builtin_align_up(note->n_namesz, 4), &p)) {
+ return false;
+ }
const char* desc = reinterpret_cast<const char*>(p);
- p += align_up(note->n_descsz, 4);
+ if (__builtin_add_overflow(p, __builtin_align_up(note->n_descsz, 4), &p)) {
+ return false;
+ }
if (p > note_end) {
- break;
- }
- if (note->n_type != note_type) {
- continue;
- }
- size_t note_name_len = strlen(note_name) + 1;
- if (note->n_namesz != note_name_len || strncmp(note_name, name, note_name_len) != 0) {
- break;
+ return false;
}
- *note_hdr = note;
- *note_desc = desc;
-
- return true;
+ // Is this the note we're looking for?
+ if (note->n_type == note_type &&
+ note->n_namesz == note_name_len &&
+ strncmp(note_name, name, note_name_len) == 0) {
+ *note_hdr = note;
+ *note_desc = desc;
+ return true;
+ }
}
return false;
}
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 863aa97..56544d0 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -41,10 +41,8 @@
#include "private/FdPath.h"
#include "private/__bionic_get_shell_path.h"
-#include "pthread_internal.h"
extern "C" char** environ;
-extern "C" int __execve(const char* pathname, char* const* argv, char* const* envp);
enum { ExecL, ExecLE, ExecLP };
@@ -183,8 +181,3 @@
if (errno == ENOENT) errno = EBADF;
return -1;
}
-
-__attribute__((no_sanitize("memtag"))) int execve(const char* pathname, char* const* argv,
- char* const* envp) {
- return __execve(pathname, argv, envp);
-}
diff --git a/libc/bionic/exit.cpp b/libc/bionic/exit.cpp
index 04baac2..8eda5b2 100644
--- a/libc/bionic/exit.cpp
+++ b/libc/bionic/exit.cpp
@@ -26,24 +26,22 @@
* SUCH DAMAGE.
*/
+#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include "private/bionic_defs.h"
-#include "pthread_internal.h"
extern "C" void __cxa_finalize(void* dso_handle);
extern "C" void __cxa_thread_finalize();
-extern "C" __noreturn void __exit_group(int status);
-__attribute__((no_sanitize("memtag"))) void _exit(int status) {
- __exit_group(status);
-}
-
-__strong_alias(_Exit, _exit);
+static pthread_mutex_t g_exit_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void exit(int status) {
+ // https://austingroupbugs.net/view.php?id=1845
+ pthread_mutex_lock(&g_exit_mutex);
+
__cxa_thread_finalize();
__cxa_finalize(nullptr);
_exit(status);
diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c
index 1287267..c36835e 100644
--- a/libc/bionic/fts.c
+++ b/libc/bionic/fts.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/param.h> /* ALIGN */
#include <sys/stat.h>
#include <dirent.h>
@@ -37,6 +36,7 @@
#include <fcntl.h>
#include <fts.h>
#include <limits.h>
+#include <stdalign.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -912,10 +912,14 @@
* be careful that the stat structure is reasonably aligned. Since the
* fts_name field is declared to be of size 1, the fts_name pointer is
* namelen + 2 before the first possible address of the stat structure.
+ *
+ * We can't use the same trick FreeBSD uses here because our fts_name
+ * is a char[1] rather than a char*. This is also the reason we don't
+ * need to say `namelen + 1`. We just assume the worst alignment.
*/
len = sizeof(FTSENT) + namelen;
if (!ISSET(FTS_NOSTAT))
- len += sizeof(struct stat) + ALIGNBYTES;
+ len += alignof(struct stat) + sizeof(struct stat);
if ((p = calloc(1, len)) == NULL)
return (NULL);
@@ -923,7 +927,7 @@
p->fts_namelen = namelen;
p->fts_instr = FTS_NOINSTR;
if (!ISSET(FTS_NOSTAT))
- p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+ p->fts_statp = (struct stat *)__builtin_align_up(p->fts_name + namelen + 2, alignof(struct stat));
memcpy(p->fts_name, name, namelen);
return (p);
diff --git a/libc/bionic/getauxval.cpp b/libc/bionic/getauxval.cpp
index e188d73..51ff949 100644
--- a/libc/bionic/getauxval.cpp
+++ b/libc/bionic/getauxval.cpp
@@ -26,14 +26,12 @@
* SUCH DAMAGE.
*/
-#include <stddef.h>
-#include <sys/cdefs.h>
-#include <sys/auxv.h>
-#include <private/bionic_auxv.h>
-#include <private/bionic_globals.h>
-#include <private/bionic_ifuncs.h>
#include <elf.h>
#include <errno.h>
+#include <private/bionic_auxv.h>
+#include <private/bionic_globals.h>
+#include <stddef.h>
+#include <sys/auxv.h>
// This function needs to be safe to call before TLS is set up, so it can't
// access errno or the stack protector.
diff --git a/libc/bionic/icu_wrappers.cpp b/libc/bionic/icu_wrappers.cpp
index d9f2745..523f5a6 100644
--- a/libc/bionic/icu_wrappers.cpp
+++ b/libc/bionic/icu_wrappers.cpp
@@ -40,10 +40,3 @@
reinterpret_cast<u_getIntPropertyValue_t>(__find_icu_symbol("u_getIntPropertyValue"));
return u_getIntPropertyValue ? u_getIntPropertyValue(wc, property) : 0;
}
-
-bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int)) {
- typedef UBool (*u_hasBinaryProperty_t)(UChar32, UProperty);
- static auto u_hasBinaryProperty =
- reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
- return u_hasBinaryProperty ? u_hasBinaryProperty(wc, property) : fallback(wc);
-}
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 1bbdb29..63c9fab 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -15,6 +15,7 @@
*/
#include <errno.h>
+#include <inttypes.h>
#include <malloc.h>
#include <sys/param.h>
#include <unistd.h>
@@ -30,6 +31,7 @@
size_t je_mallinfo_nbins();
struct mallinfo je_mallinfo_arena_info(size_t);
struct mallinfo je_mallinfo_bin_info(size_t, size_t);
+void je_stats_arena(size_t arena_index, void (*callback)(size_t, size_t, size_t));
__END_DECLS
@@ -136,29 +138,24 @@
}
return 1;
} else if (param == M_LOG_STATS) {
+ size_t total_bytes = 0;
for (size_t i = 0; i < je_mallinfo_narenas(); i++) {
struct mallinfo mi = je_mallinfo_arena_info(i);
- if (mi.hblkhd != 0) {
- async_safe_format_log(ANDROID_LOG_INFO, "jemalloc",
- "Arena %zu: large bytes %zu huge bytes %zu bin bytes %zu", i,
- mi.ordblks, mi.uordblks, mi.fsmblks);
+ size_t arena_bytes = mi.fsmblks + mi.ordblks + mi.uordblks;
+ async_safe_format_log(ANDROID_LOG_INFO, "jemalloc",
+ "Arena %zu: bin bytes=%zu large bytes=%zu total bytes=%zu", i,
+ mi.fsmblks, mi.ordblks, arena_bytes);
- for (size_t j = 0; j < je_mallinfo_nbins(); j++) {
- struct mallinfo mi = je_mallinfo_bin_info(i, j);
- if (mi.ordblks != 0) {
- size_t total_allocs = 1;
- if (mi.uordblks > mi.fordblks) {
- total_allocs = mi.uordblks - mi.fordblks;
- }
- size_t bin_size = mi.ordblks / total_allocs;
- async_safe_format_log(
- ANDROID_LOG_INFO, "jemalloc",
- " Bin %zu (%zu bytes): allocated bytes %zu nmalloc %zu ndalloc %zu", j, bin_size,
- mi.ordblks, mi.uordblks, mi.fordblks);
- }
+ je_stats_arena(i, [](size_t index, size_t size, size_t allocs) {
+ if (allocs != 0) {
+ async_safe_format_log(ANDROID_LOG_INFO, "jemalloc",
+ " Size Class %zu(%zu bytes): allocs=%zu total bytes=%zu", index,
+ size, allocs, allocs * size);
}
- }
+ });
+ total_bytes += arena_bytes;
}
+ async_safe_format_log(ANDROID_LOG_INFO, "jemalloc", "Total Bytes=%zu", total_bytes);
return 1;
}
diff --git a/libc/bionic/langinfo.cpp b/libc/bionic/langinfo.cpp
index 6f5057c..9645475 100644
--- a/libc/bionic/langinfo.cpp
+++ b/libc/bionic/langinfo.cpp
@@ -98,6 +98,4 @@
return const_cast<char*>(result);
}
-char* nl_langinfo_l(nl_item item, locale_t) {
- return nl_langinfo(item);
-}
+__strong_alias(nl_langinfo_l, nl_langinfo)
diff --git a/libc/bionic/strnlen.cpp b/libc/bionic/lchmod.cpp
similarity index 84%
rename from libc/bionic/strnlen.cpp
rename to libc/bionic/lchmod.cpp
index 7101b21..928a724 100644
--- a/libc/bionic/strnlen.cpp
+++ b/libc/bionic/lchmod.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,11 @@
* SUCH DAMAGE.
*/
-#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
-size_t strnlen(const char* s, size_t n) {
- const char* p = static_cast<const char*>(memchr(s, 0, n));
- return p ? (p - s) : n;
+int lchmod(const char* path, mode_t mode) {
+ return fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW);
}
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 4e19ebf..e66126b 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -161,3 +161,9 @@
}
return __mremap(old_address, old_size, new_size, flags, new_address);
}
+
+// mseal(2) is LP64-only.
+int mseal(void*, size_t, unsigned long) {
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 939e4e1..94ba7e4 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -64,6 +64,28 @@
__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
const char* __progname;
+#if defined(__i386__) || defined(__x86_64__)
+// Default sizes based on the old hard-coded values for Atom/Silvermont (x86) and Core 2 (x86-64)...
+size_t __x86_data_cache_size = 24 * 1024;
+size_t __x86_data_cache_size_half = __x86_data_cache_size / 2;
+size_t __x86_shared_cache_size = sizeof(long) == 8 ? 4096 * 1024 : 1024 * 1024;
+size_t __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
+// ...overwritten at runtime based on the cpu's reported cache sizes.
+static void __libc_init_x86_cache_info() {
+ // Handle the case where during early boot /sys fs may not yet be ready,
+ // resulting in sysconf() returning 0, leading to crashes.
+ // In that case (basically just init), we keep the defaults.
+ if (sysconf(_SC_LEVEL1_DCACHE_SIZE) != 0) {
+ __x86_data_cache_size = sysconf(_SC_LEVEL1_DCACHE_SIZE);
+ __x86_data_cache_size_half = __x86_data_cache_size / 2;
+ }
+ if (sysconf(_SC_LEVEL2_CACHE_SIZE) != 0) {
+ __x86_shared_cache_size = sysconf(_SC_LEVEL2_CACHE_SIZE);
+ __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
+ }
+}
+#endif
+
void __libc_init_globals() {
// Initialize libc globals that are needed in both the linker and in libc.
// In dynamic binaries, this is run at least twice for different copies of the
@@ -78,8 +100,10 @@
#if !defined(__LP64__)
static void __check_max_thread_id() {
if (gettid() > 65535) {
- async_safe_fatal("Limited by the size of pthread_mutex_t, 32 bit bionic libc only accepts "
- "pid <= 65535, but current pid is %d", gettid());
+ async_safe_fatal("32-bit pthread_mutex_t only supports pids <= 65535; "
+ "current pid %d; "
+ "`echo 65535 > /proc/sys/kernel/pid_max` as root",
+ gettid());
}
}
#endif
@@ -173,6 +197,10 @@
__system_properties_init(); // Requires 'environ'.
__libc_init_fdsan(); // Requires system properties (for debug.fdsan).
__libc_init_fdtrack();
+
+#if defined(__i386__) || defined(__x86_64__)
+ __libc_init_x86_cache_info();
+#endif
}
void __libc_init_fork_handler() {
@@ -182,9 +210,9 @@
extern "C" void scudo_malloc_set_add_large_allocation_slack(int add_slack);
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE void __libc_set_target_sdk_version(int target __unused) {
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE void __libc_set_target_sdk_version(int target_api_level __unused) {
#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
- scudo_malloc_set_add_large_allocation_slack(target < __ANDROID_API_S__);
+ scudo_malloc_set_add_large_allocation_slack(target_api_level < 31);
#endif
}
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 126f002..9e15811 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -44,10 +44,12 @@
size_t fini_array_count;
} structors_array_t;
-__BEGIN_DECLS
-
+// The main function must not be declared with a linkage-specification
+// ('extern "C"' or 'extern "C++"'), so declare it before __BEGIN_DECLS.
extern int main(int argc, char** argv, char** env);
+__BEGIN_DECLS
+
__noreturn void __libc_init(void* raw_args,
void (*onexit)(void),
int (*slingshot)(int, char**, char**),
diff --git a/libc/bionic/libc_init_mte.cpp b/libc/bionic/libc_init_mte.cpp
new file mode 100644
index 0000000..3c8ef7d
--- /dev/null
+++ b/libc/bionic/libc_init_mte.cpp
@@ -0,0 +1,325 @@
+/*
+ * 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 <android/api-level.h>
+#include <elf.h>
+#include <errno.h>
+#include <malloc.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+
+#include "async_safe/log.h"
+#include "heap_tagging.h"
+#include "libc_init_common.h"
+#include "platform/bionic/macros.h"
+#include "platform/bionic/mte.h"
+#include "platform/bionic/page.h"
+#include "platform/bionic/reserved_signals.h"
+#include "private/KernelArgumentBlock.h"
+#include "private/bionic_asm.h"
+#include "private/bionic_asm_note.h"
+#include "private/bionic_call_ifunc_resolver.h"
+#include "private/bionic_elf_tls.h"
+#include "private/bionic_globals.h"
+#include "private/bionic_tls.h"
+#include "private/elf_note.h"
+#include "pthread_internal.h"
+#include "sys/system_properties.h"
+#include "sysprop_helpers.h"
+
+#ifdef __aarch64__
+extern "C" const char* __gnu_basename(const char* path);
+
+static HeapTaggingLevel __get_memtag_level_from_note(const ElfW(Phdr) * phdr_start, size_t phdr_ct,
+ const ElfW(Addr) load_bias, bool* stack) {
+ const ElfW(Nhdr) * note;
+ const char* desc;
+ if (!__find_elf_note(NT_ANDROID_TYPE_MEMTAG, "Android", phdr_start, phdr_ct, ¬e, &desc,
+ load_bias)) {
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ }
+
+ // Previously (in Android 12), if the note was != 4 bytes, we check-failed
+ // here. Let's be more permissive to allow future expansion.
+ if (note->n_descsz < 4) {
+ async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
+ note->n_descsz);
+ }
+
+ // `desc` is always aligned due to ELF requirements, enforced in __find_elf_note().
+ ElfW(Word) note_val = *reinterpret_cast<const ElfW(Word)*>(desc);
+ *stack = (note_val & NT_MEMTAG_STACK) != 0;
+
+ // Warning: In Android 12, any value outside of bits [0..3] resulted in a check-fail.
+ if (!(note_val & (NT_MEMTAG_HEAP | NT_MEMTAG_STACK))) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "unrecognised memtag note_val did not specificy heap or stack: %u",
+ note_val);
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ }
+
+ unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
+ switch (mode) {
+ case NT_MEMTAG_LEVEL_NONE:
+ // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
+ // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
+ // by anyone, but we note it (heh) here for posterity, in case the zero
+ // level becomes meaningful, and binaries with this note can be executed
+ // on Android 12 devices.
+ return M_HEAP_TAGGING_LEVEL_TBI;
+ case NT_MEMTAG_LEVEL_ASYNC:
+ return M_HEAP_TAGGING_LEVEL_ASYNC;
+ case NT_MEMTAG_LEVEL_SYNC:
+ default:
+ // We allow future extensions to specify mode 3 (currently unused), with
+ // the idea that it might be used for ASYMM mode or something else. On
+ // this version of Android, it falls back to SYNC mode.
+ return M_HEAP_TAGGING_LEVEL_SYNC;
+ }
+}
+
+// Returns true if there's an environment setting (either sysprop or env var)
+// that should overwrite the ELF note, and places the equivalent heap tagging
+// level into *level.
+static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
+ static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
+ static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
+ static const char kMemtagOverrideSyspropPrefix[] =
+ "persist.device_config.memory_safety_native.mode_override.process.";
+
+ const char* progname = __libc_shared_globals()->init_progname;
+ if (progname == nullptr) return false;
+
+ const char* basename = __gnu_basename(progname);
+
+ char options_str[PROP_VALUE_MAX];
+ char sysprop_name[512];
+ async_safe_format_buffer(sysprop_name, sizeof(sysprop_name), "%s%s", kMemtagPrognameSyspropPrefix,
+ basename);
+ char remote_sysprop_name[512];
+ async_safe_format_buffer(remote_sysprop_name, sizeof(remote_sysprop_name), "%s%s",
+ kMemtagOverrideSyspropPrefix, basename);
+ const char* sys_prop_names[] = {sysprop_name, remote_sysprop_name, kMemtagGlobalSysprop};
+
+ if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
+ options_str, sizeof(options_str))) {
+ return false;
+ }
+
+ if (strcmp("sync", options_str) == 0) {
+ *level = M_HEAP_TAGGING_LEVEL_SYNC;
+ } else if (strcmp("async", options_str) == 0) {
+ *level = M_HEAP_TAGGING_LEVEL_ASYNC;
+ } else if (strcmp("off", options_str) == 0) {
+ *level = M_HEAP_TAGGING_LEVEL_TBI;
+ } else {
+ async_safe_format_log(
+ ANDROID_LOG_ERROR, "libc",
+ "unrecognized memtag level: \"%s\" (options are \"sync\", \"async\", or \"off\").",
+ options_str);
+ return false;
+ }
+
+ return true;
+}
+
+// Returns the initial heap tagging level. Note: This function will never return
+// M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable
+// M_HEAP_TAGGING_LEVEL_TBI.
+static HeapTaggingLevel __get_tagging_level(const memtag_dynamic_entries_t* memtag_dynamic_entries,
+ const void* phdr_start, size_t phdr_ct,
+ uintptr_t load_bias, bool* stack) {
+ HeapTaggingLevel level = M_HEAP_TAGGING_LEVEL_TBI;
+
+ // If the dynamic entries exist, use those. Otherwise, fall back to the old
+ // Android note, which is still used for fully static executables. When
+ // -fsanitize=memtag* is used in newer toolchains, currently both the dynamic
+ // entries and the old note are created, but we'd expect to move to just the
+ // dynamic entries for dynamically linked executables in the future. In
+ // addition, there's still some cleanup of the build system (that uses a
+ // manually-constructed note) needed. For more information about the dynamic
+ // entries, see:
+ // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#dynamic-section
+ if (memtag_dynamic_entries && memtag_dynamic_entries->has_memtag_mode) {
+ switch (memtag_dynamic_entries->memtag_mode) {
+ case 0:
+ level = M_HEAP_TAGGING_LEVEL_SYNC;
+ break;
+ case 1:
+ level = M_HEAP_TAGGING_LEVEL_ASYNC;
+ break;
+ default:
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "unrecognised DT_AARCH64_MEMTAG_MODE value: %u",
+ memtag_dynamic_entries->memtag_mode);
+ }
+ *stack = memtag_dynamic_entries->memtag_stack;
+ } else {
+ level = __get_memtag_level_from_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct,
+ load_bias, stack);
+ }
+
+ // We can't short-circuit the environment override, as `stack` is still inherited from the
+ // binary's settings.
+ get_environment_memtag_setting(&level);
+ return level;
+}
+
+static void __enable_mte_signal_handler(int, siginfo_t* info, void*) {
+ if (info->si_code != SI_TIMER) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Got BIONIC_ENABLE_MTE not from SI_TIMER");
+ return;
+ }
+ int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
+ if (tagged_addr_ctrl < 0) {
+ async_safe_fatal("failed to PR_GET_TAGGED_ADDR_CTRL: %m");
+ }
+ if ((tagged_addr_ctrl & PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE) {
+ return;
+ }
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Re-enabling MTE, value: %x (tagged_addr_ctrl %lu)",
+ info->si_value.sival_int, info->si_value.sival_int & PR_MTE_TCF_MASK);
+ tagged_addr_ctrl =
+ (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | (info->si_value.sival_int & PR_MTE_TCF_MASK);
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
+ async_safe_fatal("failed to PR_SET_TAGGED_ADDR_CTRL %d: %m", tagged_addr_ctrl);
+ }
+}
+
+static int64_t __get_memtag_upgrade_secs() {
+ char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ if (!env) return 0;
+ int64_t timed_upgrade = 0;
+ static const char kAppProcessName[] = "app_process64";
+ const char* progname = __libc_shared_globals()->init_progname;
+ progname = progname ? __gnu_basename(progname) : nullptr;
+ // disable timed upgrade for zygote, as the thread spawned will violate the requirement
+ // that it be single-threaded.
+ if (!progname || strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) != 0) {
+ char* endptr;
+ timed_upgrade = strtoll(env, &endptr, 10);
+ if (*endptr != '\0' || timed_upgrade < 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s", env);
+ timed_upgrade = 0;
+ }
+ }
+ // Make sure that this does not get passed to potential processes inheriting
+ // this environment.
+ unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ return timed_upgrade;
+}
+
+// Figure out the desired memory tagging mode (sync/async, heap/globals/stack) for this executable.
+// This function is called from the linker before the main executable is relocated.
+__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(
+ const memtag_dynamic_entries_t* memtag_dynamic_entries, const void* phdr_start, size_t phdr_ct,
+ uintptr_t load_bias) {
+ bool memtag_stack = false;
+ HeapTaggingLevel level =
+ __get_tagging_level(memtag_dynamic_entries, phdr_start, phdr_ct, load_bias, &memtag_stack);
+ if (memtag_stack) __libc_shared_globals()->initial_memtag_stack_abi = true;
+
+ if (int64_t timed_upgrade = __get_memtag_upgrade_secs()) {
+ if (level == M_HEAP_TAGGING_LEVEL_ASYNC) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Attempting timed MTE upgrade from async to sync.");
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = timed_upgrade;
+ level = M_HEAP_TAGGING_LEVEL_SYNC;
+ } else if (level != M_HEAP_TAGGING_LEVEL_SYNC) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Requested timed MTE upgrade from invalid %s to sync. Ignoring.",
+ DescribeTaggingLevel(level));
+ }
+ }
+ if (level == M_HEAP_TAGGING_LEVEL_SYNC || level == M_HEAP_TAGGING_LEVEL_ASYNC) {
+ unsigned long prctl_arg = PR_TAGGED_ADDR_ENABLE | PR_MTE_TAG_SET_NONZERO;
+ prctl_arg |= (level == M_HEAP_TAGGING_LEVEL_SYNC) ? PR_MTE_TCF_SYNC : PR_MTE_TCF_ASYNC;
+
+ // When entering ASYNC mode, specify that we want to allow upgrading to SYNC by OR'ing in the
+ // SYNC flag. But if the kernel doesn't support specifying multiple TCF modes, fall back to
+ // specifying a single mode.
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg | PR_MTE_TCF_SYNC, 0, 0, 0) == 0 ||
+ prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) {
+ __libc_shared_globals()->initial_heap_tagging_level = level;
+
+ struct sigaction action = {};
+ action.sa_flags = SA_SIGINFO | SA_RESTART;
+ action.sa_sigaction = __enable_mte_signal_handler;
+ sigaction(BIONIC_ENABLE_MTE, &action, nullptr);
+ return;
+ }
+ }
+
+ // MTE was either not enabled, or wasn't supported on this device. Try and use
+ // TBI.
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) {
+ __libc_shared_globals()->initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI;
+ }
+ // We did not enable MTE, so we do not need to arm the upgrade timer.
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
+}
+
+// Figure out whether we need to map the stack as PROT_MTE.
+// For dynamic executables, this has to be called after loading all
+// DT_NEEDED libraries, in case one of them needs stack MTE.
+__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte_stack(void* stack_top) {
+ if (!__libc_shared_globals()->initial_memtag_stack_abi) {
+ return;
+ }
+
+ // Even if the device doesn't support MTE, we have to allocate stack
+ // history buffers for code compiled for stack MTE. That is because the
+ // codegen expects a buffer to be present in TLS_SLOT_STACK_MTE either
+ // way.
+ __get_bionic_tcb()->tls_slot(TLS_SLOT_STACK_MTE) = __allocate_stack_mte_ringbuffer(0, nullptr);
+
+ if (__libc_mte_enabled()) {
+ __libc_shared_globals()->initial_memtag_stack = true;
+ void* pg_start = reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
+ if (mprotect(pg_start, page_size(), PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
+ async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
+ }
+ }
+}
+
+#else // __aarch64__
+void __libc_init_mte(const memtag_dynamic_entries_t*, const void*, size_t, uintptr_t) {}
+void __libc_init_mte_stack(void*) {}
+#endif // __aarch64__
+
+bool __libc_mte_enabled() {
+ HeapTaggingLevel lvl = __libc_shared_globals()->initial_heap_tagging_level;
+ return lvl == M_HEAP_TAGGING_LEVEL_SYNC || lvl == M_HEAP_TAGGING_LEVEL_ASYNC;
+}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index ac97376..cd96375 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -30,6 +30,7 @@
#include <elf.h>
#include <errno.h>
#include <malloc.h>
+#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -156,235 +157,6 @@
layout.finish_layout();
}
-
-#ifdef __aarch64__
-static HeapTaggingLevel __get_memtag_level_from_note(const ElfW(Phdr) * phdr_start, size_t phdr_ct,
- const ElfW(Addr) load_bias, bool* stack) {
- const ElfW(Nhdr) * note;
- const char* desc;
- if (!__find_elf_note(NT_ANDROID_TYPE_MEMTAG, "Android", phdr_start, phdr_ct, ¬e, &desc,
- load_bias)) {
- return M_HEAP_TAGGING_LEVEL_TBI;
- }
-
- // Previously (in Android 12), if the note was != 4 bytes, we check-failed
- // here. Let's be more permissive to allow future expansion.
- if (note->n_descsz < 4) {
- async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
- note->n_descsz);
- }
-
- // `desc` is always aligned due to ELF requirements, enforced in __find_elf_note().
- ElfW(Word) note_val = *reinterpret_cast<const ElfW(Word)*>(desc);
- *stack = (note_val & NT_MEMTAG_STACK) != 0;
-
- // Warning: In Android 12, any value outside of bits [0..3] resulted in a check-fail.
- if (!(note_val & (NT_MEMTAG_HEAP | NT_MEMTAG_STACK))) {
- async_safe_format_log(ANDROID_LOG_INFO, "libc",
- "unrecognised memtag note_val did not specificy heap or stack: %u",
- note_val);
- return M_HEAP_TAGGING_LEVEL_TBI;
- }
-
- unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
- switch (mode) {
- case NT_MEMTAG_LEVEL_NONE:
- // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
- // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
- // by anyone, but we note it (heh) here for posterity, in case the zero
- // level becomes meaningful, and binaries with this note can be executed
- // on Android 12 devices.
- return M_HEAP_TAGGING_LEVEL_TBI;
- case NT_MEMTAG_LEVEL_ASYNC:
- return M_HEAP_TAGGING_LEVEL_ASYNC;
- case NT_MEMTAG_LEVEL_SYNC:
- default:
- // We allow future extensions to specify mode 3 (currently unused), with
- // the idea that it might be used for ASYMM mode or something else. On
- // this version of Android, it falls back to SYNC mode.
- return M_HEAP_TAGGING_LEVEL_SYNC;
- }
-}
-
-// Returns true if there's an environment setting (either sysprop or env var)
-// that should overwrite the ELF note, and places the equivalent heap tagging
-// level into *level.
-static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
- static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
- static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
- static const char kMemtagOverrideSyspropPrefix[] =
- "persist.device_config.memory_safety_native.mode_override.process.";
-
- const char* progname = __libc_shared_globals()->init_progname;
- if (progname == nullptr) return false;
-
- const char* basename = __gnu_basename(progname);
-
- char options_str[PROP_VALUE_MAX];
- char sysprop_name[512];
- async_safe_format_buffer(sysprop_name, sizeof(sysprop_name), "%s%s", kMemtagPrognameSyspropPrefix,
- basename);
- char remote_sysprop_name[512];
- async_safe_format_buffer(remote_sysprop_name, sizeof(remote_sysprop_name), "%s%s",
- kMemtagOverrideSyspropPrefix, basename);
- const char* sys_prop_names[] = {sysprop_name, remote_sysprop_name, kMemtagGlobalSysprop};
-
- if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
- options_str, sizeof(options_str))) {
- return false;
- }
-
- if (strcmp("sync", options_str) == 0) {
- *level = M_HEAP_TAGGING_LEVEL_SYNC;
- } else if (strcmp("async", options_str) == 0) {
- *level = M_HEAP_TAGGING_LEVEL_ASYNC;
- } else if (strcmp("off", options_str) == 0) {
- *level = M_HEAP_TAGGING_LEVEL_TBI;
- } else {
- async_safe_format_log(
- ANDROID_LOG_ERROR, "libc",
- "unrecognized memtag level: \"%s\" (options are \"sync\", \"async\", or \"off\").",
- options_str);
- return false;
- }
-
- return true;
-}
-
-// Returns the initial heap tagging level. Note: This function will never return
-// M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable
-// M_HEAP_TAGGING_LEVEL_TBI.
-static HeapTaggingLevel __get_tagging_level(const memtag_dynamic_entries_t* memtag_dynamic_entries,
- const void* phdr_start, size_t phdr_ct,
- uintptr_t load_bias, bool* stack) {
- HeapTaggingLevel level = M_HEAP_TAGGING_LEVEL_TBI;
-
- // If the dynamic entries exist, use those. Otherwise, fall back to the old
- // Android note, which is still used for fully static executables. When
- // -fsanitize=memtag* is used in newer toolchains, currently both the dynamic
- // entries and the old note are created, but we'd expect to move to just the
- // dynamic entries for dynamically linked executables in the future. In
- // addition, there's still some cleanup of the build system (that uses a
- // manually-constructed note) needed. For more information about the dynamic
- // entries, see:
- // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#dynamic-section
- if (memtag_dynamic_entries && memtag_dynamic_entries->has_memtag_mode) {
- switch (memtag_dynamic_entries->memtag_mode) {
- case 0:
- level = M_HEAP_TAGGING_LEVEL_SYNC;
- break;
- case 1:
- level = M_HEAP_TAGGING_LEVEL_ASYNC;
- break;
- default:
- async_safe_format_log(ANDROID_LOG_INFO, "libc",
- "unrecognised DT_AARCH64_MEMTAG_MODE value: %u",
- memtag_dynamic_entries->memtag_mode);
- }
- *stack = memtag_dynamic_entries->memtag_stack;
- } else {
- level = __get_memtag_level_from_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct,
- load_bias, stack);
- }
-
- // We can't short-circuit the environment override, as `stack` is still inherited from the
- // binary's settings.
- get_environment_memtag_setting(&level);
- return level;
-}
-
-static int64_t __get_memtag_upgrade_secs() {
- char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
- if (!env) return 0;
- int64_t timed_upgrade = 0;
- static const char kAppProcessName[] = "app_process64";
- const char* progname = __libc_shared_globals()->init_progname;
- progname = progname ? __gnu_basename(progname) : nullptr;
- // disable timed upgrade for zygote, as the thread spawned will violate the requirement
- // that it be single-threaded.
- if (!progname || strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) != 0) {
- char* endptr;
- timed_upgrade = strtoll(env, &endptr, 10);
- if (*endptr != '\0' || timed_upgrade < 0) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc",
- "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s", env);
- timed_upgrade = 0;
- }
- }
- // Make sure that this does not get passed to potential processes inheriting
- // this environment.
- unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
- return timed_upgrade;
-}
-
-// Figure out the desired memory tagging mode (sync/async, heap/globals/stack) for this executable.
-// This function is called from the linker before the main executable is relocated.
-__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(
- const memtag_dynamic_entries_t* memtag_dynamic_entries, const void* phdr_start, size_t phdr_ct,
- uintptr_t load_bias, void* stack_top) {
- bool memtag_stack = false;
- HeapTaggingLevel level =
- __get_tagging_level(memtag_dynamic_entries, phdr_start, phdr_ct, load_bias, &memtag_stack);
- // 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) {
- async_safe_format_log(ANDROID_LOG_INFO, "libc",
- "Attempting timed MTE upgrade from async to sync.");
- __libc_shared_globals()->heap_tagging_upgrade_timer_sec = timed_upgrade;
- level = M_HEAP_TAGGING_LEVEL_SYNC;
- } else if (level != M_HEAP_TAGGING_LEVEL_SYNC) {
- async_safe_format_log(
- ANDROID_LOG_ERROR, "libc",
- "Requested timed MTE upgrade from invalid %s to sync. Ignoring.",
- DescribeTaggingLevel(level));
- }
- }
- if (level == M_HEAP_TAGGING_LEVEL_SYNC || level == M_HEAP_TAGGING_LEVEL_ASYNC) {
- unsigned long prctl_arg = PR_TAGGED_ADDR_ENABLE | PR_MTE_TAG_SET_NONZERO;
- prctl_arg |= (level == M_HEAP_TAGGING_LEVEL_SYNC) ? PR_MTE_TCF_SYNC : PR_MTE_TCF_ASYNC;
-
- // When entering ASYNC mode, specify that we want to allow upgrading to SYNC by OR'ing in the
- // SYNC flag. But if the kernel doesn't support specifying multiple TCF modes, fall back to
- // specifying a single mode.
- if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg | PR_MTE_TCF_SYNC, 0, 0, 0) == 0 ||
- prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) {
- __libc_shared_globals()->initial_heap_tagging_level = level;
- __libc_shared_globals()->initial_memtag_stack = memtag_stack;
-
- if (memtag_stack) {
- void* pg_start =
- reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
- if (mprotect(pg_start, page_size(), PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
- async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
- }
- }
-
- return;
- }
- }
-
- // MTE was either not enabled, or wasn't supported on this device. Try and use
- // TBI.
- if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) {
- __libc_shared_globals()->initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI;
- }
- // We did not enable MTE, so we do not need to arm the upgrade timer.
- __libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
- // We also didn't enable memtag_stack.
- __libc_shared_globals()->initial_memtag_stack = false;
-}
-#else // __aarch64__
-void __libc_init_mte(const memtag_dynamic_entries_t*, const void*, size_t, uintptr_t, void*) {}
-#endif // __aarch64__
-
void __libc_init_profiling_handlers() {
// The dynamic variant of this function is more interesting, but this
// at least ensures that static binaries aren't killed by the kernel's
@@ -395,12 +167,11 @@
}
__attribute__((no_sanitize("memtag"))) __noreturn static void __real_libc_init(
- void* raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**),
- structors_array_t const* const structors, bionic_tcb* temp_tcb) {
+ KernelArgumentBlock& args, void* raw_args, void (*onexit)(void) __unused,
+ int (*slingshot)(int, char**, char**), structors_array_t const* const structors,
+ bionic_tcb* temp_tcb) {
BIONIC_STOP_UNWIND;
- // Initialize TLS early so system calls and errno work.
- KernelArgumentBlock args(raw_args);
__libc_init_main_thread_early(args, temp_tcb);
__libc_init_main_thread_late();
__libc_init_globals();
@@ -411,7 +182,8 @@
__libc_init_common();
__libc_init_mte(/*memtag_dynamic_entries=*/nullptr,
reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM),
- /*load_bias = */ 0, /*stack_top = */ raw_args);
+ /*load_bias = */ 0);
+ __libc_init_mte_stack(/*stack_top = */ raw_args);
__libc_init_scudo();
__libc_init_profiling_handlers();
__libc_init_fork_handler();
@@ -447,17 +219,25 @@
__attribute__((no_sanitize("hwaddress", "memtag"))) __noreturn void __libc_init(
void* raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**),
structors_array_t const* const structors) {
- bionic_tcb temp_tcb = {};
+ // We _really_ don't want the compiler to call memset() here,
+ // but it's done so before for riscv64 (http://b/365618934),
+ // so we have to force it to behave.
+ bionic_tcb temp_tcb __attribute__((uninitialized));
+ __builtin_memset_inline(&temp_tcb, 0, sizeof(temp_tcb));
+
+ KernelArgumentBlock args(raw_args);
#if __has_feature(hwaddress_sanitizer)
// Install main thread TLS early. It will be initialized later in __libc_init_main_thread. For now
- // all we need is access to TLS_SLOT_SANITIZER.
+ // all we need is access to TLS_SLOT_SANITIZER and read auxval for the page size.
__set_tls(&temp_tcb.tls_slot(0));
+ __libc_shared_globals()->auxv = args.auxv;
// Initialize HWASan enough to run instrumented code. This sets up TLS_SLOT_SANITIZER, among other
// things.
__hwasan_init_static();
// We are ready to run HWASan-instrumented code, proceed with libc initialization...
#endif
- __real_libc_init(raw_args, onexit, slingshot, structors, &temp_tcb);
+
+ __real_libc_init(args, raw_args, onexit, slingshot, structors, &temp_tcb);
}
static int g_target_sdk_version{__ANDROID_API__};
@@ -475,6 +255,6 @@
// compiled with -ffreestanding to avoid implicit string.h function calls. (It shouldn't strictly
// be necessary, though.)
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
- static libc_shared_globals globals;
+ BIONIC_USED_BEFORE_LINKER_RELOCATES static libc_shared_globals globals;
return &globals;
}
diff --git a/libc/bionic/lockf.cpp b/libc/bionic/lockf.cpp
index 804ad68..54e13f5 100644
--- a/libc/bionic/lockf.cpp
+++ b/libc/bionic/lockf.cpp
@@ -68,6 +68,12 @@
return -1;
}
+#if defined(__LP64__)
+// For LP64, off_t == off64_t.
+__strong_alias(lockf, lockf64);
+#else
+// For ILP32 we need a shim that truncates the off64_t to off_t.
int lockf(int fd, int cmd, off_t length) {
return lockf64(fd, cmd, length);
}
+#endif
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 596a1fc..441d884 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -332,44 +332,6 @@
#endif
// =============================================================================
-// =============================================================================
-// Platform-internal mallopt variant.
-// =============================================================================
-#if defined(LIBC_STATIC)
-extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
- if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
- return LimitEnable(arg, arg_size);
- }
- if (opcode == M_INITIALIZE_GWP_ASAN) {
- if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) {
- errno = EINVAL;
- return false;
- }
-
- return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
- }
- if (opcode == M_MEMTAG_STACK_IS_ON) {
- if (arg == nullptr || arg_size != sizeof(bool)) {
- errno = EINVAL;
- return false;
- }
- *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_memtag_stack);
- return true;
- }
- if (opcode == M_GET_DECAY_TIME_ENABLED) {
- if (arg == nullptr || arg_size != sizeof(bool)) {
- errno = EINVAL;
- return false;
- }
- *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->decay_time_enabled);
- return true;
- }
- errno = ENOTSUP;
- return false;
-}
-#endif
-// =============================================================================
-
static constexpr MallocDispatch __libc_malloc_default_dispatch __attribute__((unused)) = {
Malloc(calloc),
Malloc(free),
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 6db6251..7b6d7d4 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -80,7 +80,7 @@
_Atomic bool gGlobalsMutating = false;
-static bool gZygoteChild = false;
+bool gZygoteChild = false;
// In a Zygote child process, this is set to true if profiling of this process
// is allowed. Note that this is set at a later time than gZygoteChild. The
@@ -89,7 +89,7 @@
// domains if applicable). These two flags are read by the
// BIONIC_SIGNAL_PROFILER handler, which does nothing if the process is not
// profileable.
-static _Atomic bool gZygoteChildProfileable = false;
+_Atomic bool gZygoteChildProfileable = false;
// =============================================================================
@@ -471,93 +471,6 @@
}
// =============================================================================
-// =============================================================================
-// Platform-internal mallopt variant.
-// =============================================================================
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
- if (opcode == M_SET_ZYGOTE_CHILD) {
- if (arg != nullptr || arg_size != 0) {
- errno = EINVAL;
- return false;
- }
- gZygoteChild = true;
- return true;
- }
- if (opcode == M_INIT_ZYGOTE_CHILD_PROFILING) {
- if (arg != nullptr || arg_size != 0) {
- errno = EINVAL;
- return false;
- }
- atomic_store_explicit(&gZygoteChildProfileable, true, memory_order_release);
- // Also check if heapprofd should start profiling from app startup.
- HeapprofdInitZygoteChildProfiling();
- return true;
- }
- if (opcode == M_GET_PROCESS_PROFILEABLE) {
- if (arg == nullptr || arg_size != sizeof(bool)) {
- errno = EINVAL;
- return false;
- }
- // Native processes are considered profileable. Zygote children are considered
- // profileable only when appropriately tagged.
- *reinterpret_cast<bool*>(arg) =
- !gZygoteChild || atomic_load_explicit(&gZygoteChildProfileable, memory_order_acquire);
- return true;
- }
- if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
- return LimitEnable(arg, arg_size);
- }
- if (opcode == M_WRITE_MALLOC_LEAK_INFO_TO_FILE) {
- if (arg == nullptr || arg_size != sizeof(FILE*)) {
- errno = EINVAL;
- return false;
- }
- return WriteMallocLeakInfo(reinterpret_cast<FILE*>(arg));
- }
- if (opcode == M_GET_MALLOC_LEAK_INFO) {
- if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
- errno = EINVAL;
- return false;
- }
- return GetMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
- }
- if (opcode == M_FREE_MALLOC_LEAK_INFO) {
- if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
- errno = EINVAL;
- return false;
- }
- return FreeMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
- }
- if (opcode == M_INITIALIZE_GWP_ASAN) {
- if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) {
- errno = EINVAL;
- return false;
- }
-
- return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
- }
- if (opcode == M_MEMTAG_STACK_IS_ON) {
- if (arg == nullptr || arg_size != sizeof(bool)) {
- errno = EINVAL;
- return false;
- }
- *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_memtag_stack);
- return true;
- }
- if (opcode == M_GET_DECAY_TIME_ENABLED) {
- if (arg == nullptr || arg_size != sizeof(bool)) {
- errno = EINVAL;
- return false;
- }
- *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->decay_time_enabled);
- return true;
- }
- // Try heapprofd's mallopt, as it handles options not covered here.
- return HeapprofdMallopt(opcode, arg, arg_size);
-}
-// =============================================================================
-
#if !defined(__LP64__) && defined(__arm__)
// =============================================================================
// Old platform only functions that some old 32 bit apps are still using.
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index 7d80b4c..5b58425 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -48,11 +48,17 @@
return __ppoll(fds, fd_count, ts_ptr, nullptr, 0);
}
+// The underlying ppoll(2) system call only takes `sigset64_t`.
+#if defined(__LP64__)
+// That's fine for LP64 where `sigset_t` and `sigset64_t` are the same.
+__strong_alias(ppoll, ppoll64);
+#else
+// ILP32 needs a shim.
int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) {
- // The underlying `__ppoll` system call only takes `sigset64_t`.
SigSetConverter set{ss};
return ppoll64(fds, fd_count, ts, set.ptr);
}
+#endif
int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) {
// The underlying __ppoll system call modifies its `struct timespec` argument.
@@ -90,12 +96,19 @@
return result;
}
+// The underlying pselect6(2) system call only takes `sigset64_t`.
+#if defined(__LP64__)
+// That's fine for LP64 where `sigset_t` and `sigset64_t` are the same.
+__strong_alias(pselect, pselect64);
+#else
+// ILP32 needs a shim.
int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
const timespec* ts, const sigset_t* ss) {
// The underlying `__pselect6` system call only takes `sigset64_t`.
SigSetConverter set{ss};
return pselect64(fd_count, read_fds, write_fds, error_fds, ts, set.ptr);
}
+#endif
int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
const timespec* ts, const sigset64_t* ss) {
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index ccbbfcf..9516059 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -117,7 +117,7 @@
pthread_kill(timer->callback_thread, TIMER_SIGNAL);
}
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_create.html
int timer_create(clockid_t clock_id, sigevent* evp, timer_t* timer_id) {
PosixTimer* timer = reinterpret_cast<PosixTimer*>(malloc(sizeof(PosixTimer)));
if (timer == nullptr) {
@@ -141,7 +141,7 @@
// Otherwise, this must be SIGEV_THREAD timer...
timer->callback = evp->sigev_notify_function;
timer->callback_argument = evp->sigev_value;
- atomic_init(&timer->deleted, false);
+ atomic_store_explicit(&timer->deleted, false, memory_order_relaxed);
// Check arguments that the kernel doesn't care about but we do.
if (timer->callback == nullptr) {
@@ -201,7 +201,7 @@
return 0;
}
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_delete.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_delete.html
int timer_delete(timer_t id) {
int rc = __timer_delete(to_kernel_timer_id(id));
if (rc == -1) {
@@ -220,12 +220,12 @@
return 0;
}
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_gettime.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_gettime.html
int timer_gettime(timer_t id, itimerspec* ts) {
return __timer_gettime(to_kernel_timer_id(id), ts);
}
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_settime.html
// When using timer_settime to disarm a repeatable SIGEV_THREAD timer with a very small
// period (like below 1ms), the kernel may continue to send events to the callback thread
// for a few extra times. This behavior is fine because in POSIX standard: The effect of
@@ -235,7 +235,7 @@
return __timer_settime(timer->kernel_timer_id, flags, ts, ots);
}
-// http://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_getoverrun.html
+// https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_getoverrun.html
int timer_getoverrun(timer_t id) {
return __timer_getoverrun(to_kernel_timer_id(id));
}
diff --git a/libc/bionic/pthread_barrier.cpp b/libc/bionic/pthread_barrier.cpp
index 1618222..ff048a6 100644
--- a/libc/bionic/pthread_barrier.cpp
+++ b/libc/bionic/pthread_barrier.cpp
@@ -95,8 +95,8 @@
return EINVAL;
}
barrier->init_count = count;
- atomic_init(&barrier->state, WAIT);
- atomic_init(&barrier->wait_count, 0);
+ atomic_store_explicit(&barrier->state, WAIT, memory_order_relaxed);
+ atomic_store_explicit(&barrier->wait_count, 0, memory_order_relaxed);
barrier->pshared = false;
if (attr != nullptr && (*attr & 1)) {
barrier->pshared = true;
diff --git a/libc/bionic/pthread_cond.cpp b/libc/bionic/pthread_cond.cpp
index f444676..197fd19 100644
--- a/libc/bionic/pthread_cond.cpp
+++ b/libc/bionic/pthread_cond.cpp
@@ -140,10 +140,10 @@
if (attr != nullptr) {
init_state = (*attr & COND_FLAGS_MASK);
}
- atomic_init(&cond->state, init_state);
+ atomic_store_explicit(&cond->state, init_state, memory_order_relaxed);
#if defined(__LP64__)
- atomic_init(&cond->waiters, 0);
+ atomic_store_explicit(&cond->waiters, 0, memory_order_relaxed);
#endif
return 0;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index a8d09eb..1bd2da7 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -118,15 +118,18 @@
static void __init_shadow_call_stack(pthread_internal_t* thread __unused) {
#if defined(__aarch64__) || defined(__riscv)
- // Allocate the stack and the guard region.
+ // Allocate the shadow call stack and its guard region.
char* scs_guard_region = reinterpret_cast<char*>(
- mmap(nullptr, SCS_GUARD_REGION_SIZE, 0, MAP_PRIVATE | MAP_ANON, -1, 0));
+ mmap(nullptr, SCS_GUARD_REGION_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0));
+ if (scs_guard_region == MAP_FAILED) {
+ async_safe_fatal("failed to allocate shadow stack: %m");
+ }
thread->shadow_call_stack_guard_region = scs_guard_region;
- // The address is aligned to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
+ // Align the address to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
// in jmp_buf. See the SCS commentary in pthread_internal.h for more detail.
char* scs_aligned_guard_region =
- reinterpret_cast<char*>(align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
+ reinterpret_cast<char*>(__builtin_align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
// We need to ensure that [scs_offset,scs_offset+SCS_SIZE) is in the guard region and that there
// is at least one unmapped page after the shadow call stack (to catch stack overflows). We can't
@@ -156,11 +159,11 @@
int __init_thread(pthread_internal_t* thread) {
thread->cleanup_stack = nullptr;
- if (__predict_true((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) == 0)) {
- atomic_init(&thread->join_state, THREAD_NOT_JOINED);
- } else {
- atomic_init(&thread->join_state, THREAD_DETACHED);
+ ThreadJoinState state = THREAD_NOT_JOINED;
+ if (__predict_false((thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) != 0)) {
+ state = THREAD_DETACHED;
}
+ atomic_store_explicit(&thread->join_state, state, memory_order_relaxed);
// Set the scheduling policy/priority of the thread if necessary.
bool need_set = true;
@@ -293,7 +296,7 @@
// memory isn't counted in pthread_attr_getstacksize.
// To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary.
- stack_top = align_down(stack_top - sizeof(pthread_internal_t), 16);
+ stack_top = __builtin_align_down(stack_top - sizeof(pthread_internal_t), 16);
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
if (!stack_clean) {
@@ -348,15 +351,20 @@
extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
-__attribute__((no_sanitize("hwaddress")))
-#ifdef __aarch64__
+__attribute__((no_sanitize("hwaddress", "memtag")))
+#if defined(__aarch64__)
// This function doesn't return, but it does appear in stack traces. Avoid using return PAC in this
// function because we may end up resetting IA, which may confuse unwinders due to mismatching keys.
__attribute__((target("branch-protection=bti")))
#endif
-static int __pthread_start(void* arg) {
+static int
+__pthread_start(void* arg) {
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
-
+#if defined(__aarch64__)
+ if (thread->should_allocate_stack_mte_ringbuffer) {
+ thread->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE) = __allocate_stack_mte_ringbuffer(0, thread);
+ }
+#endif
__hwasan_thread_enter();
// Wait for our creating thread to release us. This lets it have time to
@@ -368,13 +376,13 @@
__set_stack_and_tls_vma_name(false);
__init_additional_stacks(thread);
__rt_sigprocmask(SIG_SETMASK, &thread->start_mask, nullptr, sizeof(thread->start_mask));
-#ifdef __aarch64__
+#if defined(__aarch64__)
// Chrome's sandbox prevents this prctl, so only reset IA if the target SDK level is high enough.
// Furthermore, processes loaded from vendor partitions may have their own sandboxes that would
- // reject the prctl. Because no devices launched with PAC enabled before S, we can avoid issues on
- // upgrading devices by checking for PAC support before issuing the prctl.
+ // reject the prctl. Because no devices launched with PAC enabled before API level 31, we can
+ // avoid issues on upgrading devices by checking for PAC support before issuing the prctl.
static const bool pac_supported = getauxval(AT_HWCAP) & HWCAP_PACA;
- if (pac_supported && android_get_application_target_sdk_version() >= __ANDROID_API_S__) {
+ if (pac_supported && android_get_application_target_sdk_version() >= 31) {
prctl(PR_PAC_RESET_KEYS, PR_PAC_APIAKEY, 0, 0, 0);
}
#endif
@@ -447,9 +455,9 @@
// 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);
- }
+ thread->should_allocate_stack_mte_ringbuffer = __libc_memtag_stack_abi;
+#else
+ thread->should_allocate_stack_mte_ringbuffer = false;
#endif
sigset64_t block_all_mask;
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 0181aba..27d05c2 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -33,10 +33,11 @@
#include <string.h>
#include <sys/mman.h>
-#include "private/bionic_constants.h"
-#include "private/bionic_defs.h"
+#include "platform/bionic/mte.h"
#include "private/ScopedRWLock.h"
#include "private/ScopedSignalBlocker.h"
+#include "private/bionic_constants.h"
+#include "private/bionic_defs.h"
#include "pthread_internal.h"
extern "C" __noreturn void _exit_with_stack_teardown(void*, size_t);
@@ -67,7 +68,7 @@
}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-void pthread_exit(void* return_value) {
+__attribute__((no_sanitize("memtag"))) void pthread_exit(void* return_value) {
// Call dtors for thread_local objects first.
__cxa_thread_finalize();
@@ -138,6 +139,13 @@
__notify_thread_exit_callbacks();
__hwasan_thread_exit();
+#if defined(__aarch64__)
+ if (void* stack_mte_tls = thread->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE)) {
+ stack_mte_free_ringbuffer(reinterpret_cast<uintptr_t>(stack_mte_tls));
+ }
+#endif
+ // Everything below this line needs to be no_sanitize("memtag").
+
if (old_state == THREAD_DETACHED && thread->mmap_size != 0) {
// We need to free mapped space for detached threads when they exit.
// That's not something we can do in C.
diff --git a/libc/bionic/strnlen.cpp b/libc/bionic/pthread_getaffinity.cpp
similarity index 75%
copy from libc/bionic/strnlen.cpp
copy to libc/bionic/pthread_getaffinity.cpp
index 7101b21..9ce436c 100644
--- a/libc/bionic/strnlen.cpp
+++ b/libc/bionic/pthread_getaffinity.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,17 @@
* SUCH DAMAGE.
*/
-#include <string.h>
+#include <errno.h>
-size_t strnlen(const char* s, size_t n) {
- const char* p = static_cast<const char*>(memchr(s, 0, n));
- return p ? (p - s) : n;
+#include "private/ErrnoRestorer.h"
+#include "pthread_internal.h"
+
+int pthread_getaffinity_np(pthread_t t, size_t cpu_set_size, cpu_set_t* cpu_set) {
+ ErrnoRestorer errno_restorer;
+
+ pid_t tid = __pthread_internal_gettid(t, "pthread_getaffinity_np");
+ if (tid == -1) return ESRCH;
+
+ if (sched_getaffinity(tid, cpu_set_size, cpu_set) == -1) return errno;
+ return 0;
}
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 14cc7da..4f2ad0c 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -34,6 +34,7 @@
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
+#include <sys/types.h>
#include <async_safe/log.h>
#include <bionic/mte.h>
@@ -76,15 +77,6 @@
}
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);
@@ -216,7 +208,10 @@
__libc_memtag_stack_abi = true;
for (pthread_internal_t* t = g_thread_list; t != nullptr; t = t->next) {
- if (t->terminating) continue;
+ // should_allocate_stack_mte_ringbuffer indicates the thread is already
+ // aware that this process requires stack MTE, and will allocate the
+ // ring buffer in __pthread_start.
+ if (t->terminating || t->should_allocate_stack_mte_ringbuffer) continue;
t->bionic_tcb->tls_slot(TLS_SLOT_STACK_MTE) =
__allocate_stack_mte_ringbuffer(0, t->is_main() ? nullptr : t);
}
@@ -264,8 +259,7 @@
g_func = func;
g_arg = arg;
- static _Atomic(bool) g_retval;
- atomic_init(&g_retval, true);
+ static _Atomic(bool) g_retval(true);
auto handler = [](int, siginfo_t*, void*) {
ErrnoRestorer restorer;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 5db42ab..cbaa9a6 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -181,6 +181,7 @@
bionic_tcb* bionic_tcb;
char stack_mte_ringbuffer_vma_name_buffer[32];
+ bool should_allocate_stack_mte_ringbuffer;
bool is_main() { return start_routine == nullptr; }
};
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index 9b37225..c99717a 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -182,7 +182,12 @@
return 0;
}
if (ret == EBUSY) {
- ScopedTrace trace("Contending for pthread mutex");
+ char trace_msg[64];
+ const pid_t owner = atomic_load_explicit(&mutex.owner_tid, memory_order_relaxed)
+ & FUTEX_TID_MASK;
+ snprintf(trace_msg, sizeof(trace_msg),
+ "Contending for pthread mutex owned by tid: %d", owner);
+ ScopedTrace trace(trace_msg);
ret = -__futex_pi_lock_ex(&mutex.owner_tid, mutex.shared, use_realtime_clock, abs_timeout);
}
return ret;
@@ -504,8 +509,8 @@
memset(mutex, 0, sizeof(pthread_mutex_internal_t));
if (__predict_true(attr == nullptr)) {
- atomic_init(&mutex->state, MUTEX_TYPE_BITS_NORMAL);
- return 0;
+ atomic_store_explicit(&mutex->state, MUTEX_TYPE_BITS_NORMAL, memory_order_relaxed);
+ return 0;
}
uint16_t state = 0;
@@ -538,13 +543,13 @@
}
mutex->pi_mutex_id = id;
#endif
- atomic_init(&mutex->state, PI_MUTEX_STATE);
+ atomic_store_explicit(&mutex->state, PI_MUTEX_STATE, memory_order_relaxed);
PIMutex& pi_mutex = mutex->ToPIMutex();
pi_mutex.type = *attr & MUTEXATTR_TYPE_MASK;
pi_mutex.shared = (*attr & MUTEXATTR_SHARED_MASK) != 0;
} else {
- atomic_init(&mutex->state, state);
- atomic_init(&mutex->owner_tid, 0);
+ atomic_store_explicit(&mutex->state, state, memory_order_relaxed);
+ atomic_store_explicit(&mutex->owner_tid, 0, memory_order_relaxed);
}
return 0;
}
diff --git a/libc/bionic/pthread_rwlock.cpp b/libc/bionic/pthread_rwlock.cpp
index 6f3c6fe..92134b4 100644
--- a/libc/bionic/pthread_rwlock.cpp
+++ b/libc/bionic/pthread_rwlock.cpp
@@ -247,7 +247,7 @@
}
}
- atomic_init(&rwlock->state, 0);
+ atomic_store_explicit(&rwlock->state, 0, memory_order_relaxed);
rwlock->pending_lock.init(rwlock->pshared);
return 0;
}
diff --git a/libm/fenv-access.h b/libc/bionic/pthread_setaffinity.cpp
similarity index 74%
copy from libm/fenv-access.h
copy to libc/bionic/pthread_setaffinity.cpp
index 7acb34d..6db418e 100644
--- a/libm/fenv-access.h
+++ b/libc/bionic/pthread_setaffinity.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,17 @@
* SUCH DAMAGE.
*/
-#pragma once
+#include <errno.h>
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
-#endif
+#include "private/ErrnoRestorer.h"
+#include "pthread_internal.h"
+
+int pthread_setaffinity_np(pthread_t t, size_t cpu_set_size, const cpu_set_t* cpu_set) {
+ ErrnoRestorer errno_restorer;
+
+ pid_t tid = __pthread_internal_gettid(t, "pthread_setaffinity_np");
+ if (tid == -1) return ESRCH;
+
+ if (sched_setaffinity(tid, cpu_set_size, cpu_set) == -1) return errno;
+ return 0;
+}
diff --git a/libc/bionic/pthread_sigqueue.cpp b/libc/bionic/pthread_sigqueue.cpp
index 93c349e..7c10b25 100644
--- a/libc/bionic/pthread_sigqueue.cpp
+++ b/libc/bionic/pthread_sigqueue.cpp
@@ -40,14 +40,16 @@
int pthread_sigqueue(pthread_t t, int sig, const union sigval value) {
ErrnoRestorer errno_restorer;
+ pid_t pid = getpid();
+
pid_t tid = __pthread_internal_gettid(t, "pthread_sigqueue");
if (tid == -1) return ESRCH;
- siginfo_t siginfo;
- siginfo.si_code = SI_QUEUE;
- siginfo.si_pid = getpid();
+ siginfo_t siginfo = { .si_code = SI_QUEUE };
+ siginfo.si_signo = sig;
+ siginfo.si_pid = pid;
siginfo.si_uid = getuid();
siginfo.si_value = value;
- return syscall(__NR_rt_tgsigqueueinfo, getpid(), tid, sig, &siginfo) ? errno : 0;
+ return syscall(__NR_rt_tgsigqueueinfo, pid, tid, sig, &siginfo) ? errno : 0;
}
diff --git a/libc/bionic/semaphore.cpp b/libc/bionic/semaphore.cpp
index 33552a9..2c9b745 100644
--- a/libc/bionic/semaphore.cpp
+++ b/libc/bionic/semaphore.cpp
@@ -113,7 +113,7 @@
}
atomic_uint* sem_count_ptr = SEM_TO_ATOMIC_POINTER(sem);
- atomic_init(sem_count_ptr, count);
+ atomic_store_explicit(sem_count_ptr, count, memory_order_relaxed);
return 0;
}
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 2cf9940..5979ed7 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -219,10 +219,8 @@
}
int sigqueue(pid_t pid, int sig, const sigval value) {
- siginfo_t info;
- memset(&info, 0, sizeof(siginfo_t));
+ siginfo_t info = { .si_code = SI_QUEUE };
info.si_signo = sig;
- info.si_code = SI_QUEUE;
info.si_pid = getpid();
info.si_uid = getuid();
info.si_value = value;
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
index 6d436a6..10e2fa3 100644
--- a/libc/bionic/sigprocmask.cpp
+++ b/libc/bionic/sigprocmask.cpp
@@ -41,18 +41,6 @@
// can't allow clang to decide to inline sigprocmask.
//
-int sigprocmask(int how,
- const sigset_t* bionic_new_set,
- sigset_t* bionic_old_set) __attribute__((__noinline__)) {
- SigSetConverter new_set{bionic_new_set};
- SigSetConverter old_set{bionic_old_set};
- int rc = sigprocmask64(how, new_set.ptr, old_set.ptr);
- if (rc == 0 && bionic_old_set != nullptr) {
- old_set.copy_out();
- }
- return rc;
-}
-
int sigprocmask64(int how,
const sigset64_t* new_set,
sigset64_t* old_set) __attribute__((__noinline__)) {
@@ -70,3 +58,21 @@
}
return __rt_sigprocmask(how, mutable_new_set_ptr, old_set, sizeof(*new_set));
}
+
+#if defined(__LP64__)
+// For LP64, `sigset64_t` and `sigset_t` are the same.
+__strong_alias(sigprocmask, sigprocmask64);
+#else
+// ILP32 needs a shim.
+int sigprocmask(int how,
+ const sigset_t* bionic_new_set,
+ sigset_t* bionic_old_set) __attribute__((__noinline__)) {
+ SigSetConverter new_set{bionic_new_set};
+ SigSetConverter old_set{bionic_old_set};
+ int rc = sigprocmask64(how, new_set.ptr, old_set.ptr);
+ if (rc == 0 && bionic_old_set != nullptr) {
+ old_set.copy_out();
+ }
+ return rc;
+}
+#endif
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 38f99ad..d97057f 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -186,8 +186,8 @@
char* const argv[],
char* const env[],
int exec_fn(const char* path, char* const argv[], char* const env[])) {
- // See http://man7.org/linux/man-pages/man3/posix_spawn.3.html
- // and http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html
+ // See https://man7.org/linux/man-pages/man3/posix_spawn.3.html
+ // and https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/posix_spawn.html
ScopedSignalBlocker ssb;
diff --git a/libc/bionic/stdlib_l.cpp b/libc/bionic/stdlib_l.cpp
index 18e9f86..58a9079 100644
--- a/libc/bionic/stdlib_l.cpp
+++ b/libc/bionic/stdlib_l.cpp
@@ -26,34 +26,11 @@
* SUCH DAMAGE.
*/
+#define __BIONIC_STDLIB_INLINE /* Out of line. */
#include <stdlib.h>
-#include <xlocale.h>
+#include <bits/stdlib_inlines.h>
-double strtod_l(const char* s, char** end_ptr, locale_t) {
- return strtod(s, end_ptr);
-}
-
-float strtof_l(const char* s, char** end_ptr, locale_t) {
- return strtof(s, end_ptr);
-}
-
-long strtol_l(const char* s, char** end_ptr, int base, locale_t) {
- return strtol(s, end_ptr, base);
-}
-
+// strtold_l was introduced in API level 21, so it isn't polyfilled any more.
long double strtold_l(const char* s, char** end_ptr, locale_t) {
return strtold(s, end_ptr);
}
-
-long long strtoll_l(const char* s, char** end_ptr, int base, locale_t) {
- return strtoll(s, end_ptr, base);
-}
-
-unsigned long strtoul_l(const char* s, char** end_ptr, int base, locale_t) {
- return strtoul(s, end_ptr, base);
-}
-
-unsigned long long strtoull_l(const char* s, char** end_ptr, int base, locale_t) {
- return strtoull(s, end_ptr, base);
-}
-
diff --git a/libc/bionic/strchr.cpp b/libc/bionic/strchr.cpp
deleted file mode 100644
index fd8a924..0000000
--- a/libc/bionic/strchr.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char* strchr(const char* p, int ch) {
- return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
-}
diff --git a/libc/bionic/strchrnul.cpp b/libc/bionic/strchrnul.cpp
deleted file mode 100644
index 55422e0..0000000
--- a/libc/bionic/strchrnul.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-extern "C" const char* strchrnul(const char* s, int ch) {
- while (*s && *s != ch) {
- ++s;
- }
- return s;
-}
diff --git a/libc/bionic/strerror.cpp b/libc/bionic/strerror.cpp
index 743130d..c41b547 100644
--- a/libc/bionic/strerror.cpp
+++ b/libc/bionic/strerror.cpp
@@ -102,3 +102,4 @@
strerror_r(error_number, result, sizeof(tls.strerror_buf));
return result;
}
+__strong_alias(strerror_l, strerror);
diff --git a/libc/bionic/string_l.cpp b/libc/bionic/string_l.cpp
index 66bfb0e..84396bf 100644
--- a/libc/bionic/string_l.cpp
+++ b/libc/bionic/string_l.cpp
@@ -33,10 +33,6 @@
return strcoll(s1, s2);
}
-char* strerror_l(int error, locale_t) {
- return strerror(error);
-}
-
size_t strxfrm_l(char* dst, const char* src, size_t n, locale_t) {
return strxfrm(dst, src, n);
}
diff --git a/libc/bionic/strrchr.cpp b/libc/bionic/strrchr.cpp
deleted file mode 100644
index b6c40f4..0000000
--- a/libc/bionic/strrchr.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char* strrchr(const char* p, int ch) {
- return __strrchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
-}
diff --git a/libc/bionic/strsignal.cpp b/libc/bionic/strsignal.cpp
index f18b6d0..29c22e2 100644
--- a/libc/bionic/strsignal.cpp
+++ b/libc/bionic/strsignal.cpp
@@ -27,29 +27,29 @@
*/
#include <signal.h>
+#include <stdlib.h>
#include <string.h>
#include "bionic/pthread_internal.h"
+// Maps regular signals like SIGSEGV to strings like "Segmentation fault".
+// Signal 0 and all the real-time signals are just nullptr, but that's the ABI.
const char* const sys_siglist[NSIG] = {
#define __BIONIC_SIGDEF(signal_number, signal_description) [signal_number] = signal_description,
#include "private/bionic_sigdefs.h"
};
+// Maps regular signals like SIGSEGV to strings like "SEGV".
+// Signal 0 and all the real-time signals are just nullptr, but that's the ABI.
const char* const sys_signame[NSIG] = {
#define __BIONIC_SIGDEF(signal_number, unused) [signal_number] = &(#signal_number)[3],
#include "private/bionic_sigdefs.h"
};
extern "C" __LIBC_HIDDEN__ const char* __strsignal(int signal_number, char* buf, size_t buf_len) {
- const char* signal_name = nullptr;
- if (signal_number >= 0 && signal_number < NSIG) {
- signal_name = sys_siglist[signal_number];
+ if (signal_number >= SIGHUP && signal_number < SIGSYS) {
+ return sys_siglist[signal_number];
}
- if (signal_name != nullptr) {
- return signal_name;
- }
-
const char* prefix = "Unknown";
if (signal_number >= SIGRTMIN && signal_number <= SIGRTMAX) {
prefix = "Real-time";
@@ -66,3 +66,72 @@
bionic_tls& tls = __get_bionic_tls();
return const_cast<char*>(__strsignal(signal_number, tls.strsignal_buf, sizeof(tls.strsignal_buf)));
}
+
+int sig2str(int sig, char* str) {
+ if (sig >= SIGHUP && sig <= SIGSYS) {
+ strcpy(str, sys_signame[sig]);
+ return 0;
+ }
+ if (sig == SIGRTMIN) {
+ strcpy(str, "RTMIN");
+ return 0;
+ }
+ if (sig == SIGRTMAX) {
+ strcpy(str, "RTMAX");
+ return 0;
+ }
+ if (sig > SIGRTMIN && sig < SIGRTMAX) {
+ if (sig - SIGRTMIN <= SIGRTMAX - sig) {
+ sprintf(str, "RTMIN+%d", sig - SIGRTMIN);
+ } else {
+ sprintf(str, "RTMAX-%d", SIGRTMAX - sig);
+ }
+ return 0;
+ }
+ return -1;
+}
+
+int str2sig(const char* str, int* sig) {
+ // A name in our list, like "SEGV"?
+ for (size_t i = SIGHUP; i <= SIGSYS; ++i) {
+ if (!strcmp(str, sys_signame[i])) {
+ *sig = i;
+ return 0;
+ }
+ }
+
+ // The two named special cases?
+ if (!strcmp(str, "RTMIN")) {
+ *sig = SIGRTMIN;
+ return 0;
+ }
+ if (!strcmp(str, "RTMAX")) {
+ *sig = SIGRTMAX;
+ return 0;
+ }
+
+ // Must be either an integer corresponding to a regular signal such as "9",
+ // or a string of the form "RTMIN+%d" or "RTMAX-%d".
+ int base = 0;
+ if (!strncmp(str, "RTMIN+", 6)) {
+ base = SIGRTMIN;
+ str += 5;
+ } else if (!strncmp(str, "RTMAX-", 6)) {
+ base = SIGRTMAX;
+ str += 5;
+ }
+ char* end = nullptr;
+ errno = 0;
+ int offset = strtol(str, &end, 10);
+ if (errno || *end) return -1;
+
+ // Reject out of range integers (like "666"),
+ // and out of range real-time signals (like "RTMIN+666" or "RTMAX-666").
+ int result = base + offset;
+ bool regular = (base == 0 && result >= SIGHUP && result <= SIGSYS);
+ bool realtime = (result >= SIGRTMIN && result <= SIGRTMAX);
+ if (!regular && !realtime) return -1;
+
+ *sig = result;
+ return 0;
+}
diff --git a/libc/bionic/strtol.cpp b/libc/bionic/strtol.cpp
index def7921..607145d 100644
--- a/libc/bionic/strtol.cpp
+++ b/libc/bionic/strtol.cpp
@@ -142,34 +142,42 @@
long strtol(const char* s, char** end, int base) {
return StrToI<long, LONG_MIN, LONG_MAX, char>(s, end, base);
}
+__strong_alias(strtol_l, strtol);
long wcstol(const wchar_t* s, wchar_t** end, int base) {
return StrToI<long, LONG_MIN, LONG_MAX, wchar_t>(s, end, base);
}
+__strong_alias(wcstol_l, wcstol);
long long strtoll(const char* s, char** end, int base) {
return StrToI<long long, LLONG_MIN, LLONG_MAX, char>(s, end, base);
}
+__strong_alias(strtoll_l, strtoll);
long long wcstoll(const wchar_t* s, wchar_t** end, int base) {
return StrToI<long long, LLONG_MIN, LLONG_MAX, wchar_t>(s, end, base);
}
+__strong_alias(wcstoll_l, wcstoll);
unsigned long strtoul(const char* s, char** end, int base) {
return StrToI<unsigned long, 0, ULONG_MAX, char>(s, end, base);
}
+__strong_alias(strtoul_l, strtoul);
unsigned long wcstoul(const wchar_t* s, wchar_t** end, int base) {
return StrToI<unsigned long, 0, ULONG_MAX, wchar_t>(s, end, base);
}
+__strong_alias(wcstoul_l, wcstoul);
unsigned long long strtoull(const char* s, char** end, int base) {
return StrToI<unsigned long long, 0, ULLONG_MAX, char>(s, end, base);
}
+__strong_alias(strtoull_l, strtoull);
unsigned long long wcstoull(const wchar_t* s, wchar_t** end, int base) {
return StrToI<unsigned long long, 0, ULLONG_MAX, wchar_t>(s, end, base);
}
+__strong_alias(wcstoull_l, wcstoull);
uintmax_t strtoumax(const char* s, char** end, int base) {
return StrToI<uintmax_t, 0, UINTMAX_MAX, char>(s, end, base);
diff --git a/libc/bionic/sync_file_range.cpp b/libc/bionic/sync_file_range.cpp
index 7f60882..e7b904d 100644
--- a/libc/bionic/sync_file_range.cpp
+++ b/libc/bionic/sync_file_range.cpp
@@ -28,13 +28,12 @@
#include <fcntl.h>
-extern "C" int __sync_file_range(int, off64_t, off64_t, unsigned int);
-extern "C" int __sync_file_range2(int, unsigned int, off64_t, off64_t);
-
-int sync_file_range(int fd, off64_t offset, off64_t length, unsigned int flags) {
#if __arm__
+// Only arm32 is missing the sync_file_range() syscall,
+// and needs us to manually re-order arguments for it.
+// (Because arm32 needs register pairs for 64-bit values to start on an even register.)
+extern "C" int __sync_file_range2(int, unsigned int, off64_t, off64_t);
+int sync_file_range(int fd, off64_t offset, off64_t length, unsigned int flags) {
return __sync_file_range2(fd, flags, offset, length);
-#else
- return __sync_file_range(fd, offset, length, flags);
-#endif
}
+#endif
diff --git a/libc/bionic/system.cpp b/libc/bionic/system.cpp
index 93d7497..8349498 100644
--- a/libc/bionic/system.cpp
+++ b/libc/bionic/system.cpp
@@ -38,7 +38,7 @@
int system(const char* command) {
// "The system() function shall always return non-zero when command is NULL."
- // http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html
+ // https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/system.html
if (command == nullptr) return 1;
ScopedSignalBlocker sigchld_blocker(SIGCHLD);
diff --git a/libc/bionic/system_property_api.cpp b/libc/bionic/system_property_api.cpp
index 8fdea59..ed30fc2 100644
--- a/libc/bionic/system_property_api.cpp
+++ b/libc/bionic/system_property_api.cpp
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
+#include <sys/system_properties.h>
#include <async_safe/CHECK.h>
#include <system_properties/prop_area.h>
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index 73cf151..9d73445 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -34,11 +34,10 @@
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
+#include <sys/system_properties.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
#include <unistd.h>
#include <async_safe/log.h>
diff --git a/libc/bionic/time_l.cpp b/libc/bionic/time_l.cpp
deleted file mode 100644
index e5fa9a5..0000000
--- a/libc/bionic/time_l.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2022 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 <time.h>
-//#include <xlocale.h>
-
-char* strptime_l(const char* buf, const char* fmt, struct tm* tm, locale_t) {
- return strptime(buf, fmt, tm);
-}
diff --git a/libc/bionic/wchar_l.cpp b/libc/bionic/wchar_l.cpp
index 1e7a231..b2c4a00 100644
--- a/libc/bionic/wchar_l.cpp
+++ b/libc/bionic/wchar_l.cpp
@@ -41,34 +41,6 @@
return wcscoll(ws1, ws2);
}
-double wcstod_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
- return wcstod(s, end_ptr);
-}
-
-float wcstof_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
- return wcstof(s, end_ptr);
-}
-
-long wcstol_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
- return wcstol(s, end_ptr, base);
-}
-
-long long wcstoll_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
- return wcstoll(s, end_ptr, base);
-}
-
-unsigned long wcstoul_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
- return wcstoul(s, end_ptr, base);
-}
-
-unsigned long long wcstoull_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
- return wcstoull(s, end_ptr, base);
-}
-
-long double wcstold_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
- return wcstold(s, end_ptr);
-}
-
size_t wcsxfrm_l(wchar_t* dst, const wchar_t* src, size_t n, locale_t) {
return wcsxfrm(dst, src, n);
}
diff --git a/libc/bionic/wcstod.cpp b/libc/bionic/wcstod.cpp
index c82d788..00c8a08 100644
--- a/libc/bionic/wcstod.cpp
+++ b/libc/bionic/wcstod.cpp
@@ -94,11 +94,14 @@
float wcstof(const wchar_t* s, wchar_t** end) {
return wcstod<float>(s, end, strtof);
}
+__strong_alias(wcstof_l, wcstof);
double wcstod(const wchar_t* s, wchar_t** end) {
return wcstod<double>(s, end, strtod);
}
+__strong_alias(wcstod_l, wcstod);
long double wcstold(const wchar_t* s, wchar_t** end) {
return wcstod<long double>(s, end, strtold);
}
+__strong_alias(wcstold_l, wcstold);
diff --git a/libc/bionic/wctype.cpp b/libc/bionic/wctype.cpp
index 71caa76..94597d9 100644
--- a/libc/bionic/wctype.cpp
+++ b/libc/bionic/wctype.cpp
@@ -54,46 +54,62 @@
WC_TYPE_MAX
};
-int iswalnum(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_ALNUM, isalnum); }
-int iswalpha(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_ALPHABETIC, isalpha); }
-int iswblank(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_BLANK, isblank); }
-int iswgraph(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_GRAPH, isgraph); }
-int iswlower(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_LOWERCASE, islower); }
-int iswprint(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_PRINT, isprint); }
-int iswspace(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_WHITE_SPACE, isspace); }
-int iswupper(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_UPPERCASE, isupper); }
-int iswxdigit(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_XDIGIT, isxdigit); }
+static u_hasBinaryProperty_t __find_u_hasBinaryProperty() {
+ static auto u_hasBinaryProperty =
+ reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
+ return u_hasBinaryProperty;
+}
+
+#define DO_ISW(icu_constant, narrow_fn) \
+ u_hasBinaryProperty_t u_hasBinaryProperty; \
+ if (__predict_true(wc < 0x80) || \
+ !(u_hasBinaryProperty = __find_u_hasBinaryProperty())) { \
+ return narrow_fn(wc); \
+ } \
+ return u_hasBinaryProperty(wc, icu_constant); \
+
+int iswalnum(wint_t wc) { DO_ISW(UCHAR_POSIX_ALNUM, isalnum); }
+__strong_alias(iswalnum_l, iswalnum);
+int iswalpha(wint_t wc) { DO_ISW(UCHAR_ALPHABETIC, isalpha); }
+__strong_alias(iswalpha_l, iswalpha);
+int iswblank(wint_t wc) { DO_ISW(UCHAR_POSIX_BLANK, isblank); }
+__strong_alias(iswblank_l, iswblank);
+int iswgraph(wint_t wc) { DO_ISW(UCHAR_POSIX_GRAPH, isgraph); }
+__strong_alias(iswgraph_l, iswgraph);
+int iswlower(wint_t wc) { DO_ISW(UCHAR_LOWERCASE, islower); }
+__strong_alias(iswlower_l, iswlower);
+int iswprint(wint_t wc) { DO_ISW(UCHAR_POSIX_PRINT, isprint); }
+__strong_alias(iswprint_l, iswprint);
+int iswspace(wint_t wc) { DO_ISW(UCHAR_WHITE_SPACE, isspace); }
+__strong_alias(iswspace_l, iswspace);
+int iswupper(wint_t wc) { DO_ISW(UCHAR_UPPERCASE, isupper); }
+__strong_alias(iswupper_l, iswupper);
+int iswxdigit(wint_t wc) { DO_ISW(UCHAR_POSIX_XDIGIT, isxdigit); }
+__strong_alias(iswxdigit_l, iswxdigit);
int iswcntrl(wint_t wc) {
+ if (wc < 0x80) return iscntrl(wc);
typedef int8_t (*FnT)(UChar32);
static auto u_charType = reinterpret_cast<FnT>(__find_icu_symbol("u_charType"));
return u_charType ? (u_charType(wc) == U_CONTROL_CHAR) : iscntrl(wc);
}
+__strong_alias(iswcntrl_l, iswcntrl);
int iswdigit(wint_t wc) {
+ if (wc < 0x80) return isdigit(wc);
typedef UBool (*FnT)(UChar32);
static auto u_isdigit = reinterpret_cast<FnT>(__find_icu_symbol("u_isdigit"));
return u_isdigit ? u_isdigit(wc) : isdigit(wc);
}
+__strong_alias(iswdigit_l, iswdigit);
int iswpunct(wint_t wc) {
+ if (wc < 0x80) return ispunct(wc);
typedef UBool (*FnT)(UChar32);
static auto u_ispunct = reinterpret_cast<FnT>(__find_icu_symbol("u_ispunct"));
return u_ispunct ? u_ispunct(wc) : ispunct(wc);
}
-
-int iswalnum_l(wint_t c, locale_t) { return iswalnum(c); }
-int iswalpha_l(wint_t c, locale_t) { return iswalpha(c); }
-int iswblank_l(wint_t c, locale_t) { return iswblank(c); }
-int iswcntrl_l(wint_t c, locale_t) { return iswcntrl(c); }
-int iswdigit_l(wint_t c, locale_t) { return iswdigit(c); }
-int iswgraph_l(wint_t c, locale_t) { return iswgraph(c); }
-int iswlower_l(wint_t c, locale_t) { return iswlower(c); }
-int iswprint_l(wint_t c, locale_t) { return iswprint(c); }
-int iswpunct_l(wint_t c, locale_t) { return iswpunct(c); }
-int iswspace_l(wint_t c, locale_t) { return iswspace(c); }
-int iswupper_l(wint_t c, locale_t) { return iswupper(c); }
-int iswxdigit_l(wint_t c, locale_t) { return iswxdigit(c); }
+__strong_alias(iswpunct_l, iswpunct);
int iswctype(wint_t wc, wctype_t char_class) {
if (char_class < WC_TYPE_ALNUM || char_class > WC_TYPE_XDIGIT) return 0;
@@ -103,10 +119,7 @@
};
return fns[char_class - WC_TYPE_ALNUM](wc);
}
-
-int iswctype_l(wint_t wc, wctype_t char_class, locale_t) {
- return iswctype(wc, char_class);
-}
+__strong_alias(iswctype_l, iswctype);
wint_t towlower(wint_t wc) {
if (wc < 0x80) return tolower(wc);
@@ -115,6 +128,7 @@
static auto u_tolower = reinterpret_cast<FnT>(__find_icu_symbol("u_tolower"));
return u_tolower ? u_tolower(wc) : tolower(wc);
}
+__strong_alias(towlower_l, towlower);
wint_t towupper(wint_t wc) {
if (wc < 0x80) return toupper(wc);
@@ -123,9 +137,7 @@
static auto u_toupper = reinterpret_cast<FnT>(__find_icu_symbol("u_toupper"));
return u_toupper ? u_toupper(wc) : toupper(wc);
}
-
-wint_t towupper_l(wint_t c, locale_t) { return towupper(c); }
-wint_t towlower_l(wint_t c, locale_t) { return towlower(c); }
+__strong_alias(towupper_l, towupper);
wctype_t wctype(const char* property) {
static const char* const properties[WC_TYPE_MAX - 1] = {
@@ -139,10 +151,7 @@
}
return static_cast<wctype_t>(0);
}
-
-wctype_t wctype_l(const char* property, locale_t) {
- return wctype(property);
-}
+__strong_alias(wctype_l, wctype);
static wctrans_t wctrans_tolower = wctrans_t(1);
static wctrans_t wctrans_toupper = wctrans_t(2);
@@ -150,20 +159,15 @@
wctrans_t wctrans(const char* name) {
if (strcmp(name, "tolower") == 0) return wctrans_tolower;
if (strcmp(name, "toupper") == 0) return wctrans_toupper;
+ errno = EINVAL;
return nullptr;
}
-
-wctrans_t wctrans_l(const char* name, locale_t) {
- return wctrans(name);
-}
+__strong_alias(wctrans_l, wctrans);
wint_t towctrans(wint_t c, wctrans_t t) {
if (t == wctrans_tolower) return towlower(c);
if (t == wctrans_toupper) return towupper(c);
errno = EINVAL;
- return 0;
+ return c;
}
-
-wint_t towctrans_l(wint_t c, wctrans_t t, locale_t) {
- return towctrans(c, t);
-}
+__strong_alias(towctrans_l, towctrans);
diff --git a/libc/bionic/wcwidth.cpp b/libc/bionic/wcwidth.cpp
index 4582ef7..776321f 100644
--- a/libc/bionic/wcwidth.cpp
+++ b/libc/bionic/wcwidth.cpp
@@ -73,7 +73,9 @@
// Hangeul choseong filler U+115F is default ignorable, so we check default
// ignorability only after we've already handled Hangeul jamo above.
- if (__icu_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT, nullptr)) return 0;
+ static auto u_hasBinaryProperty =
+ reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
+ if (u_hasBinaryProperty && u_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT)) return 0;
// A few weird special cases where EastAsianWidth is not helpful for us.
if (wc >= 0x3248 && wc <= 0x4dff) {
diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c
index add124f..1ffabfa 100644
--- a/libc/dns/net/gethnamaddr.c
+++ b/libc/dns/net/gethnamaddr.c
@@ -495,7 +495,7 @@
*he = NO_RECOVERY;
return NULL;
success:
- bp = (char *)ALIGN(bp);
+ bp = __builtin_align_up(bp, sizeof(uintptr_t));
n = (int)(ap - aliases);
qlen = (n + 1) * sizeof(*hent->h_aliases);
if ((size_t)(ep - bp) < qlen)
@@ -616,7 +616,7 @@
}
// Fix alignment after variable-length data.
- ptr = (char*)ALIGN(ptr);
+ ptr = __builtin_align_up(ptr, sizeof(uintptr_t));
int aliases_len = ((int)(aliases - aliases_ptrs) + 1) * sizeof(*hp->h_aliases);
if (ptr + aliases_len > hbuf_end) {
@@ -653,7 +653,7 @@
}
// Fix alignment after variable-length data.
- ptr = (char*)ALIGN(ptr);
+ ptr = __builtin_align_up(ptr, sizeof(uintptr_t));
int addrs_len = ((int)(addr_p - addr_ptrs) + 1) * sizeof(*hp->h_addr_list);
if (ptr + addrs_len > hbuf_end) {
diff --git a/libc/dns/net/sethostent.c b/libc/dns/net/sethostent.c
index 5c4bdb5..8ea4315 100644
--- a/libc/dns/net/sethostent.c
+++ b/libc/dns/net/sethostent.c
@@ -198,7 +198,7 @@
HENT_SCOPY(aliases[anum], hp->h_aliases[anum],
ptr, len);
}
- ptr = (void *)ALIGN(ptr);
+ ptr = __builtin_align_up(ptr, sizeof(uintptr_t));
if ((size_t)(ptr - buf) >= info->buflen)
goto nospc;
}
diff --git a/libc/execinfo/include/execinfo.h b/libc/execinfo/include/execinfo.h
index e092c00..c8f9e21 100644
--- a/libc/execinfo/include/execinfo.h
+++ b/libc/execinfo/include/execinfo.h
@@ -30,8 +30,10 @@
/*
* This file is exported as part of libexecinfo for use with musl, which doesn't
- * define __INTRODUCED_IN. Stub it out.
+ * define __INTRODUCED_IN or __BIONIC_AVAILABILITY_GUARD. Stub them out.
*/
#define __INTRODUCED_IN(x)
+#define __BIONIC_AVAILABILITY_GUARD(x) 1
#include <bionic/execinfo.h>
+#undef __BIONIC_AVAILABILITY_GUARD
#undef __INTRODUCED_IN
diff --git a/libc/include/alloca.h b/libc/include/alloca.h
index e05dea6..2786e2f 100644
--- a/libc/include/alloca.h
+++ b/libc/include/alloca.h
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
/**
- * [alloca(3)](http://man7.org/linux/man-pages/man3/alloca.3.html) allocates space on the stack.
+ * [alloca(3)](https://man7.org/linux/man-pages/man3/alloca.3.html) allocates space on the stack.
*
* New code should not use alloca because it cannot report failure.
* Use regular heap allocation instead.
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 1bde3a5..c9536c1 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -189,7 +189,11 @@
*
* Available since API level 24.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int android_get_application_target_sdk_version() __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#if __ANDROID_API__ < 29
diff --git a/libc/include/android/crash_detail.h b/libc/include/android/crash_detail.h
index 946a3ab..fd1312a 100644
--- a/libc/include/android/crash_detail.h
+++ b/libc/include/android/crash_detail.h
@@ -33,9 +33,10 @@
* @brief Attach extra information to android crashes.
*/
-#include <stddef.h>
#include <sys/cdefs.h>
+#include <stddef.h>
+
__BEGIN_DECLS
typedef struct crash_detail_t crash_detail_t;
@@ -79,6 +80,8 @@
*
* \return a handle to the extra crash detail.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
crash_detail_t* _Nullable android_crash_detail_register(
const void* _Nonnull name, size_t name_size, const void* _Nullable data, size_t data_size) __INTRODUCED_IN(35);
@@ -122,5 +125,7 @@
* \param name_size number of bytes of the buffer pointed to by name
*/
void android_crash_detail_replace_name(crash_detail_t* _Nonnull crash_detail, const void* _Nonnull name, size_t name_size) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
__END_DECLS
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index b42e5b2..d8d2752 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -16,10 +16,11 @@
#pragma once
+#include <sys/cdefs.h>
+
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <sys/cdefs.h>
#include <sys/types.h> /* for off64_t */
/**
@@ -30,7 +31,7 @@
/**
* \file
* Advanced dynamic library opening support. Most users will want to use
- * the standard [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html)
+ * the standard [dlopen(3)](https://man7.org/linux/man-pages/man3/dlopen.3.html)
* functionality in `<dlfcn.h>` instead.
*/
@@ -174,7 +175,7 @@
/**
* Opens the given library. The `__filename` and `__flags` arguments are
- * the same as for [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html),
+ * the same as for [dlopen(3)](https://man7.org/linux/man-pages/man3/dlopen.3.html),
* with the Android-specific flags supplied via the `flags` member of `__info`.
*/
void* _Nullable android_dlopen_ext(const char* _Nullable __filename, int __flags, const android_dlextinfo* _Nullable __info);
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 4540498..a04fc7e 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -28,9 +28,10 @@
#pragma once
+#include <sys/cdefs.h>
+
#include <stdbool.h>
#include <stdint.h>
-#include <sys/cdefs.h>
__BEGIN_DECLS
@@ -134,6 +135,8 @@
/*
* Create an owner tag with the specified type and least significant 56 bits of tag.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
uint64_t android_fdsan_create_owner_tag(enum android_fdsan_owner_type type, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__));
/*
@@ -168,6 +171,8 @@
* Get an owner tag's value, with the type masked off.
*/
uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29);
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
enum android_fdsan_error_level {
// No errors.
@@ -186,6 +191,8 @@
/*
* Get the error level.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(29) __attribute__((__weak__));
/*
@@ -203,9 +210,15 @@
* (e.g. postfork).
*/
enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__));
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
/*
* Set the error level to the global setting if available, or a default value.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__));
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
__END_DECLS
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index f0985fe..d228e67 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -30,26 +30,9 @@
#include <sys/cdefs.h>
-
#if __ANDROID_API__ < 26
-#include <stdlib.h>
-#include <xlocale.h>
-
-__BEGIN_DECLS
-
-static __inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
- return strtod(__s, __end_ptr);
-}
-
-static __inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
- return strtof(__s, __end_ptr);
-}
-
-static __inline long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) {
- return strtol(__s, __end_ptr, __base);
-}
-
-__END_DECLS
+#define __BIONIC_THREADS_INLINE static __inline
+#include <bits/stdlib_inlines.h>
#endif
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index a778057..6ad5678 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -33,10 +33,11 @@
* @brief The android_set_abort_message() function.
*/
+#include <sys/cdefs.h>
+
#include <stddef.h>
#include <stdint.h>
#include <string.h>
-#include <sys/cdefs.h>
__BEGIN_DECLS
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 64528e1..1cf6e51 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -16,47 +16,56 @@
#pragma once
-// The `annotate` attribute always pulls the annotated (inline) function into the object files, thus
-// we should only annotate headers when we are running versioner.
-#if defined(__BIONIC_VERSIONER)
-
-#define __INTRODUCED_IN(api_level) __attribute__((__annotate__("introduced_in=" #api_level)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __attribute__((__annotate__("introduced_in=" #api_level))) __VERSIONER_NO_GUARD
-#define __DEPRECATED_IN(api_level, ...) __attribute__((__annotate__("deprecated_in=" #api_level)))
-#define __REMOVED_IN(api_level, ...) __attribute__((__annotate__("obsoleted_in=" #api_level)))
-#define __INTRODUCED_IN_32(api_level) __attribute__((__annotate__("introduced_in_32=" #api_level)))
-#define __INTRODUCED_IN_64(api_level) __attribute__((__annotate__("introduced_in_64=" #api_level)))
-
-#define __VERSIONER_NO_GUARD __attribute__((__annotate__("versioner_no_guard")))
-#define __VERSIONER_FORTIFY_INLINE __attribute__((__annotate__("versioner_fortify_inline")))
-
-#else
-
-// When headers are not processed by the versioner (i.e. compiled into object files),
-// the availability attributed is emitted instead. The clang compiler will make the symbol weak
-// when targeting old api_level and enforce the reference to the symbol to be guarded with
-// __builtin_available(android api_level, *).
-
-// The 'strict' flag is required for NDK clients where the use of "-Wunguarded-availability" cannot
-// be enforced. In the case, the absence of 'strict' makes it possible to call an unavailable API
-// without the __builtin_available check, which will cause a link error at runtime.
-// Android platform build system defines this macro along with -Wunguarded-availability
-//
-// The _NO_GUARD_FOR_NDK variants keep the __VERSIONER_NO_GUARD behavior working for the NDK. This
-// allows libc++ to refer to these functions in inlines without needing to guard them, needed since
-// libc++ doesn't currently guard these calls. There's no risk to the apps though because using
-// those APIs will still cause a link error.
+/**
+ * @def __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
+ *
+ * Controls whether calling APIs newer than the developer's minSdkVersion are a
+ * build error (when not defined) or allowed as a weak reference with a
+ * __builtin_available() guard (when defined).
+ *
+ * See https://developer.android.com/ndk/guides/using-newer-apis for more
+ * details.
+ */
#if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
+// In this mode, Clang will emit weak references to the APIs if the
+// minSdkVersion is less than the __what argument. This allows the libraries to
+// load even on systems too old to contain the API, but calls must be guarded
+// with `__builtin_available(android api_level, *)` to avoid segfaults.
#define __BIONIC_AVAILABILITY(__what, ...) __attribute__((__availability__(android,__what __VA_OPT__(,) __VA_ARGS__)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN(api_level)
+
+// When the caller is using weak API references, we should expose the decls for
+// APIs which are not available in the caller's minSdkVersion, otherwise there's
+// no way to take advantage of the weak references.
+#define __BIONIC_AVAILABILITY_GUARD(api_level) 1
#else
+// The 'strict' flag is required for NDK clients where the code was not written
+// to handle the case where the API was available at build-time but not at
+// run-time. Most 3p code ported to Android was not written to use
+// `__builtin_available()` for run-time availability checking, and so would not
+// compile in this mode (or worse, if the build doesn't use
+// -Werror=unguarded-availability, it would build but crash at runtime).
#define __BIONIC_AVAILABILITY(__what, ...) __attribute__((__availability__(android,strict,__what __VA_OPT__(,) __VA_ARGS__)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level)
+
+// When the caller is using strict API references, we hide APIs which are not
+// available in the caller's minSdkVersion. This is a bionic-only deviation in
+// behavior from the rest of the NDK headers, but it's necessary to maintain
+// source compatibility with 3p libraries that either can't correctly detect API
+// availability (either incorrectly detecting as always-available or as
+// never-available, but neither is true), or define their own polyfills which
+// conflict with our declarations.
+//
+// https://github.com/android/ndk/issues/2081
+#define __BIONIC_AVAILABILITY_GUARD(api_level) (__ANDROID_MIN_SDK_VERSION__ >= (api_level))
#endif
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc23-extensions"
+// Passing no argument for the '...' parameter of a variadic macro is a C23 extension
#define __INTRODUCED_IN(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
-#define __DEPRECATED_IN(api_level, ...) __BIONIC_AVAILABILITY(deprecated=api_level __VA_OPT__(,message=) __VA_ARGS__)
-#define __REMOVED_IN(api_level, ...) __BIONIC_AVAILABILITY(obsoleted=api_level __VA_OPT__(,message=) __VA_ARGS__)
+#pragma clang diagnostic pop
+
+#define __DEPRECATED_IN(api_level, msg) __BIONIC_AVAILABILITY(deprecated=api_level, message=msg)
+#define __REMOVED_IN(api_level, msg) __BIONIC_AVAILABILITY(obsoleted=api_level, message=msg)
// The same availability attribute can't be annotated multiple times. Therefore, the macros are
// defined for the configuration that it is valid for so that declarations like the below doesn't
@@ -71,14 +80,3 @@
#define __INTRODUCED_IN_32(api_level)
#define __INTRODUCED_IN_64(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
#endif
-
-#define __VERSIONER_NO_GUARD
-#define __VERSIONER_FORTIFY_INLINE
-
-#endif // defined(__BIONIC_VERSIONER)
-
-// Vendor modules do not follow SDK versioning. Ignore NDK guards for vendor modules.
-#if defined(__ANDROID_VENDOR__)
-#undef __BIONIC_AVAILABILITY
-#define __BIONIC_AVAILABILITY(api_level, ...)
-#endif // defined(__ANDROID_VENDOR__)
diff --git a/libc/include/arpa/ftp.h b/libc/include/arpa/ftp.h
index 081c037..fecbf7f 100644
--- a/libc/include/arpa/ftp.h
+++ b/libc/include/arpa/ftp.h
@@ -34,6 +34,8 @@
#ifndef _ARPA_FTP_H_
#define _ARPA_FTP_H_
+#include <sys/cdefs.h>
+
/* Definitions for FTP; see RFC-765. */
/*
diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h
index f00f2c1..ce9dd93 100644
--- a/libc/include/arpa/inet.h
+++ b/libc/include/arpa/inet.h
@@ -29,9 +29,10 @@
#ifndef _ARPA_INET_H_
#define _ARPA_INET_H_
+#include <sys/cdefs.h>
+
#include <netinet/in.h>
#include <stdint.h>
-#include <sys/cdefs.h>
#include <sys/types.h>
__BEGIN_DECLS
diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h
index 97109ee..3e0025e 100644
--- a/libc/include/arpa/nameser.h
+++ b/libc/include/arpa/nameser.h
@@ -55,9 +55,10 @@
#define BIND_4_COMPAT
-#include <sys/types.h>
#include <sys/cdefs.h>
+#include <sys/types.h>
+
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
@@ -547,6 +548,8 @@
#define ns_sprintrrf __ns_sprintrrf
#endif
+
+#if __BIONIC_AVAILABILITY_GUARD(22)
int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN(22);
uint16_t ns_get16(const u_char* _Nonnull __src) __INTRODUCED_IN(22);
uint32_t ns_get32(const u_char* _Nonnull __src) __INTRODUCED_IN(22);
@@ -570,6 +573,8 @@
int ns_makecanon(const char* _Nonnull __src, char* _Nonnull __dst, size_t __dst_size) __INTRODUCED_IN(22);
int ns_samename(const char* _Nonnull __lhs, const char* _Nonnull __rhs) __INTRODUCED_IN(22);
+#endif /* __BIONIC_AVAILABILITY_GUARD(22) */
+
__END_DECLS
diff --git a/libc/include/arpa/nameser_compat.h b/libc/include/arpa/nameser_compat.h
index e4e9335..027e5ca 100644
--- a/libc/include/arpa/nameser_compat.h
+++ b/libc/include/arpa/nameser_compat.h
@@ -40,9 +40,10 @@
#ifndef _ARPA_NAMESER_COMPAT_
#define _ARPA_NAMESER_COMPAT_
-#include <endian.h>
#include <sys/cdefs.h>
+#include <endian.h>
+
#define __BIND 19950621 /* (DEAD) interface version stamp. */
/*
diff --git a/libc/include/arpa/telnet.h b/libc/include/arpa/telnet.h
index 758e9b8..30d8f21 100644
--- a/libc/include/arpa/telnet.h
+++ b/libc/include/arpa/telnet.h
@@ -33,6 +33,8 @@
#ifndef _ARPA_TELNET_H_
#define _ARPA_TELNET_H_
+#include <sys/cdefs.h>
+
/*
* Definitions for the TELNET protocol.
*/
diff --git a/libc/include/bits/bionic_multibyte_result.h b/libc/include/bits/bionic_multibyte_result.h
index 0d5cf21..930e67c 100644
--- a/libc/include/bits/bionic_multibyte_result.h
+++ b/libc/include/bits/bionic_multibyte_result.h
@@ -34,9 +34,10 @@
* conversion APIs defined by C.
*/
-#include <stddef.h>
#include <sys/cdefs.h>
+#include <stddef.h>
+
__BEGIN_DECLS
/**
diff --git a/libc/include/bits/fcntl.h b/libc/include/bits/fcntl.h
index ee5a6e1..e3f3548 100644
--- a/libc/include/bits/fcntl.h
+++ b/libc/include/bits/fcntl.h
@@ -38,7 +38,7 @@
__BEGIN_DECLS
/**
- * [fcntl(3)](http://man7.org/linux/man-pages/man2/fcntl.2.html) performs various operations
+ * [fcntl(3)](https://man7.org/linux/man-pages/man2/fcntl.2.html) performs various operations
* on file descriptors.
*
* The return value depends on the operation.
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
index f2e27d7..1b4a5bf 100644
--- a/libc/include/bits/fortify/poll.h
+++ b/libc/include/bits/fortify/poll.h
@@ -30,9 +30,17 @@
#error "Never include this file directly; instead, include <poll.h>"
#endif
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int __poll_chk(struct pollfd* _Nullable, nfds_t, int, size_t) __INTRODUCED_IN(23);
int __ppoll_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset_t* _Nullable, size_t) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int __ppoll64_chk(struct pollfd* _Nullable, nfds_t, const struct timespec* _Nullable, const sigset64_t* _Nullable, size_t) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#if defined(__BIONIC_FORTIFY)
#define __bos_fd_count_trivially_safe(bos_val, fds, fd_count) \
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
index 02f94cc..bd626f9 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -30,8 +30,11 @@
#error "Never include this file directly; instead, include <sys/socket.h>"
#endif
-extern ssize_t __sendto_chk(int, const void* _Nonnull, size_t, size_t, int, const struct sockaddr* _Nullable,
- socklen_t) __INTRODUCED_IN(26);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
+ssize_t __sendto_chk(int, const void* _Nonnull, size_t, size_t, int, const struct sockaddr* _Nullable, socklen_t) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
ssize_t __recvfrom_chk(int, void* _Nullable, size_t, size_t, int, struct sockaddr* _Nullable, socklen_t* _Nullable);
#if defined(__BIONIC_FORTIFY)
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index e4607e0..f9faeba 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -31,8 +31,12 @@
#endif
char* _Nullable __fgets_chk(char* _Nonnull, int, FILE* _Nonnull, size_t);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
size_t __fread_chk(void* _Nonnull, size_t, size_t, FILE* _Nonnull, size_t) __INTRODUCED_IN(24);
size_t __fwrite_chk(const void* _Nonnull, size_t, size_t, FILE* _Nonnull, size_t) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 7df0b05..6f0ee4a 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -30,15 +30,19 @@
#error "Never include this file directly; instead, include <string.h>"
#endif
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void* _Nullable __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
void* _Nullable __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
char* _Nonnull __stpncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t);
char* _Nonnull __strncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t);
size_t __strlcpy_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t);
size_t __strlcat_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t);
#if defined(__BIONIC_FORTIFY)
-extern void* _Nullable __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
+void* _Nullable __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
/* No diag -- clang diagnoses misuses of this on its own. */
@@ -220,8 +224,13 @@
}
#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* _Nonnull const s __pass_object_size0) __overloadable {
+/*
+ * Clang, when parsing C, can fold strlen to a constant without LLVM's help.
+ * This doesn't apply to overloads of strlen, so write this differently. We
+ * can't use `__pass_object_size0` here, but that's fine: it doesn't help much
+ * on __always_inline functions.
+ */
+extern __always_inline __inline__ __attribute__((gnu_inline)) size_t strlen(const char* _Nonnull s) {
return __strlen_chk(s, __bos0(s));
}
#endif
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
index 7eda1a6..9acb942 100644
--- a/libc/include/bits/fortify/unistd.h
+++ b/libc/include/bits/fortify/unistd.h
@@ -29,24 +29,52 @@
#error "Never include this file directly; instead, include <unistd.h>"
#endif
-char* _Nullable __getcwd_chk(char* _Nullable, size_t, size_t) __INTRODUCED_IN(24);
+#if __BIONIC_AVAILABILITY_GUARD(24)
+char* _Nullable __getcwd_chk(char* _Nullable, size_t, size_t) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
+
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
ssize_t __pread_chk(int, void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
ssize_t __pread_real(int, void* _Nonnull, size_t, off_t) __RENAME(pread);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
ssize_t __pread64_chk(int, void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
ssize_t __pread64_real(int, void* _Nonnull, size_t, off64_t) __RENAME(pread64);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
ssize_t __pwrite_chk(int, const void* _Nonnull, size_t, off_t, size_t) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
ssize_t __pwrite_real(int, const void* _Nonnull, size_t, off_t) __RENAME(pwrite);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
ssize_t __pwrite64_chk(int, const void* _Nonnull, size_t, off64_t, size_t) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
ssize_t __pwrite64_real(int, const void* _Nonnull, size_t, off64_t) __RENAME(pwrite64);
ssize_t __read_chk(int, void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
ssize_t __write_chk(int, const void* __BIONIC_COMPLICATED_NULLNESS, size_t, size_t) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
ssize_t __readlink_chk(const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
ssize_t __readlinkat_chk(int dirfd, const char* _Nonnull, char* _Nonnull, size_t, size_t) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#if defined(__BIONIC_FORTIFY)
diff --git a/libc/include/bits/getentropy.h b/libc/include/bits/getentropy.h
index a5a14f7..c878470 100644
--- a/libc/include/bits/getentropy.h
+++ b/libc/include/bits/getentropy.h
@@ -39,7 +39,7 @@
__BEGIN_DECLS
/**
- * [getentropy(3)](http://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
+ * [getentropy(3)](https://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
* with random bytes.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -48,6 +48,10 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+__nodiscard int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/bits/getopt.h b/libc/include/bits/getopt.h
index 60a89ed..8fc0463 100644
--- a/libc/include/bits/getopt.h
+++ b/libc/include/bits/getopt.h
@@ -33,7 +33,7 @@
__BEGIN_DECLS
/**
- * [getopt(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
+ * [getopt(3)](https://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
*
* Returns the next option character on success, returns -1 if all options have been parsed, and
* returns `'?'` on error.
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index eceb334..8c5a91d 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -36,9 +36,6 @@
#if defined(__NR_arch_prctl)
#define SYS_arch_prctl __NR_arch_prctl
#endif
-#if defined(__NR_arch_specific_syscall)
- #define SYS_arch_specific_syscall __NR_arch_specific_syscall
-#endif
#if defined(__NR_arm_fadvise64_64)
#define SYS_arm_fadvise64_64 __NR_arm_fadvise64_64
#endif
@@ -693,6 +690,9 @@
#if defined(__NR_mremap)
#define SYS_mremap __NR_mremap
#endif
+#if defined(__NR_mseal)
+ #define SYS_mseal __NR_mseal
+#endif
#if defined(__NR_msgctl)
#define SYS_msgctl __NR_msgctl
#endif
@@ -1269,9 +1269,6 @@
#if defined(__NR_syscall)
#define SYS_syscall __NR_syscall
#endif
-#if defined(__NR_syscalls)
- #define SYS_syscalls __NR_syscalls
-#endif
#if defined(__NR_sysfs)
#define SYS_sysfs __NR_sysfs
#endif
@@ -1368,6 +1365,9 @@
#if defined(__NR_unshare)
#define SYS_unshare __NR_unshare
#endif
+#if defined(__NR_uretprobe)
+ #define SYS_uretprobe __NR_uretprobe
+#endif
#if defined(__NR_uselib)
#define SYS_uselib __NR_uselib
#endif
diff --git a/libc/include/bits/ioctl.h b/libc/include/bits/ioctl.h
index 260eb7d..ae75880 100644
--- a/libc/include/bits/ioctl.h
+++ b/libc/include/bits/ioctl.h
@@ -38,7 +38,7 @@
__BEGIN_DECLS
/**
- * [ioctl(2)](http://man7.org/linux/man-pages/man2/ioctl.2.html) operates on device files.
+ * [ioctl(2)](https://man7.org/linux/man-pages/man2/ioctl.2.html) operates on device files.
*/
int ioctl(int __fd, int __op, ...);
diff --git a/libc/include/bits/lockf.h b/libc/include/bits/lockf.h
index d9f5987..8f922b9 100644
--- a/libc/include/bits/lockf.h
+++ b/libc/include/bits/lockf.h
@@ -48,7 +48,7 @@
__BEGIN_DECLS
/**
- * [lockf(3)](http://man7.org/linux/man-pages/man3/lockf.3.html) manipulates POSIX file locks.
+ * [lockf(3)](https://man7.org/linux/man-pages/man3/lockf.3.html) manipulates POSIX file locks.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*
@@ -56,6 +56,8 @@
*
* See also flock().
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int lockf(int __fd, int __op, off_t __length) __RENAME_IF_FILE_OFFSET64(lockf64) __INTRODUCED_IN(24);
/**
@@ -63,5 +65,7 @@
* even from a 32-bit process without `_FILE_OFFSET_BITS=64`.
*/
int lockf64(int __fd, int __op, off64_t __length) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
__END_DECLS
diff --git a/libc/include/bits/posix_limits.h b/libc/include/bits/posix_limits.h
index 452f5f6..d98be27 100644
--- a/libc/include/bits/posix_limits.h
+++ b/libc/include/bits/posix_limits.h
@@ -40,7 +40,7 @@
(((__ANDROID_API__) >= (level)) ? _POSIX_VERSION : __BIONIC_POSIX_FEATURE_MISSING)
/* Availability macros. */
-/* See http://man7.org/linux/man-pages/man7/posixoptions.7.html for documentation. */
+/* See https://man7.org/linux/man-pages/man7/posixoptions.7.html for documentation. */
/* Keep this list sorted by name. */
#define _POSIX_ADVISORY_INFO __BIONIC_POSIX_FEATURE_SINCE(23) /* posix_memadvise arrived late. */
#define _POSIX_ASYNCHRONOUS_IO __BIONIC_POSIX_FEATURE_MISSING
diff --git a/libc/include/bits/pthread_types.h b/libc/include/bits/pthread_types.h
index f359696..e30c4c1 100644
--- a/libc/include/bits/pthread_types.h
+++ b/libc/include/bits/pthread_types.h
@@ -43,7 +43,6 @@
#endif
} pthread_attr_t;
-#if __ANDROID_API__ >= 24
typedef struct {
#if defined(__LP64__)
int64_t __private[4];
@@ -51,11 +50,8 @@
int32_t __private[8];
#endif
} pthread_barrier_t;
-#endif
-#if __ANDROID_API__ >= 24
typedef int pthread_barrierattr_t;
-#endif
typedef struct {
#if defined(__LP64__)
@@ -91,7 +87,6 @@
typedef long pthread_rwlockattr_t;
-#if __ANDROID_API__ >= 24
typedef struct {
#if defined(__LP64__)
int64_t __private;
@@ -99,6 +94,5 @@
int32_t __private[2];
#endif
} pthread_spinlock_t;
-#endif
typedef long pthread_t;
diff --git a/libc/include/bits/seek_constants.h b/libc/include/bits/seek_constants.h
index 6f3f22d..a4fffb2 100644
--- a/libc/include/bits/seek_constants.h
+++ b/libc/include/bits/seek_constants.h
@@ -33,6 +33,8 @@
* @brief The `SEEK_` constants.
*/
+#include <sys/cdefs.h>
+
/** Seek to an absolute offset. */
#define SEEK_SET 0
/** Seek relative to the current offset. */
@@ -46,7 +48,7 @@
* Seek to the first data (non-hole) location in the file
* greater than or equal to the given offset.
*
- * See [lseek(2)](http://man7.org/linux/man-pages/man2/lseek.2.html).
+ * See [lseek(2)](https://man7.org/linux/man-pages/man2/lseek.2.html).
*/
#define SEEK_DATA 3
@@ -54,7 +56,7 @@
* Seek to the first hole (non-data) location in the file
* greater than or equal to the given offset.
*
- * See [lseek(2)](http://man7.org/linux/man-pages/man2/lseek.2.html).
+ * See [lseek(2)](https://man7.org/linux/man-pages/man2/lseek.2.html).
*/
#define SEEK_HOLE 4
diff --git a/libc/include/bits/sockaddr_storage.h b/libc/include/bits/sockaddr_storage.h
index effafab..4b3bfb6 100644
--- a/libc/include/bits/sockaddr_storage.h
+++ b/libc/include/bits/sockaddr_storage.h
@@ -40,7 +40,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullability-completeness"
/**
- * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr.3type.html)
+ * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr_storage.3type.html)
* is a structure large enough to contain any other `sockaddr_*` type, used to
* pass socket addresses without needing to know what kind of socket address
* you're passing.
diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h
index c74eafd..ebdc9e5 100644
--- a/libc/include/bits/stdatomic.h
+++ b/libc/include/bits/stdatomic.h
@@ -134,6 +134,8 @@
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
+#define kill_dependency(y) (y)
+
/*
* 7.17.4 Fences.
*/
diff --git a/libm/fenv-access.h b/libc/include/bits/stdlib_inlines.h
similarity index 71%
copy from libm/fenv-access.h
copy to libc/include/bits/stdlib_inlines.h
index 7acb34d..fffca19 100644
--- a/libm/fenv-access.h
+++ b/libc/include/bits/stdlib_inlines.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,21 @@
#pragma once
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
+#include <xlocale.h>
+#include <sys/cdefs.h>
+
+#if !defined(__BIONIC_STDLIB_INLINE)
+#define __BIONIC_STDLIB_INLINE static __inline
#endif
+
+__BEGIN_DECLS
+
+__BIONIC_STDLIB_INLINE double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
+ return strtod(__s, __end_ptr);
+}
+
+__BIONIC_STDLIB_INLINE float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
+ return strtof(__s, __end_ptr);
+}
+
+__END_DECLS
diff --git a/libc/include/bits/strcasecmp.h b/libc/include/bits/strcasecmp.h
index 23acbe5..d76cec9 100644
--- a/libc/include/bits/strcasecmp.h
+++ b/libc/include/bits/strcasecmp.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [strcasecmp(3)](http://man7.org/linux/man-pages/man3/strcasecmp.3.html) compares two strings
+ * [strcasecmp(3)](https://man7.org/linux/man-pages/man3/strcasecmp.3.html) compares two strings
* ignoring case.
*
* Returns an integer less than, equal to, or greater than zero if the first string is less than,
@@ -51,10 +51,14 @@
/**
* Like strcasecmp() but taking a `locale_t`.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int strcasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [strncasecmp(3)](http://man7.org/linux/man-pages/man3/strncasecmp.3.html) compares the first
+ * [strncasecmp(3)](https://man7.org/linux/man-pages/man3/strncasecmp.3.html) compares the first
* `n` bytes of two strings ignoring case.
*
* Returns an integer less than, equal to, or greater than zero if the first `n` bytes of the
@@ -66,6 +70,10 @@
/**
* Like strncasecmp() but taking a `locale_t`.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int strncasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, size_t __n, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/bits/swab.h b/libc/include/bits/swab.h
index 9591c2e..da2865a 100644
--- a/libc/include/bits/swab.h
+++ b/libc/include/bits/swab.h
@@ -28,8 +28,9 @@
#pragma once
-#include <stdint.h>
#include <sys/cdefs.h>
+
+#include <stdint.h>
#include <sys/types.h>
#if !defined(__BIONIC_SWAB_INLINE)
diff --git a/libc/include/bits/termios_inlines.h b/libc/include/bits/termios_inlines.h
index a884b59..bb04e4d 100644
--- a/libc/include/bits/termios_inlines.h
+++ b/libc/include/bits/termios_inlines.h
@@ -29,8 +29,9 @@
#ifndef _BITS_TERMIOS_INLINES_H_
#define _BITS_TERMIOS_INLINES_H_
-#include <errno.h>
#include <sys/cdefs.h>
+
+#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
diff --git a/libc/include/bits/termios_winsize_inlines.h b/libc/include/bits/termios_winsize_inlines.h
index ae246e4..86777b0 100644
--- a/libc/include/bits/termios_winsize_inlines.h
+++ b/libc/include/bits/termios_winsize_inlines.h
@@ -28,8 +28,9 @@
#pragma once
-#include <errno.h>
#include <sys/cdefs.h>
+
+#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 459866e..ab294c1 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -28,6 +28,8 @@
#pragma once
+#include <sys/cdefs.h>
+
#include <threads.h>
#include <errno.h>
@@ -116,13 +118,10 @@
return __bionic_thrd_error(pthread_mutex_unlock(__mtx));
}
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
struct __bionic_thrd_data {
- thrd_start_t __func;
- void* __arg;
+ thrd_start_t _Nonnull __func;
+ void* _Nullable __arg;
};
-#pragma clang diagnostic pop
static __inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
struct __bionic_thrd_data __data =
diff --git a/libc/include/bits/wctype.h b/libc/include/bits/wctype.h
index 11d5fde..d0cffec 100644
--- a/libc/include/bits/wctype.h
+++ b/libc/include/bits/wctype.h
@@ -58,8 +58,12 @@
int iswctype(wint_t __wc, wctype_t __type);
typedef const void* wctrans_t;
-wint_t towctrans(wint_t __wc, wctrans_t _Nonnull __transform) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
-wctrans_t _Nullable wctrans(const char* _Nonnull __name) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
+wint_t towctrans(wint_t __wc, wctrans_t _Nonnull __transform) __INTRODUCED_IN(26);
+wctrans_t _Nullable wctrans(const char* _Nonnull __name) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/byteswap.h b/libc/include/byteswap.h
index 0773426..a679ea0 100644
--- a/libc/include/byteswap.h
+++ b/libc/include/byteswap.h
@@ -37,19 +37,19 @@
#include <sys/endian.h>
/**
- * [bswap_16(3)](http://man7.org/linux/man-pages/man3/bswap_16.3.html) swaps the bytes in a
+ * [bswap_16(3)](https://man7.org/linux/man-pages/man3/bswap_16.3.html) swaps the bytes in a
* 16-bit value.
*/
#define bswap_16(x) __swap16(x)
/**
- * [bswap_32(3)](http://man7.org/linux/man-pages/man3/bswap_32.3.html) swaps the bytes in a
+ * [bswap_32(3)](https://man7.org/linux/man-pages/man3/bswap_32.3.html) swaps the bytes in a
* 32-bit value.
*/
#define bswap_32(x) __swap32(x)
/**
- * [bswap_64(3)](http://man7.org/linux/man-pages/man3/bswap_64.3.html) swaps the bytes in a
+ * [bswap_64(3)](https://man7.org/linux/man-pages/man3/bswap_64.3.html) swaps the bytes in a
* 64-bit value.
*/
#define bswap_64(x) __swap64(x)
diff --git a/libc/include/complex.h b/libc/include/complex.h
index f205abd..1115862 100644
--- a/libc/include/complex.h
+++ b/libc/include/complex.h
@@ -53,76 +53,190 @@
/* 7.3.5 Trigonometric functions */
/* 7.3.5.1 The cacos functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex cacos(double complex __z) __INTRODUCED_IN(23);
float complex cacosf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex cacosl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.5.2 The casin functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex casin(double complex __z) __INTRODUCED_IN(23);
float complex casinf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex casinl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.5.1 The catan functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex catan(double complex __z) __INTRODUCED_IN(23);
float complex catanf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex catanl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.5.1 The ccos functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex ccos(double complex __z) __INTRODUCED_IN(23);
float complex ccosf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex ccosl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.5.1 The csin functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex csin(double complex __z) __INTRODUCED_IN(23);
float complex csinf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex csinl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.5.1 The ctan functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex ctan(double complex __z) __INTRODUCED_IN(23);
float complex ctanf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex ctanl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6 Hyperbolic functions */
/* 7.3.6.1 The cacosh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex cacosh(double complex __z) __INTRODUCED_IN(23);
float complex cacoshf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex cacoshl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6.2 The casinh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex casinh(double complex __z) __INTRODUCED_IN(23);
float complex casinhf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex casinhl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6.3 The catanh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex catanh(double complex __z) __INTRODUCED_IN(23);
float complex catanhf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex catanhl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6.4 The ccosh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex ccosh(double complex __z) __INTRODUCED_IN(23);
float complex ccoshf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex ccoshl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6.5 The csinh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex csinh(double complex __z) __INTRODUCED_IN(23);
float complex csinhf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex csinhl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.6.6 The ctanh functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex ctanh(double complex __z) __INTRODUCED_IN(23);
float complex ctanhf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex ctanhl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.7 Exponential and logarithmic functions */
/* 7.3.7.1 The cexp functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex cexp(double complex __z) __INTRODUCED_IN(23);
float complex cexpf(float complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
long double complex cexpl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.7.2 The clog functions */
double complex clog(double complex __z) __INTRODUCED_IN(26);
float complex clogf(float complex __z) __INTRODUCED_IN(26);
long double complex clogl(long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.8 Power and absolute-value functions */
/* 7.3.8.1 The cabs functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double cabs(double complex __z) __INTRODUCED_IN(23);
float cabsf(float complex __z) __INTRODUCED_IN(23);
long double cabsl(long double complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/* 7.3.8.2 The cpow functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
double complex cpow(double complex __x, double complex __z) __INTRODUCED_IN(26);
float complex cpowf(float complex __x, float complex __z) __INTRODUCED_IN(26);
long double complex cpowl(long double complex __x, long double complex __z) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/* 7.3.8.3 The csqrt functions */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
double complex csqrt(double complex __z) __INTRODUCED_IN(23);
float complex csqrtf(float complex __z) __INTRODUCED_IN(23);
long double complex csqrtl(long double complex __z) __INTRODUCED_IN(23);
@@ -148,6 +262,8 @@
double creal(double complex __z) __INTRODUCED_IN(23);
float crealf(float complex __z) __INTRODUCED_IN(23);
long double creall(long double complex __z) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/ctype.h b/libc/include/ctype.h
index cb926a4..dc3f673 100644
--- a/libc/include/ctype.h
+++ b/libc/include/ctype.h
@@ -95,7 +95,7 @@
/** Internal implementation detail. Do not use. */
__attribute__((__no_sanitize__("unsigned-integer-overflow")))
-static inline int __bionic_ctype_in_range(unsigned __lo, int __ch, unsigned __hi) {
+__BIONIC_CTYPE_INLINE int __bionic_ctype_in_range(unsigned __lo, int __ch, unsigned __hi) {
return (__BIONIC_CAST(static_cast, unsigned, __ch) - __lo) < (__hi - __lo + 1);
}
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 4f5d0fb..af22fb3 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -33,8 +33,9 @@
* @brief Directory entry iteration.
*/
-#include <stdint.h>
#include <sys/cdefs.h>
+
+#include <stdint.h>
#include <sys/types.h>
__BEGIN_DECLS
@@ -86,11 +87,11 @@
#define d_fileno d_ino
-/** The structure returned by opendir()/fopendir(). */
+/** The structure returned by opendir()/fdopendir(). */
typedef struct DIR DIR;
/**
- * [opendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * [opendir(3)](https://man7.org/linux/man-pages/man3/opendir.3.html)
* opens a directory stream for the directory at `__path`.
*
* Returns null and sets `errno` on failure.
@@ -98,7 +99,7 @@
DIR* _Nullable opendir(const char* _Nonnull __path);
/**
- * [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * [fdopendir(3)](https://man7.org/linux/man-pages/man3/fdopendir.3.html)
* opens a directory stream for the directory at `__dir_fd`.
*
* Returns null and sets `errno` on failure.
@@ -106,7 +107,7 @@
DIR* _Nullable fdopendir(int __dir_fd);
/**
- * [readdir(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * [readdir(3)](https://man7.org/linux/man-pages/man3/readdir.3.html)
* returns the next directory entry in the given directory.
*
* Returns a pointer to a directory entry on success,
@@ -116,7 +117,7 @@
struct dirent* _Nullable readdir(DIR* _Nonnull __dir);
/**
- * [readdir64(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * [readdir64(3)](https://man7.org/linux/man-pages/man3/readdir.3.html)
* returns the next directory entry in the given directory.
*
* Returns a pointer to a directory entry on success,
@@ -129,7 +130,7 @@
int readdir64_r(DIR* _Nonnull __dir, struct dirent64* _Nonnull __entry, struct dirent64* _Nullable * _Nonnull __buffer) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
/**
- * [closedir(3)](http://man7.org/linux/man-pages/man3/closedir.3.html)
+ * [closedir(3)](https://man7.org/linux/man-pages/man3/closedir.3.html)
* closes a directory stream.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -137,22 +138,24 @@
int closedir(DIR* _Nonnull __dir);
/**
- * [rewinddir(3)](http://man7.org/linux/man-pages/man3/rewinddir.3.html)
+ * [rewinddir(3)](https://man7.org/linux/man-pages/man3/rewinddir.3.html)
* rewinds a directory stream to the first entry.
*/
void rewinddir(DIR* _Nonnull __dir);
/**
- * [seekdir(3)](http://man7.org/linux/man-pages/man3/seekdir.3.html)
+ * [seekdir(3)](https://man7.org/linux/man-pages/man3/seekdir.3.html)
* seeks a directory stream to the given entry, which must be a value returned
* by telldir().
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void seekdir(DIR* _Nonnull __dir, long __location) __INTRODUCED_IN(23);
/**
- * [telldir(3)](http://man7.org/linux/man-pages/man3/telldir.3.html)
+ * [telldir(3)](https://man7.org/linux/man-pages/man3/telldir.3.html)
* returns a value representing the current position in the directory
* for use with seekdir().
*
@@ -161,9 +164,11 @@
* Available since API level 23.
*/
long telldir(DIR* _Nonnull __dir) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [dirfd(3)](http://man7.org/linux/man-pages/man3/dirfd.3.html)
+ * [dirfd(3)](https://man7.org/linux/man-pages/man3/dirfd.3.html)
* returns the file descriptor backing the given directory stream.
*
* Returns a file descriptor on success and returns -1 and sets `errno` on failure.
@@ -171,19 +176,19 @@
int dirfd(DIR* _Nonnull __dir);
/**
- * [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * [alphasort(3)](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
* comparator for use with scandir() that uses strcoll().
*/
int alphasort(const struct dirent* _Nonnull * _Nonnull __lhs, const struct dirent* _Nonnull * _Nonnull __rhs);
/**
- * [alphasort64](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * [alphasort64(3)](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
* comparator for use with scandir64() that uses strcmp().
*/
int alphasort64(const struct dirent64* _Nonnull * _Nonnull __lhs, const struct dirent64* _Nonnull * _Nonnull __rhs);
/**
- * [scandir(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * [scandir(3)](https://man7.org/linux/man-pages/man3/scandir.3.html)
* scans all the directory `__path`, filtering entries with `__filter` and
* sorting them with qsort() using the given `__comparator`, and storing them
* into `__name_list`. Passing NULL as the filter accepts all entries.
@@ -195,7 +200,7 @@
int scandir(const char* _Nonnull __path, struct dirent* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent* _Nonnull), int (* _Nullable __comparator)(const struct dirent* _Nonnull * _Nonnull, const struct dirent* _Nonnull * _Nonnull));
/**
- * [scandir64(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * [scandir64(3)](https://man7.org/linux/man-pages/man3/scandir.3.html)
* scans all the directory `__path`, filtering entries with `__filter` and
* sorting them with qsort() using the given `__comparator`, and storing them
* into `__name_list`. Passing NULL as the filter accepts all entries.
@@ -209,7 +214,7 @@
#if defined(__USE_GNU)
/**
- * [scandirat64(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * [scandirat64(3)](https://man7.org/linux/man-pages/man3/scandirat.3.html)
* scans all the directory referenced by the pair of `__dir_fd` and `__path`,
* filtering entries with `__filter` and sorting them with qsort() using the
* given `__comparator`, and storing them into `__name_list`. Passing NULL as
@@ -221,10 +226,12 @@
*
* Available since API level 24.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int scandirat64(int __dir_fd, const char* _Nonnull __path, struct dirent64* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent64* _Nonnull), int (* _Nullable __comparator)(const struct dirent64* _Nonnull * _Nonnull, const struct dirent64* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
/**
- * [scandirat(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * [scandirat(3)](https://man7.org/linux/man-pages/man3/scandirat.3.html)
* scans all the directory referenced by the pair of `__dir_fd` and `__path`,
* filtering entries with `__filter` and sorting them with qsort() using the
* given `__comparator`, and storing them into `__name_list`. Passing NULL as
@@ -237,6 +244,8 @@
* Available since API level 24.
*/
int scandirat(int __dir_fd, const char* _Nonnull __path, struct dirent* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent* _Nonnull), int (* _Nullable __comparator)(const struct dirent* _Nonnull * _Nonnull, const struct dirent* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#endif
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index d65a409..81045fd 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -28,9 +28,21 @@
#pragma once
-#include <stdint.h>
#include <sys/cdefs.h>
+#include <stdint.h>
+
+/**
+ * @addtogroup libdl Dynamic Linker
+ * @{
+ */
+
+/**
+ * \file
+ * Standard dynamic library support.
+ * See also the Android-specific functionality in `<android/dlext.h>`.
+ */
+
__BEGIN_DECLS
/**
@@ -48,9 +60,11 @@
} Dl_info;
/**
- * [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html)
+ * [dlopen(3)](https://man7.org/linux/man-pages/man3/dlopen.3.html)
* loads the given shared library.
*
+ * See also android_dlopen_ext().
+ *
* Returns a pointer to an opaque handle for use with other <dlfcn.h> functions
* on success, and returns NULL on failure, in which case dlerror() can be used
* to retrieve the specific error.
@@ -58,7 +72,7 @@
void* _Nullable dlopen(const char* _Nullable __filename, int __flag);
/**
- * [dlclose(3)](http://man7.org/linux/man-pages/man3/dlclose.3.html)
+ * [dlclose(3)](https://man7.org/linux/man-pages/man3/dlclose.3.html)
* decrements the reference count for the given shared library (and
* any libraries brought in by that library's DT_NEEDED entries).
*
@@ -84,7 +98,7 @@
int dlclose(void* _Nonnull __handle);
/**
- * [dlerror(3)](http://man7.org/linux/man-pages/man3/dlerror.3.html)
+ * [dlerror(3)](https://man7.org/linux/man-pages/man3/dlerror.3.html)
* returns a human-readable error message describing the most recent
* failure from one of the <dlfcn.h> functions on the calling thread.
*
@@ -97,7 +111,7 @@
char* _Nullable dlerror(void);
/**
- * [dlsym(3)](http://man7.org/linux/man-pages/man3/dlsym.3.html)
+ * [dlsym(3)](https://man7.org/linux/man-pages/man3/dlsym.3.html)
* returns a pointer to the symbol with the given name in the shared
* library represented by the given handle. The handle may have been
* returned from dlopen(), or can be RTLD_DEFAULT or RTLD_NEXT.
@@ -108,7 +122,7 @@
void* _Nullable dlsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol);
/**
- * [dlvsym(3)](http://man7.org/linux/man-pages/man3/dlvsym.3.html)
+ * [dlvsym(3)](https://man7.org/linux/man-pages/man3/dlvsym.3.html)
* returns a pointer to the symbol with the given name and version in the shared
* library represented by the given handle. The handle may have been
* returned from dlopen(), or can be RTLD_DEFAULT or RTLD_NEXT.
@@ -116,10 +130,14 @@
* Returns the address of the symbol on success, and returns NULL on failure,
* in which case dlerror() can be used to retrieve the specific error.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
void* _Nullable dlvsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol, const char* _Nullable __version) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
/**
- * [dladdr(3)](http://man7.org/linux/man-pages/man3/dladdr.3.html)
+ * [dladdr(3)](https://man7.org/linux/man-pages/man3/dladdr.3.html)
* returns information about the symbol at the given address.
*
* Returns non-zero on success, and returns 0 on failure. Note that unlike
@@ -186,3 +204,5 @@
#endif
__END_DECLS
+
+/** @} */
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 374d5bb..24454d7 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -272,14 +272,12 @@
/* riscv64 psabi. */
-/* FreeBSD is missing these, found in
+/*
* https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#relocations
- * so I've sent https://github.com/freebsd/freebsd-src/pull/1141 upstream.
+ * Missing from FreeBSD and the Linux uapi headers.
+ * TODO: upstreamed to FreeBSD as https://github.com/freebsd/freebsd-src/pull/1141.
*/
#define R_RISCV_TLSDESC 12
-#define R_RISCV_PLT32 59
-#define R_RISCV_SET_ULEB128 60
-#define R_RISCV_SUB_ULEB128 61
#define R_RISCV_TLSDESC_HI20 62
#define R_RISCV_TLSDESC_LOAD_LO12 63
#define R_RISCV_TLSDESC_ADD_LO12 64
diff --git a/libc/include/err.h b/libc/include/err.h
index af44514..81b11e3 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -36,14 +36,15 @@
* @brief BSD error reporting functions. See `<error.h>` for the GNU equivalent.
*/
-#include <stdarg.h>
#include <sys/cdefs.h>
+
+#include <stdarg.h>
#include <sys/types.h>
__BEGIN_DECLS
/**
- * [err(3)](http://man7.org/linux/man-pages/man3/err.3.html) outputs the program name,
+ * [err(3)](https://man7.org/linux/man-pages/man3/err.3.html) outputs the program name,
* the printf()-like formatted message, and the result of strerror() if `errno` is non-zero.
*
* Calls exit() with `__status`.
@@ -53,7 +54,7 @@
__noreturn void err(int __status, const char* _Nullable __fmt, ...) __printflike(2, 3);
/**
- * [verr(3)](http://man7.org/linux/man-pages/man3/verr.3.html) outputs the program name,
+ * [verr(3)](https://man7.org/linux/man-pages/man3/verr.3.html) outputs the program name,
* the vprintf()-like formatted message, and the result of strerror() if `errno` is non-zero.
*
* Calls exit() with `__status`.
@@ -63,7 +64,7 @@
__noreturn void verr(int __status, const char* _Nullable __fmt, va_list __args) __printflike(2, 0);
/**
- * [errx(3)](http://man7.org/linux/man-pages/man3/errx.3.html) outputs the program name, and
+ * [errx(3)](https://man7.org/linux/man-pages/man3/errx.3.html) outputs the program name, and
* the printf()-like formatted message.
*
* Calls exit() with `__status`.
@@ -73,7 +74,7 @@
__noreturn void errx(int __status, const char* _Nullable __fmt, ...) __printflike(2, 3);
/**
- * [verrx(3)](http://man7.org/linux/man-pages/man3/err.3.html) outputs the program name, and
+ * [verrx(3)](https://man7.org/linux/man-pages/man3/verrx.3.html) outputs the program name, and
* the vprintf()-like formatted message.
*
* Calls exit() with `__status`.
@@ -83,7 +84,7 @@
__noreturn void verrx(int __status, const char* _Nullable __fmt, va_list __args) __printflike(2, 0);
/**
- * [warn(3)](http://man7.org/linux/man-pages/man3/warn.3.html) outputs the program name,
+ * [warn(3)](https://man7.org/linux/man-pages/man3/warn.3.html) outputs the program name,
* the printf()-like formatted message, and the result of strerror() if `errno` is non-zero.
*
* New code should consider error() in `<error.h>`.
@@ -91,7 +92,7 @@
void warn(const char* _Nullable __fmt, ...) __printflike(1, 2);
/**
- * [vwarn(3)](http://man7.org/linux/man-pages/man3/vwarn.3.html) outputs the program name,
+ * [vwarn(3)](https://man7.org/linux/man-pages/man3/vwarn.3.html) outputs the program name,
* the vprintf()-like formatted message, and the result of strerror() if `errno` is non-zero.
*
* New code should consider error() in `<error.h>`.
@@ -99,7 +100,7 @@
void vwarn(const char* _Nullable __fmt, va_list __args) __printflike(1, 0);
/**
- * [warnx(3)](http://man7.org/linux/man-pages/man3/warnx.3.html) outputs the program name, and
+ * [warnx(3)](https://man7.org/linux/man-pages/man3/warnx.3.html) outputs the program name, and
* the printf()-like formatted message.
*
* New code should consider error() in `<error.h>`.
@@ -107,7 +108,7 @@
void warnx(const char* _Nullable __fmt, ...) __printflike(1, 2);
/**
- * [vwarnx(3)](http://man7.org/linux/man-pages/man3/warn.3.html) outputs the program name, and
+ * [vwarnx(3)](https://man7.org/linux/man-pages/man3/vwarnx.3.html) outputs the program name, and
* the vprintf()-like formatted message.
*
* New code should consider error() in `<error.h>`.
diff --git a/libc/include/errno.h b/libc/include/errno.h
index 12ebdf7..0b79592 100644
--- a/libc/include/errno.h
+++ b/libc/include/errno.h
@@ -52,7 +52,7 @@
int* _Nonnull __errno(void) __attribute_const__;
/**
- * [errno(3)](http://man7.org/linux/man-pages/man3/errno.3.html) is the last error on the calling
+ * [errno(3)](https://man7.org/linux/man-pages/man3/errno.3.html) is the last error on the calling
* thread.
*/
#define errno (*__errno())
diff --git a/libc/include/error.h b/libc/include/error.h
index 187ee17..a9bdc24 100644
--- a/libc/include/error.h
+++ b/libc/include/error.h
@@ -38,16 +38,18 @@
__BEGIN_DECLS
/**
- * [error_print_progname(3)](http://man7.org/linux/man-pages/man3/error_print_progname.3.html) is
+ * [error_print_progname(3)](https://man7.org/linux/man-pages/man3/error_print_progname.3.html) is
* a function pointer that, if non-null, is called by error() instead of prefixing errors with the
* program name.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
extern void (* _Nullable error_print_progname)(void) __INTRODUCED_IN(23);
/**
- * [error_message_count(3)](http://man7.org/linux/man-pages/man3/error_message_count.3.html) is
+ * [error_message_count(3)](https://man7.org/linux/man-pages/man3/error_message_count.3.html) is
* a global count of the number of calls to error() and error_at_line().
*
* Available since API level 23.
@@ -55,7 +57,7 @@
extern unsigned int error_message_count __INTRODUCED_IN(23);
/**
- * [error_one_per_line(3)](http://man7.org/linux/man-pages/man3/error_one_per_line.3.html) is
+ * [error_one_per_line(3)](https://man7.org/linux/man-pages/man3/error_one_per_line.3.html) is
* a global flag that if non-zero disables printing multiple errors with the same filename and
* line number.
*
@@ -64,7 +66,7 @@
extern int error_one_per_line __INTRODUCED_IN(23);
/**
- * [error(3)](http://man7.org/linux/man-pages/man3/error.3.html) formats the given printf()-like
+ * [error(3)](https://man7.org/linux/man-pages/man3/error.3.html) formats the given printf()-like
* error message, preceded by the program name. Calls exit if `__status` is non-zero, and appends
* the result of strerror() if `__errno` is non-zero.
*
@@ -73,7 +75,7 @@
void error(int __status, int __errno, const char* _Nonnull __fmt, ...) __printflike(3, 4) __INTRODUCED_IN(23);
/**
- * [error_at_line(3)](http://man7.org/linux/man-pages/man3/error_at_line.3.html) formats the given
+ * [error_at_line(3)](https://man7.org/linux/man-pages/man3/error_at_line.3.html) formats the given
* printf()-like error message, preceded by the program name and the given filename and line number.
* Calls exit if `__status` is non-zero, and appends the result of strerror() if `__errno` is
* non-zero.
@@ -81,5 +83,7 @@
* Available since API level 23.
*/
void error_at_line(int __status, int __errno, const char* _Nonnull __filename, unsigned int __line_number, const char* _Nonnull __fmt, ...) __printflike(5, 6) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/execinfo.h b/libc/include/execinfo.h
index 88f4ae7..84b637c 100644
--- a/libc/include/execinfo.h
+++ b/libc/include/execinfo.h
@@ -47,6 +47,8 @@
*
* Available since API level 33.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(33)
int backtrace(void* _Nonnull * _Nonnull buffer, int size) __INTRODUCED_IN(33);
/**
@@ -70,5 +72,7 @@
* Available since API level 33.
*/
void backtrace_symbols_fd(void* _Nonnull const* _Nonnull buffer, int size, int fd) __INTRODUCED_IN(33);
+#endif /* __BIONIC_AVAILABILITY_GUARD(33) */
+
__END_DECLS
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 16ce6fa..2bd1fc6 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -93,17 +93,15 @@
/** Flag for splice(). */
#define SPLICE_F_GIFT 8
-#if __ANDROID_API__ >= 26
/** Flag for sync_file_range(). */
#define SYNC_FILE_RANGE_WAIT_BEFORE 1
/** Flag for sync_file_range(). */
#define SYNC_FILE_RANGE_WRITE 2
/** Flag for sync_file_range(). */
#define SYNC_FILE_RANGE_WAIT_AFTER 4
-#endif
/**
- * [creat(2)](http://man7.org/linux/man-pages/man2/creat.2.html)
+ * [creat(2)](https://man7.org/linux/man-pages/man2/creat.2.html)
* creates a file.
*
* Returns a new file descriptor on success and returns -1 and sets `errno` on
@@ -114,7 +112,7 @@
int creat64(const char* _Nonnull __path, mode_t __mode);
/**
- * [openat(2)](http://man7.org/linux/man-pages/man2/openat.2.html)
+ * [openat(2)](https://man7.org/linux/man-pages/man2/openat.2.html)
* opens (and possibly creates) a file.
*
* Returns a new file descriptor on success and returns -1 and sets `errno` on
@@ -125,7 +123,7 @@
int openat64(int __dir_fd, const char* _Nonnull __path, int __flags, ...);
/**
- * [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)
+ * [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)
* opens (and possibly creates) a file.
*
* Returns a new file descriptor on success and returns -1 and sets `errno` on
@@ -136,7 +134,7 @@
int open64(const char* _Nonnull __path, int __flags, ...);
/**
- * [splice(2)](http://man7.org/linux/man-pages/man2/splice.2.html)
+ * [splice(2)](https://man7.org/linux/man-pages/man2/splice.2.html)
* splices data to/from a pipe.
*
* Valid flags are `SPLICE_F_MOVE`, `SPLICE_F_NONBLOCK`, `SPLICE_F_MORE`, and
@@ -148,7 +146,7 @@
ssize_t splice(int __in_fd, off64_t* __BIONIC_COMPLICATED_NULLNESS __in_offset, int __out_fd, off64_t* __BIONIC_COMPLICATED_NULLNESS __out_offset, size_t __length, unsigned int __flags);
/**
- * [tee(2)](http://man7.org/linux/man-pages/man2/tee.2.html)
+ * [tee(2)](https://man7.org/linux/man-pages/man2/tee.2.html)
* duplicates data from one pipe to another.
*
* Valid flags are `SPLICE_F_MOVE`, `SPLICE_F_NONBLOCK`, `SPLICE_F_MORE`, and
@@ -160,7 +158,7 @@
ssize_t tee(int __in_fd, int __out_fd, size_t __length, unsigned int __flags);
/**
- * [vmsplice(2)](http://man7.org/linux/man-pages/man2/vmsplice.2.html)
+ * [vmsplice(2)](https://man7.org/linux/man-pages/man2/vmsplice.2.html)
* splices data to/from a pipe.
*
* Valid flags are `SPLICE_F_MOVE`, `SPLICE_F_NONBLOCK`, `SPLICE_F_MORE`, and
@@ -172,7 +170,7 @@
ssize_t vmsplice(int __fd, const struct iovec* _Nonnull __iov, size_t __count, unsigned int __flags);
/**
- * [fallocate(2)](http://man7.org/linux/man-pages/man2/fallocate.2.html)
+ * [fallocate(2)](https://man7.org/linux/man-pages/man2/fallocate.2.html)
* is a Linux-specific extension of posix_fallocate().
*
* Valid flags are `FALLOC_FL_KEEP_SIZE`, `FALLOC_FL_PUNCH_HOLE`,
@@ -187,7 +185,7 @@
int fallocate64(int __fd, int __mode, off64_t __offset, off64_t __length);
/**
- * [posix_fadvise(2)](http://man7.org/linux/man-pages/man2/posix_fadvise.2.html)
+ * [posix_fadvise(2)](https://man7.org/linux/man-pages/man2/posix_fadvise.2.html)
* declares an expected access pattern for file data.
*
* Valid flags are `POSIX_FADV_NORMAL`, `POSIX_FADV_RANDOM`,
@@ -201,7 +199,7 @@
int posix_fadvise64(int __fd, off64_t __offset, off64_t __length, int __advice);
/**
- * [posix_fallocate(2)](http://man7.org/linux/man-pages/man2/posix_fallocate.2.html)
+ * [posix_fallocate(2)](https://man7.org/linux/man-pages/man2/posix_fallocate.2.html)
* allocates file space.
*
* Returns 0 on success and returns an error number on failure.
@@ -213,7 +211,7 @@
#if defined(__USE_GNU)
/**
- * [readahead(2)](http://man7.org/linux/man-pages/man2/readahead.2.html)
+ * [readahead(2)](https://man7.org/linux/man-pages/man2/readahead.2.html)
* initiates readahead for the given file.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -221,7 +219,7 @@
ssize_t readahead(int __fd, off64_t __offset, size_t __length);
/**
- * [sync_file_range(2)](http://man7.org/linux/man-pages/man2/sync_file_range.2.html)
+ * [sync_file_range(2)](https://man7.org/linux/man-pages/man2/sync_file_range.2.html)
* syncs part of a file with disk.
*
* Valid flags are `SYNC_FILE_RANGE_WAIT_BEFORE`, `SYNC_FILE_RANGE_WRITE`, and
@@ -229,7 +227,11 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int sync_file_range(int __fd, off64_t __offset, off64_t __length, unsigned int __flags) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
#endif
diff --git a/libc/include/fenv.h b/libc/include/fenv.h
index f7dcc8e..4c1d490 100644
--- a/libc/include/fenv.h
+++ b/libc/include/fenv.h
@@ -49,7 +49,7 @@
__BEGIN_DECLS
/**
- * [feclearexcept(3)](http://man7.org/linux/man-pages/man3/feclearexcept.3.html)
+ * [feclearexcept(3)](https://man7.org/linux/man-pages/man3/feclearexcept.3.html)
* clears the given `exceptions` in hardware.
*
* Returns 0 on success, and returns non-zero on failure.
@@ -57,7 +57,7 @@
int feclearexcept(int __exceptions);
/**
- * [fegetexceptflag(3)](http://man7.org/linux/man-pages/man3/fegetexceptflag.3.html)
+ * [fegetexceptflag(3)](https://man7.org/linux/man-pages/man3/fegetexceptflag.3.html)
* copies the state of the given `exceptions` from hardware into `*flag_ptr`.
* See fesetexceptflag().
*
@@ -66,7 +66,7 @@
int fegetexceptflag(fexcept_t* _Nonnull __flag_ptr, int __exceptions);
/**
- * [feraiseexcept(3)](http://man7.org/linux/man-pages/man3/feraiseexcept.3.html)
+ * [feraiseexcept(3)](https://man7.org/linux/man-pages/man3/feraiseexcept.3.html)
* raises the given `exceptions` in hardware.
*
* Returns 0 on success, and returns non-zero on failure.
@@ -74,7 +74,7 @@
int feraiseexcept(int __exceptions);
/**
- * [fesetexceptflag(3)](http://man7.org/linux/man-pages/man3/fesetexceptflag.3.html)
+ * [fesetexceptflag(3)](https://man7.org/linux/man-pages/man3/fesetexceptflag.3.html)
* copies the state of the given `exceptions` from `*flag_ptr` into hardware.
* See fesetexceptflag().
*
@@ -83,7 +83,7 @@
int fesetexceptflag(const fexcept_t* _Nonnull __flag_ptr, int __exceptions);
/**
- * [fetestexcept(3)](http://man7.org/linux/man-pages/man3/fetestexcept.3.html)
+ * [fetestexcept(3)](https://man7.org/linux/man-pages/man3/fetestexcept.3.html)
* tests whether the given `exceptions` are set in hardware.
*
* Returns the currently-set subset of `exceptions`.
@@ -91,7 +91,7 @@
int fetestexcept(int __exceptions);
/**
- * [fegetround(3)](http://man7.org/linux/man-pages/man3/fegetround.3.html)
+ * [fegetround(3)](https://man7.org/linux/man-pages/man3/fegetround.3.html)
* returns the current rounding mode.
*
* Returns the rounding mode on success, and returns a negative value on failure.
@@ -99,7 +99,7 @@
int fegetround(void);
/**
- * [fesetround(3)](http://man7.org/linux/man-pages/man3/fesetround.3.html)
+ * [fesetround(3)](https://man7.org/linux/man-pages/man3/fesetround.3.html)
* sets the current rounding mode.
*
* Returns 0 on success, and returns non-zero on failure.
@@ -107,7 +107,7 @@
int fesetround(int __rounding_mode);
/**
- * [fegetenv(3)](http://man7.org/linux/man-pages/man3/fegetenv.3.html)
+ * [fegetenv(3)](https://man7.org/linux/man-pages/man3/fegetenv.3.html)
* gets the current floating-point environment. See fesetenv().
*
* Returns 0 on success, and returns non-zero on failure.
@@ -115,7 +115,7 @@
int fegetenv(fenv_t* _Nonnull __env);
/**
- * [feholdexcept(3)](http://man7.org/linux/man-pages/man3/feholdexcept.3.html)
+ * [feholdexcept(3)](https://man7.org/linux/man-pages/man3/feholdexcept.3.html)
* gets the current floating-point environment, clears the status flags, and
* ignores floating point exceptions. See fesetenv()/feupdateenv().
*
@@ -124,7 +124,7 @@
int feholdexcept(fenv_t* _Nonnull __env);
/**
- * [fesetenv(3)](http://man7.org/linux/man-pages/man3/fesetenv.3.html)
+ * [fesetenv(3)](https://man7.org/linux/man-pages/man3/fesetenv.3.html)
* sets the current floating-point environment. See fegetenv().
*
* Returns 0 on success, and returns non-zero on failure.
@@ -132,7 +132,7 @@
int fesetenv(const fenv_t* _Nonnull __env);
/**
- * [feupdateenv(3)](http://man7.org/linux/man-pages/man3/feupdateenv.3.html)
+ * [feupdateenv(3)](https://man7.org/linux/man-pages/man3/feupdateenv.3.html)
* sets the current floating-point environment to `*env` but with currently-raised
* exceptions still raised. See fesetenv().
*
@@ -141,7 +141,7 @@
int feupdateenv(const fenv_t* _Nonnull __env);
/**
- * [feenableexcept(3)](http://man7.org/linux/man-pages/man3/feenableexcept.3.html)
+ * [feenableexcept(3)](https://man7.org/linux/man-pages/man3/feenableexcept.3.html)
* sets the given `exceptions` to trap, if the hardware supports it. This is not
* generally useful on Android, because only x86/x86-64 can trap.
*
@@ -150,7 +150,7 @@
int feenableexcept(int __exceptions);
/**
- * [fedisableexcept(3)](http://man7.org/linux/man-pages/man3/fedisableexcept.3.html)
+ * [fedisableexcept(3)](https://man7.org/linux/man-pages/man3/fedisableexcept.3.html)
* sets the given `exceptions` to not trap, if the hardware supports it. This is not
* generally useful on Android, because only x86/x86-64 can trap.
*
@@ -159,7 +159,7 @@
int fedisableexcept(int __exceptions);
/**
- * [fegetexcept(3)](http://man7.org/linux/man-pages/man3/fegetexcept.3.html)
+ * [fegetexcept(3)](https://man7.org/linux/man-pages/man3/fegetexcept.3.html)
* returns the exceptions that currently trap. This is not generally useful on
* Android, because only x86/x86-64 can trap.
*
diff --git a/libc/include/fnmatch.h b/libc/include/fnmatch.h
index 1788a27..e3b17fd 100644
--- a/libc/include/fnmatch.h
+++ b/libc/include/fnmatch.h
@@ -60,7 +60,7 @@
#define FNM_FILE_NAME FNM_PATHNAME
/**
- * [fnmatch(3)](http://man7.org/linux/man-pages/man3/fnmatch.3.html) matches `__string` against
+ * [fnmatch(3)](https://man7.org/linux/man-pages/man3/fnmatch.3.html) matches `__string` against
* the shell wildcard `__pattern`.
*
* Returns 0 on success, and returns `FNM_NOMATCH` on failure.
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index c1c0442..56892aa 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -70,12 +70,12 @@
__BEGIN_DECLS
/**
- * [getopt_long(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
+ * [getopt_long(3)](https://man7.org/linux/man-pages/man3/getopt_long.3.html) parses command-line options.
*/
int getopt_long(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
/**
- * [getopt_long_only(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
+ * [getopt_long_only(3)](https://man7.org/linux/man-pages/man3/getopt_long_only.3.html) parses command-line options.
*/
int getopt_long_only(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
diff --git a/libc/include/glob.h b/libc/include/glob.h
index 2c2b8d1..ccdf2e9 100644
--- a/libc/include/glob.h
+++ b/libc/include/glob.h
@@ -92,8 +92,12 @@
__BEGIN_DECLS
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int glob(const char* _Nonnull __pattern, int __flags, int (* _Nullable __error_callback)(const char* _Nonnull __failure_path, int __failure_errno), glob_t* _Nonnull __result_ptr) __INTRODUCED_IN(28);
void globfree(glob_t* _Nonnull __result_ptr) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/grp.h b/libc/include/grp.h
index 2451db5..a48c046 100644
--- a/libc/include/grp.h
+++ b/libc/include/grp.h
@@ -51,12 +51,20 @@
struct group* _Nullable getgrnam(const char* _Nonnull __name);
/* Note: Android has thousands and thousands of ids to iterate through. */
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
struct group* _Nullable getgrent(void) __INTRODUCED_IN(26);
void setgrent(void) __INTRODUCED_IN(26);
void endgrent(void) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int getgrgid_r(gid_t __gid, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable * _Nonnull __result) __INTRODUCED_IN(24);
int getgrnam_r(const char* _Nonnull __name, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable *_Nonnull __result) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
int getgrouplist(const char* _Nonnull __user, gid_t __group, gid_t* __BIONIC_COMPLICATED_NULLNESS __groups, int* _Nonnull __group_count);
int initgroups(const char* _Nonnull __user, gid_t __group);
diff --git a/libc/include/iconv.h b/libc/include/iconv.h
index 27e04bb..35328ee 100644
--- a/libc/include/iconv.h
+++ b/libc/include/iconv.h
@@ -47,7 +47,7 @@
typedef struct __iconv_t* iconv_t;
/**
- * [iconv_open(3)](http://man7.org/linux/man-pages/man3/iconv_open.3.html) allocates a new converter
+ * [iconv_open(3)](https://man7.org/linux/man-pages/man3/iconv_open.3.html) allocates a new converter
* from `__src_encoding` to `__dst_encoding`.
*
* Android supports the `utf8`, `ascii`, `usascii`, `utf16be`, `utf16le`, `utf32be`, `utf32le`,
@@ -60,10 +60,12 @@
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
iconv_t _Nonnull iconv_open(const char* _Nonnull __dst_encoding, const char* _Nonnull __src_encoding) __INTRODUCED_IN(28);
/**
- * [iconv(3)](http://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one
+ * [iconv(3)](https://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one
* encoding to another.
*
* Returns the number of characters converted on success and returns `((size_t) -1)` and
@@ -74,7 +76,7 @@
size_t iconv(iconv_t _Nonnull __converter, char* _Nullable * _Nullable __src_buf, size_t* __BIONIC_COMPLICATED_NULLNESS __src_bytes_left, char* _Nullable * _Nullable __dst_buf, size_t* __BIONIC_COMPLICATED_NULLNESS __dst_bytes_left) __INTRODUCED_IN(28);
/**
- * [iconv_close(3)](http://man7.org/linux/man-pages/man3/iconv_close.3.html) deallocates a converter
+ * [iconv_close(3)](https://man7.org/linux/man-pages/man3/iconv_close.3.html) deallocates a converter
* returned by iconv_open().
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -82,5 +84,7 @@
* Available since API level 28.
*/
int iconv_close(iconv_t _Nonnull __converter) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/ifaddrs.h b/libc/include/ifaddrs.h
index 7c0dcbf..87d2947 100644
--- a/libc/include/ifaddrs.h
+++ b/libc/include/ifaddrs.h
@@ -72,7 +72,7 @@
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
/**
- * [getifaddrs(3)](http://man7.org/linux/man-pages/man3/getifaddrs.3.html) creates a linked list
+ * [getifaddrs(3)](https://man7.org/linux/man-pages/man3/getifaddrs.3.html) creates a linked list
* of `struct ifaddrs`. The list must be freed by freeifaddrs().
*
* Returns 0 and stores the list in `*__list_ptr` on success,
@@ -80,14 +80,18 @@
*
* Available since API level 24.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int getifaddrs(struct ifaddrs* _Nullable * _Nonnull __list_ptr) __INTRODUCED_IN(24);
/**
- * [freeifaddrs(3)](http://man7.org/linux/man-pages/man3/freeifaddrs.3.html) frees a linked list
+ * [freeifaddrs(3)](https://man7.org/linux/man-pages/man3/freeifaddrs.3.html) frees a linked list
* of `struct ifaddrs` returned by getifaddrs().
*
* Available since API level 24.
*/
void freeifaddrs(struct ifaddrs* _Nullable __ptr) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
__END_DECLS
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index 9fcd9f3..790030e 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -19,8 +19,8 @@
#ifndef _INTTYPES_H_
#define _INTTYPES_H_
-#include <stdint.h>
#include <sys/cdefs.h>
+#include <stdint.h>
#ifdef __LP64__
#define __PRI_64_prefix "l"
diff --git a/libc/include/langinfo.h b/libc/include/langinfo.h
index 2b43892..b9d695c 100644
--- a/libc/include/langinfo.h
+++ b/libc/include/langinfo.h
@@ -92,8 +92,12 @@
#define NOEXPR 54
#define CRNCYSTR 55
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
char* _Nonnull nl_langinfo(nl_item __item) __INTRODUCED_IN(26);
char* _Nonnull nl_langinfo_l(nl_item __item, locale_t _Nonnull __l) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/libgen.h b/libc/include/libgen.h
index 474f066..8f2ea2b 100644
--- a/libc/include/libgen.h
+++ b/libc/include/libgen.h
@@ -41,7 +41,7 @@
__BEGIN_DECLS
/**
- * [basename(3)](http://man7.org/linux/man-pages/man3/basename.3.html)
+ * [basename(3)](https://man7.org/linux/man-pages/man3/basename.3.html)
* returns the final component of the given path.
*
* See `<string.h>` for the GNU basename(). Including `<libgen.h>`,
@@ -59,7 +59,7 @@
#define basename __posix_basename
/**
- * [dirname(3)](http://man7.org/linux/man-pages/man3/dirname.3.html)
+ * [dirname(3)](https://man7.org/linux/man-pages/man3/dirname.3.html)
* returns all but the final component of the given path.
*
* Note that Android's cv-qualifiers differ from POSIX; Android's implementation doesn't
diff --git a/libc/include/limits.h b/libc/include/limits.h
index e1f566c..5c0ef6d 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -1,6 +1,3 @@
-/* $OpenBSD: limits.h,v 1.13 2005/12/31 19:29:38 millert Exp $ */
-/* $NetBSD: limits.h,v 1.7 1994/10/26 00:56:00 cgd Exp $ */
-
/*
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
@@ -32,108 +29,83 @@
* @(#)limits.h 5.9 (Berkeley) 4/3/91
*/
-#ifndef _LIMITS_H_
-#define _LIMITS_H_
+#pragma once
+
+/**
+ * @file limits.h
+ * @brief Constants relating to implementation limits.
+ *
+ * This file is included via `#include_next` from the clang header of the same
+ * name that provides all the limits that the compiler is responsible for,
+ * primarily those relating to integer types defined by the C standard.
+ * This file defines the additional limits defined by POSIX.
+ */
+
+/*
+ * The Android build system has bionic _before_ the clang headers,
+ * so although the claim above that clang does an `#include_next`
+ * of this file is true for the NDK, it's not true for the OS,
+ * and we need to paper over that difference here until/unless
+ * the OS build changes.
+ */
+#if __has_include_next(<limits.h>)
+#include_next <limits.h>
+#endif
#include <sys/cdefs.h>
/* Historically bionic exposed the content of <float.h> from <limits.h> and <sys/limits.h> too. */
#include <float.h>
+/* Many of the POSIX limits come from the kernel. */
#include <linux/limits.h>
-#define PASS_MAX 128 /* _PASSWORD_LEN from <pwd.h> */
+/** Maximum number of positional arguments in a printf()/scanf() format string. */
+#define NL_ARGMAX 9
+/** Maximum number of bytes in a $LANG name. */
+#define NL_LANGMAX 14
+/** Irrelevant with Android's <nl_types.h>. */
+#define NL_MSGMAX 32767
+/** Obsolete; removed from POSIX. */
+#define NL_NMAX 1
+/** Irrelevant with Android's <nl_types.h>. */
+#define NL_SETMAX 255
+/** Irrelevant with Android's <nl_types.h>. */
+#define NL_TEXTMAX 255
-#define NL_ARGMAX 9
-#define NL_LANGMAX 14
-#define NL_MSGMAX 32767
-#define NL_NMAX 1
-#define NL_SETMAX 255
-#define NL_TEXTMAX 255
+/** Obsolete; removed from POSIX. */
+#define PASS_MAX 128
+/** Obsolete; removed from POSIX. */
+#define TMP_MAX 308915776
-#define TMP_MAX 308915776
-
-/* TODO: get all these from the compiler's <limits.h>? */
-
-#define CHAR_BIT 8
-#ifdef __LP64__
-# define LONG_BIT 64
+/** Number of bits in a `long` (POSIX). */
+#if __LP64__
+#define LONG_BIT 64
#else
-# define LONG_BIT 32
+#define LONG_BIT 32
#endif
+/** Number of bits in a "word" of `int` (POSIX). */
#define WORD_BIT 32
-#define SCHAR_MAX 0x7f /* max value for a signed char */
-#define SCHAR_MIN (-0x7f-1) /* min value for a signed char */
-
-#define UCHAR_MAX 0xffU /* max value for an unsigned char */
-#ifdef __CHAR_UNSIGNED__
-# define CHAR_MIN 0 /* min value for a char */
-# define CHAR_MAX 0xff /* max value for a char */
-#else
-# define CHAR_MAX 0x7f
-# define CHAR_MIN (-0x7f-1)
-#endif
-
-#define USHRT_MAX 0xffffU /* max value for an unsigned short */
-#define SHRT_MAX 0x7fff /* max value for a short */
-#define SHRT_MIN (-0x7fff-1) /* min value for a short */
-
-#define UINT_MAX 0xffffffffU /* max value for an unsigned int */
-#define INT_MAX 0x7fffffff /* max value for an int */
-#define INT_MIN (-0x7fffffff-1) /* min value for an int */
-
-#ifdef __LP64__
-# define ULONG_MAX 0xffffffffffffffffUL /* max value for unsigned long */
-# define LONG_MAX 0x7fffffffffffffffL /* max value for a signed long */
-# define LONG_MIN (-0x7fffffffffffffffL-1) /* min value for a signed long */
-#else
-# define ULONG_MAX 0xffffffffUL /* max value for an unsigned long */
-# define LONG_MAX 0x7fffffffL /* max value for a long */
-# define LONG_MIN (-0x7fffffffL-1)/* min value for a long */
-#endif
-
-# define ULLONG_MAX 0xffffffffffffffffULL /* max value for unsigned long long */
-# define LLONG_MAX 0x7fffffffffffffffLL /* max value for a signed long long */
-# define LLONG_MIN (-0x7fffffffffffffffLL-1) /* min value for a signed long long */
-
-/* GLibc compatibility definitions.
- Note that these are defined by GCC's <limits.h>
- only when __GNU_LIBRARY__ is defined, i.e. when
- targetting GLibc. */
-#ifndef LONG_LONG_MIN
-#define LONG_LONG_MIN LLONG_MIN
-#endif
-
-#ifndef LONG_LONG_MAX
-#define LONG_LONG_MAX LLONG_MAX
-#endif
-
-#ifndef ULONG_LONG_MAX
-#define ULONG_LONG_MAX ULLONG_MAX
-#endif
-
-#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
-# define UID_MAX UINT_MAX /* max value for a uid_t */
-# define GID_MAX UINT_MAX /* max value for a gid_t */
-#if defined(__LP64__)
+/** Maximum value of a uid_t. */
+#define UID_MAX UINT_MAX
+/** Maximum value of a gid_t. */
+#define GID_MAX UINT_MAX
+/** Maximum value of a size_t. */
#define SIZE_T_MAX ULONG_MAX
-#else
-#define SIZE_T_MAX UINT_MAX
-#endif
-#endif
-
-#if defined(__LP64__)
+/** Maximum value of a ssize_t. */
#define SSIZE_MAX LONG_MAX
-#else
-#define SSIZE_MAX INT_MAX
-#endif
+/** Maximum number of bytes in a multibyte character. */
#define MB_LEN_MAX 4
+/** Default process priority. */
#define NZERO 20
+/** Maximum number of struct iovec that can be passed in a single readv()/writev(). */
#define IOV_MAX 1024
+
+/** Maximum value for a semaphore. */
#define SEM_VALUE_MAX 0x3fffffff
/** Do not use: prefer getline() or asprintf() rather than hard-coding an arbitrary size. */
@@ -142,12 +114,17 @@
/* POSIX says these belong in <unistd.h> but BSD has some in <limits.h>. */
#include <bits/posix_limits.h>
+/** Maximum length of a hostname returned by gethostname(). */
#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
+
+/** Maximum length of a login name. */
#define LOGIN_NAME_MAX 256
+
+/** Maximum length of terminal device name. */
#define TTY_NAME_MAX 32
-/* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+/** Maximum number of attempts to destroy thread-specific data when a thread exits. */
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
/**
* The number of calls to pthread_key_create() without intervening calls to
@@ -156,7 +133,5 @@
*/
#define PTHREAD_KEYS_MAX 128
-/** bionic has no specific limit on the number of threads. */
+/** bionic has no fixed limit on the number of threads. */
#undef PTHREAD_THREADS_MAX
-
-#endif /* !_LIMITS_H_ */
diff --git a/libc/include/link.h b/libc/include/link.h
index ee1fc42..331070e 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -33,8 +33,9 @@
* @brief Extra dynamic linker functionality (see also <dlfcn.h>).
*/
-#include <stdint.h>
#include <sys/cdefs.h>
+
+#include <stdint.h>
#include <sys/types.h>
#include <elf.h>
@@ -99,7 +100,7 @@
};
/**
- * [dl_iterate_phdr(3)](http://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html)
+ * [dl_iterate_phdr(3)](https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html)
* calls the given callback once for every loaded shared object. The size
* argument to the callback lets you determine whether you have a smaller
* `dl_phdr_info` from before API level 30, or the newer full one.
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 3ebc1be..ba68401 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -34,7 +34,7 @@
#define __BIONIC_ALLOC_SIZE(...) __attribute__((__alloc_size__(__VA_ARGS__)))
/**
- * [malloc(3)](http://man7.org/linux/man-pages/man3/malloc.3.html) allocates
+ * [malloc(3)](https://man7.org/linux/man-pages/man3/malloc.3.html) allocates
* memory on the heap.
*
* Returns a pointer to the allocated memory on success and returns a null
@@ -55,30 +55,30 @@
* other processes. Obviously this is not the case for apps, which will
* be killed in preference to killing other processes.
*/
-void* _Nullable malloc(size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(1) __wur;
+__nodiscard void* _Nullable malloc(size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(1);
/**
- * [calloc(3)](http://man7.org/linux/man-pages/man3/calloc.3.html) allocates
+ * [calloc(3)](https://man7.org/linux/man-pages/man3/calloc.3.html) allocates
* and clears memory on the heap.
*
* Returns a pointer to the allocated memory on success and returns a null
* pointer and sets `errno` on failure (but see the notes for malloc()).
*/
-void* _Nullable calloc(size_t __item_count, size_t __item_size) __mallocfunc __BIONIC_ALLOC_SIZE(1,2) __wur;
+__nodiscard void* _Nullable calloc(size_t __item_count, size_t __item_size) __mallocfunc __BIONIC_ALLOC_SIZE(1,2);
/**
- * [realloc(3)](http://man7.org/linux/man-pages/man3/realloc.3.html) resizes
+ * [realloc(3)](https://man7.org/linux/man-pages/man3/realloc.3.html) resizes
* allocated memory on the heap.
*
* Returns a pointer (which may be different from `__ptr`) to the resized
* memory on success and returns a null pointer and sets `errno` on failure
* (but see the notes for malloc()).
*/
-void* _Nullable realloc(void* _Nullable __ptr, size_t __byte_count) __BIONIC_ALLOC_SIZE(2) __wur;
+__nodiscard void* _Nullable realloc(void* _Nullable __ptr, size_t __byte_count) __BIONIC_ALLOC_SIZE(2);
/**
- * [reallocarray(3)](http://man7.org/linux/man-pages/man3/realloc.3.html) resizes
- * allocated memory on the heap.
+ * [reallocarray(3)](https://man7.org/linux/man-pages/man3/reallocarray.3.html)
+ * resizes allocated memory on the heap.
*
* Equivalent to `realloc(__ptr, __item_count * __item_size)` but fails if the
* multiplication overflows.
@@ -87,16 +87,28 @@
* memory on success and returns a null pointer and sets `errno` on failure
* (but see the notes for malloc()).
*/
-void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) __wur __INTRODUCED_IN(29);
+#if __ANDROID_API__ >= 29
+__nodiscard void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) __INTRODUCED_IN(29);
+#elif defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
+#include <errno.h>
+static __inline __nodiscard void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) {
+ size_t __new_size;
+ if (__builtin_mul_overflow(__item_count, __item_size, &__new_size)) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(__ptr, __new_size);
+}
+#endif
/**
- * [free(3)](http://man7.org/linux/man-pages/man3/free.3.html) deallocates
+ * [free(3)](https://man7.org/linux/man-pages/man3/free.3.html) deallocates
* memory on the heap.
*/
void free(void* _Nullable __ptr);
/**
- * [memalign(3)](http://man7.org/linux/man-pages/man3/memalign.3.html) allocates
+ * [memalign(3)](https://man7.org/linux/man-pages/man3/memalign.3.html) allocates
* memory on the heap with the required alignment.
*
* Returns a pointer to the allocated memory on success and returns a null
@@ -104,13 +116,13 @@
*
* See also posix_memalign().
*/
-void* _Nullable memalign(size_t __alignment, size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(2) __wur;
+__nodiscard void* _Nullable memalign(size_t __alignment, size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(2);
/**
- * [malloc_usable_size(3)](http://man7.org/linux/man-pages/man3/malloc_usable_size.3.html)
+ * [malloc_usable_size(3)](https://man7.org/linux/man-pages/man3/malloc_usable_size.3.html)
* returns the actual size of the given heap block.
*/
-size_t malloc_usable_size(const void* _Nullable __ptr) __wur;
+__nodiscard size_t malloc_usable_size(const void* _Nullable __ptr);
#define __MALLINFO_BODY \
/** Total number of non-mmapped bytes currently allocated from OS. */ \
@@ -140,7 +152,7 @@
#endif
/**
- * [mallinfo(3)](http://man7.org/linux/man-pages/man3/mallinfo.3.html) returns
+ * [mallinfo(3)](https://man7.org/linux/man-pages/man3/mallinfo.3.html) returns
* information about the current state of the heap. Note that mallinfo() is
* inherently unreliable and consider using malloc_info() instead.
*/
@@ -152,14 +164,14 @@
struct mallinfo2 { __MALLINFO_BODY };
/**
- * [mallinfo2(3)](http://man7.org/linux/man-pages/man3/mallinfo2.3.html) returns
+ * [mallinfo2(3)](https://man7.org/linux/man-pages/man3/mallinfo2.3.html) returns
* information about the current state of the heap. Note that mallinfo2() is
* inherently unreliable and consider using malloc_info() instead.
*/
struct mallinfo2 mallinfo2(void) __RENAME(mallinfo);
/**
- * [malloc_info(3)](http://man7.org/linux/man-pages/man3/malloc_info.3.html)
+ * [malloc_info(3)](https://man7.org/linux/man-pages/man3/malloc_info.3.html)
* writes information about the current state of the heap to the given stream.
*
* The XML structure for malloc_info() is as follows:
@@ -183,7 +195,11 @@
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int malloc_info(int __must_be_zero, FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
* mallopt() option to set the decay time. Valid values are -1, 0 and 1.
@@ -349,17 +365,21 @@
#define M_LOG_STATS (-205)
/**
- * [mallopt(3)](http://man7.org/linux/man-pages/man3/mallopt.3.html) modifies
+ * [mallopt(3)](https://man7.org/linux/man-pages/man3/mallopt.3.html) modifies
* heap behavior. Values of `__option` are the `M_` constants from this header.
*
* Returns 1 on success, 0 on error.
*
* Available since API level 26.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int mallopt(int __option, int __value) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/**
- * [__malloc_hook(3)](http://man7.org/linux/man-pages/man3/__malloc_hook.3.html)
+ * [__malloc_hook(3)](https://man7.org/linux/man-pages/man3/__malloc_hook.3.html)
* is called to implement malloc(). By default this points to the system's
* implementation.
*
@@ -367,10 +387,12 @@
*
* See also: [extra documentation](https://android.googlesource.com/platform/bionic/+/main/libc/malloc_hooks/README.md)
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
extern void* _Nonnull (*volatile _Nonnull __malloc_hook)(size_t __byte_count, const void* _Nonnull __caller) __INTRODUCED_IN(28);
/**
- * [__realloc_hook(3)](http://man7.org/linux/man-pages/man3/__realloc_hook.3.html)
+ * [__realloc_hook(3)](https://man7.org/linux/man-pages/man3/__realloc_hook.3.html)
* is called to implement realloc(). By default this points to the system's
* implementation.
*
@@ -381,7 +403,7 @@
extern void* _Nonnull (*volatile _Nonnull __realloc_hook)(void* _Nullable __ptr, size_t __byte_count, const void* _Nonnull __caller) __INTRODUCED_IN(28);
/**
- * [__free_hook(3)](http://man7.org/linux/man-pages/man3/__free_hook.3.html)
+ * [__free_hook(3)](https://man7.org/linux/man-pages/man3/__free_hook.3.html)
* is called to implement free(). By default this points to the system's
* implementation.
*
@@ -392,7 +414,7 @@
extern void (*volatile _Nonnull __free_hook)(void* _Nullable __ptr, const void* _Nonnull __caller) __INTRODUCED_IN(28);
/**
- * [__memalign_hook(3)](http://man7.org/linux/man-pages/man3/__memalign_hook.3.html)
+ * [__memalign_hook(3)](https://man7.org/linux/man-pages/man3/__memalign_hook.3.html)
* is called to implement memalign(). By default this points to the system's
* implementation.
*
@@ -401,5 +423,7 @@
* See also: [extra documentation](https://android.googlesource.com/platform/bionic/+/main/libc/malloc_hooks/README.md)
*/
extern void* _Nonnull (*volatile _Nonnull __memalign_hook)(size_t __alignment, size_t __byte_count, const void* _Nonnull __caller) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/math.h b/libc/include/math.h
index 343ab98..59161bf 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -350,7 +350,11 @@
double gamma_r(double __x, int* _Nonnull __sign);
double lgamma_r(double __x, int* _Nonnull __sign);
double significand(double __x);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
long double lgammal_r(long double __x, int* _Nonnull __sign) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
long double significandl(long double __x);
float dremf(float __x, float __y);
int finitef(float __x) __attribute_const__;
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index 9a31838..4c03602 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -29,8 +29,9 @@
#ifndef _MNTENT_H_
#define _MNTENT_H_
-#include <stdio.h>
#include <sys/cdefs.h>
+
+#include <stdio.h>
#include <paths.h> /* for _PATH_MOUNTED */
#define MOUNTED _PATH_MOUNTED
@@ -61,7 +62,11 @@
struct mntent* _Nullable getmntent(FILE* _Nonnull __fp);
struct mntent* _Nullable getmntent_r(FILE* _Nonnull __fp, struct mntent* _Nonnull __entry, char* _Nonnull __buf, int __size);
FILE* _Nullable setmntent(const char* _Nonnull __filename, const char* _Nonnull __type);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
char* _Nullable hasmntopt(const struct mntent* _Nonnull __entry, const char* _Nonnull __option) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/net/if.h b/libc/include/net/if.h
index 79b4195..50bc74c 100644
--- a/libc/include/net/if.h
+++ b/libc/include/net/if.h
@@ -29,9 +29,10 @@
#ifndef _NET_IF_H_
#define _NET_IF_H_
+#include <sys/cdefs.h>
+
#include <sys/socket.h>
#include <linux/if.h>
-#include <sys/cdefs.h>
#ifndef IF_NAMESIZE
#define IF_NAMESIZE IFNAMSIZ
@@ -46,8 +47,12 @@
char* _Nullable if_indextoname(unsigned __index, char* _Nonnull __buf);
unsigned if_nametoindex(const char* _Nonnull __name);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
struct if_nameindex* _Nullable if_nameindex(void) __INTRODUCED_IN(24);
void if_freenameindex(struct if_nameindex* _Nullable __ptr) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
__END_DECLS
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 88214d5..04aaf5c 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -212,28 +212,52 @@
void herror(const char* _Nonnull __s);
const char* _Nonnull hstrerror(int __error);
struct hostent* _Nullable gethostbyaddr(const void* _Nonnull __addr, socklen_t __length, int __type);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int gethostbyaddr_r(const void* _Nonnull __addr, socklen_t __length, int __type, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
struct hostent* _Nullable gethostbyname(const char* _Nonnull __name);
int gethostbyname_r(const char* _Nonnull __name, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr);
struct hostent* _Nullable gethostbyname2(const char* _Nonnull __name, int __af);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int gethostbyname2_r(const char* _Nonnull __name, int __af, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
void endhostent(void) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
struct hostent* _Nullable gethostent(void);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
void sethostent(int __stay_open) __INTRODUCED_IN(28);
/* These functions are obsolete. None of these functions return anything but nullptr. */
void endnetent(void) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
struct netent* _Nullable getnetbyaddr(uint32_t __net, int __type);
struct netent* _Nullable getnetbyname(const char* _Nonnull __name);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
struct netent* _Nullable getnetent(void) __INTRODUCED_IN(28);
void setnetent(int __stay_open) __INTRODUCED_IN(28);
/* None of these functions return anything but nullptr. */
void endprotoent(void) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
struct protoent* _Nullable getprotobyname(const char* _Nonnull __name);
struct protoent* _Nullable getprotobynumber(int __proto);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
struct protoent* _Nullable getprotoent(void) __INTRODUCED_IN(28);
void setprotoent(int __stay_open) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
/* These functions return entries from a built-in database. */
void endservent(void);
diff --git a/libc/include/netinet/ether.h b/libc/include/netinet/ether.h
index 4af7eda..a847385 100644
--- a/libc/include/netinet/ether.h
+++ b/libc/include/netinet/ether.h
@@ -39,7 +39,7 @@
__BEGIN_DECLS
/**
- * [ether_ntoa(3)](http://man7.org/linux/man-pages/man3/ether_ntoa.3.html) returns a string
+ * [ether_ntoa(3)](https://man7.org/linux/man-pages/man3/ether_ntoa.3.html) returns a string
* representation of the given Ethernet (MAC) address.
*
* Returns a pointer to a static buffer.
@@ -47,7 +47,7 @@
char* _Nonnull ether_ntoa(const struct ether_addr* _Nonnull __addr);
/**
- * [ether_ntoa_r(3)](http://man7.org/linux/man-pages/man3/ether_ntoa_r.3.html) returns a string
+ * [ether_ntoa_r(3)](https://man7.org/linux/man-pages/man3/ether_ntoa_r.3.html) returns a string
* representation of the given Ethernet (MAC) address.
*
* Returns a pointer to the given buffer.
@@ -55,7 +55,7 @@
char* _Nonnull ether_ntoa_r(const struct ether_addr* _Nonnull __addr, char* _Nonnull __buf);
/**
- * [ether_aton(3)](http://man7.org/linux/man-pages/man3/ether_aton.3.html) returns an `ether_addr`
+ * [ether_aton(3)](https://man7.org/linux/man-pages/man3/ether_aton.3.html) returns an `ether_addr`
* corresponding to the given Ethernet (MAC) address string.
*
* Returns a pointer to a static buffer, or NULL if the given string isn't a valid MAC address.
@@ -63,7 +63,7 @@
struct ether_addr* _Nullable ether_aton(const char* _Nonnull __ascii);
/**
- * [ether_aton_r(3)](http://man7.org/linux/man-pages/man3/ether_aton_r.3.html) returns an
+ * [ether_aton_r(3)](https://man7.org/linux/man-pages/man3/ether_aton_r.3.html) returns an
* `ether_addr` corresponding to the given Ethernet (MAC) address string.
*
* Returns a pointer to the given buffer, or NULL if the given string isn't a valid MAC address.
diff --git a/libc/include/netinet/icmp6.h b/libc/include/netinet/icmp6.h
index 2b237a8..ebd9f6c 100644
--- a/libc/include/netinet/icmp6.h
+++ b/libc/include/netinet/icmp6.h
@@ -65,9 +65,10 @@
#ifndef _NETINET_ICMP6_H_
#define _NETINET_ICMP6_H_
-#include <netinet/in.h> /* android-added: glibc source compatibility. */
#include <sys/cdefs.h>
+#include <netinet/in.h> /* android-added: glibc source compatibility. */
+
#define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr)
- sizeof(struct icmp6_hdr) */
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 163e614..d4ce302 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -28,9 +28,10 @@
#pragma once
+#include <sys/cdefs.h>
+
#include <endian.h>
#include <netinet/in6.h>
-#include <sys/cdefs.h>
#include <sys/socket.h>
#include <linux/in.h>
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index ae20f83..44b3e3e 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -89,7 +89,7 @@
(IN6_IS_ADDR_MULTICAST(a) && (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
#define IN6_ARE_ADDR_EQUAL(a, b) \
- (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+ (__builtin_memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
#define INET6_ADDRSTRLEN 46
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
index f4d7f43..172d80d 100644
--- a/libc/include/nl_types.h
+++ b/libc/include/nl_types.h
@@ -56,16 +56,18 @@
typedef int nl_item;
/**
- * [catopen(3)](http://man7.org/linux/man-pages/man3/catopen.3.html) opens a message catalog.
+ * [catopen(3)](https://man7.org/linux/man-pages/man3/catopen.3.html) opens a message catalog.
*
* On Android, this always returns failure: `((nl_catd) -1)`.
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
nl_catd _Nonnull catopen(const char* _Nonnull __name, int __flag) __INTRODUCED_IN(26);
/**
- * [catgets(3)](http://man7.org/linux/man-pages/man3/catgets.3.html) translates the given message
+ * [catgets(3)](https://man7.org/linux/man-pages/man3/catgets.3.html) translates the given message
* using the given message catalog.
*
* On Android, this always returns `__msg`.
@@ -75,10 +77,12 @@
char* _Nonnull catgets(nl_catd _Nonnull __catalog, int __set_number, int __msg_number, const char* _Nonnull __msg) __INTRODUCED_IN(26);
/**
- * [catclose(3)](http://man7.org/linux/man-pages/man3/catclose.3.html) closes a message catalog.
+ * [catclose(3)](https://man7.org/linux/man-pages/man3/catclose.3.html) closes a message catalog.
*
* On Android, this always returns -1 with `errno` set to `EBADF`.
*/
int catclose(nl_catd _Nonnull __catalog) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 6bdc886..e57f812 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -44,7 +44,7 @@
typedef unsigned int nfds_t;
/**
- * [poll(3)](http://man7.org/linux/man-pages/man3/poll.3.html) waits on a set of file descriptors.
+ * [poll(3)](https://man7.org/linux/man-pages/man3/poll.3.html) waits on a set of file descriptors.
*
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
@@ -52,7 +52,7 @@
int poll(struct pollfd* _Nullable __fds, nfds_t __count, int __timeout_ms);
/**
- * [ppoll(3)](http://man7.org/linux/man-pages/man3/ppoll.3.html) waits on a set of file descriptors
+ * [ppoll(3)](https://man7.org/linux/man-pages/man3/ppoll.3.html) waits on a set of file descriptors
* or a signal. Set `__timeout` to null for no timeout. Set `__mask` to null to not set the signal
* mask.
*
@@ -64,7 +64,11 @@
/**
* Like ppoll() but allows setting a signal mask with RT signals even from a 32-bit process.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int ppoll64(struct pollfd* _Nullable __fds, nfds_t __count, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#define _POLL_H_
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index ef41e2d..cdf1b8c 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -33,11 +33,12 @@
* @brief POSIX threads.
*/
+#include <sys/cdefs.h>
+
#include <limits.h>
#include <bits/page_size.h>
#include <bits/pthread_types.h>
#include <sched.h>
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <time.h>
@@ -70,9 +71,7 @@
#define PTHREAD_ONCE_INIT 0
-#if __ANDROID_API__ >= 24
#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
-#endif
#if defined(__LP64__)
#define PTHREAD_STACK_MIN 16384
@@ -100,7 +99,11 @@
int pthread_attr_destroy(pthread_attr_t* _Nonnull __attr);
int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __state);
int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_attr_getinheritsched(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __flag) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull __attr, struct sched_param* _Nonnull __param);
int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __policy);
int pthread_attr_getscope(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __scope);
@@ -109,7 +112,11 @@
int pthread_attr_init(pthread_attr_t* _Nonnull __attr);
int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull __attr, int __state);
int pthread_attr_setguardsize(pthread_attr_t* _Nonnull __attr, size_t __size);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_attr_setinheritsched(pthread_attr_t* _Nonnull __attr, int __flag) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_attr_setschedparam(pthread_attr_t* _Nonnull __attr, const struct sched_param* _Nonnull __param);
int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull __attr, int __policy);
int pthread_attr_setscope(pthread_attr_t* _Nonnull __attr, int __scope);
@@ -124,8 +131,12 @@
int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull __attr, int __shared);
int pthread_cond_broadcast(pthread_cond_t* _Nonnull __cond);
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int pthread_cond_clockwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
int pthread_cond_destroy(pthread_cond_t* _Nonnull __cond);
int pthread_cond_init(pthread_cond_t* _Nonnull __cond, const pthread_condattr_t* _Nullable __attr);
int pthread_cond_signal(pthread_cond_t* _Nonnull __cond);
@@ -140,24 +151,15 @@
* Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this
* function.
*/
+
+#if (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28)
int pthread_cond_timedwait_monotonic_np(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN_64(28);
+#endif /* (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28) */
+
int pthread_cond_wait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex);
-#if defined(__clang__)
-/*
- * Disable -Wbuiltin-requires-header because clang confuses this declaration with the one defined in
- * "llvm/tools/clang/include/clang/Basic/Builtins.def", which did not define any formal arguments.
- * It seems to be an upstream bug and the fix (https://reviews.llvm.org/D58531) is still under
- * review. Thus, let's disable the warning for this function declaration.
- */
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
-#endif
-int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nonnull (* _Nonnull __start_routine)(void* _Nonnull), void* _Nullable);
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nullable (* _Nonnull __start_routine)(void* _Nullable), void* _Nullable);
int pthread_detach(pthread_t __pthread);
void pthread_exit(void* _Nullable __return_value) __noreturn;
@@ -202,14 +204,26 @@
int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull __attr);
int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __shared);
int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __type);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __protocol) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull __attr);
int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull __attr, int __shared);
int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull __attr, int __type);
-int pthread_mutexattr_setprotocol(pthread_mutexattr_t* _Nonnull __attr, int __protocol) __INTRODUCED_IN(28);
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* _Nonnull __attr, int __protocol) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int pthread_mutex_clocklock(pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
const struct timespec* _Nullable __abstime) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
int pthread_mutex_destroy(pthread_mutex_t* _Nonnull __mutex);
int pthread_mutex_init(pthread_mutex_t* _Nonnull __mutex, const pthread_mutexattr_t* _Nullable __attr);
int pthread_mutex_lock(pthread_mutex_t* _Nonnull __mutex);
@@ -224,8 +238,12 @@
* Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this
* function.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
__INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_mutex_trylock(pthread_mutex_t* _Nonnull __mutex);
int pthread_mutex_unlock(pthread_mutex_t* _Nonnull __mutex);
@@ -235,60 +253,121 @@
int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull __attr);
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __shared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull __attr, int __shared);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __kind)
__INTRODUCED_IN(23);
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull __attr, int __kind) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int pthread_rwlock_clockrdlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
int pthread_rwlock_clockwrlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_init(pthread_rwlock_t* _Nonnull __rwlock, const pthread_rwlockattr_t* _Nullable __attr);
int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull __rwlock);
-#if __ANDROID_API__ >= 24
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int pthread_barrierattr_init(pthread_barrierattr_t* _Nonnull __attr) __INTRODUCED_IN(24);
int pthread_barrierattr_destroy(pthread_barrierattr_t* _Nonnull __attr) __INTRODUCED_IN(24);
int pthread_barrierattr_getpshared(const pthread_barrierattr_t* _Nonnull __attr, int* _Nonnull __shared) __INTRODUCED_IN(24);
int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull __attr, int __shared) __INTRODUCED_IN(24);
-#endif
-#if __ANDROID_API__ >= 24
int pthread_barrier_init(pthread_barrier_t* _Nonnull __barrier, const pthread_barrierattr_t* _Nullable __attr, unsigned __count) __INTRODUCED_IN(24);
int pthread_barrier_destroy(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
int pthread_barrier_wait(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
-#endif
-#if __ANDROID_API__ >= 24
int pthread_spin_destroy(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
int pthread_spin_init(pthread_spinlock_t* _Nonnull __spinlock, int __shared) __INTRODUCED_IN(24);
int pthread_spin_lock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
int pthread_spin_trylock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
int pthread_spin_unlock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
-#endif
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
pthread_t pthread_self(void) __attribute_const__;
-#if defined(__USE_GNU)
+#if defined(__USE_GNU) && __BIONIC_AVAILABILITY_GUARD(26)
+/**
+ * [pthread_getname_np(3)](https://man7.org/linux/man-pages/man3/pthread_getname_np.3.html)
+ * gets the name of the given thread.
+ * Names are at most 16 bytes (including '\0').
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 26.
+ */
int pthread_getname_np(pthread_t __pthread, char* _Nonnull __buf, size_t __n) __INTRODUCED_IN(26);
#endif
-/* TODO: this should be __USE_GNU too. */
+
+/**
+ * [pthread_setname_np(3)](https://man7.org/linux/man-pages/man3/pthread_setname_np.3.html)
+ * sets the name of the given thread.
+ * Names are at most 16 bytes (including '\0').
+ * Truncation must be done by the caller;
+ * calls with longer names will fail with ERANGE.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * This should only have been available under _GNU_SOURCE,
+ * but is always available on Android by historical accident.
+ */
int pthread_setname_np(pthread_t __pthread, const char* _Nonnull __name);
/**
+ * [pthread_getaffinity_np(3)](https://man7.org/linux/man-pages/man3/pthread_getaffinity_np.3.html)
+ * gets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 36.
+ * See sched_getaffinity() and pthread_gettid_np() for greater portability.
+ */
+#if defined(__USE_GNU) && __BIONIC_AVAILABILITY_GUARD(36)
+int pthread_getaffinity_np(pthread_t __pthread, size_t __cpu_set_size, cpu_set_t* __cpu_set) __INTRODUCED_IN(36);
+#endif
+
+/**
+ * [pthread_setaffinity_np(3)](https://man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html)
+ * sets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ *
+ * Available since API level 36.
+ * See sched_getaffinity() and pthread_gettid_np() for greater portability.
+ */
+#if defined(__USE_GNU) && __BIONIC_AVAILABILITY_GUARD(36)
+int pthread_setaffinity_np(pthread_t __pthread, size_t __cpu_set_size, const cpu_set_t* __cpu_set) __INTRODUCED_IN(36);
+#endif
+
+/**
* [pthread_setschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html)
* sets the scheduler policy and parameters of the given thread.
*
@@ -322,7 +401,11 @@
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int pthread_setspecific(pthread_key_t __key, const void* _Nullable __value);
diff --git a/libc/include/pty.h b/libc/include/pty.h
index be447d6..92d7fbb 100644
--- a/libc/include/pty.h
+++ b/libc/include/pty.h
@@ -41,7 +41,7 @@
__BEGIN_DECLS
/**
- * [openpty(3)](http://man7.org/linux/man-pages/man3/openpty.3.html) finds
+ * [openpty(3)](https://man7.org/linux/man-pages/man3/openpty.3.html) finds
* a free pseudoterminal and configures it with the given terminal and window
* size settings.
*
@@ -49,10 +49,12 @@
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int openpty(int* _Nonnull __pty_fd, int* _Nonnull __tty_fd, char* _Nullable __tty_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
/**
- * [forkpty(3)](http://man7.org/linux/man-pages/man3/forkpty.3.html) creates
+ * [forkpty(3)](https://man7.org/linux/man-pages/man3/forkpty.3.html) creates
* a new process connected to a pseudoterminal from openpty().
*
* Returns 0 in the child/the pid of the child in the parent on success,
@@ -61,5 +63,7 @@
* Available since API level 23.
*/
int forkpty(int* _Nonnull __parent_pty_fd, char* _Nullable __child_tty_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/pwd.h b/libc/include/pwd.h
index 2b17fbf..09592bc 100644
--- a/libc/include/pwd.h
+++ b/libc/include/pwd.h
@@ -84,10 +84,14 @@
struct passwd* _Nullable getpwuid(uid_t __uid);
/* Note: Android has thousands and thousands of ids to iterate through */
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
struct passwd* _Nullable getpwent(void) __INTRODUCED_IN(26);
void setpwent(void) __INTRODUCED_IN(26);
void endpwent(void) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
int getpwnam_r(const char* _Nonnull __name, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
int getpwuid_r(uid_t __uid, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index f25484a..c49cefc 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -29,9 +29,10 @@
#ifndef _RESOLV_H_
#define _RESOLV_H_
+#include <sys/cdefs.h>
+
#include <sys/param.h>
#include <sys/types.h>
-#include <sys/cdefs.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/nameser.h>
@@ -60,7 +61,11 @@
int res_search(const char* _Nonnull __name, int __class, int __type, u_char* _Nonnull __answer, int __answer_size);
#define res_randomid __res_randomid
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
u_int __res_randomid(void) __INTRODUCED_IN(29);
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
__END_DECLS
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 9f043b6..58dd9a6 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -33,9 +33,10 @@
* @brief Thread execution scheduling.
*/
+#include <sys/cdefs.h>
+
#include <bits/timespec.h>
#include <linux/sched.h>
-#include <sys/cdefs.h>
__BEGIN_DECLS
@@ -45,42 +46,42 @@
*
* (Linux's name for POSIX's SCHED_OTHER.)
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
* @def SCHED_FIFO
* The real-time first-in/first-out scheduling policy.
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
* @def SCHED_RR
* The real-time round-robin policy. (See also SCHED_NORMAL/SCHED_OTHER.)
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
* @def SCHED_BATCH
* The batch scheduling policy.
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
* @def SCHED_IDLE
* The low priority "only when otherwise idle" scheduling priority.
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
* @def SCHED_DEADLINE
* The deadline scheduling policy.
*
- * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ * See [sched(7)](https://man7.org/linux/man-pages/man7/sched.7.html)
*/
/*
@@ -116,7 +117,7 @@
int sched_getscheduler(pid_t __pid);
/**
- * [sched_yield(2)](http://man7.org/linux/man-pages/man2/sched_yield.2.html)
+ * [sched_yield(2)](https://man7.org/linux/man-pages/man2/sched_yield.2.html)
* voluntarily gives up using the CPU so that another thread can run.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -124,7 +125,7 @@
int sched_yield(void);
/**
- * [sched_get_priority_max(2)](http://man7.org/linux/man-pages/man2/sched_get_priority_max.2.html)
+ * [sched_get_priority_max(2)](https://man7.org/linux/man-pages/man2/sched_get_priority_max.2.html)
* gets the maximum priority value allowed for the given scheduling policy.
*
* Returns a priority on success and returns -1 and sets `errno` on failure.
@@ -132,7 +133,7 @@
int sched_get_priority_max(int __policy);
/**
- * [sched_get_priority_min(2)](http://man7.org/linux/man-pages/man2/sched_get_priority_min.2.html)
+ * [sched_get_priority_min(2)](https://man7.org/linux/man-pages/man2/sched_get_priority_min.2.html)
* gets the minimum priority value allowed for the given scheduling policy.
*
* Returns a priority on success and returns -1 and sets `errno` on failure.
@@ -140,7 +141,7 @@
int sched_get_priority_min(int __policy);
/**
- * [sched_setparam(2)](http://man7.org/linux/man-pages/man2/sched_setparam.2.html)
+ * [sched_setparam(2)](https://man7.org/linux/man-pages/man2/sched_setparam.2.html)
* sets the scheduling parameters for the given thread.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -148,7 +149,7 @@
int sched_setparam(pid_t __pid, const struct sched_param* _Nonnull __param);
/**
- * [sched_getparam(2)](http://man7.org/linux/man-pages/man2/sched_getparam.2.html)
+ * [sched_getparam(2)](https://man7.org/linux/man-pages/man2/sched_getparam.2.html)
* gets the scheduling parameters for the given thread.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -156,7 +157,7 @@
int sched_getparam(pid_t __pid, struct sched_param* _Nonnull __param);
/**
- * [sched_rr_get_interval(2)](http://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html)
+ * [sched_rr_get_interval(2)](https://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html)
* queries the round-robin time quantum for the given thread.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -166,7 +167,7 @@
#if defined(__USE_GNU)
/**
- * [clone(2)](http://man7.org/linux/man-pages/man2/clone.2.html)
+ * [clone(2)](https://man7.org/linux/man-pages/man2/clone.2.html)
* creates a new child process.
*
* Returns the pid of the child to the caller on success and
@@ -175,7 +176,7 @@
int clone(int (* __BIONIC_COMPLICATED_NULLNESS __fn)(void* __BIONIC_COMPLICATED_NULLNESS ), void* __BIONIC_COMPLICATED_NULLNESS __child_stack, int __flags, void* _Nullable __arg, ...);
/**
- * [unshare(2)](http://man7.org/linux/man-pages/man2/unshare.2.html)
+ * [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
* disassociates part of the caller's execution context.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -183,7 +184,7 @@
int unshare(int __flags);
/**
- * [setns(2)](http://man7.org/linux/man-pages/man2/setns.2.html)
+ * [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
* reassociates a thread with a different namespace.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -191,7 +192,7 @@
int setns(int __fd, int __ns_type);
/**
- * [sched_getcpu(3)](http://man7.org/linux/man-pages/man3/sched_getcpu.3.html)
+ * [sched_getcpu(3)](https://man7.org/linux/man-pages/man3/sched_getcpu.3.html)
* reports which CPU the caller is running on.
*
* Returns a non-negative CPU number on success and returns -1 and sets
@@ -219,7 +220,7 @@
} cpu_set_t;
/**
- * [sched_setaffinity(2)](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)
+ * [sched_setaffinity(2)](https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)
* sets the CPU affinity mask for the given thread.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -227,7 +228,7 @@
int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* _Nonnull __set);
/**
- * [sched_getaffinity(2)](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)
+ * [sched_getaffinity(2)](https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)
* gets the CPU affinity mask for the given thread.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -235,12 +236,12 @@
int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* _Nonnull __set);
/**
- * [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
+ * [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_ZERO.3.html) clears all
* bits in a static CPU set.
*/
#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set)
/**
- * [CPU_ZERO_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
+ * [CPU_ZERO_S](https://man7.org/linux/man-pages/man3/CPU_ZERO_S.3.html) clears all
* bits in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_ZERO_S(setsize, set) __builtin_memset(set, 0, setsize)
@@ -251,7 +252,7 @@
*/
#define CPU_SET(cpu, set) CPU_SET_S(cpu, sizeof(cpu_set_t), set)
/**
- * [CPU_SET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) sets one
+ * [CPU_SET_S](https://man7.org/linux/man-pages/man3/CPU_SET_S.3.html) sets one
* bit in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_SET_S(cpu, setsize, set) \
@@ -262,12 +263,12 @@
} while (0)
/**
- * [CPU_CLR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * [CPU_CLR](https://man7.org/linux/man-pages/man3/CPU_CLR.3.html) clears one
* bit in a static CPU set.
*/
#define CPU_CLR(cpu, set) CPU_CLR_S(cpu, sizeof(cpu_set_t), set)
/**
- * [CPU_CLR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * [CPU_CLR_S](https://man7.org/linux/man-pages/man3/CPU_CLR_S.3.html) clears one
* bit in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_CLR_S(cpu, setsize, set) \
@@ -278,12 +279,12 @@
} while (0)
/**
- * [CPU_ISSET](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_ISSET](https://man7.org/linux/man-pages/man3/CPU_ISSET.3.html) tests
* whether the given bit is set in a static CPU set.
*/
#define CPU_ISSET(cpu, set) CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)
/**
- * [CPU_ISSET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_ISSET_S](https://man7.org/linux/man-pages/man3/CPU_ISSET_S.3.html) tests
* whether the given bit is set in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_ISSET_S(cpu, setsize, set) \
@@ -295,58 +296,58 @@
}))
/**
- * [CPU_COUNT](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * [CPU_COUNT](https://man7.org/linux/man-pages/man3/CPU_COUNT.3.html) counts
* how many bits are set in a static CPU set.
*/
#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t), set)
/**
- * [CPU_COUNT_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * [CPU_COUNT_S](https://man7.org/linux/man-pages/man3/CPU_COUNT_S.3.html) counts
* how many bits are set in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_COUNT_S(setsize, set) __sched_cpucount((setsize), (set))
int __sched_cpucount(size_t __set_size, const cpu_set_t* _Nonnull __set);
/**
- * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_EQUAL.3.html) tests
* whether two static CPU sets have the same bits set and cleared as each other.
*/
#define CPU_EQUAL(set1, set2) CPU_EQUAL_S(sizeof(cpu_set_t), set1, set2)
/**
- * [CPU_EQUAL_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_EQUAL_S](https://man7.org/linux/man-pages/man3/CPU_EQUAL_S.3.html) tests
* whether two dynamic CPU sets allocated by `CPU_ALLOC` have the same bits
* set and cleared as each other.
*/
#define CPU_EQUAL_S(setsize, set1, set2) (__builtin_memcmp(set1, set2, setsize) == 0)
/**
- * [CPU_AND](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * [CPU_AND](https://man7.org/linux/man-pages/man3/CPU_AND.3.html) ands two
* static CPU sets.
*/
#define CPU_AND(dst, set1, set2) __CPU_OP(dst, set1, set2, &)
/**
- * [CPU_AND_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * [CPU_AND_S](https://man7.org/linux/man-pages/man3/CPU_AND_S.3.html) ands two
* dynamic CPU sets allocated by `CPU_ALLOC`.
*/
#define CPU_AND_S(setsize, dst, set1, set2) __CPU_OP_S(setsize, dst, set1, set2, &)
/**
- * [CPU_OR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * [CPU_OR](https://man7.org/linux/man-pages/man3/CPU_OR.3.html) ors two
* static CPU sets.
*/
#define CPU_OR(dst, set1, set2) __CPU_OP(dst, set1, set2, |)
/**
- * [CPU_OR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * [CPU_OR_S](https://man7.org/linux/man-pages/man3/CPU_OR_S.3.html) ors two
* dynamic CPU sets allocated by `CPU_ALLOC`.
*/
#define CPU_OR_S(setsize, dst, set1, set2) __CPU_OP_S(setsize, dst, set1, set2, |)
/**
- * [CPU_XOR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_XOR](https://man7.org/linux/man-pages/man3/CPU_XOR.3.html)
* exclusive-ors two static CPU sets.
*/
#define CPU_XOR(dst, set1, set2) __CPU_OP(dst, set1, set2, ^)
/**
- * [CPU_XOR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_XOR_S](https://man7.org/linux/man-pages/man3/CPU_XOR_S.3.html)
* exclusive-ors two dynamic CPU sets allocated by `CPU_ALLOC`.
*/
#define CPU_XOR_S(setsize, dst, set1, set2) __CPU_OP_S(setsize, dst, set1, set2, ^)
@@ -364,21 +365,21 @@
} while (0)
/**
- * [CPU_ALLOC_SIZE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_ALLOC_SIZE](https://man7.org/linux/man-pages/man3/CPU_ALLOC_SIZE.3.html)
* returns the size of a CPU set large enough for CPUs in the range 0..count-1.
*/
#define CPU_ALLOC_SIZE(count) \
__CPU_ELT((count) + (__CPU_BITS - 1)) * sizeof(__CPU_BITTYPE)
/**
- * [CPU_ALLOC](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_ALLOC](https://man7.org/linux/man-pages/man3/CPU_ALLOC.3.html)
* allocates a CPU set large enough for CPUs in the range 0..count-1.
*/
#define CPU_ALLOC(count) __sched_cpualloc((count))
cpu_set_t* _Nullable __sched_cpualloc(size_t __count);
/**
- * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_FREE.3.html)
* deallocates a CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_FREE(set) __sched_cpufree((set))
diff --git a/libc/include/search.h b/libc/include/search.h
index fe897d1..2f43d91 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -64,19 +64,19 @@
__BEGIN_DECLS
/**
- * [insque(3)](http://man7.org/linux/man-pages/man3/insque.3.html) inserts
+ * [insque(3)](https://man7.org/linux/man-pages/man3/insque.3.html) inserts
* an item in a queue (an intrusive doubly-linked list).
*/
void insque(void* _Nonnull __element, void* _Nullable __previous);
/**
- * [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
+ * [remque(3)](https://man7.org/linux/man-pages/man3/remque.3.html) removes
* an item from a queue (an intrusive doubly-linked list).
*/
void remque(void* _Nonnull __element);
/**
- * [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
+ * [hcreate(3)](https://man7.org/linux/man-pages/man3/hcreate.3.html)
* initializes the global hash table, with space for at least `__n` elements.
*
* See hcreate_r() if you need more than one hash table.
@@ -85,10 +85,12 @@
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int hcreate(size_t __n) __INTRODUCED_IN(28);
/**
- * [hdestroy(3)](http://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
+ * [hdestroy(3)](https://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
* the global hash table.
*
* See hdestroy_r() if you need more than one hash table.
@@ -98,7 +100,7 @@
void hdestroy(void) __INTRODUCED_IN(28);
/**
- * [hsearch(3)](http://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
+ * [hsearch(3)](https://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
* inserts `__entry` in the global hash table, based on `__action`.
*
* See hsearch_r() if you need more than one hash table.
@@ -109,21 +111,25 @@
* Available since API level 28.
*/
ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#if defined(__USE_BSD) || defined(__USE_GNU)
/**
- * [hcreate_r(3)](http://man7.org/linux/man-pages/man3/hcreate_r.3.html)
+ * [hcreate_r(3)](https://man7.org/linux/man-pages/man3/hcreate_r.3.html)
* initializes a hash table `__table` with space for at least `__n` elements.
*
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
/**
- * [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
+ * [hdestroy_r(3)](https://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
* the hash table `__table`.
*
* Available since API level 28.
@@ -131,7 +137,7 @@
void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
/**
- * [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
+ * [hsearch_r(3)](https://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
* inserts `__entry` in the hash table `__table`, based on `__action`.
*
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
@@ -140,11 +146,13 @@
* Available since API level 28.
*/
int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#endif
/**
- * [lfind(3)](http://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
+ * [lfind(3)](https://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
* searches the unsorted array `__array` (of `__count` items each of size `__size`)
* for `__key`, using `__comparator`.
*
@@ -155,7 +163,7 @@
void* _Nullable lfind(const void* _Nonnull __key, const void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
/**
- * [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
+ * [lsearch(3)](https://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
* searches the unsorted array `__array` (of `__count` items each of size `__size`)
* for `__key`, using `__comparator`.
*
@@ -168,7 +176,7 @@
void* _Nonnull lsearch(const void* _Nonnull __key, void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
/**
- * [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
+ * [tdelete(3)](https://man7.org/linux/man-pages/man3/tdelete.3.html) searches
* for and removes an element in the tree `*__root_ptr`. The search is performed
* using `__comparator`.
*
@@ -177,13 +185,13 @@
void* _Nullable tdelete(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
/**
- * [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
+ * [tdestroy(3)](https://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
* the hash table `__root` using `__free_fn` on each node.
*/
void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
/**
- * [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
+ * [tfind(3)](https://man7.org/linux/man-pages/man3/tfind.3.html) searches
* for an element in the tree `*__root_ptr`. The search is performed using
* `__comparator`.
*
@@ -192,7 +200,7 @@
void* _Nullable tfind(const void* _Nonnull __key, void* _Nullable const* _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
/**
- * [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches
+ * [tsearch(3)](https://man7.org/linux/man-pages/man3/tsearch.3.html) searches
* for an element in the tree `*__root_ptr`. The search is performed using
* `__comparator`.
*
@@ -203,7 +211,7 @@
void* _Nullable tsearch(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
/**
- * [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls
+ * [twalk(3)](https://man7.org/linux/man-pages/man3/twalk.3.html) calls
* `__visitor` on every node in the tree.
*/
void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int));
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 6ad9ea3..9c4702d 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -45,7 +45,11 @@
#define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int sem_clockwait(sem_t* _Nonnull __sem, clockid_t __clock, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
int sem_destroy(sem_t* _Nonnull __sem);
int sem_getvalue(sem_t* _Nonnull __sem, int* _Nonnull __value);
int sem_init(sem_t* _Nonnull __sem, int __shared, unsigned int __value);
@@ -59,7 +63,11 @@
* Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this
* function.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sem_timedwait_monotonic_np(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sem_trywait(sem_t* _Nonnull __sem);
int sem_wait(sem_t* _Nonnull __sem);
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 0aaaac5..6c141cb 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -111,7 +111,7 @@
__noreturn void longjmp(jmp_buf __env, int __value);
/**
- * [sigsetjmp(3)](http://man7.org/linux/man-pages/man3/sigsetjmp.3.html)
+ * [sigsetjmp(3)](https://man7.org/linux/man-pages/man3/sigsetjmp.3.html)
* sets the target of a future siglongjmp() call, saving or not saving the
* current signal mask based on the second argument.
*
@@ -121,7 +121,7 @@
int sigsetjmp(sigjmp_buf __env, int __save_signal_mask) __returns_twice;
/**
- * [siglongjmp(3)](http://man7.org/linux/man-pages/man3/siglongjmp.3.html)
+ * [siglongjmp(3)](https://man7.org/linux/man-pages/man3/siglongjmp.3.html)
* transfers control back to the site of the sigsetjmp() call that initialized
* the given jump buffer, returning the given value.
*
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 9d47bcc..38dcbde 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -60,31 +60,73 @@
#define si_timerid si_tid /* glibc compatibility. */
int sigaction(int __signal, const struct sigaction* _Nullable __new_action, struct sigaction* _Nullable __old_action);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigaction64(int __signal, const struct sigaction64* _Nullable __new_action, struct sigaction64* _Nullable __old_action) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int siginterrupt(int __signal, int __flag);
sighandler_t _Nonnull signal(int __signal, sighandler_t _Nullable __handler);
int sigaddset(sigset_t* _Nonnull __set, int __signal);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigaddset64(sigset64_t* _Nonnull __set, int __signal) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sigdelset(sigset_t* _Nonnull __set, int __signal);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigdelset64(sigset64_t* _Nonnull __set, int __signal) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sigemptyset(sigset_t* _Nonnull __set);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigemptyset64(sigset64_t* _Nonnull __set) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sigfillset(sigset_t* _Nonnull __set);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigfillset64(sigset64_t* _Nonnull __set) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sigismember(const sigset_t* _Nonnull __set, int __signal);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigismember64(const sigset64_t* _Nonnull __set, int __signal) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int sigpending(sigset_t* _Nonnull __set);
-int sigpending64(sigset64_t* _Nonnull __set) __INTRODUCED_IN(28);
-int sigprocmask(int __how, const sigset_t* _Nullable __new_set, sigset_t* _Nullable __old_set);
-int sigprocmask64(int __how, const sigset64_t* _Nullable __new_set, sigset64_t* _Nullable __old_set) __INTRODUCED_IN(28);
-int sigsuspend(const sigset_t* _Nonnull __mask);
-int sigsuspend64(const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
-int sigwait(const sigset_t* _Nonnull __set, int* _Nonnull __signal);
-int sigwait64(const sigset64_t* _Nonnull __set, int* _Nonnull __signal) __INTRODUCED_IN(28);
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int sigpending64(sigset64_t* _Nonnull __set) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+int sigprocmask(int __how, const sigset_t* _Nullable __new_set, sigset_t* _Nullable __old_set);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int sigprocmask64(int __how, const sigset64_t* _Nullable __new_set, sigset64_t* _Nullable __old_set) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+int sigsuspend(const sigset_t* _Nonnull __mask);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int sigsuspend64(const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+int sigwait(const sigset_t* _Nonnull __set, int* _Nonnull __signal);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int sigwait64(const sigset64_t* _Nonnull __set, int* _Nonnull __signal) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int sighold(int __signal)
__attribute__((__deprecated__("use sigprocmask() or pthread_sigmask() instead")))
__INTRODUCED_IN(26);
@@ -97,6 +139,8 @@
__INTRODUCED_IN(26);
sighandler_t _Nonnull sigset(int __signal, sighandler_t _Nullable __handler)
__attribute__((__deprecated__("use sigaction() instead"))) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
int raise(int __signal);
int kill(pid_t __pid, int __signal);
@@ -110,17 +154,73 @@
int pthread_kill(pthread_t __pthread, int __signal);
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
int pthread_sigqueue(pthread_t __pthread, int __signal, const union sigval __value) __INTRODUCED_IN(29);
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
#endif
int pthread_sigmask(int __how, const sigset_t* _Nullable __new_set, sigset_t* _Nullable __old_set);
-int pthread_sigmask64(int __how, const sigset64_t* _Nullable __new_set, sigset64_t* _Nullable __old_set) __INTRODUCED_IN(28);
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int pthread_sigmask64(int __how, const sigset64_t* _Nullable __new_set, sigset64_t* _Nullable __old_set) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int sigqueue(pid_t __pid, int __signal, const union sigval __value) __INTRODUCED_IN(23);
int sigtimedwait(const sigset_t* _Nonnull __set, siginfo_t* _Nullable __info, const struct timespec* _Nullable __timeout) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigtimedwait64(const sigset64_t* _Nonnull __set, siginfo_t* _Nullable __info, const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int sigwaitinfo(const sigset_t* _Nonnull __set, siginfo_t* _Nullable __info) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int sigwaitinfo64(const sigset64_t* _Nonnull __set, siginfo_t* _Nullable __info) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+/**
+ * Buffer size suitable for any call to sig2str().
+ */
+#define SIG2STR_MAX 32
+
+/**
+ * [sig2str(3)](https://man7.org/linux/man-pages/man3/sig2str.3.html)
+ * converts the integer corresponding to SIGSEGV (say) into a string
+ * like "SEGV" (not including the "SIG" used in the constants).
+ * SIG2STR_MAX is a safe size to use for the buffer.
+ *
+ * Returns 0 on success, and returns -1 _without_ setting errno otherwise.
+ *
+ * Available since API level 36.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(36)
+int sig2str(int __signal, char* _Nonnull __buf) __INTRODUCED_IN(36);
+
+/**
+ * [str2sig(3)](https://man7.org/linux/man-pages/man3/str2sig.3.html)
+ * converts a string like "SEGV" (not including the "SIG" used in the constants)
+ * into the integer corresponding to SIGSEGV.
+ *
+ * Returns 0 on success, and returns -1 _without_ setting errno otherwise.
+ *
+ * Available since API level 36.
+ */
+int str2sig(const char* _Nonnull __name, int* _Nonnull __signal) __INTRODUCED_IN(36);
+#endif /* __BIONIC_AVAILABILITY_GUARD(36) */
+
__END_DECLS
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index 3ce402f..b105754 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -46,14 +46,19 @@
#define POSIX_SPAWN_USEVFORK 64
#define POSIX_SPAWN_SETSID 128
#endif
-// mark all fds (except stdin/out/err) as close-on-exec prior to executing registered file actions
+/**
+ * Used with posix_spawnattr_setflags() to mark all fds except
+ * stdin/stdout/stderr as O_CLOEXEC prior to executing registered file actions.
+ */
#define POSIX_SPAWN_CLOEXEC_DEFAULT 256
typedef struct __posix_spawnattr* posix_spawnattr_t;
typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
-int posix_spawn(pid_t* _Nullable __pid, const char* _Nonnull __path, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
-int posix_spawnp(pid_t* _Nullable __pid, const char* _Nonnull __file, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+int posix_spawn(pid_t* _Nullable __pid, const char* _Nonnull __path, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nullable __argv[_Nullable], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
+int posix_spawnp(pid_t* _Nullable __pid, const char* _Nonnull __file, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nullable __argv[_Nullable], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
int posix_spawnattr_init(posix_spawnattr_t _Nullable * _Nonnull __attr) __INTRODUCED_IN(28);
int posix_spawnattr_destroy(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28);
@@ -86,9 +91,15 @@
int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, const char* _Nonnull __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(28);
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(34)
int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, const char* _Nonnull __path) __INTRODUCED_IN(34);
int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(34);
+#endif /* __BIONIC_AVAILABILITY_GUARD(34) */
+
__END_DECLS
diff --git a/libc/include/stdint.h b/libc/include/stdint.h
index 322a81c..772fe8b 100644
--- a/libc/include/stdint.h
+++ b/libc/include/stdint.h
@@ -29,9 +29,10 @@
#ifndef _STDINT_H
#define _STDINT_H
+#include <sys/cdefs.h>
+
#include <bits/wchar_limits.h>
#include <stddef.h>
-#include <sys/cdefs.h>
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 279c658..2c2dc01 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -105,10 +105,10 @@
void clearerr(FILE* _Nonnull __fp);
int fclose(FILE* _Nonnull __fp);
-__wur int feof(FILE* _Nonnull __fp);
-__wur int ferror(FILE* _Nonnull __fp);
+__nodiscard int feof(FILE* _Nonnull __fp);
+__nodiscard int ferror(FILE* _Nonnull __fp);
int fflush(FILE* _Nullable __fp);
-__wur int fgetc(FILE* _Nonnull __fp);
+__nodiscard int fgetc(FILE* _Nonnull __fp);
char* _Nullable fgets(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
int fprintf(FILE* _Nonnull __fp , const char* _Nonnull __fmt, ...) __printflike(2, 3);
int fputc(int __ch, FILE* _Nonnull __fp);
@@ -116,8 +116,8 @@
size_t fread(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
int fscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
size_t fwrite(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
-__wur int getc(FILE* _Nonnull __fp);
-__wur int getchar(void);
+__nodiscard int getc(FILE* _Nonnull __fp);
+__nodiscard int getchar(void);
ssize_t getdelim(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, int __delimiter, FILE* _Nonnull __fp);
ssize_t getline(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, FILE* _Nonnull __fp);
@@ -154,7 +154,7 @@
__warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
/**
- * [rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html) changes
+ * [rename(2)](https://man7.org/linux/man-pages/man2/rename.2.html) changes
* the name or location of a file.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -162,7 +162,7 @@
int rename(const char* _Nonnull __old_path, const char* _Nonnull __new_path);
/**
- * [renameat(2)](http://man7.org/linux/man-pages/man2/renameat.2.html) changes
+ * [renameat(2)](https://man7.org/linux/man-pages/man2/renameat.2.html) changes
* the name or location of a file, interpreting relative paths using an fd.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -172,84 +172,116 @@
#if defined(__USE_GNU)
/**
- * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html)
+ * Flag for [renameat2(2)](https://man7.org/linux/man-pages/man2/renameat2.2.html)
* to fail if the new path already exists.
*/
#define RENAME_NOREPLACE (1<<0)
/**
- * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html)
+ * Flag for [renameat2(2)](https://man7.org/linux/man-pages/man2/renameat2.2.html)
* to atomically exchange the two paths.
*/
#define RENAME_EXCHANGE (1<<1)
/**
- * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html)
+ * Flag for [renameat2(2)](https://man7.org/linux/man-pages/man2/renameat2.2.html)
* to create a union/overlay filesystem object.
*/
#define RENAME_WHITEOUT (1<<2)
/**
- * [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) changes
+ * [renameat2(2)](https://man7.org/linux/man-pages/man2/renameat2.2.html) changes
* the name or location of a file, interpreting relative paths using an fd,
* with optional `RENAME_` flags.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int renameat2(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path, unsigned __flags) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
#endif
int fseek(FILE* _Nonnull __fp, long __offset, int __whence);
-__wur long ftell(FILE* _Nonnull __fp);
+__nodiscard long ftell(FILE* _Nonnull __fp);
/* See https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md */
#if defined(__USE_FILE_OFFSET64)
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
-__wur off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
+__nodiscard off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
# if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-__wur FILE* _Nullable funopen(const void* _Nullable __cookie,
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
+__nodiscard FILE* _Nullable funopen(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
int (* _Nullable __close_fn)(void* _Nonnull)) __RENAME(funopen64) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
# endif
#else
int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos);
int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos);
int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence);
-__wur off_t ftello(FILE* _Nonnull __fp);
+__nodiscard off_t ftello(FILE* _Nonnull __fp);
# if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-__wur FILE* _Nullable funopen(const void* _Nullable __cookie,
+__nodiscard FILE* _Nullable funopen(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
int (* _Nullable __close_fn)(void* _Nonnull));
# endif
#endif
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int fgetpos64(FILE* _Nonnull __fp, fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
int fsetpos64(FILE* _Nonnull __fp, const fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
int fseeko64(FILE* _Nonnull __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
-__wur off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+__nodiscard off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-__wur FILE* _Nullable funopen64(const void* _Nullable __cookie,
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
+__nodiscard FILE* _Nullable funopen64(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos64_t (* _Nullable __seek_fn)(void* _Nonnull, fpos64_t, int),
int (* _Nullable __close_fn)(void* _Nonnull)) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#endif
-__wur FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
-__wur FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
+__nodiscard FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
+__nodiscard FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
FILE* _Nullable freopen(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
FILE* _Nullable freopen64(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp) __INTRODUCED_IN(24);
-__wur FILE* _Nullable tmpfile(void);
-__wur FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
+__nodiscard FILE* _Nullable tmpfile(void);
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
+__nodiscard FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
int snprintf(char* __BIONIC_COMPLICATED_NULLNESS __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
int vfscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
@@ -258,22 +290,30 @@
int vsscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
#define L_ctermid 1024 /* size for ctermid() */
-char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26);
-__wur FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
-__wur int fileno(FILE* _Nonnull __fp);
+#if __BIONIC_AVAILABILITY_GUARD(26)
+char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
+
+__nodiscard FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
+__nodiscard int fileno(FILE* _Nonnull __fp);
int pclose(FILE* _Nonnull __fp);
-__wur FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
+__nodiscard FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
void flockfile(FILE* _Nonnull __fp);
int ftrylockfile(FILE* _Nonnull __fp);
void funlockfile(FILE* _Nonnull __fp);
-__wur int getc_unlocked(FILE* _Nonnull __fp);
-__wur int getchar_unlocked(void);
+__nodiscard int getc_unlocked(FILE* _Nonnull __fp);
+__nodiscard int getchar_unlocked(void);
int putc_unlocked(int __ch, FILE* _Nonnull __fp);
int putchar_unlocked(int __ch);
-__wur FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
-__wur FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
+__nodiscard FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
+__nodiscard FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
int asprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, ...) __printflike(2, 3);
@@ -282,25 +322,41 @@
void setbuffer(FILE* _Nonnull __fp, char* _Nullable __buf, int __size);
int setlinebuf(FILE* _Nonnull __fp);
int vasprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void clearerr_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-__wur int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-__wur int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-__wur int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+__nodiscard int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+__nodiscard int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
+__nodiscard int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif
#if defined(__USE_BSD)
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int fflush_unlocked(FILE* _Nullable __fp) __INTRODUCED_IN(28);
-__wur int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+__nodiscard int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
int fputc_unlocked(int __ch, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
size_t fread_unlocked(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
size_t fwrite_unlocked(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#endif
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int fputs_unlocked(const char* _Nonnull __s, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
char* _Nullable fgets_unlocked(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#endif
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index 8b106a6..9ff07da 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -39,68 +39,90 @@
__BEGIN_DECLS
/**
- * [__fbufsize(3)](http://man7.org/linux/man-pages/man3/__fbufsize.3.html) returns the size of
+ * [__fbufsize(3)](https://man7.org/linux/man-pages/man3/__fbufsize.3.html) returns the size of
* the stream's buffer.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
size_t __fbufsize(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
/**
- * [__freadable(3)](http://man7.org/linux/man-pages/man3/__freadable.3.html) returns non-zero if
+ * [__freadable(3)](https://man7.org/linux/man-pages/man3/__freadable.3.html) returns non-zero if
* the stream allows reading, 0 otherwise.
*
* Available since API level 23.
*/
int __freadable(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [__freading(3)](http://man7.org/linux/man-pages/man3/__freading.3.html) returns non-zero if
+ * [__freading(3)](https://man7.org/linux/man-pages/man3/__freading.3.html) returns non-zero if
* the stream's last operation was a read, 0 otherwise.
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int __freading(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
/**
- * [__fwritable(3)](http://man7.org/linux/man-pages/man3/__fwritable.3.html) returns non-zero if
+ * [__fwritable(3)](https://man7.org/linux/man-pages/man3/__fwritable.3.html) returns non-zero if
* the stream allows writing, 0 otherwise.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int __fwritable(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [__fwriting(3)](http://man7.org/linux/man-pages/man3/__fwriting.3.html) returns non-zero if
+ * [__fwriting(3)](https://man7.org/linux/man-pages/man3/__fwriting.3.html) returns non-zero if
* the stream's last operation was a write, 0 otherwise.
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int __fwriting(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
/**
- * [__flbf(3)](http://man7.org/linux/man-pages/man3/__flbf.3.html) returns non-zero if
+ * [__flbf(3)](https://man7.org/linux/man-pages/man3/__flbf.3.html) returns non-zero if
* the stream is line-buffered, 0 otherwise.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int __flbf(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [__fpurge(3)](http://man7.org/linux/man-pages/man3/__fpurge.3.html) discards the contents of
+ * [__fpurge(3)](https://man7.org/linux/man-pages/man3/__fpurge.3.html) discards the contents of
* the stream's buffer.
- *
- * Available since API level 23.
*/
-void __fpurge(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+void __fpurge(FILE* _Nonnull __fp) __RENAME(fpurge);
/**
- * [__fpending(3)](http://man7.org/linux/man-pages/man3/__fpending.3.html) returns the number of
+ * [__fpending(3)](https://man7.org/linux/man-pages/man3/__fpending.3.html) returns the number of
* bytes in the output buffer. See __freadahead() for the input buffer.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
size_t __fpending(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
* __freadahead(3) returns the number of bytes in the input buffer.
@@ -108,15 +130,23 @@
*
* Available since API level 34.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(34)
size_t __freadahead(FILE* _Nonnull __fp) __INTRODUCED_IN(34);
+#endif /* __BIONIC_AVAILABILITY_GUARD(34) */
+
/**
- * [_flushlbf(3)](http://man7.org/linux/man-pages/man3/_flushlbf.3.html) flushes all
+ * [_flushlbf(3)](https://man7.org/linux/man-pages/man3/_flushlbf.3.html) flushes all
* line-buffered streams.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void _flushlbf(void) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
* `__fseterr` sets the
@@ -124,7 +154,11 @@
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
void __fseterr(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
/** __fsetlocking() constant to query locking type. */
#define FSETLOCKING_QUERY 0
@@ -134,13 +168,17 @@
#define FSETLOCKING_BYCALLER 2
/**
- * [__fsetlocking(3)](http://man7.org/linux/man-pages/man3/__fsetlocking.3.html) sets the
+ * [__fsetlocking(3)](https://man7.org/linux/man-pages/man3/__fsetlocking.3.html) sets the
* stream's locking mode to one of the `FSETLOCKING_` types.
*
* Returns the current locking style, `FSETLOCKING_INTERNAL` or `FSETLOCKING_BYCALLER`.
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int __fsetlocking(FILE* _Nonnull __fp, int __type) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index d0efc4c..7081d7c 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -29,11 +29,12 @@
#ifndef _STDLIB_H
#define _STDLIB_H
+#include <sys/cdefs.h>
+
#include <alloca.h>
#include <bits/wait.h>
#include <malloc.h>
#include <stddef.h>
-#include <sys/cdefs.h>
#include <xlocale.h>
__BEGIN_DECLS
@@ -59,37 +60,44 @@
char* _Nullable mkdtemp(char* _Nonnull __template);
char* _Nullable mktemp(char* _Nonnull __template) __attribute__((__deprecated__("mktemp is unsafe, use mkstemp or tmpfile instead")));
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int mkostemp64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
int mkostemp(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
int mkostemps64(char* _Nonnull __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
int mkostemps(char* _Nonnull __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
int mkstemp64(char* _Nonnull __template);
int mkstemp(char* _Nonnull __template);
-int mkstemps64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
-int mkstemps(char* _Nonnull __template, int __flags);
-long strtol(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
-long long strtoll(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
-unsigned long strtoul(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
-unsigned long long strtoull(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+#if __BIONIC_AVAILABILITY_GUARD(23)
+int mkstemps64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+int mkstemps(char* _Nonnull __template, int __flags);
int posix_memalign(void* _Nullable * _Nullable __memptr, size_t __alignment, size_t __size);
-void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
+/**
+ * [aligned_alloc(3)](https://man7.org/linux/man-pages/man3/aligned_alloc.3.html)
+ * allocates the given number of bytes with the given alignment.
+ *
+ * Returns a pointer to the allocated memory on success and returns a null
+ * pointer and sets `errno` on failure.
+ *
+ * Available since API level 28.
+ */
-double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
+#if __BIONIC_AVAILABILITY_GUARD(28)
+__nodiscard void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
-unsigned long strtoul_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(26);
-int atoi(const char* _Nonnull __s) __attribute_pure__;
-long atol(const char* _Nonnull __s) __attribute_pure__;
-long long atoll(const char* _Nonnull __s) __attribute_pure__;
-
-__wur char* _Nullable realpath(const char* _Nonnull __path, char* _Nullable __resolved);
+__nodiscard char* _Nullable realpath(const char* _Nonnull __path, char* _Nullable __resolved);
/**
- * [system(3)](http://man7.org/linux/man-pages/man3/system.3.html) executes
+ * [system(3)](https://man7.org/linux/man-pages/man3/system.3.html) executes
* the given command in a new shell process.
*
* On Android, the special case of `system(NULL)` always returns 1,
@@ -100,21 +108,38 @@
* or permanently (for lack of permission, say).
*
* Returns -1 and sets errno if process creation fails; returns a
- * [waitpid(2)](http://man7.org/linux/man-pages/man2/waitpid.2.html)
+ * [waitpid(2)](https://man7.org/linux/man-pages/man2/waitpid.2.html)
* status otherwise.
*/
int system(const char* _Nonnull __command);
/**
- * [bsearch(3)](http://man7.org/linux/man-pages/man3/bsearch.3.html) searches
+ * [bsearch(3)](https://man7.org/linux/man-pages/man3/bsearch.3.html) searches
* a sorted array.
*
* Returns a pointer to a matching item on success,
* or NULL if no matching item is found.
*/
-__wur void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
+__nodiscard void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
-void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs));
+/**
+ * [qsort(3)](https://man7.org/linux/man-pages/man3/qsort.3.html) sorts an array
+ * of n elements each of the given size, using the given comparator.
+ */
+void qsort(void* _Nullable __array, size_t __n, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs));
+
+/**
+ * [qsort_r(3)](https://man7.org/linux/man-pages/man3/qsort_r.3.html) sorts an
+ * array of n elements each of the given size, using the given comparator,
+ * and passing the given context argument to the comparator.
+ *
+ * Available since API level 36.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(36)
+void qsort_r(void* _Nullable __array, size_t __n, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs, void* _Nullable __context), void* _Nullable __context) __INTRODUCED_IN(36);
+#endif /* __BIONIC_AVAILABILITY_GUARD(36) */
+
uint32_t arc4random(void);
uint32_t arc4random_uniform(uint32_t __upper_bound);
@@ -127,7 +152,11 @@
double drand48(void);
double erand48(unsigned short __xsubi[_Nonnull 3]);
long jrand48(unsigned short __xsubi[_Nonnull 3]);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void lcong48(unsigned short __param[_Nonnull 7]) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
long lrand48(void);
long mrand48(void);
long nrand48(unsigned short __xsubi[_Nonnull 3]);
@@ -143,7 +172,11 @@
int ptsname_r(int __fd, char* _Nonnull __buf, size_t __n);
int unlockpt(int __fd);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int getsubopt(char* _Nonnull * _Nonnull __option, char* _Nonnull const* _Nonnull __tokens, char* _Nullable * _Nonnull __value_ptr) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
typedef struct {
int quot;
@@ -167,19 +200,27 @@
lldiv_t lldiv(long long __numerator, long long __denominator) __attribute_const__;
/**
- * [getloadavg(3)](http://man7.org/linux/man-pages/man3/getloadavg.3.html) queries the
+ * [getloadavg(3)](https://man7.org/linux/man-pages/man3/getloadavg.3.html) queries the
* number of runnable processes averaged over time. The Linux kernel supports averages
* over the last 1, 5, and 15 minutes.
*
* Returns the number of samples written to `__averages` (at most 3), and returns -1 on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
int getloadavg(double __averages[_Nonnull], int __n) __INTRODUCED_IN(29);
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
/* BSD compatibility. */
const char* _Nullable getprogname(void);
void setprogname(const char* _Nonnull __name);
-int mblen(const char* _Nullable __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
+int mblen(const char* _Nullable __s, size_t __n) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
size_t mbstowcs(wchar_t* _Nullable __dst, const char* _Nullable __src, size_t __n);
int mbtowc(wchar_t* _Nullable __wc_ptr, const char* _Nullable __s, size_t __n);
int wctomb(char* _Nullable __dst, wchar_t __wc);
@@ -197,22 +238,134 @@
long labs(long __x) __attribute_const__;
long long llabs(long long __x) __attribute_const__;
-float strtof(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-double atof(const char* _Nonnull __s) __attribute_pure__;
int rand(void);
void srand(unsigned int __seed);
long random(void);
void srandom(unsigned int __seed);
int grantpt(int __fd);
+/**
+ * [atof(3)](https://man7.org/linux/man-pages/man3/atof.3.html) converts a
+ * string to a double.
+ *
+ * Returns the double; use strtof() or strtod() if you need to detect errors.
+ */
+double atof(const char* _Nonnull __s) __attribute_pure__;
+
+/**
+ * [atoi(3)](https://man7.org/linux/man-pages/man3/atoi.3.html) converts a
+ * string to an int.
+ *
+ * Returns the int or 0 on error; use strtol() if you need to detect errors.
+ */
+int atoi(const char* _Nonnull __s) __attribute_pure__;
+
+/**
+ * [atol(3)](https://man7.org/linux/man-pages/man3/atol.3.html) converts a
+ * string to a long.
+ *
+ * Returns the long or 0 on error; use strtol() if you need to detect errors.
+ */
+long atol(const char* _Nonnull __s) __attribute_pure__;
+
+/**
+ * [atoll(3)](https://man7.org/linux/man-pages/man3/atoll.3.html) converts a
+ * string to a long long.
+ *
+ * Returns the long long or 0 on error; use strtol() if you need to detect errors.
+ */
+long long atoll(const char* _Nonnull __s) __attribute_pure__;
+
+/**
+ * [strtol(3)](https://man7.org/linux/man-pages/man3/strtol.3.html) converts a
+ * string to a long.
+ *
+ * Returns the long.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+long strtol(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+
+/** Equivalent to strtol() on Android. */
+long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int, locale_t _Nonnull __l) __RENAME(strtol);
+
+/**
+ * [strtoll(3)](https://man7.org/linux/man-pages/man3/strtoll.3.html) converts a
+ * string to a long long.
+ *
+ * Returns the long long.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+long long strtoll(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+
+/** Equivalent to strtoll() on Android. */
long long strtoll_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l);
+
+/**
+ * [strtoul(3)](https://man7.org/linux/man-pages/man3/strtoul.3.html) converts a
+ * string to an unsigned long.
+ *
+ * Returns the unsigned long.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+unsigned long strtoul(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+
+/** Equivalent to strtoul() on Android. */
+unsigned long strtoul_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __RENAME(strtoul);
+
+/**
+ * [strtoull(3)](https://man7.org/linux/man-pages/man3/strtoull.3.html) converts a
+ * string to an unsigned long long.
+ *
+ * Returns the unsigned long long.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+unsigned long long strtoull(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base);
+
+/** Equivalent to strtoull() on Android. */
unsigned long long strtoull_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l);
+
+/**
+ * [strtof(3)](https://man7.org/linux/man-pages/man3/strtof.3.html) converts a
+ * string to a float.
+ *
+ * Returns the float.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+float strtof(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
+
+/**
+ * [strtod(3)](https://man7.org/linux/man-pages/man3/strtod.3.html) converts a
+ * string to a double.
+ *
+ * Returns the double.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
+
+/**
+ * [strtold(3)](https://man7.org/linux/man-pages/man3/strtold.3.html) converts a
+ * string to a long double.
+ *
+ * Returns the long double.
+ * `__end_ptr` is set to the last character in `__s` that was converted.
+ * errno is set to ERANGE if the result overflowed or underflowed.
+ */
+long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
+
+/** Equivalent to strtold() on Android. */
long double strtold_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l);
#if __ANDROID_API__ >= 26
+/** Equivalent to strtod() on Android. */
double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(26);
+/** Equivalent to strtof() on Android. */
float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(26);
-long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int, locale_t _Nonnull __l) __INTRODUCED_IN(26);
#else
// Implemented as static inlines before 26.
#endif
diff --git a/libc/include/string.h b/libc/include/string.h
index 47bdd72..a0a7cc4 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -52,12 +52,16 @@
int memcmp(const void* _Nonnull __lhs, const void* _Nonnull __rhs, size_t __n) __attribute_pure__;
void* _Nonnull memcpy(void* _Nonnull, const void* _Nonnull, size_t);
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
void* _Nonnull mempcpy(void* _Nonnull __dst, const void* _Nonnull __src, size_t __n) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#endif
void* _Nonnull memmove(void* _Nonnull __dst, const void* _Nonnull __src, size_t __n);
/**
- * [memset(3)](http://man7.org/linux/man-pages/man3/memset.3.html) writes the
+ * [memset(3)](https://man7.org/linux/man-pages/man3/memset.3.html) writes the
* bottom 8 bits of the given int to the next `n` bytes of `dst`.
*
* Returns `dst`.
@@ -65,13 +69,17 @@
void* _Nonnull memset(void* _Nonnull __dst, int __ch, size_t __n);
/**
- * [memset_explicit(3)](http://man7.org/linux/man-pages/man3/memset_explicit.3.html)
+ * [memset_explicit(3)](https://man7.org/linux/man-pages/man3/memset_explicit.3.html)
* writes the bottom 8 bits of the given int to the next `n` bytes of `dst`,
* but won't be optimized out by the compiler.
*
* Returns `dst`.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(34)
void* _Nonnull memset_explicit(void* _Nonnull __dst, int __ch, size_t __n) __INTRODUCED_IN(34);
+#endif /* __BIONIC_AVAILABILITY_GUARD(34) */
+
void* _Nullable memmem(const void* _Nonnull __haystack, size_t __haystack_size, const void* _Nonnull __needle, size_t __needle_size) __attribute_pure__;
@@ -79,10 +87,18 @@
char* _Nullable __strchr_chk(const char* _Nonnull __s, int __ch, size_t __n);
#if defined(__USE_GNU)
#if defined(__cplusplus)
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
extern "C++" char* _Nonnull strchrnul(char* _Nonnull __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
extern "C++" const char* _Nonnull strchrnul(const char* _Nonnull __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#else
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
char* _Nonnull strchrnul(const char* _Nonnull __s, int __ch) __attribute_pure__ __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
#endif
#endif
@@ -108,8 +124,35 @@
char* _Nullable strtok(char* _Nullable __s, const char* _Nonnull __delimiter);
char* _Nullable strtok_r(char* _Nullable __s, const char* _Nonnull __delimiter, char* _Nonnull * _Nonnull __pos_ptr);
+/**
+ * [strerror(3)](https://man7.org/linux/man-pages/man3/strerror.3.html)
+ * returns a string describing the given errno value.
+ * `strerror(EINVAL)` would return "Invalid argument", for example.
+ *
+ * On Android, unknown errno values return a string such as "Unknown error 666".
+ * These unknown errno value strings live in thread-local storage, and are valid
+ * until the next call of strerror() on the same thread.
+ *
+ * Returns a pointer to a string.
+ */
char* _Nonnull strerror(int __errno_value);
-char* _Nonnull strerror_l(int __errno_value, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+
+/**
+ * Equivalent to strerror() on Android where only C/POSIX locales are available.
+ */
+char* _Nonnull strerror_l(int __errno_value, locale_t _Nonnull __l) __RENAME(strerror);
+
+/**
+ * [strerror_r(3)](https://man7.org/linux/man-pages/man3/strerror_r.3.html)
+ * writes a string describing the given errno value into the given buffer.
+ *
+ * There are two variants of this function, POSIX and GNU.
+ * The GNU variant returns a pointer to the buffer.
+ * The POSIX variant returns 0 on success or an errno value on failure.
+ *
+ * The GNU variant is available since API level 23 if `_GNU_SOURCE` is defined.
+ * The POSIX variant is available otherwise.
+ */
#if defined(__USE_GNU) && __ANDROID_API__ >= 23
char* _Nonnull strerror_r(int __errno_value, char* _Nullable __buf, size_t __n) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
#else /* POSIX */
@@ -117,7 +160,7 @@
#endif
/**
- * [strerrorname_np(3)](http://man7.org/linux/man-pages/man3/strerrordesc_np.3.html)
+ * [strerrorname_np(3)](https://man7.org/linux/man-pages/man3/strerrorname_np.3.html)
* returns the name of the errno constant corresponding to its argument.
* `strerrorname_np(38)` would return "ENOSYS", because `ENOSYS` is errno 38. This
* is mostly useful for error reporting in cases where a string like "ENOSYS" is
@@ -129,11 +172,15 @@
* Available since API level 35.
*/
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
const char* _Nullable strerrorname_np(int __errno_value) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
#endif
/**
- * [strerrordesc_np(3)](http://man7.org/linux/man-pages/man3/strerrordesc_np.3.html)
+ * [strerrordesc_np(3)](https://man7.org/linux/man-pages/man3/strerrordesc_np.3.html)
* is like strerror() but without localization. Since Android's strerror()
* does not localize, this is the same as strerror() on Android.
*
@@ -172,10 +219,18 @@
* It doesn't modify its argument, and in C++ it's const-correct.
*/
#if defined(__cplusplus)
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
extern "C++" char* _Nonnull basename(char* _Nullable __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
extern "C++" const char* _Nonnull basename(const char* _Nonnull __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#else
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
char* _Nonnull basename(const char* _Nonnull __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#endif
#endif
@@ -185,11 +240,10 @@
/* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
#if defined(__cplusplus)
-/*
- * Use two enable_ifs so these overloads don't conflict with + are preferred over libcxx's. This can
- * be reduced to 1 after libcxx recognizes that we have const-correct overloads.
- */
-#define __prefer_this_overload __enable_if(true, "preferred overload") __enable_if(true, "")
+/* libcxx tries to provide these. Suppress that, since libcxx's impl doesn't respect FORTIFY. */
+#define __CORRECT_ISO_CPP_STRING_H_PROTO
+/* Used to make these preferable over regular <string.h> signatures for overload resolution. */
+#define __prefer_this_overload __enable_if(true, "")
extern "C++" {
inline __always_inline
void* _Nullable __bionic_memchr(const void* _Nonnull const s __pass_object_size, int c, size_t n) {
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 4b8cc08..7543edc 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -43,8 +43,9 @@
* @brief Extra string functions.
*/
-#include <sys/types.h>
#include <sys/cdefs.h>
+
+#include <sys/types.h>
#include <xlocale.h>
#include <bits/strcasecmp.h>
@@ -72,7 +73,7 @@
}
/**
- * [ffs(3)](http://man7.org/linux/man-pages/man3/ffs.3.html) finds the
+ * [ffs(3)](https://man7.org/linux/man-pages/man3/ffs.3.html) finds the
* first set bit in `__n`.
*
* Returns 0 if no bit is set, or the index of the lowest set bit (counting
@@ -83,7 +84,7 @@
}
/**
- * [ffsl(3)](http://man7.org/linux/man-pages/man3/ffsl.3.html) finds the
+ * [ffsl(3)](https://man7.org/linux/man-pages/man3/ffsl.3.html) finds the
* first set bit in `__n`.
*
* Returns 0 if no bit is set, or the index of the lowest set bit (counting
@@ -94,7 +95,7 @@
}
/**
- * [ffsll(3)](http://man7.org/linux/man-pages/man3/ffsll.3.html) finds the
+ * [ffsll(3)](https://man7.org/linux/man-pages/man3/ffsll.3.html) finds the
* first set bit in `__n`.
*
* Returns 0 if no bit is set, or the index of the lowest set bit (counting
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 078e857..12cafec 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -1,150 +1 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#ifndef _INCLUDE_SYS__SYSTEM_PROPERTIES_H
-#define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
-
-#include <sys/cdefs.h>
-#include <stdint.h>
-
-#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#error you should #include <sys/system_properties.h> instead
-#endif
-
#include <sys/system_properties.h>
-
-__BEGIN_DECLS
-
-#define PROP_SERVICE_NAME "property_service"
-#define PROP_SERVICE_FOR_SYSTEM_NAME "property_service_for_system"
-#define PROP_DIRNAME "/dev/__properties__"
-
-#define PROP_MSG_SETPROP 1
-#define PROP_MSG_SETPROP2 0x00020001
-
-#define PROP_SUCCESS 0
-#define PROP_ERROR_READ_CMD 0x0004
-#define PROP_ERROR_READ_DATA 0x0008
-#define PROP_ERROR_READ_ONLY_PROPERTY 0x000B
-#define PROP_ERROR_INVALID_NAME 0x0010
-#define PROP_ERROR_INVALID_VALUE 0x0014
-#define PROP_ERROR_PERMISSION_DENIED 0x0018
-#define PROP_ERROR_INVALID_CMD 0x001B
-#define PROP_ERROR_HANDLE_CONTROL_MESSAGE 0x0020
-#define PROP_ERROR_SET_FAILED 0x0024
-
-/*
-** This was previously for testing, but now that SystemProperties is its own testable class,
-** there is never a reason to call this function and its implementation simply returns -1.
-*/
-int __system_property_set_filename(const char* __unused __filename);
-
-/*
-** Initialize the area to be used to store properties. Can
-** only be done by a single process that has write access to
-** the property area.
-*/
-int __system_property_area_init(void);
-
-/* Read the global serial number of the system properties
-**
-** Called to predict if a series of cached __system_property_find
-** objects will have seen __system_property_serial values change.
-** But also aids the converse, as changes in the global serial can
-** also be used to predict if a failed __system_property_find
-** could in-turn now find a new object; thus preventing the
-** cycles of effort to poll __system_property_find.
-**
-** Typically called at beginning of a cache cycle to signal if _any_ possible
-** changes have occurred since last. If there is, one may check each individual
-** __system_property_serial to confirm dirty, or __system_property_find
-** to check if the property now exists. If a call to __system_property_add
-** or __system_property_update has completed between two calls to
-** __system_property_area_serial then the second call will return a larger
-** value than the first call. Beware of race conditions as changes to the
-** properties are not atomic, the main value of this call is to determine
-** whether the expensive __system_property_find is worth retrying to see if
-** a property now exists.
-**
-** Returns the serial number on success, -1 on error.
-*/
-uint32_t __system_property_area_serial(void);
-
-/* Add a new system property. Can only be done by a single
-** process that has write access to the property area, and
-** that process must handle sequencing to ensure the property
-** does not already exist and that only one property is added
-** or updated at a time.
-**
-** Returns 0 on success, -1 if the property area is full.
-*/
-int __system_property_add(const char* _Nonnull __name, unsigned int __name_length, const char* _Nonnull __value, unsigned int __value_length);
-
-/* Update the value of a system property returned by
-** __system_property_find. Can only be done by a single process
-** that has write access to the property area, and that process
-** must handle sequencing to ensure that only one property is
-** updated at a time.
-**
-** Returns 0 on success, -1 if the parameters are incorrect.
-*/
-int __system_property_update(prop_info* _Nonnull __pi, const char* _Nonnull __value, unsigned int __value_length);
-
-/* Read the serial number of a system property returned by
-** __system_property_find.
-**
-** Returns the serial number on success, -1 on error.
-*/
-uint32_t __system_property_serial(const prop_info* _Nonnull __pi);
-
-/* Initialize the system properties area in read only mode.
- * Should be done by all processes that need to read system
- * properties.
- *
- * Returns 0 on success, -1 otherwise.
- */
-int __system_properties_init(void);
-
-/*
- * Reloads the system properties from disk.
- * Not intended for use by any apps except the Zygote. Should only be called from the main thread.
- *
- * NOTE: Any pointers received from methods such as __system_property_find should be assumed to be
- * invalid after this method is called.
- *
- * Returns 0 on success, -1 if the system properties failed to re-initialize (same conditions as
- * __system properties_init)
- */
-int __system_properties_zygote_reload(void) __INTRODUCED_IN(__ANDROID_API_V__);
-
-/* Deprecated: use __system_property_wait instead. */
-uint32_t __system_property_wait_any(uint32_t __old_serial);
-
-__END_DECLS
-
-#endif
diff --git a/libc/include/sys/auxv.h b/libc/include/sys/auxv.h
index b664e2a..732f944 100644
--- a/libc/include/sys/auxv.h
+++ b/libc/include/sys/auxv.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [getauxval(3)](http://man7.org/linux/man-pages/man3/getauxval.3.html) returns values from
+ * [getauxval(3)](https://man7.org/linux/man-pages/man3/getauxval.3.html) returns values from
* the ELF auxiliary vector passed by the kernel.
*
* Returns the corresponding value on success,
diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h
index b5fabe3..d06d683 100644
--- a/libc/include/sys/cachectl.h
+++ b/libc/include/sys/cachectl.h
@@ -48,7 +48,7 @@
/**
* __riscv_flush_icache(2) flushes the instruction cache for the given range of addresses.
- * The address range is currently (Linux 6.4) ignored, so both pointers may be null.
+ * The address range is currently (Linux 6.12) ignored, so both pointers may be null.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
diff --git a/libc/include/sys/capability.h b/libc/include/sys/capability.h
index b43bbf0..3d1d896 100644
--- a/libc/include/sys/capability.h
+++ b/libc/include/sys/capability.h
@@ -39,7 +39,7 @@
__BEGIN_DECLS
/**
- * [capget(2)](http://man7.org/linux/man-pages/man2/capget.2.html) gets the calling
+ * [capget(2)](https://man7.org/linux/man-pages/man2/capget.2.html) gets the calling
* thread's capabilities.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -47,7 +47,7 @@
int capget(cap_user_header_t _Nonnull __hdr_ptr, cap_user_data_t _Nullable __data_ptr);
/**
- * [capset(2)](http://man7.org/linux/man-pages/man2/capset.2.html) sets the calling
+ * [capset(2)](https://man7.org/linux/man-pages/man2/capset.2.html) sets the calling
* thread's capabilities.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 5d1718e..9bd35bb 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -140,7 +140,8 @@
#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#define __wur __attribute__((__warn_unused_result__))
+#define __nodiscard __attribute__((__warn_unused_result__))
+#define __wur __nodiscard
#define __errorattr(msg) __attribute__((__unavailable__(msg)))
#define __warnattr(msg) __attribute__((__deprecated__(msg)))
@@ -264,7 +265,7 @@
* having stack protectors detracts from that (b/182948263).
*/
# define __BIONIC_FORTIFY_INLINE static __inline __attribute__((__no_stack_protector__)) \
- __always_inline __VERSIONER_FORTIFY_INLINE
+ __always_inline
/*
* We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
* for variadic functions because compilers cannot inline them.
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index 2bad655..bec7c64 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -42,8 +42,8 @@
__BEGIN_DECLS
/**
- * [epoll_create(2)](http://man7.org/linux/man-pages/man2/epoll_create.2.html)
- * creates a new [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html)
+ * [epoll_create(2)](https://man7.org/linux/man-pages/man2/epoll_create.2.html)
+ * creates a new [epoll](https://man7.org/linux/man-pages/man7/epoll.7.html)
* file descriptor.
*
* Returns a new file descriptor on success and returns -1 and sets `errno` on
@@ -52,8 +52,8 @@
int epoll_create(int __size);
/**
- * [epoll_create1(2)](http://man7.org/linux/man-pages/man2/epoll_create1.2.html)
- * creates a new [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html)
+ * [epoll_create1(2)](https://man7.org/linux/man-pages/man2/epoll_create1.2.html)
+ * creates a new [epoll](https://man7.org/linux/man-pages/man7/epoll.7.html)
* file descriptor with the given flags.
*
* Returns a new file descriptor on success and returns -1 and sets `errno` on
@@ -62,7 +62,7 @@
int epoll_create1(int __flags);
/**
- * [epoll_ctl(2)](http://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
+ * [epoll_ctl(2)](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
* adds/modifies/removes file descriptors from the given epoll file descriptor.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -70,7 +70,7 @@
int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __BIONIC_COMPLICATED_NULLNESS __event);
/**
- * [epoll_wait(2)](http://man7.org/linux/man-pages/man2/epoll_wait.2.html)
+ * [epoll_wait(2)](https://man7.org/linux/man-pages/man2/epoll_wait.2.html)
* waits for an event on the given epoll file descriptor.
*
* Returns the number of ready file descriptors on success, 0 on timeout,
@@ -88,13 +88,19 @@
*
* Available since API level 28.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int epoll_pwait64(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, int __timeout_ms, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
/**
* Like epoll_pwait() but with a `struct timespec` timeout, for nanosecond resolution.
*
* Available since API level 35.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
int epoll_pwait2(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, const struct timespec* _Nullable __timeout, const sigset_t* _Nullable __mask) __INTRODUCED_IN(35);
/**
@@ -103,5 +109,7 @@
* Available since API level 35.
*/
int epoll_pwait2_64(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
__END_DECLS
diff --git a/libc/include/sys/eventfd.h b/libc/include/sys/eventfd.h
index 1ad11e3..3000737 100644
--- a/libc/include/sys/eventfd.h
+++ b/libc/include/sys/eventfd.h
@@ -35,18 +35,22 @@
#include <sys/cdefs.h>
#include <fcntl.h>
+#include <linux/eventfd.h>
__BEGIN_DECLS
-/** The eventfd() flag to provide semaphore-like semantics for reads. */
-#define EFD_SEMAPHORE (1 << 0)
-/** The eventfd() flag for a close-on-exec file descriptor. */
-#define EFD_CLOEXEC O_CLOEXEC
-/** The eventfd() flag for a non-blocking file descriptor. */
-#define EFD_NONBLOCK O_NONBLOCK
+/*! \macro EFD_SEMAPHORE
+ * The eventfd() flag to provide semaphore-like semantics for reads.
+ */
+/*! \macro EFD_CLOEXEC
+ * The eventfd() flag for a close-on-exec file descriptor.
+ */
+/*! \macro EFD_NONBLOCK
+ * The eventfd() flag for a non-blocking file descriptor.
+ */
/**
- * [eventfd(2)](http://man7.org/linux/man-pages/man2/eventfd.2.html) creates a file descriptor
+ * [eventfd(2)](https://man7.org/linux/man-pages/man2/eventfd.2.html) creates a file descriptor
* for event notification.
*
* Returns a new file descriptor on success, and returns -1 and sets `errno` on failure.
@@ -57,7 +61,7 @@
typedef uint64_t eventfd_t;
/**
- * [eventfd_read(3)](http://man7.org/linux/man-pages/man2/eventfd.2.html) is a convenience
+ * [eventfd_read(3)](https://man7.org/linux/man-pages/man2/eventfd.2.html) is a convenience
* wrapper to read an `eventfd_t` from an eventfd file descriptor.
*
* Returns 0 on success, or returns -1 otherwise.
@@ -65,7 +69,7 @@
int eventfd_read(int __fd, eventfd_t* _Nonnull __value);
/**
- * [eventfd_write(3)](http://man7.org/linux/man-pages/man2/eventfd.2.html) is a convenience
+ * [eventfd_write(3)](https://man7.org/linux/man-pages/man2/eventfd.2.html) is a convenience
* wrapper to write an `eventfd_t` to an eventfd file descriptor.
*
* Returns 0 on success, or returns -1 otherwise.
diff --git a/libc/include/sys/file.h b/libc/include/sys/file.h
index ccdfeea..45117fa 100644
--- a/libc/include/sys/file.h
+++ b/libc/include/sys/file.h
@@ -41,7 +41,7 @@
__BEGIN_DECLS
/**
- * [flock(2)](http://man7.org/linux/man-pages/man2/flock.2.html) performs
+ * [flock(2)](https://man7.org/linux/man-pages/man2/flock.2.html) performs
* advisory file lock operations.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/fsuid.h b/libc/include/sys/fsuid.h
index 273749f..eeb5783 100644
--- a/libc/include/sys/fsuid.h
+++ b/libc/include/sys/fsuid.h
@@ -39,7 +39,7 @@
__BEGIN_DECLS
/**
- * [setfsuid(2)](http://man7.org/linux/man-pages/man2/setfsuid.2.html) sets the UID used for
+ * [setfsuid(2)](https://man7.org/linux/man-pages/man2/setfsuid.2.html) sets the UID used for
* filesystem checks.
*
* Returns the previous UID.
@@ -47,7 +47,7 @@
int setfsuid(uid_t __uid);
/**
- * [setfsgid(2)](http://man7.org/linux/man-pages/man2/setfsgid.2.html) sets the GID used for
+ * [setfsgid(2)](https://man7.org/linux/man-pages/man2/setfsgid.2.html) sets the GID used for
* filesystem checks.
*
* Returns the previous GID.
diff --git a/libc/include/sys/inotify.h b/libc/include/sys/inotify.h
index f070857..75ed542 100644
--- a/libc/include/sys/inotify.h
+++ b/libc/include/sys/inotify.h
@@ -33,13 +33,9 @@
#include <sys/types.h>
#include <stdint.h>
#include <linux/inotify.h>
-#include <asm/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK. */
__BEGIN_DECLS
-#define IN_CLOEXEC O_CLOEXEC
-#define IN_NONBLOCK O_NONBLOCK
-
int inotify_init(void);
int inotify_init1(int __flags);
int inotify_add_watch(int __fd, const char* _Nonnull __path, uint32_t __mask);
diff --git a/libc/include/sys/io.h b/libc/include/sys/io.h
index d187b78..11f3f3a 100644
--- a/libc/include/sys/io.h
+++ b/libc/include/sys/io.h
@@ -42,7 +42,7 @@
__BEGIN_DECLS
/**
- * [iopl(2)](http://man7.org/linux/man-pages/man2/iopl.2.html) changes the I/O
+ * [iopl(2)](https://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.
@@ -58,7 +58,7 @@
#endif
/**
- * [ioperm(2)](http://man7.org/linux/man-pages/man2/ioperm.2.html) sets the I/O
+ * [ioperm(2)](https://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.
*
diff --git a/libc/include/sys/ipc.h b/libc/include/sys/ipc.h
index 2e2b8cf..f557ce5 100644
--- a/libc/include/sys/ipc.h
+++ b/libc/include/sys/ipc.h
@@ -47,7 +47,7 @@
__BEGIN_DECLS
/**
- * [ftok(3)](http://man7.org/linux/man-pages/man3/ftok.3.html) converts a path and id to a
+ * [ftok(3)](https://man7.org/linux/man-pages/man3/ftok.3.html) converts a path and id to a
* System V IPC key.
*
* Returns a key on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/klog.h b/libc/include/sys/klog.h
index b60c2c4..6ee410f 100644
--- a/libc/include/sys/klog.h
+++ b/libc/include/sys/klog.h
@@ -61,7 +61,7 @@
#define KLOG_SIZE_BUFFER 10
/**
- * [klogctl(2)](http://man7.org/linux/man-pages/man2/syslog.2.html) operates on the kernel log.
+ * [klogctl(3)](https://man7.org/linux/man-pages/man2/klogctl.3.html) operates on the kernel log.
*
* This system call is not available to applications.
* Use syslog() or `<android/log.h>` instead.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 823c9ba..3fe1f9c 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -43,7 +43,7 @@
#define MAP_FAILED __BIONIC_CAST(reinterpret_cast, void*, -1)
/**
- * [mmap(2)](http://man7.org/linux/man-pages/man2/mmap.2.html)
+ * [mmap(2)](https://man7.org/linux/man-pages/man2/mmap.2.html)
* creates a memory mapping for the given range.
*
* Returns the address of the mapping on success,
@@ -63,7 +63,7 @@
void* _Nonnull mmap64(void* _Nullable __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset);
/**
- * [munmap(2)](http://man7.org/linux/man-pages/man2/munmap.2.html)
+ * [munmap(2)](https://man7.org/linux/man-pages/man2/munmap.2.html)
* deletes a memory mapping for the given range.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -71,7 +71,7 @@
int munmap(void* _Nonnull __addr, size_t __size);
/**
- * [msync(2)](http://man7.org/linux/man-pages/man2/msync.2.html)
+ * [msync(2)](https://man7.org/linux/man-pages/man2/msync.2.html)
* flushes changes to a memory-mapped file to disk.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -79,7 +79,7 @@
int msync(void* _Nonnull __addr, size_t __size, int __flags);
/**
- * [mprotect(2)](http://man7.org/linux/man-pages/man2/mprotect.2.html)
+ * [mprotect(2)](https://man7.org/linux/man-pages/man2/mprotect.2.html)
* sets the protection on a memory region.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -93,7 +93,7 @@
#define MREMAP_FIXED 2
/**
- * [mremap(2)](http://man7.org/linux/man-pages/man2/mremap.2.html)
+ * [mremap(2)](https://man7.org/linux/man-pages/man2/mremap.2.html)
* expands or shrinks an existing memory mapping.
*
* Returns the address of the mapping on success,
@@ -102,7 +102,7 @@
void* _Nonnull mremap(void* _Nonnull __old_addr, size_t __old_size, size_t __new_size, int __flags, ...);
/**
- * [mlockall(2)](http://man7.org/linux/man-pages/man2/mlockall.2.html)
+ * [mlockall(2)](https://man7.org/linux/man-pages/man2/mlockall.2.html)
* locks pages (preventing swapping).
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -110,7 +110,7 @@
int mlockall(int __flags);
/**
- * [munlockall(2)](http://man7.org/linux/man-pages/man2/munlockall.2.html)
+ * [munlockall(2)](https://man7.org/linux/man-pages/man2/munlockall.2.html)
* unlocks pages (allowing swapping).
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -118,7 +118,7 @@
int munlockall(void);
/**
- * [mlock(2)](http://man7.org/linux/man-pages/man2/mlock.2.html)
+ * [mlock(2)](https://man7.org/linux/man-pages/man2/mlock.2.html)
* locks pages (preventing swapping).
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -126,17 +126,21 @@
int mlock(const void* _Nonnull __addr, size_t __size);
/**
- * [mlock2(2)](http://man7.org/linux/man-pages/man2/mlock.2.html)
+ * [mlock2(2)](https://man7.org/linux/man-pages/man2/mlock2.2.html)
* locks pages (preventing swapping), with optional flags.
*
* Available since API level 30.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int mlock2(const void* _Nonnull __addr, size_t __size, int __flags) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
/**
- * [munlock(2)](http://man7.org/linux/man-pages/man2/munlock.2.html)
+ * [munlock(2)](https://man7.org/linux/man-pages/man2/munlock.2.html)
* unlocks pages (allowing swapping).
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -144,7 +148,7 @@
int munlock(const void* _Nonnull __addr, size_t __size);
/**
- * [mincore(2)](http://man7.org/linux/man-pages/man2/mincore.2.html)
+ * [mincore(2)](https://man7.org/linux/man-pages/man2/mincore.2.html)
* tests whether pages are resident in memory.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -152,7 +156,7 @@
int mincore(void* _Nonnull __addr, size_t __size, unsigned char* _Nonnull __vector);
/**
- * [madvise(2)](http://man7.org/linux/man-pages/man2/madvise.2.html)
+ * [madvise(2)](https://man7.org/linux/man-pages/man2/madvise.2.html)
* gives the kernel advice about future usage patterns.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -160,7 +164,7 @@
int madvise(void* _Nonnull __addr, size_t __size, int __advice);
/**
- * [process_madvise(2)](http://man7.org/linux/man-pages/man2/process_madvise.2.html)
+ * [process_madvise(2)](https://man7.org/linux/man-pages/man2/process_madvise.2.html)
* works just like madvise(2) but applies to the process specified by the given
* PID file descriptor.
*
@@ -171,19 +175,27 @@
*
* Returns the number of bytes advised on success, and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(31)
ssize_t process_madvise(int __pid_fd, const struct iovec* _Nonnull __iov, size_t __count, int __advice, unsigned __flags) __INTRODUCED_IN(31);
+#endif /* __BIONIC_AVAILABILITY_GUARD(31) */
+
#if defined(__USE_GNU)
/**
- * [memfd_create(2)](http://man7.org/linux/man-pages/man2/memfd_create.2.html)
+ * [memfd_create(2)](https://man7.org/linux/man-pages/man2/memfd_create.2.html)
* creates an anonymous file.
*
* Available since API level 30.
*
* Returns an fd on success, and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
int memfd_create(const char* _Nonnull __name, unsigned __flags) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
#endif
@@ -212,7 +224,7 @@
#endif
/**
- * [posix_madvise(3)](http://man7.org/linux/man-pages/man3/posix_madvise.3.html)
+ * [posix_madvise(3)](https://man7.org/linux/man-pages/man3/posix_madvise.3.html)
* gives the kernel advice about future usage patterns.
*
* Available since API level 23.
@@ -220,6 +232,26 @@
*
* Returns 0 on success, and returns a positive error number on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int posix_madvise(void* _Nonnull __addr, size_t __size, int __advice) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
+
+/**
+ * [mseal(2)](https://man7.org/linux/man-pages/man2/mseal.2.html)
+ * seals the given range to prevent modifications such as mprotect() calls.
+ *
+ * Available since API level 36.
+ * Requires a Linux 6.10 or newer kernel.
+ * Always fails for 32-bit processes.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(36)
+int mseal(void* _Nonnull __addr, size_t __size, unsigned long __flags) __INTRODUCED_IN(36);
+#endif /* __BIONIC_AVAILABILITY_GUARD(36) */
+
__END_DECLS
diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h
index aace205..0880c98 100644
--- a/libc/include/sys/mount.h
+++ b/libc/include/sys/mount.h
@@ -50,7 +50,7 @@
#define UMOUNT_NOFOLLOW 8
/**
- * [mount(2)](http://man7.org/linux/man-pages/man2/mount.2.html) mounts the filesystem `source` at
+ * [mount(2)](https://man7.org/linux/man-pages/man2/mount.2.html) mounts the filesystem `source` at
* the mount point `target`.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -58,7 +58,7 @@
int mount(const char* __BIONIC_COMPLICATED_NULLNESS __source, const char* _Nonnull __target, const char* __BIONIC_COMPLICATED_NULLNESS __fs_type, unsigned long __flags, const void* _Nullable __data);
/**
- * [umount(2)](http://man7.org/linux/man-pages/man2/umount.2.html) unmounts the filesystem at
+ * [umount(2)](https://man7.org/linux/man-pages/man2/umount.2.html) unmounts the filesystem at
* the given mount point.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -66,7 +66,7 @@
int umount(const char* _Nonnull __target);
/**
- * [umount2(2)](http://man7.org/linux/man-pages/man2/umount2.2.html) unmounts the filesystem at
+ * [umount2(2)](https://man7.org/linux/man-pages/man2/umount2.2.html) unmounts the filesystem at
* the given mount point, according to the supplied flags.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/msg.h b/libc/include/sys/msg.h
index 26071b1..8b619be 100644
--- a/libc/include/sys/msg.h
+++ b/libc/include/sys/msg.h
@@ -46,6 +46,8 @@
typedef __kernel_ulong_t msglen_t;
/** Not useful on Android; disallowed by SELinux. */
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int msgctl(int __msg_id, int __op, struct msqid_ds* _Nullable __buf) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
int msgget(key_t __key, int __flags) __INTRODUCED_IN(26);
@@ -53,5 +55,7 @@
ssize_t msgrcv(int __msg_id, void* _Nonnull __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
int msgsnd(int __msg_id, const void* _Nonnull __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index 1c991ae..99b6a07 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -33,10 +33,11 @@
* @brief Various macros.
*/
+#include <sys/cdefs.h>
+
#include <endian.h>
#include <limits.h>
#include <linux/param.h>
-#include <sys/cdefs.h>
/** The unit of `st_blocks` in `struct stat`. */
#define DEV_BSIZE 512
diff --git a/libc/include/sys/personality.h b/libc/include/sys/personality.h
index 9eb992f..34d1a1a 100644
--- a/libc/include/sys/personality.h
+++ b/libc/include/sys/personality.h
@@ -39,7 +39,7 @@
__BEGIN_DECLS
/**
- * [personality(2)](http://man7.org/linux/man-pages/man2/personality.2.html) sets the calling
+ * [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html) sets the calling
* process' personality.
*
* Returns the previous persona on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/pidfd.h b/libc/include/sys/pidfd.h
index 30455bb..bd2b01e 100644
--- a/libc/include/sys/pidfd.h
+++ b/libc/include/sys/pidfd.h
@@ -49,10 +49,12 @@
*
* Available since API level 31.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(31)
int pidfd_open(pid_t __pid, unsigned int __flags) __INTRODUCED_IN(31);
/**
- * [pidfd_getfd(2)](https://man7.org/linux/man-pages/man2/pidfd_open.2.html)
+ * [pidfd_getfd(2)](https://man7.org/linux/man-pages/man2/pidfd_getfd.2.html)
* dups a file descriptor from another process. This file descriptor will have
* the close-on-exec flag set by default.
*
@@ -72,5 +74,7 @@
* Available since API level 31.
*/
int pidfd_send_signal(int __pidfd, int __sig, siginfo_t * _Nullable __info, unsigned int __flags) __INTRODUCED_IN(31);
+#endif /* __BIONIC_AVAILABILITY_GUARD(31) */
+
__END_DECLS
diff --git a/libc/include/sys/prctl.h b/libc/include/sys/prctl.h
index 1c80415..4e0b4b5 100644
--- a/libc/include/sys/prctl.h
+++ b/libc/include/sys/prctl.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [prctl(2)](http://man7.org/linux/man-pages/man2/prctl.2.html) performs a variety of
+ * [prctl(2)](https://man7.org/linux/man-pages/man2/prctl.2.html) performs a variety of
* operations based on the `PR_` constant passed as the first argument.
*
* Returns -1 and sets `errno` on failure; success values vary by option.
diff --git a/libc/include/sys/quota.h b/libc/include/sys/quota.h
index 37f8925..af09674 100644
--- a/libc/include/sys/quota.h
+++ b/libc/include/sys/quota.h
@@ -45,12 +45,16 @@
__BEGIN_DECLS
/**
- * [quotactl(2)](http://man7.org/linux/man-pages/man2/quotactl.2.html) manipulates disk quotas.
+ * [quotactl(2)](https://man7.org/linux/man-pages/man2/quotactl.2.html) manipulates disk quotas.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*
* Available since API level 26.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int quotactl(int __op, const char* _Nullable __special, int __id, char* __BIONIC_COMPLICATED_NULLNESS __addr) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index 2ff5349..23d2c3a 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -43,7 +43,7 @@
__BEGIN_DECLS
/**
- * [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
+ * [getrandom(2)](https://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
* with random bytes.
*
* Returns the number of bytes copied on success, and returns -1 and sets `errno` on failure.
@@ -52,6 +52,10 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
+__nodiscard ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/sys/reboot.h b/libc/include/sys/reboot.h
index 5d9e1a7..f4bc861 100644
--- a/libc/include/sys/reboot.h
+++ b/libc/include/sys/reboot.h
@@ -50,7 +50,7 @@
#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
/**
- * [reboot(2)](http://man7.org/linux/man-pages/man2/reboot.2.html) reboots the device.
+ * [reboot(2)](https://man7.org/linux/man-pages/man2/reboot.2.html) reboots the device.
*
* Does not return on successful reboot, returns 0 if CAD was successfully enabled/disabled,
* and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index 6743343..05ef2c2 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -54,7 +54,11 @@
int getrusage(int __who, struct rusage* _Nonnull __usage);
+
+#if (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__))
int prlimit(pid_t __pid, int __resource, const struct rlimit* _Nullable __new_limit, struct rlimit* _Nullable __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
+#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__)) */
+
int prlimit64(pid_t __pid, int __resource, const struct rlimit64* _Nullable __new_limit, struct rlimit64* _Nullable __old_limit);
__END_DECLS
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index 84c2621..685e6ac 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -30,7 +30,9 @@
/**
* @file sys/select.h
- * @brief Wait for events on a set of file descriptors (but use <poll.h> instead).
+ * @brief Wait for events on a set of file descriptors.
+ * New code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*/
#include <sys/cdefs.h>
@@ -44,15 +46,21 @@
typedef unsigned long fd_mask;
/**
- * The limit on the largest fd that can be used with this API.
- * Use <poll.h> instead.
+ * The limit on the largest fd that can be used with type `fd_set`.
+ * You can allocate your own memory,
+ * but new code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*/
#define FD_SETSIZE 1024
#define NFDBITS (8 * sizeof(fd_mask))
/**
* The type of a file descriptor set. Limited to 1024 fds.
- * Use <poll.h> instead.
+ * The underlying system calls do not have this limit,
+ * and callers can allocate their own sets with calloc().
+ *
+ * New code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*/
typedef struct {
fd_mask fds_bits[FD_SETSIZE/NFDBITS];
@@ -60,37 +68,68 @@
#define __FDELT(fd) ((fd) / NFDBITS)
#define __FDMASK(fd) (1UL << ((fd) % NFDBITS))
-#define __FDS_BITS(type,set) (__BIONIC_CAST(static_cast, type, set)->fds_bits)
-
-/* Inline loop so we don't have to declare memset. */
-#define FD_ZERO(set) \
- do { \
- size_t __i; \
- for (__i = 0; __i < sizeof(fd_set)/sizeof(fd_mask); ++__i) { \
- (set)->fds_bits[__i] = 0; \
- } \
- } while (0)
+#define __FDS_BITS(type, set) (__BIONIC_CAST(static_cast, type, set)->fds_bits)
void __FD_CLR_chk(int, fd_set* _Nonnull , size_t);
void __FD_SET_chk(int, fd_set* _Nonnull, size_t);
int __FD_ISSET_chk(int, const fd_set* _Nonnull, size_t);
-#define __FD_CLR(fd, set) (__FDS_BITS(fd_set*,set)[__FDELT(fd)] &= ~__FDMASK(fd))
-#define __FD_SET(fd, set) (__FDS_BITS(fd_set*,set)[__FDELT(fd)] |= __FDMASK(fd))
-#define __FD_ISSET(fd, set) ((__FDS_BITS(const fd_set*,set)[__FDELT(fd)] & __FDMASK(fd)) != 0)
+/**
+ * FD_CLR() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
+#define __FD_CLR(fd, set) (__FDS_BITS(fd_set*, set)[__FDELT(fd)] &= ~__FDMASK(fd))
-/** Removes `fd` from the given set. Use <poll.h> instead. */
+/**
+ * FD_SET() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
+#define __FD_SET(fd, set) (__FDS_BITS(fd_set*, set)[__FDELT(fd)] |= __FDMASK(fd))
+
+/**
+ * FD_ISSET() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
+#define __FD_ISSET(fd, set) ((__FDS_BITS(const fd_set*, set)[__FDELT(fd)] & __FDMASK(fd)) != 0)
+
+/**
+ * Removes all 1024 fds from the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using memset() directly.
+ */
+#define FD_ZERO(set) __builtin_memset(set, 0, sizeof(*__BIONIC_CAST(static_cast, const fd_set*, set)))
+
+/**
+ * Removes `fd` from the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_CLR().
+ */
#define FD_CLR(fd, set) __FD_CLR_chk(fd, set, __bos(set))
-/** Adds `fd` to the given set. Use <poll.h> instead. */
+
+/**
+ * Adds `fd` to the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_SET().
+ */
#define FD_SET(fd, set) __FD_SET_chk(fd, set, __bos(set))
-/** Tests whether `fd` is in the given set. Use <poll.h> instead. */
+
+/**
+ * Tests whether `fd` is in the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_ISSET().
+ */
#define FD_ISSET(fd, set) __FD_ISSET_chk(fd, set, __bos(set))
/**
- * [select(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
+ * [select(2)](https://man7.org/linux/man-pages/man2/select.2.html) waits on a
* set of file descriptors.
*
- * Use poll() instead.
+ * New code should prefer poll() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
@@ -98,10 +137,11 @@
int select(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, struct timeval* _Nullable __timeout);
/**
- * [pselect(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
+ * [pselect(2)](https://man7.org/linux/man-pages/man2/pselect.2.html) waits on a
* set of file descriptors.
*
- * Use ppoll() instead.
+ * New code should prefer ppoll() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
@@ -109,16 +149,19 @@
int pselect(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, const struct timespec* _Nullable __timeout, const sigset_t* _Nullable __mask);
/**
- * [pselect64(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
+ * [pselect64(2)](https://man7.org/linux/man-pages/man2/select.2.html) waits on a
* set of file descriptors.
*
- * Use ppoll64() instead.
+ * New code should prefer ppoll64() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
*
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
*
* Available since API level 28.
*/
+#if __BIONIC_AVAILABILITY_GUARD(28)
int pselect64(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
__END_DECLS
diff --git a/libc/include/sys/sem.h b/libc/include/sys/sem.h
index 5682282..72f567e 100644
--- a/libc/include/sys/sem.h
+++ b/libc/include/sys/sem.h
@@ -51,12 +51,20 @@
void* _Nullable __pad;
};
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int semctl(int __sem_id, int __sem_num, int __op, ...) __INTRODUCED_IN(26);
int semget(key_t __key, int __sem_count, int __flags) __INTRODUCED_IN(26);
int semop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int semtimedop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count, const struct timespec* _Nullable __timeout) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
#endif
__END_DECLS
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 26522a6..ac623e7 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -43,7 +43,7 @@
ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count) __RENAME(sendfile64);
#else
/**
- * [sendfile(2)](http://man7.org/linux/man-pages/man2/sendfile.2.html) copies data directly
+ * [sendfile(2)](https://man7.org/linux/man-pages/man2/sendfile.2.html) copies data directly
* between two file descriptors.
*
* Returns the number of bytes copied on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/shm.h b/libc/include/sys/shm.h
index 8ab3d9a..a960781 100644
--- a/libc/include/sys/shm.h
+++ b/libc/include/sys/shm.h
@@ -48,6 +48,8 @@
typedef unsigned long shmatt_t;
/** Not useful on Android; disallowed by SELinux. */
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
void* _Nonnull shmat(int __shm_id, const void* _Nullable __addr, int __flags) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
int shmctl(int __shm_id, int __op, struct shmid_ds* _Nullable __buf) __INTRODUCED_IN(26);
@@ -55,5 +57,7 @@
int shmdt(const void* _Nonnull __addr) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
int shmget(key_t __key, size_t __size, int __flags) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
__END_DECLS
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index 2be9bdc..eaea525 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -41,7 +41,7 @@
__BEGIN_DECLS
/**
- * [signalfd(2)](http://man7.org/linux/man-pages/man2/signalfd.2.html) creates/manipulates a
+ * [signalfd(2)](https://man7.org/linux/man-pages/man2/signalfd.2.html) creates/manipulates a
* file descriptor for reading signal events.
*
* Returns the file descriptor on success, and returns -1 and sets `errno` on failure.
@@ -51,6 +51,10 @@
/**
* Like signalfd() but allows setting a signal mask with RT signals even from a 32-bit process.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int signalfd64(int __fd, const sigset64_t* _Nonnull __mask, int __flags) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
__END_DECLS
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index f916573..12bfedc 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -33,9 +33,10 @@
* @brief File status.
*/
+#include <sys/cdefs.h>
+
#include <bits/timespec.h>
#include <linux/stat.h>
-#include <sys/cdefs.h>
#include <sys/types.h>
__BEGIN_DECLS
@@ -99,7 +100,13 @@
#endif
+/** The file information returned by fstat()/fstatat()/lstat()/stat(). */
struct stat { __STAT64_BODY };
+
+/**
+ * A synonym for `struct stat` on Android,
+ * provided for source compatibility with other systems.
+ */
struct stat64 { __STAT64_BODY };
#undef __STAT64_BODY
@@ -136,32 +143,153 @@
#define S_TYPEISSHM(__sb) 0
#define S_TYPEISTMO(__sb) 0
+/**
+ * [chmod(2)](https://man7.org/linux/man-pages/man2/chmod.2.html)
+ * changes the mode of a file given a path.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int chmod(const char* _Nonnull __path, mode_t __mode);
+
+/**
+ * [fchmod(2)](https://man7.org/linux/man-pages/man2/fchmod.2.html)
+ * changes the mode of a file given a file descriptor.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int fchmod(int __fd, mode_t __mode);
+
+/**
+ * [fchmodat(2)](https://man7.org/linux/man-pages/man2/fchmodat.2.html)
+ * changes the mode of a file.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int fchmodat(int __dir_fd, const char* _Nonnull __path, mode_t __mode, int __flags);
+
+/**
+ * [chmod(2)](https://man7.org/linux/man-pages/man2/chmod.2.html)
+ * changes the mode of a file given a path, without following symlinks.
+ *
+ * Equivalent to `fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW)`.
+ *
+ * Available since API 36.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(36)
+int lchmod(const char* _Nonnull __path, mode_t __mode) __INTRODUCED_IN(36);
+#endif /* __BIONIC_AVAILABILITY_GUARD(36) */
+
+
+/**
+ * [mkdir(2)](https://man7.org/linux/man-pages/man2/mkdir.2.html)
+ * creates a directory.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int mkdir(const char* _Nonnull __path, mode_t __mode);
+/**
+ * [mkdirat(2)](https://man7.org/linux/man-pages/man2/mkdirat.2.html)
+ * creates a directory.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int mkdirat(int __dir_fd, const char* _Nonnull __path, mode_t __mode);
+
+/**
+ * [fstat(2)](https://man7.org/linux/man-pages/man2/fstat.2.html)
+ * gets file status given a file descriptor.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int fstat(int __fd, struct stat* _Nonnull __buf);
+
+/** An alias for fstat(). */
int fstat64(int __fd, struct stat64* _Nonnull __buf);
-int fstatat(int __dir_fd, const char* _Nonnull __path, struct stat* _Nonnull __buf, int __flags);
-int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags);
+
+/**
+ * [fstatat(2)](https://man7.org/linux/man-pages/man2/fstatat.2.html)
+ * gets file status.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int fstatat(int __dir_fd, const char* _Nullable __path, struct stat* _Nonnull __buf, int __flags);
+
+/** An alias for fstatat(). */
+int fstatat64(int __dir_fd, const char* _Nullable __path, struct stat64* _Nonnull __buf, int __flags);
+
+/**
+ * [lstat(2)](https://man7.org/linux/man-pages/man2/lstat.2.html)
+ * gets file status given a path, without following symlinks.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int lstat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
+
+/** An alias for lstat(). */
int lstat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf);
+
+/**
+ * [stat(2)](https://man7.org/linux/man-pages/man2/stat.2.html)
+ * gets file status given a path.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int stat(const char* _Nonnull __path, struct stat* _Nonnull __buf);
+
+/** An alias for stat(). */
int stat64(const char* _Nonnull __path, struct stat64* _Nonnull __buf);
+/**
+ * [mknod(2)](https://man7.org/linux/man-pages/man2/mknod.2.html)
+ * creates a directory, special, or regular file.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int mknod(const char* _Nonnull __path, mode_t __mode, dev_t __dev);
+
+/**
+ * [mknodat(2)](https://man7.org/linux/man-pages/man2/mknodat.2.html)
+ * creates a directory, special, or regular file.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int mknodat(int __dir_fd, const char* _Nonnull __path, mode_t __mode, dev_t __dev);
+
+/**
+ * [umask(2)](https://man7.org/linux/man-pages/man2/umask.2.html)
+ * gets and sets the process-wide file mode creation mask.
+ *
+ * Returns the previous file mode creation mask.
+ */
mode_t umask(mode_t __mask);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#include <bits/fortify/stat.h>
#endif
+/**
+ * [mkfifo(2)](https://man7.org/linux/man-pages/man2/mkfifo.2.html)
+ * creates a FIFO.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
int mkfifo(const char* _Nonnull __path, mode_t __mode);
-int mkfifoat(int __dir_fd, const char* _Nonnull __path, mode_t __mode) __INTRODUCED_IN(23);
-int fchmodat(int __dir_fd, const char* _Nonnull __path, mode_t __mode, int __flags);
-int mkdirat(int __dir_fd, const char* _Nonnull __path, mode_t __mode);
-int mknodat(int __dir_fd, const char* _Nonnull __path, mode_t __mode, dev_t __dev);
+/**
+ * [mkfifoat(2)](https://man7.org/linux/man-pages/man2/mkfifoat.2.html)
+ * creates a FIFO.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
+int mkfifoat(int __dir_fd, const char* _Nonnull __path, mode_t __mode) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
* Used in the tv_nsec field of an argument to utimensat()/futimens()
@@ -192,7 +320,7 @@
int utimensat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timespec __times[_Nullable 2], int __flags);
/**
- * [futimens(2)](https://man7.org/linux/man-pages/man2/utimensat.2.html) sets
+ * [futimens(3)](https://man7.org/linux/man-pages/man3/futimens.3.html) sets
* the given file descriptor's timestamp.
*
* `__times[0]` is the access time (atime), and `__times[1]` the last modification time (mtime).
@@ -205,14 +333,18 @@
#if defined(__USE_GNU)
/**
- * [statx(2)](http://man7.org/linux/man-pages/man2/statx.2.html) returns
+ * [statx(2)](https://man7.org/linux/man-pages/man2/statx.2.html) returns
* extended file status information.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*
* Available since API level 30.
*/
-int statx(int __dir_fd, const char* _Nonnull __path, int __flags, unsigned __mask, struct statx* _Nonnull __buf) __INTRODUCED_IN(30);
+
+#if __BIONIC_AVAILABILITY_GUARD(30)
+int statx(int __dir_fd, const char* _Nullable __path, int __flags, unsigned __mask, struct statx* _Nonnull __buf) __INTRODUCED_IN(30);
+#endif /* __BIONIC_AVAILABILITY_GUARD(30) */
+
#endif
__END_DECLS
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index 7bc5e63..860824b 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -21,8 +21,9 @@
* @brief Filesystem statistics.
*/
-#include <stdint.h>
#include <sys/cdefs.h>
+
+#include <stdint.h>
#include <sys/types.h>
__BEGIN_DECLS
@@ -92,7 +93,7 @@
#define ST_NOSYMFOLLOW 0x2000
/**
- * [statvfs(3)](http://man7.org/linux/man-pages/man3/statvfs.3.html)
+ * [statvfs(3)](https://man7.org/linux/man-pages/man3/statvfs.3.html)
* queries filesystem statistics for the given path.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -100,7 +101,7 @@
int statvfs(const char* _Nonnull __path, struct statvfs* _Nonnull __buf);
/**
- * [fstatvfs(3)](http://man7.org/linux/man-pages/man3/fstatvfs.3.html)
+ * [fstatvfs(3)](https://man7.org/linux/man-pages/man3/fstatvfs.3.html)
* queries filesystem statistics for the given file descriptor.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/swap.h b/libc/include/sys/swap.h
index 474aed7..2aaf86e 100644
--- a/libc/include/sys/swap.h
+++ b/libc/include/sys/swap.h
@@ -52,14 +52,14 @@
#define SWAP_FLAG_PRIO_SHIFT 0
/**
- * [swapon(2)](http://man7.org/linux/man-pages/man2/swapon.2.html) enables swapping.
+ * [swapon(2)](https://man7.org/linux/man-pages/man2/swapon.2.html) enables swapping.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
int swapon(const char* _Nonnull __path, int __flags);
/**
- * [swapoff(2)](http://man7.org/linux/man-pages/man2/swapoff.2.html) disables swapping.
+ * [swapoff(2)](https://man7.org/linux/man-pages/man2/swapoff.2.html) disables swapping.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h
index a49323d..9341ffb 100644
--- a/libc/include/sys/syscall.h
+++ b/libc/include/sys/syscall.h
@@ -29,9 +29,10 @@
#ifndef _SYS_SYSCALL_H_
#define _SYS_SYSCALL_H_
+#include <sys/cdefs.h>
+
#include <asm/unistd.h> /* Linux kernel __NR_* names. */
#include <bits/glibc-syscalls.h> /* glibc-compatible SYS_* aliases. */
-#include <sys/cdefs.h>
/* The syscall function itself is declared in <unistd.h>, not here. */
diff --git a/libc/include/sys/sysinfo.h b/libc/include/sys/sysinfo.h
index cae5c49..ed6a007 100644
--- a/libc/include/sys/sysinfo.h
+++ b/libc/include/sys/sysinfo.h
@@ -39,24 +39,26 @@
__BEGIN_DECLS
/**
- * [sysinfo(2)](http://man7.org/linux/man-pages/man2/sysinfo.2.html) queries system information.
+ * [sysinfo(2)](https://man7.org/linux/man-pages/man2/sysinfo.2.html) queries system information.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
int sysinfo(struct sysinfo* _Nonnull __info);
/**
- * [get_nprocs_conf(3)](http://man7.org/linux/man-pages/man3/get_nprocs_conf.3.html) returns
+ * [get_nprocs_conf(3)](https://man7.org/linux/man-pages/man3/get_nprocs_conf.3.html) returns
* the total number of processors in the system.
*
* Available since API level 23.
*
* See also sysconf().
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int get_nprocs_conf(void) __INTRODUCED_IN(23);
/**
- * [get_nprocs(3)](http://man7.org/linux/man-pages/man3/get_nprocs.3.html) returns
+ * [get_nprocs(3)](https://man7.org/linux/man-pages/man3/get_nprocs.3.html) returns
* the number of processors in the system that are currently on-line.
*
* Available since API level 23.
@@ -66,7 +68,7 @@
int get_nprocs(void) __INTRODUCED_IN(23);
/**
- * [get_phys_pages(3)](http://man7.org/linux/man-pages/man3/get_phys_pages.3.html) returns
+ * [get_phys_pages(3)](https://man7.org/linux/man-pages/man3/get_phys_pages.3.html) returns
* the total number of physical pages in the system.
*
* Available since API level 23.
@@ -76,7 +78,7 @@
long get_phys_pages(void) __INTRODUCED_IN(23);
/**
- * [get_avphys_pages(3)](http://man7.org/linux/man-pages/man3/get_avphys_pages.3.html) returns
+ * [get_avphys_pages(3)](https://man7.org/linux/man-pages/man3/get_avphys_pages.3.html) returns
* the number of physical pages in the system that are currently available.
*
* Available since API level 23.
@@ -84,5 +86,7 @@
* See also sysconf().
*/
long get_avphys_pages(void) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index ae94db5..1303079 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -71,9 +71,13 @@
*
* Available since API level 26.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
void __system_property_read_callback(const prop_info* _Nonnull __pi,
void (* _Nonnull __callback)(void* _Nullable __cookie, const char* _Nonnull __name, const char* _Nonnull __value, uint32_t __serial),
void* _Nullable __cookie) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/**
* Passes a `prop_info` for each system property to the provided
@@ -101,8 +105,12 @@
* Available since API level 26.
*/
struct timespec;
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
bool __system_property_wait(const prop_info* _Nullable __pi, uint32_t __old_serial, uint32_t* _Nonnull __new_serial_ptr, const struct timespec* _Nullable __relative_timeout)
__INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/**
* Deprecated: there's no limit on the length of a property name since
@@ -110,11 +118,140 @@
*/
#define PROP_NAME_MAX 32
+/** Deprecated. Use __system_property_foreach() instead. */
+const prop_info* _Nullable __system_property_find_nth(unsigned __n);
/** Deprecated. Use __system_property_read_callback() instead. */
int __system_property_read(const prop_info* _Nonnull __pi, char* _Nullable __name, char* _Nonnull __value);
/** Deprecated. Use __system_property_read_callback() instead. */
int __system_property_get(const char* _Nonnull __name, char* _Nonnull __value);
-/** Deprecated. Use __system_property_foreach() instead. */
-const prop_info* _Nullable __system_property_find_nth(unsigned __n);
+/** Deprecated: use __system_property_wait() instead. */
+uint32_t __system_property_wait_any(uint32_t __old_serial);
+
+/**
+ * Reads the global serial number of the system properties _area_.
+ *
+ * Called to predict if a series of cached __system_property_find()
+ * objects will have seen __system_property_serial() values change.
+ * Also aids the converse, as changes in the global serial can
+ * also be used to predict if a failed __system_property_find()
+ * could in turn now find a new object; thus preventing the
+ * cycles of effort to poll __system_property_find().
+ *
+ * Typically called at beginning of a cache cycle to signal if _any_ possible
+ * changes have occurred since last. If there is, one may check each individual
+ * __system_property_serial() to confirm dirty, or __system_property_find()
+ * to check if the property now exists. If a call to __system_property_add()
+ * or __system_property_update() has completed between two calls to
+ * __system_property_area_serial() then the second call will return a larger
+ * value than the first call. Beware of race conditions as changes to the
+ * properties are not atomic, the main value of this call is to determine
+ * whether the expensive __system_property_find() is worth retrying to see if
+ * a property now exists.
+ *
+ * Returns the serial number on success, -1 on error.
+ */
+uint32_t __system_property_area_serial(void);
+
+/**
+ * Reads the serial number of a specific system property previously returned by
+ * __system_property_find(). This is a cheap way to check whether a system
+ * property has changed or not.
+ *
+ * Returns the serial number on success, -1 on error.
+ */
+uint32_t __system_property_serial(const prop_info* _Nonnull __pi);
+
+//
+// libc implementation detail.
+//
+
+/**
+ * Initializes the system properties area in read-only mode.
+ *
+ * This is called automatically during libc initialization,
+ * so user code should never need to call this.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int __system_properties_init(void);
+
+//
+// init implementation details.
+//
+
+#define PROP_SERVICE_NAME "property_service"
+#define PROP_SERVICE_FOR_SYSTEM_NAME "property_service_for_system"
+#define PROP_DIRNAME "/dev/__properties__"
+
+// Messages sent to init.
+#define PROP_MSG_SETPROP 1
+#define PROP_MSG_SETPROP2 0x00020001
+
+// Status codes returned by init (but not passed from libc to the caller).
+#define PROP_SUCCESS 0
+#define PROP_ERROR_READ_CMD 0x0004
+#define PROP_ERROR_READ_DATA 0x0008
+#define PROP_ERROR_READ_ONLY_PROPERTY 0x000B
+#define PROP_ERROR_INVALID_NAME 0x0010
+#define PROP_ERROR_INVALID_VALUE 0x0014
+#define PROP_ERROR_PERMISSION_DENIED 0x0018
+#define PROP_ERROR_INVALID_CMD 0x001B
+#define PROP_ERROR_HANDLE_CONTROL_MESSAGE 0x0020
+#define PROP_ERROR_SET_FAILED 0x0024
+
+/**
+ * Initializes the area to be used to store properties.
+ *
+ * Can only be done by the process that has write access to the property area,
+ * typically init.
+ *
+ * See __system_properties_init() for the equivalent for all other processes.
+ */
+int __system_property_area_init(void);
+
+/**
+ * Adds a new system property.
+ * Can only be done by the process that has write access to the property area --
+ * typically init -- which must handle sequencing to ensure that only one property is
+ * updated at a time.
+ *
+ * Returns 0 on success, -1 if the property area is full.
+ */
+int __system_property_add(const char* _Nonnull __name, unsigned int __name_length, const char* _Nonnull __value, unsigned int __value_length);
+
+/**
+ * Updates the value of a system property returned by __system_property_find().
+ * Can only be done by the process that has write access to the property area --
+ * typically init -- which must handle sequencing to ensure that only one property is
+ * updated at a time.
+ *
+ * Returns 0 on success, -1 if the parameters are incorrect.
+ */
+int __system_property_update(prop_info* _Nonnull __pi, const char* _Nonnull __value, unsigned int __value_length);
+
+/**
+ * Reloads the system properties from disk.
+ * Not intended for use by any apps except the Zygote.
+ * Should only be called from the main thread.
+ *
+ * Pointers received from functions such as __system_property_find()
+ * may be invalidated by calls to this function.
+ *
+ * Returns 0 on success, -1 otherwise.
+ *
+ * Available since API level 35.
+ */
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
+int __system_properties_zygote_reload(void) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
+
+/**
+ * Deprecated: previously for testing, but now that SystemProperties is its own
+ * testable class, there is never a reason to call this function and its
+ * implementation simply returns -1.
+ */
+int __system_property_set_filename(const char* _Nullable __unused __filename);
__END_DECLS
diff --git a/libc/include/sys/thread_properties.h b/libc/include/sys/thread_properties.h
index efd212a..b6214ee 100644
--- a/libc/include/sys/thread_properties.h
+++ b/libc/include/sys/thread_properties.h
@@ -50,6 +50,8 @@
*
* Available since API level 31.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(31)
void __libc_get_static_tls_bounds(void* _Nonnull * _Nonnull __static_tls_begin,
void* _Nonnull * _Nonnull __static_tls_end) __INTRODUCED_IN(31);
@@ -93,5 +95,7 @@
void* _Nonnull __dynamic_tls_end),
void (* _Nonnull __on_destruction)(void* _Nonnull __dynamic_tls_begin,
void* _Nonnull __dynamic_tls_end)) __INTRODUCED_IN(31);
+#endif /* __BIONIC_AVAILABILITY_GUARD(31) */
+
__END_DECLS
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 6ba7a37..d12c306 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -47,8 +47,12 @@
int utimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]);
#if defined(__USE_BSD)
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int futimes(int __fd, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
int lutimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
#endif
#if defined(__USE_GNU)
@@ -65,7 +69,11 @@
*
* Available since API level 26.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int futimesat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
#endif
#define timerclear(a) \
diff --git a/libc/include/sys/timerfd.h b/libc/include/sys/timerfd.h
index de1f55b..f7f1ffa 100644
--- a/libc/include/sys/timerfd.h
+++ b/libc/include/sys/timerfd.h
@@ -33,20 +33,24 @@
* @brief Timer file descriptors.
*/
-#include <fcntl.h> /* For O_CLOEXEC and O_NONBLOCK. */
-#include <time.h>
#include <sys/cdefs.h>
+
+#include <fcntl.h>
+#include <linux/timerfd.h>
+#include <time.h>
#include <sys/types.h>
__BEGIN_DECLS
-/** The timerfd_create() flag for a close-on-exec file descriptor. */
-#define TFD_CLOEXEC O_CLOEXEC
-/** The timerfd_create() flag for a non-blocking file descriptor. */
-#define TFD_NONBLOCK O_NONBLOCK
+/*! \macro TFD_CLOEXEC
+ * The timerfd_create() flag for a close-on-exec file descriptor.
+ */
+/*! \macro TFD_NONBLOCK
+ * The timerfd_create() flag for a non-blocking file descriptor.
+ */
/**
- * [timerfd_create(2)](http://man7.org/linux/man-pages/man2/timerfd_create.2.html) creates a
+ * [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html) creates a
* timer file descriptor.
*
* Returns the new file descriptor on success, and returns -1 and sets `errno` on failure.
@@ -59,7 +63,7 @@
#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
/**
- * [timerfd_settime(2)](http://man7.org/linux/man-pages/man2/timerfd_settime.2.html) starts or
+ * [timerfd_settime(2)](https://man7.org/linux/man-pages/man2/timerfd_settime.2.html) starts or
* stops a timer.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -67,7 +71,7 @@
int timerfd_settime(int __fd, int __flags, const struct itimerspec* _Nonnull __new_value, struct itimerspec* _Nullable __old_value);
/**
- * [timerfd_gettime(2)](http://man7.org/linux/man-pages/man2/timerfd_gettime.2.html) queries the
+ * [timerfd_gettime(2)](https://man7.org/linux/man-pages/man2/timerfd_gettime.2.html) queries the
* current timer settings.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/times.h b/libc/include/sys/times.h
index 8b6e91d..ac6ec18 100644
--- a/libc/include/sys/times.h
+++ b/libc/include/sys/times.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [times(2)](http://man7.org/linux/man-pages/man2/times.2.html) fills a buffer with the
+ * [times(2)](https://man7.org/linux/man-pages/man2/times.2.html) fills a buffer with the
* calling process' CPU usage.
*
* Returns a (possibly overflowed) absolute time on success,
diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h
index 4823edf..6fb58e4 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -40,12 +40,14 @@
__BEGIN_DECLS
/**
- * [adjtimex(2)](http://man7.org/linux/man-pages/man2/adjtimex.2.html) adjusts the kernel clock.
+ * [adjtimex(2)](https://man7.org/linux/man-pages/man2/adjtimex.2.html) adjusts the kernel clock.
*
* Returns the clock state on success, and returns -1 and sets `errno` on failure.
*
* Available since API level 24.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
int adjtimex(struct timex* _Nonnull __buf) __INTRODUCED_IN(24);
/**
@@ -56,5 +58,7 @@
* Available since API level 24.
*/
int clock_adjtime(clockid_t __clock, struct timex* _Nonnull __tx) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
__END_DECLS
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index 4622a4e..0446260 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -29,9 +29,10 @@
#ifndef _SYS_TYPES_H_
#define _SYS_TYPES_H_
+#include <sys/cdefs.h>
+
#include <stddef.h>
#include <stdint.h>
-#include <sys/cdefs.h>
#include <linux/types.h>
#include <linux/posix_types.h>
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index c8c64ae..eff3b14 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [readv(2)](http://man7.org/linux/man-pages/man2/readv.2.html) reads
+ * [readv(2)](https://man7.org/linux/man-pages/man2/readv.2.html) reads
* from an fd into the `__count` buffers described by `__iov`.
*
* Returns the number of bytes read on success,
@@ -49,7 +49,7 @@
ssize_t readv(int __fd, const struct iovec* _Nonnull __iov, int __count);
/**
- * [writev(2)](http://man7.org/linux/man-pages/man2/writev.2.html) writes
+ * [writev(2)](https://man7.org/linux/man-pages/man2/writev.2.html) writes
* to an fd from the `__count` buffers described by `__iov`.
*
* Returns the number of bytes written on success,
@@ -60,7 +60,7 @@
#if defined(__USE_GNU)
/**
- * [preadv(2)](http://man7.org/linux/man-pages/man2/preadv.2.html) reads
+ * [preadv(2)](https://man7.org/linux/man-pages/man2/preadv.2.html) reads
* from an fd into the `__count` buffers described by `__iov`, starting at
* offset `__offset` into the file.
*
@@ -69,10 +69,12 @@
*
* Available since API level 24.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(24)
ssize_t preadv(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
/**
- * [pwritev(2)](http://man7.org/linux/man-pages/man2/pwritev.2.html) writes
+ * [pwritev(2)](https://man7.org/linux/man-pages/man2/pwritev.2.html) writes
* to an fd from the `__count` buffers described by `__iov`, starting at offset
* `__offset` into the file.
*
@@ -96,9 +98,11 @@
* Available since API level 24.
*/
ssize_t pwritev64(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+#endif /* __BIONIC_AVAILABILITY_GUARD(24) */
+
/**
- * [preadv2(2)](http://man7.org/linux/man-pages/man2/preadv2.2.html) reads
+ * [preadv2(2)](https://man7.org/linux/man-pages/man2/preadv2.2.html) reads
* from an fd into the `__count` buffers described by `__iov`, starting at
* offset `__offset` into the file, with the given flags.
*
@@ -107,10 +111,12 @@
*
* Available since API level 33.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(33)
ssize_t preadv2(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
/**
- * [pwritev2(2)](http://man7.org/linux/man-pages/man2/pwritev2.2.html) writes
+ * [pwritev2(2)](https://man7.org/linux/man-pages/man2/pwritev2.2.html) writes
* to an fd from the `__count` buffers described by `__iov`, starting at offset
* `__offset` into the file, with the given flags.
*
@@ -134,9 +140,11 @@
* Available since API level 33.
*/
ssize_t pwritev64v2(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+#endif /* __BIONIC_AVAILABILITY_GUARD(33) */
+
/**
- * [process_vm_readv(2)](http://man7.org/linux/man-pages/man2/process_vm_readv.2.html)
+ * [process_vm_readv(2)](https://man7.org/linux/man-pages/man2/process_vm_readv.2.html)
* reads from the address space of another process.
*
* Returns the number of bytes read on success,
@@ -144,10 +152,12 @@
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
ssize_t process_vm_readv(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
/**
- * [process_vm_writev(2)](http://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
+ * [process_vm_writev(2)](https://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
* writes to the address space of another process.
*
* Returns the number of bytes read on success,
@@ -156,6 +166,8 @@
* Available since API level 23.
*/
ssize_t process_vm_writev(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#endif
diff --git a/libc/include/sys/un.h b/libc/include/sys/un.h
index 83c1d17..c2bfcb0 100644
--- a/libc/include/sys/un.h
+++ b/libc/include/sys/un.h
@@ -33,9 +33,10 @@
* @brief Unix domain sockets.
*/
+#include <sys/cdefs.h>
+
#include <bits/sa_family_t.h>
#include <linux/un.h>
-#include <sys/cdefs.h>
#if defined(__USE_BSD) || defined(__USE_GNU)
#include <string.h>
diff --git a/libc/include/sys/utsname.h b/libc/include/sys/utsname.h
index aa8c1a0..23d1282 100644
--- a/libc/include/sys/utsname.h
+++ b/libc/include/sys/utsname.h
@@ -57,7 +57,7 @@
};
/**
- * [uname(2)](http://man7.org/linux/man-pages/man2/uname.2.html) returns information
+ * [uname(2)](https://man7.org/linux/man-pages/man2/uname.2.html) returns information
* about the kernel.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
diff --git a/libc/include/sys/vfs.h b/libc/include/sys/vfs.h
index 3579799..5d078be 100644
--- a/libc/include/sys/vfs.h
+++ b/libc/include/sys/vfs.h
@@ -29,8 +29,9 @@
#ifndef _SYS_VFS_H_
#define _SYS_VFS_H_
-#include <stdint.h>
#include <sys/cdefs.h>
+
+#include <stdint.h>
#include <sys/types.h>
__BEGIN_DECLS
@@ -40,6 +41,8 @@
typedef __fsid_t fsid_t;
#if defined(__LP64__)
+/* We can't just use the kernel struct statfs directly here because
+ * it's reused for both struct statfs *and* struct statfs64. */
#define __STATFS64_BODY \
uint64_t f_type; \
uint64_t f_bsize; \
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 5208366..632aa43 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -28,8 +28,9 @@
#pragma once
-#include <bits/wait.h>
#include <sys/cdefs.h>
+
+#include <bits/wait.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <linux/wait.h>
diff --git a/libc/include/sys/xattr.h b/libc/include/sys/xattr.h
index 745f50c..ebe4eb8 100644
--- a/libc/include/sys/xattr.h
+++ b/libc/include/sys/xattr.h
@@ -33,14 +33,15 @@
* @brief Extended attribute functions.
*/
-#include <linux/xattr.h>
#include <sys/cdefs.h>
+
+#include <linux/xattr.h>
#include <sys/types.h>
__BEGIN_DECLS
/**
- * [fsetxattr(2)](http://man7.org/linux/man-pages/man2/fsetxattr.2.html)
+ * [fsetxattr(2)](https://man7.org/linux/man-pages/man2/fsetxattr.2.html)
* sets an extended attribute on the file referred to by the given file
* descriptor.
*
@@ -55,7 +56,7 @@
int fsetxattr(int __fd, const char* _Nonnull __name, const void* _Nullable __value, size_t __size, int __flags);
/**
- * [setxattr(2)](http://man7.org/linux/man-pages/man2/setxattr.2.html)
+ * [setxattr(2)](https://man7.org/linux/man-pages/man2/setxattr.2.html)
* sets an extended attribute on the file referred to by the given path.
*
* A `size` of 0 can be used to set an empty value, in which case `value` is
@@ -69,7 +70,7 @@
int setxattr(const char* _Nonnull __path, const char* _Nonnull __name, const void* _Nullable __value, size_t __size, int __flags);
/**
- * [lsetxattr(2)](http://man7.org/linux/man-pages/man2/lsetxattr.2.html)
+ * [lsetxattr(2)](https://man7.org/linux/man-pages/man2/lsetxattr.2.html)
* sets an extended attribute on the file referred to by the given path, which
* is the link itself rather than its target in the case of a symbolic link.
*
@@ -84,7 +85,7 @@
int lsetxattr(const char* _Nonnull __path, const char* _Nonnull __name, const void* _Nullable __value, size_t __size, int __flags);
/**
- * [fgetxattr(2)](http://man7.org/linux/man-pages/man2/fgetxattr.2.html)
+ * [fgetxattr(2)](https://man7.org/linux/man-pages/man2/fgetxattr.2.html)
* gets an extended attribute on the file referred to by the given file
* descriptor.
*
@@ -96,7 +97,7 @@
ssize_t fgetxattr(int __fd, const char* _Nonnull __name, void* _Nullable __value, size_t __size);
/**
- * [getxattr(2)](http://man7.org/linux/man-pages/man2/getxattr.2.html)
+ * [getxattr(2)](https://man7.org/linux/man-pages/man2/getxattr.2.html)
* gets an extended attribute on the file referred to by the given path.
*
* A `size` of 0 can be used to query the current length, in which case `value` is ignored and may be null.
@@ -107,7 +108,7 @@
ssize_t getxattr(const char* _Nonnull __path, const char* _Nonnull __name, void* _Nullable __value, size_t __size);
/**
- * [lgetxattr(2)](http://man7.org/linux/man-pages/man2/lgetxattr.2.html)
+ * [lgetxattr(2)](https://man7.org/linux/man-pages/man2/lgetxattr.2.html)
* gets an extended attribute on the file referred to by the given path, which
* is the link itself rather than its target in the case of a symbolic link.
*
@@ -119,7 +120,7 @@
ssize_t lgetxattr(const char* _Nonnull __path, const char* _Nonnull __name, void* _Nullable __value, size_t __size);
/**
- * [flistxattr(2)](http://man7.org/linux/man-pages/man2/flistxattr.2.html)
+ * [flistxattr(2)](https://man7.org/linux/man-pages/man2/flistxattr.2.html)
* lists the extended attributes on the file referred to by the given file
* descriptor.
*
@@ -131,7 +132,7 @@
ssize_t flistxattr(int __fd, char* _Nullable __list, size_t __size);
/**
- * [listxattr(2)](http://man7.org/linux/man-pages/man2/listxattr.2.html)
+ * [listxattr(2)](https://man7.org/linux/man-pages/man2/listxattr.2.html)
* lists the extended attributes on the file referred to by the given path.
*
* A `size` of 0 can be used to query the current length, in which case `list` is ignored and may be null.
@@ -142,7 +143,7 @@
ssize_t listxattr(const char* _Nonnull __path, char* _Nullable __list, size_t __size);
/**
- * [llistxattr(2)](http://man7.org/linux/man-pages/man2/llistxattr.2.html)
+ * [llistxattr(2)](https://man7.org/linux/man-pages/man2/llistxattr.2.html)
* lists the extended attributes on the file referred to by the given path, which
* is the link itself rather than its target in the case of a symbolic link.
*
@@ -154,7 +155,7 @@
ssize_t llistxattr(const char* _Nonnull __path, char* _Nullable __list, size_t __size);
/**
- * [fremovexattr(2)](http://man7.org/linux/man-pages/man2/fremovexattr.2.html)
+ * [fremovexattr(2)](https://man7.org/linux/man-pages/man2/fremovexattr.2.html)
* removes an extended attribute on the file referred to by the given file
* descriptor.
*
@@ -163,7 +164,7 @@
int fremovexattr(int __fd, const char* _Nonnull __name);
/**
- * [lremovexattr(2)](http://man7.org/linux/man-pages/man2/lremovexattr.2.html)
+ * [lremovexattr(2)](https://man7.org/linux/man-pages/man2/lremovexattr.2.html)
* removes an extended attribute on the file referred to by the given path, which
* is the link itself rather than its target in the case of a symbolic link.
*
@@ -172,7 +173,7 @@
int lremovexattr(const char* _Nonnull __path, const char* _Nonnull __name);
/**
- * [removexattr(2)](http://man7.org/linux/man-pages/man2/removexattr.2.html)
+ * [removexattr(2)](https://man7.org/linux/man-pages/man2/removexattr.2.html)
* removes an extended attribute on the file referred to by the given path.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index 1e2fcc4..7a594f1 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -56,8 +56,9 @@
#pragma once
-#include <stdio.h>
#include <sys/cdefs.h>
+
+#include <stdio.h>
#include <stdarg.h>
__BEGIN_DECLS
@@ -212,34 +213,34 @@
#endif
/**
- * [closelog(3)](http://man7.org/linux/man-pages/man3/closelog.3.html) does
+ * [closelog(3)](https://man7.org/linux/man-pages/man3/closelog.3.html) does
* nothing on Android.
*/
void closelog(void);
/**
- * [openlog(3)](http://man7.org/linux/man-pages/man3/openlog.3.html) sets
+ * [openlog(3)](https://man7.org/linux/man-pages/man3/openlog.3.html) sets
* the log tag to `__prefix`, which can be NULL to return to the default of
* getprogname(). On Android, the other two arguments are ignored.
*/
void openlog(const char* _Nullable __prefix, int __option, int __facility);
/**
- * [setlogmask(3)](http://man7.org/linux/man-pages/man3/setlogmask.3.html)
+ * [setlogmask(3)](https://man7.org/linux/man-pages/man3/setlogmask.3.html)
* sets which log priorities will actually be logged. See `LOG_MASK` and
* `LOG_UPTO`.
*/
int setlogmask(int __mask);
/**
- * [syslog(3)](http://man7.org/linux/man-pages/man3/syslog.3.html) formats
+ * [syslog(3)](https://man7.org/linux/man-pages/man3/syslog.3.html) formats
* the printf()-like message and logs it with the given priority, unless
* suppressed by setlogmask(). On Android, the output goes to logcat.
*/
void syslog(int __priority, const char* _Nonnull __fmt, ...) __printflike(2, 3);
/**
- * [vsyslog(3)](http://man7.org/linux/man-pages/man3/vsyslog.3.html) formats
+ * [vsyslog(3)](https://man7.org/linux/man-pages/man3/vsyslog.3.html) formats
* the vprintf()-like message and logs it with the given priority, unless
* suppressed by setlogmask(). On Android, the output goes to logcat.
*/
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 7abff5d..5eecfcd 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -46,25 +46,25 @@
// in cfmakeraw() and cfsetspeed() until 28.
/**
- * [cfgetispeed(3)](http://man7.org/linux/man-pages/man3/cfgetispeed.3.html)
+ * [cfgetispeed(3)](https://man7.org/linux/man-pages/man3/cfgetispeed.3.html)
* returns the terminal input baud rate.
*/
speed_t cfgetispeed(const struct termios* _Nonnull __t);
/**
- * [cfgetospeed(3)](http://man7.org/linux/man-pages/man3/cfgetospeed.3.html)
+ * [cfgetospeed(3)](https://man7.org/linux/man-pages/man3/cfgetospeed.3.html)
* returns the terminal output baud rate.
*/
speed_t cfgetospeed(const struct termios* _Nonnull __t);
/**
- * [cfmakeraw(3)](http://man7.org/linux/man-pages/man3/cfmakeraw.3.html)
+ * [cfmakeraw(3)](https://man7.org/linux/man-pages/man3/cfmakeraw.3.html)
* configures the terminal for "raw" mode.
*/
void cfmakeraw(struct termios* _Nonnull __t);
/**
- * [cfsetspeed(3)](http://man7.org/linux/man-pages/man3/cfsetspeed.3.html)
+ * [cfsetspeed(3)](https://man7.org/linux/man-pages/man3/cfsetspeed.3.html)
* sets the terminal input and output baud rate.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -72,7 +72,7 @@
int cfsetspeed(struct termios* _Nonnull __t, speed_t __speed);
/**
- * [cfsetispeed(3)](http://man7.org/linux/man-pages/man3/cfsetispeed.3.html)
+ * [cfsetispeed(3)](https://man7.org/linux/man-pages/man3/cfsetispeed.3.html)
* sets the terminal input baud rate.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -80,7 +80,7 @@
int cfsetispeed(struct termios* _Nonnull _t, speed_t __speed);
/**
- * [cfsetospeed(3)](http://man7.org/linux/man-pages/man3/cfsetospeed.3.html)
+ * [cfsetospeed(3)](https://man7.org/linux/man-pages/man3/cfsetospeed.3.html)
* sets the terminal output baud rate.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -88,7 +88,7 @@
int cfsetospeed(struct termios* _Nonnull __t, speed_t __speed);
/**
- * [tcdrain(3)](http://man7.org/linux/man-pages/man3/tcdrain.3.html)
+ * [tcdrain(3)](https://man7.org/linux/man-pages/man3/tcdrain.3.html)
* waits until all output has been written.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -96,7 +96,7 @@
int tcdrain(int __fd);
/**
- * [tcflow(3)](http://man7.org/linux/man-pages/man3/tcflow.3.html)
+ * [tcflow(3)](https://man7.org/linux/man-pages/man3/tcflow.3.html)
* suspends (`TCOOFF`) or resumes (`TCOON`) output, or transmits a
* stop (`TCIOFF`) or start (`TCION`) to suspend or resume input.
*
@@ -105,7 +105,7 @@
int tcflow(int __fd, int __action);
/**
- * [tcflush(3)](http://man7.org/linux/man-pages/man3/tcflush.3.html)
+ * [tcflush(3)](https://man7.org/linux/man-pages/man3/tcflush.3.html)
* discards pending input (`TCIFLUSH`), output (`TCOFLUSH`), or
* both (`TCIOFLUSH`). (In `<stdio.h>` terminology, this is a purge rather
* than a flush.)
@@ -115,7 +115,7 @@
int tcflush(int __fd, int __queue);
/**
- * [tcgetattr(3)](http://man7.org/linux/man-pages/man3/tcgetattr.3.html)
+ * [tcgetattr(3)](https://man7.org/linux/man-pages/man3/tcgetattr.3.html)
* reads the configuration of the given terminal.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -123,7 +123,7 @@
int tcgetattr(int __fd, struct termios* _Nonnull __t);
/**
- * [tcgetsid(3)](http://man7.org/linux/man-pages/man3/tcgetsid.3.html)
+ * [tcgetsid(3)](https://man7.org/linux/man-pages/man3/tcgetsid.3.html)
* returns the session id corresponding to the given fd.
*
* Returns a non-negative session id on success and
@@ -132,7 +132,7 @@
pid_t tcgetsid(int __fd);
/**
- * [tcsendbreak(3)](http://man7.org/linux/man-pages/man3/tcsendbreak.3.html)
+ * [tcsendbreak(3)](https://man7.org/linux/man-pages/man3/tcsendbreak.3.html)
* sends a break.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -140,7 +140,7 @@
int tcsendbreak(int __fd, int __duration);
/**
- * [tcsetattr(3)](http://man7.org/linux/man-pages/man3/tcsetattr.3.html)
+ * [tcsetattr(3)](https://man7.org/linux/man-pages/man3/tcsetattr.3.html)
* writes the configuration of the given terminal.
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
diff --git a/libc/include/threads.h b/libc/include/threads.h
index b1008de..1074fa4 100644
--- a/libc/include/threads.h
+++ b/libc/include/threads.h
@@ -72,8 +72,10 @@
thrd_timedout = 4,
};
-#if !defined(__cplusplus)
-#define thread_local _Thread_local
+/* `thread_local` is a keyword in C++11 and C23; C11 had `_Thread_local` instead. */
+#if !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L && __STDC_VERSION__ < 202311L)
+# undef thread_local
+# define thread_local _Thread_local
#endif
__BEGIN_DECLS
diff --git a/libc/include/time.h b/libc/include/time.h
index f448851..777e648 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -100,7 +100,7 @@
#define TM_ZONE tm_zone
/**
- * [time(2)](http://man7.org/linux/man-pages/man2/time.2.html) returns
+ * [time(2)](https://man7.org/linux/man-pages/man2/time.2.html) returns
* the number of seconds since the Unix epoch (1970-01-01 00:00:00 +0000).
*
* Returns the time in seconds on success, and returns -1 and sets `errno` on failure.
@@ -108,7 +108,7 @@
time_t time(time_t* _Nullable __t);
/**
- * [nanosleep(2)](http://man7.org/linux/man-pages/man2/nanosleep.2.html) sleeps
+ * [nanosleep(2)](https://man7.org/linux/man-pages/man2/nanosleep.2.html) sleeps
* for at least the given time (or until a signal arrives).
*
* Returns 0 on success, and returns -1 and sets `errno` on failure. If the sleep
@@ -118,7 +118,7 @@
int nanosleep(const struct timespec* _Nonnull __duration, struct timespec* _Nullable __remainder);
/**
- * [asctime(3)](http://man7.org/linux/man-pages/man3/asctime.3p.html) formats
+ * [asctime(3)](https://man7.org/linux/man-pages/man3/asctime.3p.html) formats
* the time `tm` as a string.
*
* Returns a pointer to a string on success, and returns NULL on failure.
@@ -130,7 +130,7 @@
char* _Nullable asctime(const struct tm* _Nonnull __tm);
/**
- * [asctime_r(3)](http://man7.org/linux/man-pages/man3/asctime_r.3p.html) formats
+ * [asctime_r(3)](https://man7.org/linux/man-pages/man3/asctime_r.3p.html) formats
* the time `tm` as a string in the given buffer `buf`.
*
* Returns a pointer to a string on success, and returns NULL on failure.
@@ -140,7 +140,7 @@
char* _Nullable asctime_r(const struct tm* _Nonnull __tm, char* _Nonnull __buf);
/**
- * [difftime(3)](http://man7.org/linux/man-pages/man3/difftime.3.html) returns
+ * [difftime(3)](https://man7.org/linux/man-pages/man3/difftime.3.html) returns
* the difference between two times.
*
* Returns the difference in seconds.
@@ -148,7 +148,7 @@
double difftime(time_t __lhs, time_t __rhs);
/**
- * [mktime(3)](http://man7.org/linux/man-pages/man3/mktime.3p.html) converts
+ * [mktime(3)](https://man7.org/linux/man-pages/man3/mktime.3p.html) converts
* broken-down time `tm` into the number of seconds since the Unix epoch.
*
* See tzset() for details of how the timezone is set, and mktime_rz()
@@ -166,10 +166,14 @@
*
* Available since API level 35.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
time_t mktime_z(timezone_t _Nonnull __tz, struct tm* _Nonnull __tm) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
/**
- * [localtime(3)](http://man7.org/linux/man-pages/man3/localtime.3p.html) converts
+ * [localtime(3)](https://man7.org/linux/man-pages/man3/localtime.3p.html) converts
* the number of seconds since the Unix epoch in `t` to a broken-down time, taking
* the device's timezone into account.
*
@@ -180,7 +184,7 @@
struct tm* _Nullable localtime(const time_t* _Nonnull __t);
/**
- * [localtime_r(3)](http://man7.org/linux/man-pages/man3/localtime_r.3p.html) converts
+ * [localtime_r(3)](https://man7.org/linux/man-pages/man3/localtime_r.3p.html) converts
* the number of seconds since the Unix epoch in `t` to a broken-down time.
* That broken-down time will be written to the given struct `tm`.
*
@@ -200,7 +204,11 @@
*
* Available since API level 35.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
struct tm* _Nullable localtime_rz(timezone_t _Nonnull __tz, const time_t* _Nonnull __t, struct tm* _Nonnull __tm) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
/**
* Inverse of localtime().
@@ -208,7 +216,7 @@
time_t timelocal(struct tm* _Nonnull __tm);
/**
- * [gmtime(3)](http://man7.org/linux/man-pages/man3/gmtime.3p.html) converts
+ * [gmtime(3)](https://man7.org/linux/man-pages/man3/gmtime.3p.html) converts
* the number of seconds since the Unix epoch in `t` to a broken-down time, using
* UTC (historically also known as GMT).
*
@@ -219,7 +227,7 @@
struct tm* _Nullable gmtime(const time_t* _Nonnull __t);
/**
- * [gmtime_r(3)](http://man7.org/linux/man-pages/man3/gmtime_r.3p.html) converts
+ * [gmtime_r(3)](https://man7.org/linux/man-pages/man3/gmtime_r.3p.html) converts
* the number of seconds since the Unix epoch in `t` to a broken-down time, using
* UTC (historically also known as GMT).
*
@@ -235,7 +243,7 @@
time_t timegm(struct tm* _Nonnull __tm);
/**
- * [strptime(3)](http://man7.org/linux/man-pages/man3/strptime.3.html) parses
+ * [strptime(3)](https://man7.org/linux/man-pages/man3/strptime.3.html) parses
* a string `s` assuming format `fmt` into broken-down time `tm`.
*
* Returns a pointer to the first character _not_ parsed, or null if no characters were parsed.
@@ -245,10 +253,10 @@
/**
* Equivalent to strptime() on Android where only C/POSIX locales are available.
*/
-char* _Nullable strptime_l(const char* _Nonnull __s, const char* _Nonnull __fmt, struct tm* _Nonnull __tm, locale_t _Nonnull __l) __strftimelike(2) __INTRODUCED_IN(28);
+char* _Nullable strptime_l(const char* _Nonnull __s, const char* _Nonnull __fmt, struct tm* _Nonnull __tm, locale_t _Nonnull __l) __strftimelike(2) __RENAME(strptime);
/**
- * [strftime(3)](http://man7.org/linux/man-pages/man3/strftime.3.html) formats
+ * [strftime(3)](https://man7.org/linux/man-pages/man3/strftime.3.html) formats
* a broken-down time `tm` into the buffer `buf` using format `fmt`.
*
* Returns a pointer to the first character _not_ parsed, or null if no characters were parsed.
@@ -261,7 +269,7 @@
size_t strftime_l(char* _Nonnull __buf, size_t __n, const char* _Nonnull __fmt, const struct tm* _Nullable __tm, locale_t _Nonnull __l) __strftimelike(3);
/**
- * [ctime(3)](http://man7.org/linux/man-pages/man3/ctime.3p.html) formats
+ * [ctime(3)](https://man7.org/linux/man-pages/man3/ctime.3p.html) formats
* the time `tm` as a string.
*
* Returns a pointer to a string on success, and returns NULL on failure.
@@ -273,7 +281,7 @@
char* _Nullable ctime(const time_t* _Nonnull __t);
/**
- * [ctime_r(3)](http://man7.org/linux/man-pages/man3/ctime.3p.html) formats
+ * [ctime_r(3)](https://man7.org/linux/man-pages/man3/ctime_r.3p.html) formats
* the time `tm` as a string in the given buffer `buf`.
*
* Returns a pointer to a string on success, and returns NULL on failure.
@@ -283,7 +291,7 @@
char* _Nullable ctime_r(const time_t* _Nonnull __t, char* _Nonnull __buf);
/**
- * [tzset(3)](http://man7.org/linux/man-pages/man3/tzset.3.html) tells
+ * [tzset(3)](https://man7.org/linux/man-pages/man3/tzset.3.html) tells
* libc that the timezone has changed.
*
* tzset() on Android looks at both the system property
@@ -314,6 +322,8 @@
*
* Available since API level 35.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
timezone_t _Nullable tzalloc(const char* _Nullable __id) __INTRODUCED_IN(35);
/**
@@ -326,9 +336,11 @@
* Available since API level 35.
*/
void tzfree(timezone_t _Nullable __tz) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
/**
- * [clock(3)](http://man7.org/linux/man-pages/man3/clock.3.html)
+ * [clock(3)](https://man7.org/linux/man-pages/man3/clock.3.html)
* returns an approximation of CPU time used, equivalent to
* `clock_gettime(CLOCK_PROCESS_CPUTIME_ID)` but with more confusing
* units. Use `CLOCKS_PER_SEC` to convert the result to seconds.
@@ -340,15 +352,19 @@
clock_t clock(void);
/**
- * [clock_getcpuclockid(3)](http://man7.org/linux/man-pages/man3/clock_getcpuclockid.3.html)
+ * [clock_getcpuclockid(3)](https://man7.org/linux/man-pages/man3/clock_getcpuclockid.3.html)
* gets the clock ID of the cpu-time clock for the given `pid`.
*
* Returns 0 on success, and returns -1 and returns an error number on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int clock_getcpuclockid(pid_t __pid, clockid_t* _Nonnull __clock) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
/**
- * [clock_getres(2)](http://man7.org/linux/man-pages/man2/clock_getres.2.html)
+ * [clock_getres(2)](https://man7.org/linux/man-pages/man2/clock_getres.2.html)
* gets the resolution of the given clock.
*
* Returns 0 on success, and returns -1 and returns an error number on failure.
@@ -356,7 +372,7 @@
int clock_getres(clockid_t __clock, struct timespec* _Nullable __resolution);
/**
- * [clock_gettime(2)](http://man7.org/linux/man-pages/man2/clock_gettime.2.html)
+ * [clock_gettime(2)](https://man7.org/linux/man-pages/man2/clock_gettime.2.html)
* gets the time according to the given clock.
*
* Returns 0 on success, and returns -1 and returns an error number on failure.
@@ -364,7 +380,7 @@
int clock_gettime(clockid_t __clock, struct timespec* _Nonnull __ts);
/**
- * [clock_nanosleep(2)](http://man7.org/linux/man-pages/man2/clock_nanosleep.2.html)
+ * [clock_nanosleep(2)](https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html)
* sleeps for the given time (or until the given time if the TIMER_ABSTIME flag
* is used), as measured by the given clock.
*
@@ -375,7 +391,7 @@
int clock_nanosleep(clockid_t __clock, int __flags, const struct timespec* _Nonnull __time, struct timespec* _Nullable __remainder);
/**
- * [clock_settime(2)](http://man7.org/linux/man-pages/man2/clock_settime.2.html)
+ * [clock_settime(2)](https://man7.org/linux/man-pages/man2/clock_settime.2.html)
* sets the time for the given clock.
*
* Returns 0 on success, and returns -1 and returns an error number on failure.
@@ -383,7 +399,7 @@
int clock_settime(clockid_t __clock, const struct timespec* _Nonnull __ts);
/**
- * [timer_create(2)](http://man7.org/linux/man-pages/man2/timer_create.2.html)
+ * [timer_create(2)](https://man7.org/linux/man-pages/man2/timer_create.2.html)
* creates a POSIX timer.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -391,7 +407,7 @@
int timer_create(clockid_t __clock, struct sigevent* _Nullable __event, timer_t _Nonnull * _Nonnull __timer_ptr);
/**
- * [timer_delete(2)](http://man7.org/linux/man-pages/man2/timer_delete.2.html)
+ * [timer_delete(2)](https://man7.org/linux/man-pages/man2/timer_delete.2.html)
* destroys a POSIX timer.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -399,7 +415,7 @@
int timer_delete(timer_t _Nonnull __timer);
/**
- * [timer_settime(2)](http://man7.org/linux/man-pages/man2/timer_settime.2.html)
+ * [timer_settime(2)](https://man7.org/linux/man-pages/man2/timer_settime.2.html)
* starts or stops a POSIX timer.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -407,7 +423,7 @@
int timer_settime(timer_t _Nonnull __timer, int __flags, const struct itimerspec* _Nonnull __new_value, struct itimerspec* _Nullable __old_value);
/**
- * [timer_gettime(2)](http://man7.org/linux/man-pages/man2/timer_gettime.2.html)
+ * [timer_gettime(2)](https://man7.org/linux/man-pages/man2/timer_gettime.2.html)
* gets the time until the given timer next fires.
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
@@ -415,7 +431,7 @@
int timer_gettime(timer_t _Nonnull _timer, struct itimerspec* _Nonnull __ts);
/**
- * [timer_getoverrun(2)](http://man7.org/linux/man-pages/man2/timer_getoverrun.2.html)
+ * [timer_getoverrun(2)](https://man7.org/linux/man-pages/man2/timer_getoverrun.2.html)
* gets the overrun count (the number of times the timer should have fired, but
* didn't) for the last time the timer fired.
*
@@ -459,7 +475,11 @@
* Available since API level 29 for TIME_UTC; other bases arrived later.
* Code for Android should prefer clock_gettime().
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(29)
int timespec_get(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(29);
+#endif /* __BIONIC_AVAILABILITY_GUARD(29) */
+
/**
* timespec_getres(3) is equivalent to clock_getres() for the clock corresponding to the given base.
@@ -469,6 +489,10 @@
* Available since API level 35.
* Code for Android should prefer clock_gettime().
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
int timespec_getres(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
__END_DECLS
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 626372a..94efb2d 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -33,9 +33,10 @@
* @brief Unicode functions.
*/
-#include <stddef.h>
#include <sys/cdefs.h>
+#include <stddef.h>
+
#include <bits/bionic_multibyte_result.h>
#include <bits/mbstate_t.h>
@@ -55,7 +56,7 @@
#define __STD_UTF_32__ 1
/**
- * [c16rtomb(3)](http://man7.org/linux/man-pages/man3/c16rtomb.3.html) converts a single UTF-16
+ * [c16rtomb(3)](https://man7.org/linux/man-pages/man3/c16rtomb.3.html) converts a single UTF-16
* character to UTF-8.
*
* Returns the number of bytes written to `__buf` on success, and returns -1 and sets `errno`
@@ -64,7 +65,7 @@
size_t c16rtomb(char* _Nullable __buf, char16_t __ch16, mbstate_t* _Nullable __ps);
/**
- * [c32rtomb(3)](http://man7.org/linux/man-pages/man3/c32rtomb.3.html) converts a single UTF-32
+ * [c32rtomb(3)](https://man7.org/linux/man-pages/man3/c32rtomb.3.html) converts a single UTF-32
* character to UTF-8.
*
* Returns the number of bytes written to `__buf` on success, and returns -1 and sets `errno`
@@ -73,13 +74,13 @@
size_t c32rtomb(char* _Nullable __buf, char32_t __ch32, mbstate_t* _Nullable __ps);
/**
- * [mbrtoc16(3)](http://man7.org/linux/man-pages/man3/mbrtoc16.3.html) converts the next UTF-8
+ * [mbrtoc16(3)](https://man7.org/linux/man-pages/man3/mbrtoc16.3.html) converts the next UTF-8
* sequence to a UTF-16 code point.
*/
size_t mbrtoc16(char16_t* _Nullable __ch16, const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
/**
- * [mbrtoc32(3)](http://man7.org/linux/man-pages/man3/mbrtoc32.3.html) converts the next UTF-8
+ * [mbrtoc32(3)](https://man7.org/linux/man-pages/man3/mbrtoc32.3.html) converts the next UTF-8
* sequence to a UTF-32 code point.
*/
size_t mbrtoc32(char32_t* _Nullable __ch32, const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 2552ca8..808568a 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -28,8 +28,9 @@
#pragma once
-#include <stddef.h>
#include <sys/cdefs.h>
+
+#include <stddef.h>
#include <sys/types.h>
#include <sys/select.h>
@@ -79,7 +80,7 @@
__noreturn void _exit(int __status);
/**
- * [fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html) creates a new
+ * [fork(2)](https://man7.org/linux/man-pages/man2/fork.2.html) creates a new
* process. fork() runs any handlers set by pthread_atfork().
*
* Returns 0 in the child, the pid of the child in the parent,
@@ -100,10 +101,14 @@
*
* Available since API level 35.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(35)
pid_t _Fork(void) __INTRODUCED_IN(35);
+#endif /* __BIONIC_AVAILABILITY_GUARD(35) */
+
/**
- * [vfork(2)](http://man7.org/linux/man-pages/man2/vfork.2.html) creates a new
+ * [vfork(2)](https://man7.org/linux/man-pages/man2/vfork.2.html) creates a new
* process. vfork() differs from fork() in that it does not run any handlers
* set by pthread_atfork(), and the parent is suspended until the child calls
* exec() or exits.
@@ -114,7 +119,7 @@
pid_t vfork(void) __returns_twice;
/**
- * [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html) returns
+ * [getpid(2)](https://man7.org/linux/man-pages/man2/getpid.2.html) returns
* the caller's process ID.
*
* Returns the caller's process ID.
@@ -122,7 +127,7 @@
pid_t getpid(void);
/**
- * [gettid(2)](http://man7.org/linux/man-pages/man2/gettid.2.html) returns
+ * [gettid(2)](https://man7.org/linux/man-pages/man2/gettid.2.html) returns
* the caller's thread ID.
*
* Returns the caller's thread ID.
@@ -145,12 +150,16 @@
int execlp(const char* _Nonnull __file, const char* _Nullable __arg0, ...) __attribute__((__sentinel__));
int execle(const char* _Nonnull __path, const char* _Nullable __arg0, ... /*, char* const* __envp */)
__attribute__((__sentinel__(1)));
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int fexecve(int __fd, char* _Nullable const* _Nullable __argv, char* _Nullable const* _Nullable __envp) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
int nice(int __incr);
/**
- * [setegid(2)](http://man7.org/linux/man-pages/man2/setegid.2.html) sets
+ * [setegid(2)](https://man7.org/linux/man-pages/man2/setegid.2.html) sets
* the effective group ID.
*
* On Android, this function only affects the calling thread, not all threads
@@ -161,7 +170,7 @@
int setegid(gid_t __gid);
/**
- * [seteuid(2)](http://man7.org/linux/man-pages/man2/seteuid.2.html) sets
+ * [seteuid(2)](https://man7.org/linux/man-pages/man2/seteuid.2.html) sets
* the effective user ID.
*
* On Android, this function only affects the calling thread, not all threads
@@ -172,7 +181,7 @@
int seteuid(uid_t __uid);
/**
- * [setgid(2)](http://man7.org/linux/man-pages/man2/setgid.2.html) sets
+ * [setgid(2)](https://man7.org/linux/man-pages/man2/setgid.2.html) sets
* the group ID.
*
* On Android, this function only affects the calling thread, not all threads
@@ -183,7 +192,7 @@
int setgid(gid_t __gid);
/**
- * [setregid(2)](http://man7.org/linux/man-pages/man2/setregid.2.html) sets
+ * [setregid(2)](https://man7.org/linux/man-pages/man2/setregid.2.html) sets
* the real and effective group IDs (use -1 to leave an ID unchanged).
*
* On Android, this function only affects the calling thread, not all threads
@@ -194,7 +203,7 @@
int setregid(gid_t __rgid, gid_t __egid);
/**
- * [setresgid(2)](http://man7.org/linux/man-pages/man2/setresgid.2.html) sets
+ * [setresgid(2)](https://man7.org/linux/man-pages/man2/setresgid.2.html) sets
* the real, effective, and saved group IDs (use -1 to leave an ID unchanged).
*
* On Android, this function only affects the calling thread, not all threads
@@ -205,7 +214,7 @@
int setresgid(gid_t __rgid, gid_t __egid, gid_t __sgid);
/**
- * [setresuid(2)](http://man7.org/linux/man-pages/man2/setresuid.2.html) sets
+ * [setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html) sets
* the real, effective, and saved user IDs (use -1 to leave an ID unchanged).
*
* On Android, this function only affects the calling thread, not all threads
@@ -216,7 +225,7 @@
int setresuid(uid_t __ruid, uid_t __euid, uid_t __suid);
/**
- * [setreuid(2)](http://man7.org/linux/man-pages/man2/setreuid.2.html) sets
+ * [setreuid(2)](https://man7.org/linux/man-pages/man2/setreuid.2.html) sets
* the real and effective group IDs (use -1 to leave an ID unchanged).
*
* On Android, this function only affects the calling thread, not all threads
@@ -227,7 +236,7 @@
int setreuid(uid_t __ruid, uid_t __euid);
/**
- * [setuid(2)](http://man7.org/linux/man-pages/man2/setuid.2.html) sets
+ * [setuid(2)](https://man7.org/linux/man-pages/man2/setuid.2.html) sets
* the user ID.
*
* On Android, this function only affects the calling thread, not all threads
@@ -246,7 +255,11 @@
int getresuid(uid_t* _Nonnull __ruid, uid_t* _Nonnull __euid, uid_t* _Nonnull __suid);
int getresgid(gid_t* _Nonnull __rgid, gid_t* _Nonnull __egid, gid_t* _Nonnull __sgid);
char* _Nullable getlogin(void);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int getlogin_r(char* _Nonnull __buffer, size_t __buffer_size) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
long fpathconf(int __fd, int __name);
long pathconf(const char* _Nonnull __path, int __name);
@@ -257,8 +270,29 @@
int linkat(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path, int __flags);
int unlink(const char* _Nonnull __path);
int unlinkat(int __dirfd, const char* _Nonnull __path, int __flags);
+
+/**
+ * [chdir(2)](https://man7.org/linux/man-pages/man2/chdir.2.html) changes
+ * the current working directory to the given path.
+ *
+ * This function affects all threads in the process, so is generally a bad idea
+ * on Android where most code will be running in a multi-threaded context.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
int chdir(const char* _Nonnull __path);
+
+/**
+ * [fchdir(2)](https://man7.org/linux/man-pages/man2/fchdir.2.html) changes
+ * the current working directory to the given fd.
+ *
+ * This function affects all threads in the process, so is generally a bad idea
+ * on Android where most code will be running in a multi-threaded context.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
int fchdir(int __fd);
+
int rmdir(const char* _Nonnull __path);
int pipe(int __fds[_Nonnull 2]);
#if defined(__USE_GNU)
@@ -277,7 +311,11 @@
void sync(void);
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
int syncfs(int __fd) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
#endif
int close(int __fd);
@@ -339,7 +377,11 @@
int usleep(useconds_t __microseconds);
int gethostname(char* _Nonnull _buf, size_t __buf_size);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int sethostname(const char* _Nonnull __name, size_t __n) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
int brk(void* _Nonnull __addr);
void* _Nullable sbrk(ptrdiff_t __increment);
@@ -382,8 +424,12 @@
} while (_rc == -1 && errno == EINTR); \
_rc; })
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
int getdomainname(char* _Nonnull __buf, size_t __buf_size) __INTRODUCED_IN(26);
int setdomainname(const char* _Nonnull __name, size_t __n) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
/**
* [copy_file_range(2)](https://man7.org/linux/man-pages/man2/copy_file_range.2.html) copies
@@ -394,7 +440,11 @@
* Returns the number of bytes copied on success, and returns -1 and sets
* `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(34)
ssize_t copy_file_range(int __fd_in, off64_t* _Nullable __off_in, int __fd_out, off64_t* _Nullable __off_out, size_t __length, unsigned int __flags) __INTRODUCED_IN(34);
+#endif /* __BIONIC_AVAILABILITY_GUARD(34) */
+
#if __ANDROID_API__ >= 28
void swab(const void* _Nonnull __src, void* _Nonnull __dst, ssize_t __byte_count) __INTRODUCED_IN(28);
@@ -414,7 +464,11 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(34)
int close_range(unsigned int __min_fd, unsigned int __max_fd, int __flags) __INTRODUCED_IN(34);
+#endif /* __BIONIC_AVAILABILITY_GUARD(34) */
+
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#define _UNISTD_H_
diff --git a/libc/include/utime.h b/libc/include/utime.h
index 4d181a8..f06a028 100644
--- a/libc/include/utime.h
+++ b/libc/include/utime.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
/**
- * [utime(2)](http://man7.org/linux/man-pages/man2/utime.2.html) changes the access and
+ * [utime(2)](https://man7.org/linux/man-pages/man2/utime.2.html) changes the access and
* modification time of `__filename`. If `__times` is null, the current time is used.
*
* New code should prefer utimensat().
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index d249f8a..1674491 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -131,6 +131,10 @@
*
* Available since API level 23.
*/
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int login_tty(int __fd) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
__END_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index c4e9679..56594dc 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -58,7 +58,7 @@
size_t mbrlen(const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
size_t mbrtowc(wchar_t* _Nullable __buf, const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
size_t mbsrtowcs(wchar_t* _Nullable __dst, const char* _Nullable * _Nonnull __src, size_t __dst_n, mbstate_t* _Nullable __ps);
-size_t mbsrtowcs_l(wchar_t* _Nullable __dst, const char* _Nullable * _Nonnull __src, size_t __dst_n, mbstate_t* _Nullable __ps, locale_t _Nonnull __l) __INTRODUCED_IN(35);
+size_t mbsrtowcs_l(wchar_t* _Nullable __dst, const char* _Nullable * _Nonnull __src, size_t __dst_n, mbstate_t* _Nullable __ps, locale_t _Nonnull __l) __RENAME(mbsrtowcs);
size_t mbsnrtowcs(wchar_t* _Nullable __dst, const char* _Nullable * _Nullable __src, size_t __src_n, size_t __dst_n, mbstate_t* _Nullable __ps);
wint_t putwc(wchar_t __wc, FILE* _Nonnull __fp);
wint_t putwchar(wchar_t __wc);
@@ -75,7 +75,11 @@
wchar_t* _Nonnull wcpncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
size_t wcrtomb(char* _Nullable __buf, wchar_t __wc, mbstate_t* _Nullable __ps);
int wcscasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int wcscasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
wchar_t* _Nonnull wcscat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
wchar_t* _Nullable wcschr(const wchar_t * _Nonnull __s, wchar_t __wc);
int wcscmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
@@ -83,10 +87,18 @@
wchar_t* _Nonnull wcscpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
size_t wcscspn(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
size_t wcsftime(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm);
+
+#if __BIONIC_AVAILABILITY_GUARD(28)
size_t wcsftime_l(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
+
size_t wcslen(const wchar_t* _Nonnull __s);
int wcsncasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
int wcsncasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
wchar_t* _Nonnull wcsncat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
int wcsncmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
wchar_t* _Nonnull wcsncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
@@ -94,20 +106,20 @@
wchar_t* _Nullable wcspbrk(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
wchar_t* _Nullable wcsrchr(const wchar_t* _Nonnull __s, wchar_t __wc);
size_t wcsrtombs(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __dst_n, mbstate_t* _Nullable __ps);
-size_t wcsrtombs_l(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __dst_n, mbstate_t* _Nullable __ps, locale_t _Nonnull __l) __INTRODUCED_IN(35);
+size_t wcsrtombs_l(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __dst_n, mbstate_t* _Nullable __ps, locale_t _Nonnull __l) __RENAME(wcsrtombs);
size_t wcsspn(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
wchar_t* _Nullable wcsstr(const wchar_t* _Nonnull __haystack, const wchar_t* _Nonnull __needle);
double wcstod(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr);
-double wcstod_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+double wcstod_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __RENAME(wcstod);
float wcstof(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr);
-float wcstof_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+float wcstof_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __RENAME(wcstof);
wchar_t* _Nullable wcstok(wchar_t* _Nullable __s, const wchar_t* _Nonnull __delimiter, wchar_t* _Nonnull * _Nonnull __ptr);
long wcstol(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
-long wcstol_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+long wcstol_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __RENAME(wcstol);
long long wcstoll(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr);
unsigned long wcstoul(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
-unsigned long wcstoul_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+unsigned long wcstoul_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __RENAME(wcstoul);
unsigned long long wcstoull(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
int wcswidth(const wchar_t* _Nonnull __s, size_t __n);
size_t wcsxfrm(wchar_t* __BIONIC_COMPLICATED_NULLNESS __dst, const wchar_t* _Nonnull __src, size_t __n);
@@ -117,7 +129,11 @@
int wmemcmp(const wchar_t* _Nullable __lhs, const wchar_t* _Nullable __rhs, size_t __n);
wchar_t* _Nonnull wmemcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
#if defined(__USE_GNU)
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
wchar_t* _Nonnull wmempcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
#endif
wchar_t* _Nonnull wmemmove(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
wchar_t* _Nonnull wmemset(wchar_t* _Nonnull __dst, wchar_t __wc, size_t __n);
@@ -133,7 +149,11 @@
size_t wcslcat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
size_t wcslcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+
+#if __BIONIC_AVAILABILITY_GUARD(23)
FILE* _Nullable open_wmemstream(wchar_t* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
+#endif /* __BIONIC_AVAILABILITY_GUARD(23) */
+
wchar_t* _Nullable wcsdup(const wchar_t* _Nonnull __s);
size_t wcsnlen(const wchar_t* _Nonnull __s, size_t __n);
diff --git a/libc/include/wctype.h b/libc/include/wctype.h
index 4f6f81f..30ec04f 100644
--- a/libc/include/wctype.h
+++ b/libc/include/wctype.h
@@ -29,8 +29,9 @@
#ifndef _WCTYPE_H_
#define _WCTYPE_H_
-#include <bits/wctype.h>
#include <sys/cdefs.h>
+
+#include <bits/wctype.h>
#include <xlocale.h>
__BEGIN_DECLS
@@ -51,8 +52,12 @@
wint_t towlower_l(wint_t __wc, locale_t _Nonnull __l);
wint_t towupper_l(wint_t __wc, locale_t _Nonnull __l);
+
+#if __BIONIC_AVAILABILITY_GUARD(26)
wint_t towctrans_l(wint_t __wc, wctrans_t _Nonnull __transform, locale_t _Nonnull __l) __INTRODUCED_IN(26);
wctrans_t _Nonnull wctrans_l(const char* _Nonnull __name, locale_t _Nonnull __l) __INTRODUCED_IN(26);
+#endif /* __BIONIC_AVAILABILITY_GUARD(26) */
+
wctype_t wctype_l(const char* _Nonnull __name, locale_t _Nonnull __l);
int iswctype_l(wint_t __wc, wctype_t __transform, locale_t _Nonnull __l);
diff --git a/libc/kernel/android/scsi/scsi/scsi.h b/libc/kernel/android/scsi/scsi/scsi.h
index 3559028..4efeada 100644
--- a/libc/kernel/android/scsi/scsi/scsi.h
+++ b/libc/kernel/android/scsi/scsi/scsi.h
@@ -7,6 +7,7 @@
#ifndef _SCSI_SCSI_H
#define _SCSI_SCSI_H
#include <linux/types.h>
+#include <asm/param.h>
#include <scsi/scsi_proto.h>
#include <scsi/scsi_status.h>
struct ccs_modesel_head {
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index d873fad..754e12a 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -109,6 +109,7 @@
#define WRITE_SAME_16 0x93
#define ZBC_OUT 0x94
#define ZBC_IN 0x95
+#define WRITE_ATOMIC_16 0x9c
#define SERVICE_ACTION_BIDIRECTIONAL 0x9d
#define SERVICE_ACTION_IN_16 0x9e
#define SERVICE_ACTION_OUT_16 0x9f
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 08b786a..df50806 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1430,7 +1430,7 @@
state = VAR_DECL
elif state == NORMAL and token_id in ['struct', 'typedef',
'enum', 'union',
- '__extension__']:
+ '__extension__', '=']:
state = OTHER_DECL
state_token = token_id
elif block.tokens[i].kind == TokenKind.IDENTIFIER:
@@ -2057,7 +2057,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_struct_from_end(self):
text = """\
@@ -2076,7 +2076,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_minimal_struct(self):
text = """\
@@ -2084,7 +2084,7 @@
};
"""
expected = "";
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_struct_with_struct_fields(self):
text = """\
@@ -2104,7 +2104,7 @@
struct remove val2;
};
"""
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_consecutive_structs(self):
text = """\
@@ -2136,7 +2136,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
+ self.assertEqual(self.parse(text, {"remove1": None, "remove2": None}), expected)
def test_remove_multiple_structs(self):
text = """\
@@ -2169,7 +2169,7 @@
int val;
};
"""
- self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
+ self.assertEqual(self.parse(text, {"remove1": None, "remove2": None}), expected)
def test_remove_struct_with_inline_structs(self):
text = """\
@@ -2194,7 +2194,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_struct_across_blocks(self):
text = """\
@@ -2219,7 +2219,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove": True}), expected)
+ self.assertEqual(self.parse(text, {"remove": None}), expected)
def test_remove_struct_across_blocks_multiple_structs(self):
text = """\
@@ -2246,7 +2246,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
+ self.assertEqual(self.parse(text, {"remove1": None, "remove2": None}), expected)
def test_remove_multiple_struct_and_add_includes(self):
text = """\
@@ -2263,7 +2263,7 @@
#include <bits/remove1.h>
#include <bits/remove2.h>
"""
- self.assertEqual(self.parse(text, {"remove1": False, "remove2": False}), expected)
+ self.assertEqual(self.parse(text, {"remove1": "bits/remove1.h", "remove2": "bits/remove2.h"}), expected)
class FullPathTest(unittest.TestCase):
@@ -2580,6 +2580,71 @@
struct timeval timeval;
struct itimerval itimerval;
};
+#include <linux/time.h>
+"""
+ self.assertEqual(self.parse(text), expected)
+
+ def test_var_definition(self):
+ # If we're definining the whole thing, it's probably worth keeping.
+ text = """\
+static const char *kString = "hello world";
+static const int kInteger = 42;
+"""
+ expected = """\
+static const char * kString = "hello world";
+static const int kInteger = 42;
+"""
+ self.assertEqual(self.parse(text), expected)
+
+ def test_struct_array_definition(self):
+ text = """\
+struct descriptor {
+ int args;
+ int size;
+};
+static const struct descriptor[] = {
+ {0, 0},
+ {1, 12},
+ {0, 42},
+};
+"""
+ expected = """\
+struct descriptor {
+ int args;
+ int size;
+};
+static const struct descriptor[] = {
+ {
+ 0, 0
+ }
+ , {
+ 1, 12
+ }
+ , {
+ 0, 42
+ }
+ ,
+};
+"""
+ self.assertEqual(self.parse(text), expected)
+
+ def test_array_definition(self):
+ text = """\
+static const char *arr[] = {
+ "foo",
+ "bar",
+ "baz",
+};
+
+static int another_arr[5] = { 1, 2, 3, 4, 5};
+"""
+ expected = """\
+static const char * arr[] = {
+ "foo", "bar", "baz",
+};
+static int another_arr[5] = {
+ 1, 2, 3, 4, 5
+};
"""
self.assertEqual(self.parse(text), expected)
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 06afb25..2994e5e 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -25,6 +25,23 @@
# Otherwise, there will be two struct timeval definitions when
# __kernel_old_timeval is renamed to timeval.
"__kernel_old_timeval": "1",
+ # Drop the custom byte swap functions and just use the clang builtins.
+ # https://github.com/android/ndk/issues/2107
+ "__arch_swab16": kCppUndefinedMacro,
+ "__arch_swab16p": kCppUndefinedMacro,
+ "__arch_swab16s": kCppUndefinedMacro,
+ "__arch_swab32": kCppUndefinedMacro,
+ "__arch_swab32p": kCppUndefinedMacro,
+ "__arch_swab32s": kCppUndefinedMacro,
+ "__arch_swab64": kCppUndefinedMacro,
+ "__arch_swab64p": kCppUndefinedMacro,
+ "__arch_swab64s": kCppUndefinedMacro,
+ "__arch_swahb32": kCppUndefinedMacro,
+ "__arch_swahb32p": kCppUndefinedMacro,
+ "__arch_swahb32s": kCppUndefinedMacro,
+ "__arch_swahw32": kCppUndefinedMacro,
+ "__arch_swahw32p": kCppUndefinedMacro,
+ "__arch_swahw32s": kCppUndefinedMacro,
}
# This is the set of known kernel data structures we want to remove from
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index ae89a80..331a957 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -88,15 +88,8 @@
# Collect the set of all syscalls for all architectures.
syscalls = set()
pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
- for unistd_h in ['kernel/uapi/asm-generic/unistd.h',
- 'kernel/uapi/asm-arm/asm/unistd.h',
- 'kernel/uapi/asm-arm/asm/unistd-eabi.h',
- 'kernel/uapi/asm-arm/asm/unistd-oabi.h',
- 'kernel/uapi/asm-riscv/asm/unistd.h',
- 'kernel/uapi/asm-x86/asm/unistd_32.h',
- 'kernel/uapi/asm-x86/asm/unistd_64.h',
- 'kernel/uapi/asm-x86/asm/unistd_x32.h']:
- for line in open(os.path.join(libc_root, unistd_h)):
+ for unistd_h in glob.glob('%s/kernel/uapi/asm-*/asm/unistd*.h' % libc_root):
+ for line in open(unistd_h):
m = re.search(pattern, line)
if m:
nr_name = m.group(1)
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
index 1032131..9c4e459 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
@@ -420,4 +420,5 @@
#define __NR_lsm_get_self_attr (__NR_SYSCALL_BASE + 459)
#define __NR_lsm_set_self_attr (__NR_SYSCALL_BASE + 460)
#define __NR_lsm_list_modules (__NR_SYSCALL_BASE + 461)
+#define __NR_mseal (__NR_SYSCALL_BASE + 462)
#endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
index 1f57604..5060c2f 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
@@ -432,4 +432,5 @@
#define __NR_lsm_get_self_attr (__NR_SYSCALL_BASE + 459)
#define __NR_lsm_set_self_attr (__NR_SYSCALL_BASE + 460)
#define __NR_lsm_list_modules (__NR_SYSCALL_BASE + 461)
+#define __NR_mseal (__NR_SYSCALL_BASE + 462)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index f5c720a..45cc945 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -101,4 +101,5 @@
#define HWCAP2_SME_SF8FMA (1UL << 60)
#define HWCAP2_SME_SF8DP4 (1UL << 61)
#define HWCAP2_SME_SF8DP2 (1UL << 62)
+#define HWCAP2_POE (1UL << 63)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/mman.h b/libc/kernel/uapi/asm-arm64/asm/mman.h
index 1561053..cc92abe 100644
--- a/libc/kernel/uapi/asm-arm64/asm/mman.h
+++ b/libc/kernel/uapi/asm-arm64/asm/mman.h
@@ -9,4 +9,8 @@
#include <asm-generic/mman.h>
#define PROT_BTI 0x10
#define PROT_MTE 0x20
+#define PKEY_DISABLE_EXECUTE 0x4
+#define PKEY_DISABLE_READ 0x8
+#undef PKEY_ACCESS_MASK
+#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE | PKEY_DISABLE_READ | PKEY_DISABLE_EXECUTE)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 8e48d55..a845a03 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -32,6 +32,11 @@
struct _aarch64_ctx head;
__u64 esr;
};
+#define POE_MAGIC 0x504f4530
+struct poe_context {
+ struct _aarch64_ctx head;
+ __u64 por_el0;
+};
#define EXTRA_MAGIC 0x45585401
struct extra_context {
struct _aarch64_ctx head;
@@ -95,12 +100,12 @@
#define SVE_SIG_REGS_SIZE(vq) (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
#define ZA_SIG_REGS_OFFSET ((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
-#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * n))
+#define ZA_SIG_REGS_SIZE(vq) (((vq) * __SVE_VQ_BYTES) * ((vq) * __SVE_VQ_BYTES))
+#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * (n)))
#define ZA_SIG_CONTEXT_SIZE(vq) (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
#define ZT_SIG_REG_SIZE 512
#define ZT_SIG_REG_BYTES (ZT_SIG_REG_SIZE / 8)
#define ZT_SIG_REGS_OFFSET sizeof(struct zt_context)
-#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n)
+#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * (n))
#define ZT_SIG_CONTEXT_SIZE(n) (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/unistd.h b/libc/kernel/uapi/asm-arm64/asm/unistd.h
index 7457ebc..178578f 100644
--- a/libc/kernel/uapi/asm-arm64/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm64/asm/unistd.h
@@ -4,10 +4,4 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#define __ARCH_WANT_RENAMEAT
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_TIME32_SYSCALLS
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_MEMFD_SECRET
-#include <asm-generic/unistd.h>
+#include <asm/unistd_64.h>
diff --git a/libc/kernel/uapi/asm-arm64/asm/unistd_64.h b/libc/kernel/uapi/asm-arm64/asm/unistd_64.h
new file mode 100644
index 0000000..0a0a1c0
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm64/asm/unistd_64.h
@@ -0,0 +1,327 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_UNISTD_64_H
+#define _UAPI_ASM_UNISTD_64_H
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_renameat 38
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_newfstatat 79
+#define __NR_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap 222
+#define __NR_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_io_pgetevents 292
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_epoll_pwait2 441
+#define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_memfd_secret 447
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
+#define __NR_fchmodat2 452
+#define __NR_map_shadow_stack 453
+#define __NR_futex_wake 454
+#define __NR_futex_wait 455
+#define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
+#endif
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 2d90586..a580c4c 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -92,6 +92,11 @@
#define SO_RCVMARK 75
#define SO_PASSPIDFD 76
#define SO_PEERPIDFD 77
+#define SO_DEVMEM_LINEAR 78
+#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF 79
+#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED 80
#if __BITS_PER_LONG == 64 || defined(__x86_64__) && defined(__ILP32__)
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index c882751..652e7a2 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -381,9 +381,7 @@
#define __NR_fsmount 432
#define __NR_fspick 433
#define __NR_pidfd_open 434
-#ifdef __ARCH_WANT_SYS_CLONE3
#define __NR_clone3 435
-#endif
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
@@ -412,8 +410,9 @@
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
#undef __NR_syscalls
-#define __NR_syscalls 462
+#define __NR_syscalls 463
#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
#define __NR_fcntl __NR3264_fcntl
#define __NR_statfs __NR3264_statfs
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
index 5c82561..2e5f9a4 100644
--- a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -53,6 +53,19 @@
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
+#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
+#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
+#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
+#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
+#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
+#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
+#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
+#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
+#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
+#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
+#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
+#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
+#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
@@ -61,5 +74,13 @@
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
+#define RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS 7
+#define RISCV_HWPROBE_KEY_TIME_CSR_FREQ 8
+#define RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF 9
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN 0
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_EMULATED 1
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW 2
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_FAST 3
+#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNSUPPORTED 4
#define RISCV_HWPROBE_WHICH_CPUS (1 << 0)
#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
index 4c759ed..51f4977 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -127,6 +127,14 @@
KVM_RISCV_ISA_EXT_ZFA,
KVM_RISCV_ISA_EXT_ZTSO,
KVM_RISCV_ISA_EXT_ZACAS,
+ KVM_RISCV_ISA_EXT_SSCOFPMF,
+ KVM_RISCV_ISA_EXT_ZIMOP,
+ KVM_RISCV_ISA_EXT_ZCA,
+ KVM_RISCV_ISA_EXT_ZCB,
+ KVM_RISCV_ISA_EXT_ZCD,
+ KVM_RISCV_ISA_EXT_ZCF,
+ KVM_RISCV_ISA_EXT_ZCMOP,
+ KVM_RISCV_ISA_EXT_ZAWRS,
KVM_RISCV_ISA_EXT_MAX,
};
enum KVM_RISCV_SBI_EXT_ID {
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd.h b/libc/kernel/uapi/asm-riscv/asm/unistd.h
index 0c58887..f395f71 100644
--- a/libc/kernel/uapi/asm-riscv/asm/unistd.h
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd.h
@@ -4,18 +4,9 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
-#define __ARCH_WANT_NEW_STAT
-#define __ARCH_WANT_SET_GET_RLIMIT
+#include <asm/bitsperlong.h>
+#if __BITS_PER_LONG == 64
+#include <asm/unistd_64.h>
+#else
+#include <asm/unistd_32.h>
#endif
-#define __ARCH_WANT_SYS_CLONE3
-#define __ARCH_WANT_MEMFD_SECRET
-#include <asm-generic/unistd.h>
-#ifndef __NR_riscv_flush_icache
-#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
-#endif
-__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
-#ifndef __NR_riscv_hwprobe
-#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14)
-#endif
-__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe)
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd_32.h b/libc/kernel/uapi/asm-riscv/asm/unistd_32.h
new file mode 100644
index 0000000..864a556
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd_32.h
@@ -0,0 +1,318 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_UNISTD_32_H
+#define _UAPI_ASM_UNISTD_32_H
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl64 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs64 43
+#define __NR_fstatfs64 44
+#define __NR_truncate64 45
+#define __NR_ftruncate64 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_llseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile64 71
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_getoverrun 109
+#define __NR_timer_delete 111
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap2 222
+#define __NR_fadvise64_64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_riscv_hwprobe 258
+#define __NR_riscv_flush_icache 259
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#define __NR_clock_gettime64 403
+#define __NR_clock_settime64 404
+#define __NR_clock_adjtime64 405
+#define __NR_clock_getres_time64 406
+#define __NR_clock_nanosleep_time64 407
+#define __NR_timer_gettime64 408
+#define __NR_timer_settime64 409
+#define __NR_timerfd_gettime64 410
+#define __NR_timerfd_settime64 411
+#define __NR_utimensat_time64 412
+#define __NR_pselect6_time64 413
+#define __NR_ppoll_time64 414
+#define __NR_io_pgetevents_time64 416
+#define __NR_recvmmsg_time64 417
+#define __NR_mq_timedsend_time64 418
+#define __NR_mq_timedreceive_time64 419
+#define __NR_semtimedop_time64 420
+#define __NR_rt_sigtimedwait_time64 421
+#define __NR_futex_time64 422
+#define __NR_sched_rr_get_interval_time64 423
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_epoll_pwait2 441
+#define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_memfd_secret 447
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
+#define __NR_fchmodat2 452
+#define __NR_map_shadow_stack 453
+#define __NR_futex_wake 454
+#define __NR_futex_wait 455
+#define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd_64.h b/libc/kernel/uapi/asm-riscv/asm/unistd_64.h
new file mode 100644
index 0000000..f15b65b
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd_64.h
@@ -0,0 +1,328 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_UNISTD_64_H
+#define _UAPI_ASM_UNISTD_64_H
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_io_getevents 4
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs 43
+#define __NR_fstatfs 44
+#define __NR_truncate 45
+#define __NR_ftruncate 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR_lseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile 71
+#define __NR_pselect6 72
+#define __NR_ppoll 73
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_newfstatat 79
+#define __NR_fstat 80
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_timerfd_settime 86
+#define __NR_timerfd_gettime 87
+#define __NR_utimensat 88
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_futex 98
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_gettime 108
+#define __NR_timer_getoverrun 109
+#define __NR_timer_settime 110
+#define __NR_timer_delete 111
+#define __NR_clock_settime 112
+#define __NR_clock_gettime 113
+#define __NR_clock_getres 114
+#define __NR_clock_nanosleep 115
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_sched_rr_get_interval 127
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigtimedwait 137
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrlimit 163
+#define __NR_setrlimit 164
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_gettimeofday 169
+#define __NR_settimeofday 170
+#define __NR_adjtimex 171
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_timedsend 182
+#define __NR_mq_timedreceive 183
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semtimedop 192
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap 222
+#define __NR_fadvise64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_recvmmsg 243
+#define __NR_riscv_hwprobe 258
+#define __NR_riscv_flush_icache 259
+#define __NR_wait4 260
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_clock_adjtime 266
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_io_pgetevents 292
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#define __NR_pidfd_send_signal 424
+#define __NR_io_uring_setup 425
+#define __NR_io_uring_enter 426
+#define __NR_io_uring_register 427
+#define __NR_open_tree 428
+#define __NR_move_mount 429
+#define __NR_fsopen 430
+#define __NR_fsconfig 431
+#define __NR_fsmount 432
+#define __NR_fspick 433
+#define __NR_pidfd_open 434
+#define __NR_clone3 435
+#define __NR_close_range 436
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
+#define __NR_process_madvise 440
+#define __NR_epoll_pwait2 441
+#define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_memfd_secret 447
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
+#define __NR_fchmodat2 452
+#define __NR_map_shadow_stack 453
+#define __NR_futex_wake 454
+#define __NR_futex_wait 455
+#define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/elf.h b/libc/kernel/uapi/asm-x86/asm/elf.h
new file mode 100644
index 0000000..b66a229
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/elf.h
@@ -0,0 +1,16 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_X86_ELF_H
+#define _UAPI_ASM_X86_ELF_H
+#include <linux/types.h>
+struct x86_xfeat_component {
+ __u32 type;
+ __u32 size;
+ __u32 offset;
+ __u32 flags;
+} __attribute__((__packed__));
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 440ffb8..0a35412 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -94,6 +94,7 @@
#define KVM_NR_IRQCHIPS 3
#define KVM_RUN_X86_SMM (1 << 0)
#define KVM_RUN_X86_BUS_LOCK (1 << 1)
+#define KVM_RUN_X86_GUEST_MODE (1 << 2)
struct kvm_regs {
__u64 rax, rbx, rcx, rdx;
__u64 rsi, rdi, rsp, rbp;
@@ -341,6 +342,7 @@
#define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4)
#define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5)
#define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6)
+#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)
#define KVM_STATE_NESTED_FORMAT_VMX 0
#define KVM_STATE_NESTED_FORMAT_SVM 1
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
@@ -353,7 +355,10 @@
#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000
#define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000
#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001
+#define KVM_X86_GRP_SYSTEM 0
#define KVM_X86_XCOMP_GUEST_SUPP 0
+#define KVM_X86_GRP_SEV 1
+#define KVM_X86_SEV_VMSA_FEATURES 0
struct kvm_vmx_nested_state_data {
__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
__u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
@@ -528,6 +533,10 @@
KVM_SEV_CERT_EXPORT,
KVM_SEV_GET_ATTESTATION_REPORT,
KVM_SEV_SEND_CANCEL,
+ KVM_SEV_INIT2,
+ KVM_SEV_SNP_LAUNCH_START = 100,
+ KVM_SEV_SNP_LAUNCH_UPDATE,
+ KVM_SEV_SNP_LAUNCH_FINISH,
KVM_SEV_NR_MAX,
};
struct kvm_sev_cmd {
@@ -537,6 +546,13 @@
__u32 error;
__u32 sev_fd;
};
+struct kvm_sev_init {
+ __u64 vmsa_features;
+ __u32 flags;
+ __u16 ghcb_version;
+ __u16 pad1;
+ __u32 pad2[8];
+};
struct kvm_sev_launch_start {
__u32 handle;
__u32 policy;
@@ -633,6 +649,42 @@
__u32 trans_len;
__u32 pad2;
};
+struct kvm_sev_snp_launch_start {
+ __u64 policy;
+ __u8 gosvw[16];
+ __u16 flags;
+ __u8 pad0[6];
+ __u64 pad1[4];
+};
+#define KVM_SEV_SNP_PAGE_TYPE_NORMAL 0x1
+#define KVM_SEV_SNP_PAGE_TYPE_ZERO 0x3
+#define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED 0x4
+#define KVM_SEV_SNP_PAGE_TYPE_SECRETS 0x5
+#define KVM_SEV_SNP_PAGE_TYPE_CPUID 0x6
+struct kvm_sev_snp_launch_update {
+ __u64 gfn_start;
+ __u64 uaddr;
+ __u64 len;
+ __u8 type;
+ __u8 pad0;
+ __u16 flags;
+ __u32 pad1;
+ __u64 pad2[4];
+};
+#define KVM_SEV_SNP_ID_BLOCK_SIZE 96
+#define KVM_SEV_SNP_ID_AUTH_SIZE 4096
+#define KVM_SEV_SNP_FINISH_DATA_SIZE 32
+struct kvm_sev_snp_launch_finish {
+ __u64 id_block_uaddr;
+ __u64 id_auth_uaddr;
+ __u8 id_block_en;
+ __u8 auth_key_en;
+ __u8 vcek_disabled;
+ __u8 host_data[KVM_SEV_SNP_FINISH_DATA_SIZE];
+ __u8 pad0[3];
+ __u16 flags;
+ __u64 pad1[4];
+};
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
struct kvm_hyperv_eventfd {
@@ -654,4 +706,7 @@
#define KVM_EXIT_HYPERCALL_LONG_MODE _BITULL(0)
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1
+#define KVM_X86_SEV_VM 2
+#define KVM_X86_SEV_ES_VM 3
+#define KVM_X86_SNP_VM 4
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/svm.h b/libc/kernel/uapi/asm-x86/asm/svm.h
index ffbf0b3..4f165fa 100644
--- a/libc/kernel/uapi/asm-x86/asm/svm.h
+++ b/libc/kernel/uapi/asm-x86/asm/svm.h
@@ -117,6 +117,7 @@
#define SVM_VMGEXIT_AP_CREATE_ON_INIT 0
#define SVM_VMGEXIT_AP_CREATE 1
#define SVM_VMGEXIT_AP_DESTROY 2
+#define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
#define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe
#define SVM_VMGEXIT_TERM_REASON(reason_set,reason_code) (((((u64) reason_set) & 0xf)) | ((((u64) reason_code) & 0xff) << 4))
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index 72076fd..59c693d 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -457,4 +457,5 @@
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index 8c4f76e..d5408a3 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -341,6 +341,7 @@
#define __NR_statx 332
#define __NR_io_pgetevents 333
#define __NR_rseq 334
+#define __NR_uretprobe 335
#define __NR_pidfd_send_signal 424
#define __NR_io_uring_setup 425
#define __NR_io_uring_enter 426
@@ -379,4 +380,5 @@
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
+#define __NR_mseal 462
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 984cfca..fdcf7e6 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -294,6 +294,7 @@
#define __NR_statx (__X32_SYSCALL_BIT + 332)
#define __NR_io_pgetevents (__X32_SYSCALL_BIT + 333)
#define __NR_rseq (__X32_SYSCALL_BIT + 334)
+#define __NR_uretprobe (__X32_SYSCALL_BIT + 335)
#define __NR_pidfd_send_signal (__X32_SYSCALL_BIT + 424)
#define __NR_io_uring_setup (__X32_SYSCALL_BIT + 425)
#define __NR_io_uring_enter (__X32_SYSCALL_BIT + 426)
@@ -323,6 +324,7 @@
#define __NR_set_mempolicy_home_node (__X32_SYSCALL_BIT + 450)
#define __NR_cachestat (__X32_SYSCALL_BIT + 451)
#define __NR_fchmodat2 (__X32_SYSCALL_BIT + 452)
+#define __NR_map_shadow_stack (__X32_SYSCALL_BIT + 453)
#define __NR_futex_wake (__X32_SYSCALL_BIT + 454)
#define __NR_futex_wait (__X32_SYSCALL_BIT + 455)
#define __NR_futex_requeue (__X32_SYSCALL_BIT + 456)
@@ -331,6 +333,7 @@
#define __NR_lsm_get_self_attr (__X32_SYSCALL_BIT + 459)
#define __NR_lsm_set_self_attr (__X32_SYSCALL_BIT + 460)
#define __NR_lsm_list_modules (__X32_SYSCALL_BIT + 461)
+#define __NR_mseal (__X32_SYSCALL_BIT + 462)
#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 0ad0bc2..7bbd5de 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -65,6 +65,7 @@
#define AMDGPU_GEM_CREATE_COHERENT (1 << 13)
#define AMDGPU_GEM_CREATE_UNCACHED (1 << 14)
#define AMDGPU_GEM_CREATE_EXT_COHERENT (1 << 15)
+#define AMDGPU_GEM_CREATE_GFX12_DCC (1 << 16)
struct drm_amdgpu_gem_create_in {
__u64 bo_size;
__u64 alignment;
@@ -216,6 +217,14 @@
#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1
#define AMDGPU_TILING_SCANOUT_SHIFT 63
#define AMDGPU_TILING_SCANOUT_MASK 0x1
+#define AMDGPU_TILING_GFX12_SWIZZLE_MODE_SHIFT 0
+#define AMDGPU_TILING_GFX12_SWIZZLE_MODE_MASK 0x7
+#define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_SHIFT 3
+#define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3
+#define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_SHIFT 5
+#define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_MASK 0x7
+#define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_SHIFT 8
+#define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_MASK 0x3f
#define AMDGPU_TILING_SET(field,value) (((__u64) (value) & AMDGPU_TILING_ ##field ##_MASK) << AMDGPU_TILING_ ##field ##_SHIFT)
#define AMDGPU_TILING_GET(value,field) (((__u64) (value) >> AMDGPU_TILING_ ##field ##_SHIFT) & AMDGPU_TILING_ ##field ##_MASK)
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
@@ -744,6 +753,10 @@
#define AMDGPU_FAMILY_GC_10_3_6 149
#define AMDGPU_FAMILY_GC_10_3_7 151
#define AMDGPU_FAMILY_GC_11_5_0 150
+#define AMDGPU_FAMILY_GC_12_0_0 152
+struct drm_color_ctm_3x4 {
+ __u64 matrix[12];
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 6fd2eb8..c0f5ff1 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -172,6 +172,8 @@
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13)
#define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14)
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15)
+#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16)
+#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17)
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
#define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2)
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
@@ -255,12 +257,17 @@
#define AMD_FMT_MOD_TILE_VER_GFX10 2
#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
#define AMD_FMT_MOD_TILE_VER_GFX11 4
+#define AMD_FMT_MOD_TILE_VER_GFX12 5
#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
#define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31
+#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1
+#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2
+#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3
+#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4
#define AMD_FMT_MOD_DCC_BLOCK_64B 0
#define AMD_FMT_MOD_DCC_BLOCK_128B 1
#define AMD_FMT_MOD_DCC_BLOCK_256B 2
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 9e6296c..06c91c5 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -357,15 +357,16 @@
struct drm_color_ctm {
__u64 matrix[9];
};
-struct drm_color_ctm_3x4 {
- __u64 matrix[12];
-};
struct drm_color_lut {
__u16 red;
__u16 green;
__u16 blue;
__u16 reserved;
};
+struct drm_plane_size_hint {
+ __u16 width;
+ __u16 height;
+};
struct hdr_metadata_infoframe {
__u8 eotf;
__u8 metadata_type;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 0738cee..b43d8df 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -365,6 +365,7 @@
#define I915_PARAM_HAS_USERPTR_PROBE 56
#define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
#define I915_PARAM_PXP_STATUS 58
+#define I915_PARAM_HAS_CONTEXT_FREQ_HINT 59
struct drm_i915_getparam {
__s32 param;
int * value;
@@ -743,6 +744,8 @@
#define I915_CONTEXT_PARAM_PERSISTENCE 0xb
#define I915_CONTEXT_PARAM_RINGSIZE 0xc
#define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd
+#define I915_CONTEXT_PARAM_LOW_LATENCY 0xe
+#define I915_CONTEXT_PARAM_CONTEXT_IMAGE 0xf
__u64 value;
};
struct drm_i915_gem_context_param_sseu {
@@ -797,6 +800,14 @@
} __attribute__((packed));
#define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__,N__) struct { __u64 extensions; struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
+struct i915_gem_context_param_context_image {
+ struct i915_engine_class_instance engine;
+ __u32 flags;
+#define I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX (1u << 0)
+ __u32 size;
+ __u32 mbz;
+ __u64 image;
+} __attribute__((packed));
struct drm_i915_gem_context_create_ext_setparam {
struct i915_user_extension base;
struct drm_i915_gem_context_param param;
diff --git a/libc/kernel/uapi/drm/ivpu_accel.h b/libc/kernel/uapi/drm/ivpu_accel.h
index fcbf6f7..960bd43 100644
--- a/libc/kernel/uapi/drm/ivpu_accel.h
+++ b/libc/kernel/uapi/drm/ivpu_accel.h
@@ -18,12 +18,20 @@
#define DRM_IVPU_BO_INFO 0x03
#define DRM_IVPU_SUBMIT 0x05
#define DRM_IVPU_BO_WAIT 0x06
+#define DRM_IVPU_METRIC_STREAMER_START 0x07
+#define DRM_IVPU_METRIC_STREAMER_STOP 0x08
+#define DRM_IVPU_METRIC_STREAMER_GET_DATA 0x09
+#define DRM_IVPU_METRIC_STREAMER_GET_INFO 0x0a
#define DRM_IOCTL_IVPU_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param)
#define DRM_IOCTL_IVPU_SET_PARAM DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_SET_PARAM, struct drm_ivpu_param)
#define DRM_IOCTL_IVPU_BO_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_CREATE, struct drm_ivpu_bo_create)
#define DRM_IOCTL_IVPU_BO_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_INFO, struct drm_ivpu_bo_info)
#define DRM_IOCTL_IVPU_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_SUBMIT, struct drm_ivpu_submit)
#define DRM_IOCTL_IVPU_BO_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_WAIT, struct drm_ivpu_bo_wait)
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_START DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_START, struct drm_ivpu_metric_streamer_start)
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_STOP DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_STOP, struct drm_ivpu_metric_streamer_stop)
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_DATA DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_DATA, struct drm_ivpu_metric_streamer_get_data)
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_INFO, struct drm_ivpu_metric_streamer_get_data)
#define DRM_IVPU_PARAM_DEVICE_ID 0
#define DRM_IVPU_PARAM_DEVICE_REVISION 1
#define DRM_IVPU_PARAM_PLATFORM_TYPE 2
@@ -96,6 +104,22 @@
__u32 job_status;
__u32 pad;
};
+struct drm_ivpu_metric_streamer_start {
+ __u64 metric_group_mask;
+ __u64 sampling_period_ns;
+ __u32 read_period_samples;
+ __u32 sample_size;
+ __u32 max_data_size;
+};
+struct drm_ivpu_metric_streamer_get_data {
+ __u64 metric_group_mask;
+ __u64 buffer_ptr;
+ __u64 buffer_size;
+ __u64 data_size;
+};
+struct drm_ivpu_metric_streamer_stop {
+ __u64 metric_group_mask;
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 4d83744..582da62 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -37,6 +37,9 @@
#define MSM_PARAM_VA_START 0x0e
#define MSM_PARAM_VA_SIZE 0x0f
#define MSM_PARAM_HIGHEST_BANK_BIT 0x10
+#define MSM_PARAM_RAYTRACING 0x11
+#define MSM_PARAM_UBWC_SWIZZLE 0x12
+#define MSM_PARAM_MACROTILE_MODE 0x13
#define MSM_PARAM_NR_RINGS MSM_PARAM_PRIORITIES
struct drm_msm_param {
__u32 pipe;
diff --git a/libc/kernel/uapi/drm/nouveau_drm.h b/libc/kernel/uapi/drm/nouveau_drm.h
index f7d870e..01897af 100644
--- a/libc/kernel/uapi/drm/nouveau_drm.h
+++ b/libc/kernel/uapi/drm/nouveau_drm.h
@@ -25,10 +25,16 @@
#define NOUVEAU_GETPARAM_EXEC_PUSH_MAX 17
#define NOUVEAU_GETPARAM_VRAM_BAR_SIZE 18
#define NOUVEAU_GETPARAM_VRAM_USED 19
+#define NOUVEAU_GETPARAM_HAS_VMA_TILEMODE 20
struct drm_nouveau_getparam {
__u64 param;
__u64 value;
};
+#define NOUVEAU_FIFO_ENGINE_GR 0x01
+#define NOUVEAU_FIFO_ENGINE_VP 0x02
+#define NOUVEAU_FIFO_ENGINE_PPP 0x04
+#define NOUVEAU_FIFO_ENGINE_BSP 0x08
+#define NOUVEAU_FIFO_ENGINE_CE 0x30
struct drm_nouveau_channel_alloc {
__u32 fb_ctxdma_handle;
__u32 tt_ctxdma_handle;
@@ -44,6 +50,16 @@
struct drm_nouveau_channel_free {
__s32 channel;
};
+struct drm_nouveau_notifierobj_alloc {
+ __u32 channel;
+ __u32 handle;
+ __u32 size;
+ __u32 offset;
+};
+struct drm_nouveau_gpuobj_free {
+ __s32 channel;
+ __u32 handle;
+};
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
diff --git a/libc/kernel/uapi/drm/panthor_drm.h b/libc/kernel/uapi/drm/panthor_drm.h
new file mode 100644
index 0000000..b45c1dc
--- /dev/null
+++ b/libc/kernel/uapi/drm/panthor_drm.h
@@ -0,0 +1,240 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _PANTHOR_DRM_H_
+#define _PANTHOR_DRM_H_
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define DRM_PANTHOR_USER_MMIO_OFFSET_32BIT (1ull << 43)
+#define DRM_PANTHOR_USER_MMIO_OFFSET_64BIT (1ull << 56)
+#define DRM_PANTHOR_USER_MMIO_OFFSET (sizeof(unsigned long) < 8 ? DRM_PANTHOR_USER_MMIO_OFFSET_32BIT : DRM_PANTHOR_USER_MMIO_OFFSET_64BIT)
+#define DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET (DRM_PANTHOR_USER_MMIO_OFFSET | 0)
+enum drm_panthor_ioctl_id {
+ DRM_PANTHOR_DEV_QUERY = 0,
+ DRM_PANTHOR_VM_CREATE,
+ DRM_PANTHOR_VM_DESTROY,
+ DRM_PANTHOR_VM_BIND,
+ DRM_PANTHOR_VM_GET_STATE,
+ DRM_PANTHOR_BO_CREATE,
+ DRM_PANTHOR_BO_MMAP_OFFSET,
+ DRM_PANTHOR_GROUP_CREATE,
+ DRM_PANTHOR_GROUP_DESTROY,
+ DRM_PANTHOR_GROUP_SUBMIT,
+ DRM_PANTHOR_GROUP_GET_STATE,
+ DRM_PANTHOR_TILER_HEAP_CREATE,
+ DRM_PANTHOR_TILER_HEAP_DESTROY,
+};
+#define DRM_IOCTL_PANTHOR(__access,__id,__type) DRM_IO ##__access(DRM_COMMAND_BASE + DRM_PANTHOR_ ##__id, struct drm_panthor_ ##__type)
+#define DRM_IOCTL_PANTHOR_DEV_QUERY DRM_IOCTL_PANTHOR(WR, DEV_QUERY, dev_query)
+#define DRM_IOCTL_PANTHOR_VM_CREATE DRM_IOCTL_PANTHOR(WR, VM_CREATE, vm_create)
+#define DRM_IOCTL_PANTHOR_VM_DESTROY DRM_IOCTL_PANTHOR(WR, VM_DESTROY, vm_destroy)
+#define DRM_IOCTL_PANTHOR_VM_BIND DRM_IOCTL_PANTHOR(WR, VM_BIND, vm_bind)
+#define DRM_IOCTL_PANTHOR_VM_GET_STATE DRM_IOCTL_PANTHOR(WR, VM_GET_STATE, vm_get_state)
+#define DRM_IOCTL_PANTHOR_BO_CREATE DRM_IOCTL_PANTHOR(WR, BO_CREATE, bo_create)
+#define DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET DRM_IOCTL_PANTHOR(WR, BO_MMAP_OFFSET, bo_mmap_offset)
+#define DRM_IOCTL_PANTHOR_GROUP_CREATE DRM_IOCTL_PANTHOR(WR, GROUP_CREATE, group_create)
+#define DRM_IOCTL_PANTHOR_GROUP_DESTROY DRM_IOCTL_PANTHOR(WR, GROUP_DESTROY, group_destroy)
+#define DRM_IOCTL_PANTHOR_GROUP_SUBMIT DRM_IOCTL_PANTHOR(WR, GROUP_SUBMIT, group_submit)
+#define DRM_IOCTL_PANTHOR_GROUP_GET_STATE DRM_IOCTL_PANTHOR(WR, GROUP_GET_STATE, group_get_state)
+#define DRM_IOCTL_PANTHOR_TILER_HEAP_CREATE DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create)
+#define DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy)
+struct drm_panthor_obj_array {
+ __u32 stride;
+ __u32 count;
+ __u64 array;
+};
+#define DRM_PANTHOR_OBJ_ARRAY(cnt,ptr) {.stride = sizeof((ptr)[0]),.count = (cnt),.array = (__u64) (uintptr_t) (ptr) }
+enum drm_panthor_sync_op_flags {
+ DRM_PANTHOR_SYNC_OP_HANDLE_TYPE_MASK = 0xff,
+ DRM_PANTHOR_SYNC_OP_HANDLE_TYPE_SYNCOBJ = 0,
+ DRM_PANTHOR_SYNC_OP_HANDLE_TYPE_TIMELINE_SYNCOBJ = 1,
+ DRM_PANTHOR_SYNC_OP_WAIT = 0 << 31,
+ DRM_PANTHOR_SYNC_OP_SIGNAL = (int) (1u << 31),
+};
+struct drm_panthor_sync_op {
+ __u32 flags;
+ __u32 handle;
+ __u64 timeline_value;
+};
+enum drm_panthor_dev_query_type {
+ DRM_PANTHOR_DEV_QUERY_GPU_INFO = 0,
+ DRM_PANTHOR_DEV_QUERY_CSIF_INFO,
+};
+struct drm_panthor_gpu_info {
+ __u32 gpu_id;
+#define DRM_PANTHOR_ARCH_MAJOR(x) ((x) >> 28)
+#define DRM_PANTHOR_ARCH_MINOR(x) (((x) >> 24) & 0xf)
+#define DRM_PANTHOR_ARCH_REV(x) (((x) >> 20) & 0xf)
+#define DRM_PANTHOR_PRODUCT_MAJOR(x) (((x) >> 16) & 0xf)
+#define DRM_PANTHOR_VERSION_MAJOR(x) (((x) >> 12) & 0xf)
+#define DRM_PANTHOR_VERSION_MINOR(x) (((x) >> 4) & 0xff)
+#define DRM_PANTHOR_VERSION_STATUS(x) ((x) & 0xf)
+ __u32 gpu_rev;
+ __u32 csf_id;
+#define DRM_PANTHOR_CSHW_MAJOR(x) (((x) >> 26) & 0x3f)
+#define DRM_PANTHOR_CSHW_MINOR(x) (((x) >> 20) & 0x3f)
+#define DRM_PANTHOR_CSHW_REV(x) (((x) >> 16) & 0xf)
+#define DRM_PANTHOR_MCU_MAJOR(x) (((x) >> 10) & 0x3f)
+#define DRM_PANTHOR_MCU_MINOR(x) (((x) >> 4) & 0x3f)
+#define DRM_PANTHOR_MCU_REV(x) ((x) & 0xf)
+ __u32 l2_features;
+ __u32 tiler_features;
+ __u32 mem_features;
+ __u32 mmu_features;
+#define DRM_PANTHOR_MMU_VA_BITS(x) ((x) & 0xff)
+ __u32 thread_features;
+ __u32 max_threads;
+ __u32 thread_max_workgroup_size;
+ __u32 thread_max_barrier_size;
+ __u32 coherency_features;
+ __u32 texture_features[4];
+ __u32 as_present;
+ __u64 shader_present;
+ __u64 l2_present;
+ __u64 tiler_present;
+ __u32 core_features;
+ __u32 pad;
+};
+struct drm_panthor_csif_info {
+ __u32 csg_slot_count;
+ __u32 cs_slot_count;
+ __u32 cs_reg_count;
+ __u32 scoreboard_slot_count;
+ __u32 unpreserved_cs_reg_count;
+ __u32 pad;
+};
+struct drm_panthor_dev_query {
+ __u32 type;
+ __u32 size;
+ __u64 pointer;
+};
+struct drm_panthor_vm_create {
+ __u32 flags;
+ __u32 id;
+ __u64 user_va_range;
+};
+struct drm_panthor_vm_destroy {
+ __u32 id;
+ __u32 pad;
+};
+enum drm_panthor_vm_bind_op_flags {
+ DRM_PANTHOR_VM_BIND_OP_MAP_READONLY = 1 << 0,
+ DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC = 1 << 1,
+ DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED = 1 << 2,
+ DRM_PANTHOR_VM_BIND_OP_TYPE_MASK = (int) (0xfu << 28),
+ DRM_PANTHOR_VM_BIND_OP_TYPE_MAP = 0 << 28,
+ DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP = 1 << 28,
+ DRM_PANTHOR_VM_BIND_OP_TYPE_SYNC_ONLY = 2 << 28,
+};
+struct drm_panthor_vm_bind_op {
+ __u32 flags;
+ __u32 bo_handle;
+ __u64 bo_offset;
+ __u64 va;
+ __u64 size;
+ struct drm_panthor_obj_array syncs;
+};
+enum drm_panthor_vm_bind_flags {
+ DRM_PANTHOR_VM_BIND_ASYNC = 1 << 0,
+};
+struct drm_panthor_vm_bind {
+ __u32 vm_id;
+ __u32 flags;
+ struct drm_panthor_obj_array ops;
+};
+enum drm_panthor_vm_state {
+ DRM_PANTHOR_VM_STATE_USABLE,
+ DRM_PANTHOR_VM_STATE_UNUSABLE,
+};
+struct drm_panthor_vm_get_state {
+ __u32 vm_id;
+ __u32 state;
+};
+enum drm_panthor_bo_flags {
+ DRM_PANTHOR_BO_NO_MMAP = (1 << 0),
+};
+struct drm_panthor_bo_create {
+ __u64 size;
+ __u32 flags;
+ __u32 exclusive_vm_id;
+ __u32 handle;
+ __u32 pad;
+};
+struct drm_panthor_bo_mmap_offset {
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+};
+struct drm_panthor_queue_create {
+ __u8 priority;
+ __u8 pad[3];
+ __u32 ringbuf_size;
+};
+enum drm_panthor_group_priority {
+ PANTHOR_GROUP_PRIORITY_LOW = 0,
+ PANTHOR_GROUP_PRIORITY_MEDIUM,
+ PANTHOR_GROUP_PRIORITY_HIGH,
+};
+struct drm_panthor_group_create {
+ struct drm_panthor_obj_array queues;
+ __u8 max_compute_cores;
+ __u8 max_fragment_cores;
+ __u8 max_tiler_cores;
+ __u8 priority;
+ __u32 pad;
+ __u64 compute_core_mask;
+ __u64 fragment_core_mask;
+ __u64 tiler_core_mask;
+ __u32 vm_id;
+ __u32 group_handle;
+};
+struct drm_panthor_group_destroy {
+ __u32 group_handle;
+ __u32 pad;
+};
+struct drm_panthor_queue_submit {
+ __u32 queue_index;
+ __u32 stream_size;
+ __u64 stream_addr;
+ __u32 latest_flush;
+ __u32 pad;
+ struct drm_panthor_obj_array syncs;
+};
+struct drm_panthor_group_submit {
+ __u32 group_handle;
+ __u32 pad;
+ struct drm_panthor_obj_array queue_submits;
+};
+enum drm_panthor_group_state_flags {
+ DRM_PANTHOR_GROUP_STATE_TIMEDOUT = 1 << 0,
+ DRM_PANTHOR_GROUP_STATE_FATAL_FAULT = 1 << 1,
+};
+struct drm_panthor_group_get_state {
+ __u32 group_handle;
+ __u32 state;
+ __u32 fatal_queues;
+ __u32 pad;
+};
+struct drm_panthor_tiler_heap_create {
+ __u32 vm_id;
+ __u32 initial_chunk_count;
+ __u32 chunk_size;
+ __u32 max_chunks;
+ __u32 target_in_flight;
+ __u32 handle;
+ __u64 tiler_heap_ctx_gpu_va;
+ __u64 first_heap_chunk_gpu_va;
+};
+struct drm_panthor_tiler_heap_destroy {
+ __u32 handle;
+ __u32 pad;
+};
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/drm/v3d_drm.h b/libc/kernel/uapi/drm/v3d_drm.h
index 4000fd3..b7aca21 100644
--- a/libc/kernel/uapi/drm/v3d_drm.h
+++ b/libc/kernel/uapi/drm/v3d_drm.h
@@ -22,6 +22,7 @@
#define DRM_V3D_PERFMON_DESTROY 0x09
#define DRM_V3D_PERFMON_GET_VALUES 0x0a
#define DRM_V3D_SUBMIT_CPU 0x0b
+#define DRM_V3D_PERFMON_GET_COUNTER 0x0c
#define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
#define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
#define DRM_IOCTL_V3D_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_CREATE_BO, struct drm_v3d_create_bo)
@@ -34,6 +35,7 @@
#define DRM_IOCTL_V3D_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_DESTROY, struct drm_v3d_perfmon_destroy)
#define DRM_IOCTL_V3D_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_VALUES, struct drm_v3d_perfmon_get_values)
#define DRM_IOCTL_V3D_SUBMIT_CPU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CPU, struct drm_v3d_submit_cpu)
+#define DRM_IOCTL_V3D_PERFMON_GET_COUNTER DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_COUNTER, struct drm_v3d_perfmon_get_counter)
#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
#define DRM_V3D_SUBMIT_EXTENSION 0x02
struct drm_v3d_extension {
@@ -119,6 +121,7 @@
DRM_V3D_PARAM_SUPPORTS_PERFMON,
DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT,
DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE,
+ DRM_V3D_PARAM_MAX_PERF_COUNTERS,
};
struct drm_v3d_get_param {
__u32 param;
@@ -324,6 +327,16 @@
__u32 pad;
__u64 values_ptr;
};
+#define DRM_V3D_PERFCNT_MAX_NAME 64
+#define DRM_V3D_PERFCNT_MAX_CATEGORY 32
+#define DRM_V3D_PERFCNT_MAX_DESCRIPTION 256
+struct drm_v3d_perfmon_get_counter {
+ __u8 counter;
+ __u8 name[DRM_V3D_PERFCNT_MAX_NAME];
+ __u8 category[DRM_V3D_PERFCNT_MAX_CATEGORY];
+ __u8 description[DRM_V3D_PERFCNT_MAX_DESCRIPTION];
+ __u8 reserved[7];
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/xe_drm.h b/libc/kernel/uapi/drm/xe_drm.h
index dd0da6f..16bc3b3 100644
--- a/libc/kernel/uapi/drm/xe_drm.h
+++ b/libc/kernel/uapi/drm/xe_drm.h
@@ -21,6 +21,7 @@
#define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x08
#define DRM_XE_EXEC 0x09
#define DRM_XE_WAIT_USER_FENCE 0x0a
+#define DRM_XE_OBSERVATION 0x0b
#define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query)
#define DRM_IOCTL_XE_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_GEM_CREATE, struct drm_xe_gem_create)
#define DRM_IOCTL_XE_GEM_MMAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_GEM_MMAP_OFFSET, struct drm_xe_gem_mmap_offset)
@@ -32,6 +33,7 @@
#define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_GET_PROPERTY, struct drm_xe_exec_queue_get_property)
#define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
+#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
struct drm_xe_user_extension {
__u64 next_extension;
__u32 name;
@@ -105,7 +107,11 @@
__u32 reference_clock;
__u64 near_mem_regions;
__u64 far_mem_regions;
- __u64 reserved[8];
+ __u16 ip_ver_major;
+ __u16 ip_ver_minor;
+ __u16 ip_ver_rev;
+ __u16 pad2;
+ __u64 reserved[7];
};
struct drm_xe_query_gt_list {
__u32 num_gt;
@@ -114,9 +120,11 @@
};
struct drm_xe_query_topology_mask {
__u16 gt_id;
-#define DRM_XE_TOPO_DSS_GEOMETRY (1 << 0)
-#define DRM_XE_TOPO_DSS_COMPUTE (1 << 1)
-#define DRM_XE_TOPO_EU_PER_DSS (1 << 2)
+#define DRM_XE_TOPO_DSS_GEOMETRY 1
+#define DRM_XE_TOPO_DSS_COMPUTE 2
+#define DRM_XE_TOPO_L3_BANK 3
+#define DRM_XE_TOPO_EU_PER_DSS 4
+#define DRM_XE_TOPO_SIMD16_EU_PER_DSS 5
__u16 type;
__u32 num_bytes;
__u8 mask[];
@@ -131,6 +139,7 @@
};
struct drm_xe_query_uc_fw_version {
#define XE_QUERY_UC_TYPE_GUC_SUBMISSION 0
+#define XE_QUERY_UC_TYPE_HUC 1
__u16 uc_type;
__u16 pad;
__u32 branch_ver;
@@ -150,6 +159,7 @@
#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
#define DRM_XE_DEVICE_QUERY_UC_FW_VERSION 7
+#define DRM_XE_DEVICE_QUERY_OA_UNITS 8
__u32 query;
__u32 size;
__u64 data;
@@ -209,6 +219,8 @@
#define DRM_XE_VM_BIND_OP_UNMAP_ALL 0x3
#define DRM_XE_VM_BIND_OP_PREFETCH 0x4
__u32 op;
+#define DRM_XE_VM_BIND_FLAG_READONLY (1 << 0)
+#define DRM_XE_VM_BIND_FLAG_IMMEDIATE (1 << 1)
#define DRM_XE_VM_BIND_FLAG_NULL (1 << 2)
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
__u32 flags;
@@ -302,6 +314,92 @@
__u32 pad2;
__u64 reserved[2];
};
+enum drm_xe_observation_type {
+ DRM_XE_OBSERVATION_TYPE_OA,
+};
+enum drm_xe_observation_op {
+ DRM_XE_OBSERVATION_OP_STREAM_OPEN,
+ DRM_XE_OBSERVATION_OP_ADD_CONFIG,
+ DRM_XE_OBSERVATION_OP_REMOVE_CONFIG,
+};
+struct drm_xe_observation_param {
+ __u64 extensions;
+ __u64 observation_type;
+ __u64 observation_op;
+ __u64 param;
+};
+enum drm_xe_observation_ioctls {
+ DRM_XE_OBSERVATION_IOCTL_ENABLE = _IO('i', 0x0),
+ DRM_XE_OBSERVATION_IOCTL_DISABLE = _IO('i', 0x1),
+ DRM_XE_OBSERVATION_IOCTL_CONFIG = _IO('i', 0x2),
+ DRM_XE_OBSERVATION_IOCTL_STATUS = _IO('i', 0x3),
+ DRM_XE_OBSERVATION_IOCTL_INFO = _IO('i', 0x4),
+};
+enum drm_xe_oa_unit_type {
+ DRM_XE_OA_UNIT_TYPE_OAG,
+ DRM_XE_OA_UNIT_TYPE_OAM,
+};
+struct drm_xe_oa_unit {
+ __u64 extensions;
+ __u32 oa_unit_id;
+ __u32 oa_unit_type;
+ __u64 capabilities;
+#define DRM_XE_OA_CAPS_BASE (1 << 0)
+ __u64 oa_timestamp_freq;
+ __u64 reserved[4];
+ __u64 num_engines;
+ struct drm_xe_engine_class_instance eci[];
+};
+struct drm_xe_query_oa_units {
+ __u64 extensions;
+ __u32 num_oa_units;
+ __u32 pad;
+ __u64 oa_units[];
+};
+enum drm_xe_oa_format_type {
+ DRM_XE_OA_FMT_TYPE_OAG,
+ DRM_XE_OA_FMT_TYPE_OAR,
+ DRM_XE_OA_FMT_TYPE_OAM,
+ DRM_XE_OA_FMT_TYPE_OAC,
+ DRM_XE_OA_FMT_TYPE_OAM_MPEC,
+ DRM_XE_OA_FMT_TYPE_PEC,
+};
+enum drm_xe_oa_property_id {
+#define DRM_XE_OA_EXTENSION_SET_PROPERTY 0
+ DRM_XE_OA_PROPERTY_OA_UNIT_ID = 1,
+ DRM_XE_OA_PROPERTY_SAMPLE_OA,
+ DRM_XE_OA_PROPERTY_OA_METRIC_SET,
+ DRM_XE_OA_PROPERTY_OA_FORMAT,
+#define DRM_XE_OA_FORMAT_MASK_FMT_TYPE (0xffu << 0)
+#define DRM_XE_OA_FORMAT_MASK_COUNTER_SEL (0xffu << 8)
+#define DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE (0xffu << 16)
+#define DRM_XE_OA_FORMAT_MASK_BC_REPORT (0xffu << 24)
+ DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT,
+ DRM_XE_OA_PROPERTY_OA_DISABLED,
+ DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID,
+ DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE,
+ DRM_XE_OA_PROPERTY_NO_PREEMPT,
+};
+struct drm_xe_oa_config {
+ __u64 extensions;
+ char uuid[36];
+ __u32 n_regs;
+ __u64 regs_ptr;
+};
+struct drm_xe_oa_stream_status {
+ __u64 extensions;
+ __u64 oa_status;
+#define DRM_XE_OASTATUS_MMIO_TRG_Q_FULL (1 << 3)
+#define DRM_XE_OASTATUS_COUNTER_OVERFLOW (1 << 2)
+#define DRM_XE_OASTATUS_BUFFER_OVERFLOW (1 << 1)
+#define DRM_XE_OASTATUS_REPORT_LOST (1 << 0)
+ __u64 reserved[3];
+};
+struct drm_xe_oa_stream_info {
+ __u64 extensions;
+ __u64 oa_buf_size;
+ __u64 reserved[3];
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 6e64ebc..273ee59 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -115,6 +115,11 @@
__u32 sync_recv;
__u32 async_recv;
};
+struct binder_frozen_state_info {
+ binder_uintptr_t cookie;
+ __u32 is_frozen;
+ __u32 reserved;
+};
struct binder_extended_error {
__u32 id;
__u32 command;
@@ -212,6 +217,8 @@
BR_FROZEN_REPLY = _IO('r', 18),
BR_ONEWAY_SPAM_SUSPECT = _IO('r', 19),
BR_TRANSACTION_PENDING_FROZEN = _IO('r', 20),
+ BR_FROZEN_BINDER = _IOR('r', 21, struct binder_frozen_state_info),
+ BR_CLEAR_FREEZE_NOTIFICATION_DONE = _IOR('r', 22, binder_uintptr_t),
};
enum binder_driver_command_protocol {
BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
@@ -233,5 +240,8 @@
BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t),
BC_TRANSACTION_SG = _IOW('c', 17, struct binder_transaction_data_sg),
BC_REPLY_SG = _IOW('c', 18, struct binder_transaction_data_sg),
+ BC_REQUEST_FREEZE_NOTIFICATION = _IOW('c', 19, struct binder_handle_cookie),
+ BC_CLEAR_FREEZE_NOTIFICATION = _IOW('c', 20, struct binder_handle_cookie),
+ BC_FREEZE_NOTIFICATION_DONE = _IOW('c', 21, binder_uintptr_t),
};
#endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 98849f1..ae50fcc 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -95,6 +95,9 @@
#define AUDIT_MAC_UNLBL_STCDEL 1417
#define AUDIT_MAC_CALIPSO_ADD 1418
#define AUDIT_MAC_CALIPSO_DEL 1419
+#define AUDIT_IPE_ACCESS 1420
+#define AUDIT_IPE_CONFIG_CHANGE 1421
+#define AUDIT_IPE_POLICY_LOAD 1422
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700
diff --git a/libc/kernel/uapi/linux/auto_fs.h b/libc/kernel/uapi/linux/auto_fs.h
index dd11a93..a48a887 100644
--- a/libc/kernel/uapi/linux/auto_fs.h
+++ b/libc/kernel/uapi/linux/auto_fs.h
@@ -12,7 +12,7 @@
#define AUTOFS_PROTO_VERSION 5
#define AUTOFS_MIN_PROTO_VERSION 3
#define AUTOFS_MAX_PROTO_VERSION 5
-#define AUTOFS_PROTO_SUBVERSION 5
+#define AUTOFS_PROTO_SUBVERSION 6
#if defined(__ia64__) || defined(__alpha__)
typedef unsigned long autofs_wqt_t;
#else
diff --git a/libc/kernel/uapi/linux/bits.h b/libc/kernel/uapi/linux/bits.h
index d747e24..2b8dbe2 100644
--- a/libc/kernel/uapi/linux/bits.h
+++ b/libc/kernel/uapi/linux/bits.h
@@ -8,4 +8,5 @@
#define _UAPI_LINUX_BITS_H
#define __GENMASK(h,l) (((~_UL(0)) - (_UL(1) << (l)) + 1) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
#define __GENMASK_ULL(h,l) (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
+#define __GENMASK_U128(h,l) ((_BIT128((h)) << 1) - (_BIT128(l)))
#endif
diff --git a/libc/kernel/uapi/linux/blkdev.h b/libc/kernel/uapi/linux/blkdev.h
new file mode 100644
index 0000000..103fa0f
--- /dev/null
+++ b/libc/kernel/uapi/linux/blkdev.h
@@ -0,0 +1,12 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_BLKDEV_H
+#define _UAPI_LINUX_BLKDEV_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define BLOCK_URING_CMD_DISCARD _IO(0x12, 0)
+#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 0e9e883..c0d862d 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -272,6 +272,7 @@
BPF_CGROUP_UNIX_GETSOCKNAME,
BPF_NETKIT_PRIMARY,
BPF_NETKIT_PEER,
+ BPF_TRACE_KPROBE_SESSION,
__MAX_BPF_ATTACH_TYPE
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -290,6 +291,7 @@
BPF_LINK_TYPE_TCX = 11,
BPF_LINK_TYPE_UPROBE_MULTI = 12,
BPF_LINK_TYPE_NETKIT = 13,
+ BPF_LINK_TYPE_SOCKMAP = 14,
__MAX_BPF_LINK_TYPE,
};
#define MAX_BPF_LINK_TYPE __MAX_BPF_LINK_TYPE
@@ -365,6 +367,7 @@
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
#define BPF_F_TEST_RUN_ON_CPU (1U << 0)
#define BPF_F_TEST_XDP_LIVE_FRAMES (1U << 1)
+#define BPF_F_TEST_SKB_CHECKSUM_COMPLETE (1U << 2)
enum bpf_stats_type {
BPF_STATS_RUN_TIME = 0,
};
@@ -529,6 +532,8 @@
struct {
__u64 name;
__u32 prog_fd;
+ __u32 : 32;
+ __aligned_u64 cookie;
} raw_tracepoint;
struct {
__aligned_u64 btf;
@@ -666,9 +671,6 @@
BPF_F_MARK_ENFORCE = (1ULL << 6),
};
enum {
- BPF_F_INGRESS = (1ULL << 0),
-};
-enum {
BPF_F_TUNINFO_IPV6 = (1ULL << 0),
};
enum {
@@ -763,14 +765,19 @@
BPF_F_BPRM_SECUREEXEC = (1ULL << 0),
};
enum {
+ BPF_F_INGRESS = (1ULL << 0),
BPF_F_BROADCAST = (1ULL << 3),
BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
+#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
};
#define __bpf_md_ptr(type,name) union { type name; __u64 : 64; \
} __attribute__((aligned(8)))
enum {
- BPF_SKB_TSTAMP_UNSPEC,
- BPF_SKB_TSTAMP_DELIVERY_MONO,
+ BPF_SKB_TSTAMP_UNSPEC = 0,
+ BPF_SKB_TSTAMP_DELIVERY_MONO = 1,
+ BPF_SKB_CLOCK_REALTIME = 0,
+ BPF_SKB_CLOCK_MONOTONIC = 1,
+ BPF_SKB_CLOCK_TAI = 2,
};
struct __sk_buff {
__u32 len;
@@ -1150,6 +1157,10 @@
__u32 ifindex;
__u32 attach_type;
} netkit;
+ struct {
+ __u32 map_id;
+ __u32 attach_type;
+ } sockmap;
};
} __attribute__((aligned(8)));
struct bpf_sock_addr {
@@ -1263,6 +1274,7 @@
TCP_BPF_SYN = 1005,
TCP_BPF_SYN_IP = 1006,
TCP_BPF_SYN_MAC = 1007,
+ TCP_BPF_SOCK_OPS_CB_FLAGS = 1008,
};
enum {
BPF_LOAD_HDR_OPT_TCP_SYN = (1ULL << 0),
@@ -1299,6 +1311,7 @@
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
BPF_FIB_LOOKUP_TBID = (1U << 3),
BPF_FIB_LOOKUP_SRC = (1U << 4),
+ BPF_FIB_LOOKUP_MARK = (1U << 5),
};
enum {
BPF_FIB_LKUP_RET_SUCCESS,
@@ -1320,7 +1333,7 @@
union {
__u16 tot_len;
__u16 mtu_result;
- };
+ } __attribute__((packed, aligned(2)));
__u32 ifindex;
union {
__u8 tos;
@@ -1342,8 +1355,15 @@
};
__u32 tbid;
};
- __u8 smac[6];
- __u8 dmac[6];
+ union {
+ struct {
+ __u32 mark;
+ };
+ struct {
+ __u8 smac[6];
+ __u8 dmac[6];
+ };
+ };
};
struct bpf_redir_neigh {
__u32 nh_family;
@@ -1415,6 +1435,9 @@
struct bpf_timer {
__u64 __opaque[2];
} __attribute__((aligned(8)));
+struct bpf_wq {
+ __u64 __opaque[2];
+} __attribute__((aligned(8)));
struct bpf_dynptr {
__u64 __opaque[2];
} __attribute__((aligned(8)));
@@ -1505,4 +1528,7 @@
struct bpf_iter_num {
__u64 __opaque[1];
} __attribute__((aligned(8)));
+enum bpf_kfunc_flags {
+ BPF_F_PAD_ZEROS = (1ULL << 0),
+};
#endif
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index ea33eee..88f44d9 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -279,18 +279,8 @@
__le64 devid;
__le64 physical;
} __attribute__((__packed__));
-#define BTRFS_STRIPE_RAID0 1
-#define BTRFS_STRIPE_RAID1 2
-#define BTRFS_STRIPE_DUP 3
-#define BTRFS_STRIPE_RAID10 4
-#define BTRFS_STRIPE_RAID5 5
-#define BTRFS_STRIPE_RAID6 6
-#define BTRFS_STRIPE_RAID1C3 7
-#define BTRFS_STRIPE_RAID1C4 8
struct btrfs_stripe_extent {
- __u8 encoding;
- __u8 reserved[7];
- struct btrfs_raid_stride strides[];
+ __DECLARE_FLEX_ARRAY(struct btrfs_raid_stride, strides);
} __attribute__((__packed__));
#define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0)
#define BTRFS_HEADER_FLAG_RELOC (1ULL << 1)
@@ -300,6 +290,9 @@
#define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34)
#define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35)
#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36)
+#define BTRFS_SUPER_FLAG_CHANGING_BG_TREE (1ULL << 38)
+#define BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM (1ULL << 39)
+#define BTRFS_SUPER_FLAG_CHANGING_META_CSUM (1ULL << 40)
struct btrfs_extent_item {
__le64 refs;
__le64 generation;
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 43e8456..91f4d67 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -27,6 +27,7 @@
};
#define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0)
#define CEC_MSG_FL_RAW (1 << 1)
+#define CEC_MSG_FL_REPLY_VENDOR_ID (1 << 2)
#define CEC_TX_STATUS_OK (1 << 0)
#define CEC_TX_STATUS_ARB_LOST (1 << 1)
#define CEC_TX_STATUS_NACK (1 << 2)
@@ -96,6 +97,7 @@
#define CEC_CAP_NEEDS_HPD (1 << 6)
#define CEC_CAP_MONITOR_PIN (1 << 7)
#define CEC_CAP_CONNECTOR_INFO (1 << 8)
+#define CEC_CAP_REPLY_VENDOR_ID (1 << 9)
struct cec_caps {
char driver[32];
char name[32];
diff --git a/libc/kernel/uapi/linux/const.h b/libc/kernel/uapi/linux/const.h
index c091f8d..b45b722 100644
--- a/libc/kernel/uapi/linux/const.h
+++ b/libc/kernel/uapi/linux/const.h
@@ -18,6 +18,9 @@
#define _ULL(x) (_AC(x, ULL))
#define _BITUL(x) (_UL(1) << (x))
#define _BITULL(x) (_ULL(1) << (x))
+#ifndef __ASSEMBLY__
+#define _BIT128(x) ((unsigned __int128) (1) << (x))
+#endif
#define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (__typeof__(x)) (a) - 1)
#define __ALIGN_KERNEL_MASK(x,mask) (((x) + (mask)) & ~(mask))
#define __KERNEL_DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 942e817..abe6573 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -9,7 +9,7 @@
#include <linux/types.h>
#define CXL_MEM_QUERY_COMMANDS _IOR(0xCE, 1, struct cxl_mem_query_commands)
#define CXL_MEM_SEND_COMMAND _IOWR(0xCE, 2, struct cxl_send_command)
-#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___DEPRECATED(GET_POISON, "Get Poison List"), ___DEPRECATED(INJECT_POISON, "Inject Poison"), ___DEPRECATED(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___DEPRECATED(SCAN_MEDIA, "Scan Media"), ___DEPRECATED(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(GET_TIMESTAMP, "Get Timestamp"), ___C(MAX, "invalid / last command")
+#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___DEPRECATED(GET_POISON, "Get Poison List"), ___DEPRECATED(INJECT_POISON, "Inject Poison"), ___DEPRECATED(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___DEPRECATED(SCAN_MEDIA, "Scan Media"), ___DEPRECATED(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(GET_TIMESTAMP, "Get Timestamp"), ___C(GET_LOG_CAPS, "Get Log Capabilities"), ___C(CLEAR_LOG, "Clear Log"), ___C(GET_SUP_LOG_SUBLIST, "Get Supported Logs Sub-List"), ___C(MAX, "invalid / last command")
#define ___C(a,b) CXL_MEM_COMMAND_ID_ ##a
#define ___DEPRECATED(a,b) CXL_MEM_DEPRECATED_ID_ ##a
enum {
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index 968d6be..d87c189 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -466,6 +466,7 @@
DEVLINK_PORT_FN_ATTR_OPSTATE,
DEVLINK_PORT_FN_ATTR_CAPS,
DEVLINK_PORT_FN_ATTR_DEVLINK,
+ DEVLINK_PORT_FN_ATTR_MAX_IO_EQS,
__DEVLINK_PORT_FUNCTION_ATTR_MAX,
DEVLINK_PORT_FUNCTION_ATTR_MAX = __DEVLINK_PORT_FUNCTION_ATTR_MAX - 1
};
diff --git a/libc/kernel/uapi/linux/dlm.h b/libc/kernel/uapi/linux/dlm.h
index 3c73908..1344f9b 100644
--- a/libc/kernel/uapi/linux/dlm.h
+++ b/libc/kernel/uapi/linux/dlm.h
@@ -20,4 +20,5 @@
};
#define DLM_LSFL_TIMEWARN 0x00000002
#define DLM_LSFL_NEWEXCL 0x00000008
+#define __DLM_LSFL_RESERVED0 0x00000010
#endif
diff --git a/libc/kernel/uapi/linux/dma-heap.h b/libc/kernel/uapi/linux/dma-heap.h
index 467e336..ac86b59 100644
--- a/libc/kernel/uapi/linux/dma-heap.h
+++ b/libc/kernel/uapi/linux/dma-heap.h
@@ -9,7 +9,7 @@
#include <linux/ioctl.h>
#include <linux/types.h>
#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
-#define DMA_HEAP_VALID_HEAP_FLAGS (0)
+#define DMA_HEAP_VALID_HEAP_FLAGS (0ULL)
struct dma_heap_allocation_data {
__u64 len;
__u32 fd;
diff --git a/libc/kernel/uapi/linux/dpll.h b/libc/kernel/uapi/linux/dpll.h
index dd692f6..7d6182b 100644
--- a/libc/kernel/uapi/linux/dpll.h
+++ b/libc/kernel/uapi/linux/dpll.h
@@ -108,6 +108,9 @@
DPLL_A_PIN_PHASE_ADJUST,
DPLL_A_PIN_PHASE_OFFSET,
DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
+ DPLL_A_PIN_ESYNC_FREQUENCY,
+ DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED,
+ DPLL_A_PIN_ESYNC_PULSE,
__DPLL_A_PIN_MAX,
DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/dvb/frontend.h b/libc/kernel/uapi/linux/dvb/frontend.h
index 64e2cae..9428cc0 100644
--- a/libc/kernel/uapi/linux/dvb/frontend.h
+++ b/libc/kernel/uapi/linux/dvb/frontend.h
@@ -341,7 +341,7 @@
union {
__u64 uvalue;
__s64 svalue;
- };
+ } __attribute__((packed));
} __attribute__((packed));
#define MAX_DTV_STATS 4
struct dtv_fe_stats {
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index f1cf522..ea40103 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -329,6 +329,7 @@
#define NT_386_IOPERM 0x201
#define NT_X86_XSTATE 0x202
#define NT_X86_SHSTK 0x204
+#define NT_X86_XSAVE_LAYOUT 0x205
#define NT_S390_HIGH_GPRS 0x300
#define NT_S390_TIMER 0x301
#define NT_S390_TODCMP 0x302
@@ -359,6 +360,7 @@
#define NT_ARM_ZA 0x40c
#define NT_ARM_ZT 0x40d
#define NT_ARM_FPMR 0x40e
+#define NT_ARM_POE 0x40f
#define NT_ARC_V2 0x600
#define NT_VMCOREDD 0x700
#define NT_MIPS_DSP 0x800
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 48b4544..323c4fc 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -270,6 +270,75 @@
ETHTOOL_MODULE_POWER_MODE_LOW = 1,
ETHTOOL_MODULE_POWER_MODE_HIGH,
};
+enum ethtool_c33_pse_ext_state {
+ ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION = 1,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
+ ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE,
+ ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
+};
+enum ethtool_c33_pse_ext_substate_mr_mps_valid {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN,
+};
+enum ethtool_c33_pse_ext_substate_error_condition {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP,
+};
+enum ethtool_c33_pse_ext_substate_mr_pse_enable {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE = 1,
+};
+enum ethtool_c33_pse_ext_substate_option_detect_ted {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR,
+};
+enum ethtool_c33_pse_ext_substate_option_vport_lim {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION,
+};
+enum ethtool_c33_pse_ext_substate_ovld_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD = 1,
+};
+enum ethtool_c33_pse_ext_substate_power_not_available {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT,
+};
+enum ethtool_c33_pse_ext_substate_short_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION = 1,
+};
+enum ethtool_pse_types {
+ ETHTOOL_PSE_UNKNOWN = 1 << 0,
+ ETHTOOL_PSE_PODL = 1 << 1,
+ ETHTOOL_PSE_C33 = 1 << 2,
+};
+enum ethtool_c33_pse_admin_state {
+ ETHTOOL_C33_PSE_ADMIN_STATE_UNKNOWN = 1,
+ ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED,
+ ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED,
+};
+enum ethtool_c33_pse_pw_d_status {
+ ETHTOOL_C33_PSE_PW_D_STATUS_UNKNOWN = 1,
+ ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED,
+ ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING,
+ ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING,
+ ETHTOOL_C33_PSE_PW_D_STATUS_TEST,
+ ETHTOOL_C33_PSE_PW_D_STATUS_FAULT,
+ ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT,
+};
enum ethtool_podl_pse_admin_state {
ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN = 1,
ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,
@@ -292,6 +361,12 @@
ETHTOOL_MM_VERIFY_STATUS_FAILED,
ETHTOOL_MM_VERIFY_STATUS_DISABLED,
};
+enum ethtool_module_fw_flash_status {
+ ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED = 1,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR,
+};
struct ethtool_gstrings {
__u32 cmd;
__u32 string_set;
@@ -730,6 +805,7 @@
ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99,
ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100,
ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101,
+ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT = 102,
__ETHTOOL_LINK_MODE_MASK_NBITS
};
#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
@@ -950,4 +1026,8 @@
__u32 reserved[7];
__u32 link_mode_masks[];
};
+enum phy_upstream {
+ PHY_UPSTREAM_MAC,
+ PHY_UPSTREAM_PHY,
+};
#endif
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index e4fc40e..7120c03 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -52,6 +52,8 @@
ETHTOOL_MSG_PLCA_GET_STATUS,
ETHTOOL_MSG_MM_GET,
ETHTOOL_MSG_MM_SET,
+ ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
+ ETHTOOL_MSG_PHY_GET,
__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
};
@@ -100,18 +102,24 @@
ETHTOOL_MSG_PLCA_NTF,
ETHTOOL_MSG_MM_GET_REPLY,
ETHTOOL_MSG_MM_NTF,
+ ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
+ ETHTOOL_MSG_PHY_GET_REPLY,
+ ETHTOOL_MSG_PHY_NTF,
__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
};
-#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0)
-#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1)
-#define ETHTOOL_FLAG_STATS (1 << 2)
+enum ethtool_header_flags {
+ ETHTOOL_FLAG_COMPACT_BITSETS = 1 << 0,
+ ETHTOOL_FLAG_OMIT_REPLY = 1 << 1,
+ ETHTOOL_FLAG_STATS = 1 << 2,
+};
#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | ETHTOOL_FLAG_OMIT_REPLY | ETHTOOL_FLAG_STATS)
enum {
ETHTOOL_A_HEADER_UNSPEC,
ETHTOOL_A_HEADER_DEV_INDEX,
ETHTOOL_A_HEADER_DEV_NAME,
ETHTOOL_A_HEADER_FLAGS,
+ ETHTOOL_A_HEADER_PHY_INDEX,
__ETHTOOL_A_HEADER_CNT,
ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1
};
@@ -314,10 +322,26 @@
ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES,
ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES,
ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS,
+ ETHTOOL_A_COALESCE_RX_PROFILE,
+ ETHTOOL_A_COALESCE_TX_PROFILE,
__ETHTOOL_A_COALESCE_CNT,
ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1)
};
enum {
+ ETHTOOL_A_PROFILE_UNSPEC,
+ ETHTOOL_A_PROFILE_IRQ_MODERATION,
+ __ETHTOOL_A_PROFILE_CNT,
+ ETHTOOL_A_PROFILE_MAX = (__ETHTOOL_A_PROFILE_CNT - 1)
+};
+enum {
+ ETHTOOL_A_IRQ_MODERATION_UNSPEC,
+ ETHTOOL_A_IRQ_MODERATION_USEC,
+ ETHTOOL_A_IRQ_MODERATION_PKTS,
+ ETHTOOL_A_IRQ_MODERATION_COMPS,
+ __ETHTOOL_A_IRQ_MODERATION_CNT,
+ ETHTOOL_A_IRQ_MODERATION_MAX = (__ETHTOOL_A_IRQ_MODERATION_CNT - 1)
+};
+enum {
ETHTOOL_A_PAUSE_UNSPEC,
ETHTOOL_A_PAUSE_HEADER,
ETHTOOL_A_PAUSE_AUTONEG,
@@ -355,10 +379,19 @@
ETHTOOL_A_TSINFO_TX_TYPES,
ETHTOOL_A_TSINFO_RX_FILTERS,
ETHTOOL_A_TSINFO_PHC_INDEX,
+ ETHTOOL_A_TSINFO_STATS,
__ETHTOOL_A_TSINFO_CNT,
ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
};
enum {
+ ETHTOOL_A_TS_STAT_UNSPEC,
+ ETHTOOL_A_TS_STAT_TX_PKTS,
+ ETHTOOL_A_TS_STAT_TX_LOST,
+ ETHTOOL_A_TS_STAT_TX_ERR,
+ __ETHTOOL_A_TS_STAT_CNT,
+ ETHTOOL_A_TS_STAT_MAX = (__ETHTOOL_A_TS_STAT_CNT - 1)
+};
+enum {
ETHTOOL_A_PHC_VCLOCKS_UNSPEC,
ETHTOOL_A_PHC_VCLOCKS_HEADER,
ETHTOOL_A_PHC_VCLOCKS_NUM,
@@ -378,6 +411,9 @@
ETHTOOL_A_CABLE_RESULT_CODE_OPEN,
ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT,
ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT,
+ ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH,
+ ETHTOOL_A_CABLE_RESULT_CODE_NOISE,
+ ETHTOOL_A_CABLE_RESULT_CODE_RESOLUTION_NOT_POSSIBLE,
};
enum {
ETHTOOL_A_CABLE_PAIR_A,
@@ -386,9 +422,15 @@
ETHTOOL_A_CABLE_PAIR_D,
};
enum {
+ ETHTOOL_A_CABLE_INF_SRC_UNSPEC,
+ ETHTOOL_A_CABLE_INF_SRC_TDR,
+ ETHTOOL_A_CABLE_INF_SRC_ALCD,
+};
+enum {
ETHTOOL_A_CABLE_RESULT_UNSPEC,
ETHTOOL_A_CABLE_RESULT_PAIR,
ETHTOOL_A_CABLE_RESULT_CODE,
+ ETHTOOL_A_CABLE_RESULT_SRC,
__ETHTOOL_A_CABLE_RESULT_CNT,
ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1)
};
@@ -396,6 +438,7 @@
ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC,
ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR,
ETHTOOL_A_CABLE_FAULT_LENGTH_CM,
+ ETHTOOL_A_CABLE_FAULT_LENGTH_SRC,
__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT,
ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1)
};
@@ -623,11 +666,25 @@
ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1)
};
enum {
+ ETHTOOL_A_C33_PSE_PW_LIMIT_UNSPEC,
+ ETHTOOL_A_C33_PSE_PW_LIMIT_MIN,
+ ETHTOOL_A_C33_PSE_PW_LIMIT_MAX,
+};
+enum {
ETHTOOL_A_PSE_UNSPEC,
ETHTOOL_A_PSE_HEADER,
ETHTOOL_A_PODL_PSE_ADMIN_STATE,
ETHTOOL_A_PODL_PSE_ADMIN_CONTROL,
ETHTOOL_A_PODL_PSE_PW_D_STATUS,
+ ETHTOOL_A_C33_PSE_ADMIN_STATE,
+ ETHTOOL_A_C33_PSE_ADMIN_CONTROL,
+ ETHTOOL_A_C33_PSE_PW_D_STATUS,
+ ETHTOOL_A_C33_PSE_PW_CLASS,
+ ETHTOOL_A_C33_PSE_ACTUAL_PW,
+ ETHTOOL_A_C33_PSE_EXT_STATE,
+ ETHTOOL_A_C33_PSE_EXT_SUBSTATE,
+ ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT,
+ ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES,
__ETHTOOL_A_PSE_CNT,
ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1)
};
@@ -639,6 +696,7 @@
ETHTOOL_A_RSS_INDIR,
ETHTOOL_A_RSS_HKEY,
ETHTOOL_A_RSS_INPUT_XFRM,
+ ETHTOOL_A_RSS_START_CONTEXT,
__ETHTOOL_A_RSS_CNT,
ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1),
};
@@ -684,6 +742,31 @@
__ETHTOOL_A_MM_CNT,
ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1)
};
+enum {
+ ETHTOOL_A_MODULE_FW_FLASH_UNSPEC,
+ ETHTOOL_A_MODULE_FW_FLASH_HEADER,
+ ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME,
+ ETHTOOL_A_MODULE_FW_FLASH_PASSWORD,
+ ETHTOOL_A_MODULE_FW_FLASH_STATUS,
+ ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG,
+ ETHTOOL_A_MODULE_FW_FLASH_DONE,
+ ETHTOOL_A_MODULE_FW_FLASH_TOTAL,
+ __ETHTOOL_A_MODULE_FW_FLASH_CNT,
+ ETHTOOL_A_MODULE_FW_FLASH_MAX = (__ETHTOOL_A_MODULE_FW_FLASH_CNT - 1)
+};
+enum {
+ ETHTOOL_A_PHY_UNSPEC,
+ ETHTOOL_A_PHY_HEADER,
+ ETHTOOL_A_PHY_INDEX,
+ ETHTOOL_A_PHY_DRVNAME,
+ ETHTOOL_A_PHY_NAME,
+ ETHTOOL_A_PHY_UPSTREAM_TYPE,
+ ETHTOOL_A_PHY_UPSTREAM_INDEX,
+ ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,
+ ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,
+ __ETHTOOL_A_PHY_CNT,
+ ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
+};
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
#define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
diff --git a/libc/kernel/uapi/linux/exfat.h b/libc/kernel/uapi/linux/exfat.h
new file mode 100644
index 0000000..b813581
--- /dev/null
+++ b/libc/kernel/uapi/linux/exfat.h
@@ -0,0 +1,15 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_EXFAT_H
+#define _UAPI_LINUX_EXFAT_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define EXFAT_IOC_SHUTDOWN _IOR('X', 125, __u32)
+#define EXFAT_GOING_DOWN_DEFAULT 0x0
+#define EXFAT_GOING_DOWN_FULLSYNC 0x1
+#define EXFAT_GOING_DOWN_NOSYNC 0x2
+#endif
diff --git a/libc/kernel/uapi/linux/falloc.h b/libc/kernel/uapi/linux/falloc.h
index cca488e..cd7017e 100644
--- a/libc/kernel/uapi/linux/falloc.h
+++ b/libc/kernel/uapi/linux/falloc.h
@@ -6,6 +6,7 @@
*/
#ifndef _UAPI_FALLOC_H_
#define _UAPI_FALLOC_H_
+#define FALLOC_FL_ALLOCATE_RANGE 0x00
#define FALLOC_FL_KEEP_SIZE 0x01
#define FALLOC_FL_PUNCH_HOLE 0x02
#define FALLOC_FL_NO_HIDE_STALE 0x04
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index 0e5c84d..22ca65d 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -10,9 +10,11 @@
#include <linux/openat2.h>
#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
+#define F_NOTIFY (F_LINUX_SPECIFIC_BASE + 2)
+#define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
+#define F_CREATED_QUERY (F_LINUX_SPECIFIC_BASE + 4)
#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
-#define F_NOTIFY (F_LINUX_SPECIFIC_BASE + 2)
#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
@@ -43,8 +45,6 @@
#define DN_MULTISHOT 0x80000000
#define AT_FDCWD - 100
#define AT_SYMLINK_NOFOLLOW 0x100
-#define AT_EACCESS 0x200
-#define AT_REMOVEDIR 0x200
#define AT_SYMLINK_FOLLOW 0x400
#define AT_NO_AUTOMOUNT 0x800
#define AT_EMPTY_PATH 0x1000
@@ -53,5 +53,11 @@
#define AT_STATX_FORCE_SYNC 0x2000
#define AT_STATX_DONT_SYNC 0x4000
#define AT_RECURSIVE 0x8000
-#define AT_HANDLE_FID AT_REMOVEDIR
+#define AT_RENAME_NOREPLACE 0x0001
+#define AT_RENAME_EXCHANGE 0x0002
+#define AT_RENAME_WHITEOUT 0x0004
+#define AT_EACCESS 0x200
+#define AT_REMOVEDIR 0x200
+#define AT_HANDLE_FID 0x200
+#define AT_HANDLE_MNT_ID_UNIQUE 0x001
#endif
diff --git a/libc/kernel/uapi/linux/fib_rules.h b/libc/kernel/uapi/linux/fib_rules.h
index ee9cabc..339ccce 100644
--- a/libc/kernel/uapi/linux/fib_rules.h
+++ b/libc/kernel/uapi/linux/fib_rules.h
@@ -61,6 +61,7 @@
FRA_IP_PROTO,
FRA_SPORT_RANGE,
FRA_DPORT_RANGE,
+ FRA_DSCP,
__FRA_MAX
};
#define FRA_MAX (__FRA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 38a2d9e..adab56f 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -194,8 +194,10 @@
#define RWF_NOWAIT (( __kernel_rwf_t) 0x00000008)
#define RWF_APPEND (( __kernel_rwf_t) 0x00000010)
#define RWF_NOAPPEND (( __kernel_rwf_t) 0x00000020)
-#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND | RWF_NOAPPEND)
-#define PAGEMAP_SCAN _IOWR('f', 16, struct pm_scan_arg)
+#define RWF_ATOMIC (( __kernel_rwf_t) 0x00000040)
+#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC)
+#define PROCFS_IOCTL_MAGIC 'f'
+#define PAGEMAP_SCAN _IOWR(PROCFS_IOCTL_MAGIC, 16, struct pm_scan_arg)
#define PAGE_IS_WPALLOWED (1 << 0)
#define PAGE_IS_WRITTEN (1 << 1)
#define PAGE_IS_FILE (1 << 2)
@@ -225,4 +227,30 @@
__u64 category_anyof_mask;
__u64 return_mask;
};
+#define PROCMAP_QUERY _IOWR(PROCFS_IOCTL_MAGIC, 17, struct procmap_query)
+enum procmap_query_flags {
+ PROCMAP_QUERY_VMA_READABLE = 0x01,
+ PROCMAP_QUERY_VMA_WRITABLE = 0x02,
+ PROCMAP_QUERY_VMA_EXECUTABLE = 0x04,
+ PROCMAP_QUERY_VMA_SHARED = 0x08,
+ PROCMAP_QUERY_COVERING_OR_NEXT_VMA = 0x10,
+ PROCMAP_QUERY_FILE_BACKED_VMA = 0x20,
+};
+struct procmap_query {
+ __u64 size;
+ __u64 query_flags;
+ __u64 query_addr;
+ __u64 vma_start;
+ __u64 vma_end;
+ __u64 vma_flags;
+ __u64 vma_page_size;
+ __u64 vma_offset;
+ __u64 inode;
+ __u32 dev_major;
+ __u32 dev_minor;
+ __u32 vma_name_size;
+ __u32 build_id_size;
+ __u64 vma_name_addr;
+ __u64 build_id_addr;
+};
#endif
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index 4ac2d2c..c1d64ce 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -8,7 +8,7 @@
#define _LINUX_FUSE_H
#include <stdint.h>
#define FUSE_KERNEL_VERSION 7
-#define FUSE_KERNEL_MINOR_VERSION 40
+#define FUSE_KERNEL_MINOR_VERSION 41
#define FUSE_ROOT_ID 1
struct fuse_attr {
uint64_t ino;
@@ -135,6 +135,7 @@
#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38)
#define FUSE_HAS_RESEND (1ULL << 39)
#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
+#define FUSE_ALLOW_IDMAP (1ULL << 40)
#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
#define FUSE_RELEASE_FLUSH (1 << 0)
#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
@@ -214,6 +215,7 @@
FUSE_SYNCFS = 50,
FUSE_TMPFILE = 51,
FUSE_STATX = 52,
+ FUSE_CANONICAL_PATH = 2016,
CUSE_INIT = 4096,
CUSE_INIT_BSWAP_RESERVED = 1048576,
FUSE_INIT_BSWAP_RESERVED = 436207616,
@@ -497,6 +499,7 @@
uint32_t padding;
};
#define FUSE_UNIQUE_RESEND (1ULL << 63)
+#define FUSE_INVALID_UIDGID ((uint32_t) (- 1))
struct fuse_in_header {
uint32_t len;
uint32_t opcode;
diff --git a/libc/kernel/uapi/linux/gtp.h b/libc/kernel/uapi/linux/gtp.h
index c828470..5a8cdde 100644
--- a/libc/kernel/uapi/linux/gtp.h
+++ b/libc/kernel/uapi/linux/gtp.h
@@ -31,6 +31,9 @@
GTPA_I_TEI,
GTPA_O_TEI,
GTPA_PAD,
+ GTPA_PEER_ADDR6,
+ GTPA_MS_ADDR6,
+ GTPA_FAMILY,
__GTPA_MAX,
};
#define GTPA_MAX (__GTPA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/hidraw.h b/libc/kernel/uapi/linux/hidraw.h
index 25a9a17..1eb024c 100644
--- a/libc/kernel/uapi/linux/hidraw.h
+++ b/libc/kernel/uapi/linux/hidraw.h
@@ -29,6 +29,7 @@
#define HIDIOCGINPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0A, len)
#define HIDIOCSOUTPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0B, len)
#define HIDIOCGOUTPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0C, len)
+#define HIDIOCREVOKE _IOW('H', 0x0D, int)
#define HIDRAW_FIRST_MINOR 0
#define HIDRAW_MAX_DEVICES 64
#define HIDRAW_BUFFER_SIZE 64
diff --git a/libc/kernel/uapi/linux/icmpv6.h b/libc/kernel/uapi/linux/icmpv6.h
index 9df18ad..a2ca922 100644
--- a/libc/kernel/uapi/linux/icmpv6.h
+++ b/libc/kernel/uapi/linux/icmpv6.h
@@ -81,6 +81,7 @@
#define ICMPV6_MOBILE_PREFIX_SOL 146
#define ICMPV6_MOBILE_PREFIX_ADV 147
#define ICMPV6_MRDISC_ADV 151
+#define ICMPV6_MRDISC_SOL 152
#define ICMPV6_MSG_MAX 255
#define ICMPV6_NOROUTE 0
#define ICMPV6_ADM_PROHIBITED 1
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 397adfe..c2483a2 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -610,6 +610,8 @@
IFLA_GTP_ROLE,
IFLA_GTP_CREATE_SOCKETS,
IFLA_GTP_RESTART_COUNT,
+ IFLA_GTP_LOCAL,
+ IFLA_GTP_LOCAL6,
__IFLA_GTP_MAX,
};
#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
@@ -845,6 +847,7 @@
IFLA_HSR_SEQ_NR,
IFLA_HSR_VERSION,
IFLA_HSR_PROTOCOL,
+ IFLA_HSR_INTERLINK,
__IFLA_HSR_MAX,
};
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_team.h b/libc/kernel/uapi/linux/if_team.h
index b22be7e..9985f63 100644
--- a/libc/kernel/uapi/linux/if_team.h
+++ b/libc/kernel/uapi/linux/if_team.h
@@ -4,30 +4,25 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#ifndef _UAPI_LINUX_IF_TEAM_H_
-#define _UAPI_LINUX_IF_TEAM_H_
+#ifndef _UAPI_LINUX_IF_TEAM_H
+#define _UAPI_LINUX_IF_TEAM_H
+#define TEAM_GENL_NAME "team"
+#define TEAM_GENL_VERSION 1
#define TEAM_STRING_MAX_LEN 32
-enum {
- TEAM_CMD_NOOP,
- TEAM_CMD_OPTIONS_SET,
- TEAM_CMD_OPTIONS_GET,
- TEAM_CMD_PORT_LIST_GET,
- __TEAM_CMD_MAX,
- TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1),
-};
+#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event"
enum {
TEAM_ATTR_UNSPEC,
TEAM_ATTR_TEAM_IFINDEX,
TEAM_ATTR_LIST_OPTION,
TEAM_ATTR_LIST_PORT,
__TEAM_ATTR_MAX,
- TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1,
+ TEAM_ATTR_MAX = (__TEAM_ATTR_MAX - 1)
};
enum {
TEAM_ATTR_ITEM_OPTION_UNSPEC,
TEAM_ATTR_ITEM_OPTION,
__TEAM_ATTR_ITEM_OPTION_MAX,
- TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1,
+ TEAM_ATTR_ITEM_OPTION_MAX = (__TEAM_ATTR_ITEM_OPTION_MAX - 1)
};
enum {
TEAM_ATTR_OPTION_UNSPEC,
@@ -39,13 +34,13 @@
TEAM_ATTR_OPTION_PORT_IFINDEX,
TEAM_ATTR_OPTION_ARRAY_INDEX,
__TEAM_ATTR_OPTION_MAX,
- TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
+ TEAM_ATTR_OPTION_MAX = (__TEAM_ATTR_OPTION_MAX - 1)
};
enum {
TEAM_ATTR_ITEM_PORT_UNSPEC,
TEAM_ATTR_ITEM_PORT,
__TEAM_ATTR_ITEM_PORT_MAX,
- TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1,
+ TEAM_ATTR_ITEM_PORT_MAX = (__TEAM_ATTR_ITEM_PORT_MAX - 1)
};
enum {
TEAM_ATTR_PORT_UNSPEC,
@@ -56,9 +51,14 @@
TEAM_ATTR_PORT_DUPLEX,
TEAM_ATTR_PORT_REMOVED,
__TEAM_ATTR_PORT_MAX,
- TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1,
+ TEAM_ATTR_PORT_MAX = (__TEAM_ATTR_PORT_MAX - 1)
};
-#define TEAM_GENL_NAME "team"
-#define TEAM_GENL_VERSION 0x1
-#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event"
+enum {
+ TEAM_CMD_NOOP,
+ TEAM_CMD_OPTIONS_SET,
+ TEAM_CMD_OPTIONS_GET,
+ TEAM_CMD_PORT_LIST_GET,
+ __TEAM_CMD_MAX,
+ TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1)
+};
#endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index e87daf2..fa6825a 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -159,4 +159,26 @@
#define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000)
#define TUNNEL_GTP_OPT __cpu_to_be16(0x8000)
#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT | TUNNEL_GTP_OPT)
+enum {
+ IP_TUNNEL_CSUM_BIT = 0U,
+ IP_TUNNEL_ROUTING_BIT,
+ IP_TUNNEL_KEY_BIT,
+ IP_TUNNEL_SEQ_BIT,
+ IP_TUNNEL_STRICT_BIT,
+ IP_TUNNEL_REC_BIT,
+ IP_TUNNEL_VERSION_BIT,
+ IP_TUNNEL_NO_KEY_BIT,
+ IP_TUNNEL_DONT_FRAGMENT_BIT,
+ IP_TUNNEL_OAM_BIT,
+ IP_TUNNEL_CRIT_OPT_BIT,
+ IP_TUNNEL_GENEVE_OPT_BIT,
+ IP_TUNNEL_VXLAN_OPT_BIT,
+ IP_TUNNEL_NOCACHE_BIT,
+ IP_TUNNEL_ERSPAN_OPT_BIT,
+ IP_TUNNEL_GTP_OPT_BIT,
+ IP_TUNNEL_VTI_BIT,
+ IP_TUNNEL_SIT_ISATAP_BIT = IP_TUNNEL_VTI_BIT,
+ IP_TUNNEL_PFCP_OPT_BIT,
+ __IP_TUNNEL_FLAG_NUM,
+};
#endif
diff --git a/libc/kernel/uapi/linux/if_xdp.h b/libc/kernel/uapi/linux/if_xdp.h
index b7eec87..7201e06 100644
--- a/libc/kernel/uapi/linux/if_xdp.h
+++ b/libc/kernel/uapi/linux/if_xdp.h
@@ -14,6 +14,7 @@
#define XDP_USE_SG (1 << 4)
#define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0)
#define XDP_UMEM_TX_SW_CSUM (1 << 1)
+#define XDP_UMEM_TX_METADATA_LEN (1 << 2)
struct sockaddr_xdp {
__u16 sxdp_family;
__u16 sxdp_flags;
diff --git a/libc/kernel/uapi/linux/iio/buffer.h b/libc/kernel/uapi/linux/iio/buffer.h
index 45c6f65..7e03a8c 100644
--- a/libc/kernel/uapi/linux/iio/buffer.h
+++ b/libc/kernel/uapi/linux/iio/buffer.h
@@ -6,5 +6,16 @@
*/
#ifndef _UAPI_IIO_BUFFER_H_
#define _UAPI_IIO_BUFFER_H_
+#include <linux/types.h>
+#define IIO_BUFFER_DMABUF_CYCLIC (1 << 0)
+#define IIO_BUFFER_DMABUF_SUPPORTED_FLAGS 0x00000001
+struct iio_dmabuf {
+ __u32 fd;
+ __u32 flags;
+ __u64 bytes_used;
+};
#define IIO_BUFFER_GET_FD_IOCTL _IOWR('i', 0x91, int)
+#define IIO_BUFFER_DMABUF_ATTACH_IOCTL _IOW('i', 0x92, int)
+#define IIO_BUFFER_DMABUF_DETACH_IOCTL _IOW('i', 0x93, int)
+#define IIO_BUFFER_DMABUF_ENQUEUE_IOCTL _IOW('i', 0x94, struct iio_dmabuf)
#endif
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 44efdd8..97bf493 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -69,6 +69,8 @@
#define IPPROTO_ETHERNET IPPROTO_ETHERNET
IPPROTO_RAW = 255,
#define IPPROTO_RAW IPPROTO_RAW
+ IPPROTO_SMC = 256,
+#define IPPROTO_SMC IPPROTO_SMC
IPPROTO_MPTCP = 262,
#define IPPROTO_MPTCP IPPROTO_MPTCP
IPPROTO_MAX
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 0fe5a14..4f93d5e 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -543,6 +543,8 @@
#define KEY_CAMERA_ACCESS_ENABLE 0x24b
#define KEY_CAMERA_ACCESS_DISABLE 0x24c
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d
+#define KEY_ACCESSIBILITY 0x24e
+#define KEY_DO_NOT_DISTURB 0x24f
#define KEY_BRIGHTNESS_MIN 0x250
#define KEY_BRIGHTNESS_MAX 0x251
#define KEY_KBDINPUTASSIST_PREV 0x260
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 10936f2..5564bff 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -59,6 +59,7 @@
__u32 waitid_flags;
__u32 futex_flags;
__u32 install_fd_flags;
+ __u32 nop_flags;
};
__u64 user_data;
union {
@@ -85,7 +86,7 @@
};
};
#define IORING_FILE_INDEX_ALLOC (~0U)
-enum {
+enum io_uring_sqe_flags_bit {
IOSQE_FIXED_FILE_BIT,
IOSQE_IO_DRAIN_BIT,
IOSQE_IO_LINK_BIT,
@@ -175,6 +176,8 @@
IORING_OP_FUTEX_WAITV,
IORING_OP_FIXED_FD_INSTALL,
IORING_OP_FTRUNCATE,
+ IORING_OP_BIND,
+ IORING_OP_LISTEN,
IORING_OP_LAST,
};
#define IORING_URING_CMD_FIXED (1U << 0)
@@ -204,15 +207,19 @@
#define IORING_RECV_MULTISHOT (1U << 1)
#define IORING_RECVSEND_FIXED_BUF (1U << 2)
#define IORING_SEND_ZC_REPORT_USAGE (1U << 3)
+#define IORING_RECVSEND_BUNDLE (1U << 4)
#define IORING_NOTIF_USAGE_ZC_COPIED (1U << 31)
#define IORING_ACCEPT_MULTISHOT (1U << 0)
-enum {
+#define IORING_ACCEPT_DONTWAIT (1U << 1)
+#define IORING_ACCEPT_POLL_FIRST (1U << 2)
+enum io_uring_msg_ring_flags {
IORING_MSG_DATA,
IORING_MSG_SEND_FD,
};
#define IORING_MSG_RING_CQE_SKIP (1U << 0)
#define IORING_MSG_RING_FLAGS_PASS (1U << 1)
#define IORING_FIXED_FD_NO_CLOEXEC (1U << 0)
+#define IORING_NOP_INJECT_RESULT (1U << 0)
struct io_uring_cqe {
__u64 user_data;
__s32 res;
@@ -223,9 +230,8 @@
#define IORING_CQE_F_MORE (1U << 1)
#define IORING_CQE_F_SOCK_NONEMPTY (1U << 2)
#define IORING_CQE_F_NOTIF (1U << 3)
-enum {
- IORING_CQE_BUFFER_SHIFT = 16,
-};
+#define IORING_CQE_F_BUF_MORE (1U << 4)
+#define IORING_CQE_BUFFER_SHIFT 16
#define IORING_OFF_SQ_RING 0ULL
#define IORING_OFF_CQ_RING 0x8000000ULL
#define IORING_OFF_SQES 0x10000000ULL
@@ -263,6 +269,7 @@
#define IORING_ENTER_SQ_WAIT (1U << 2)
#define IORING_ENTER_EXT_ARG (1U << 3)
#define IORING_ENTER_REGISTERED_RING (1U << 4)
+#define IORING_ENTER_ABS_TIMER (1U << 5)
struct io_uring_params {
__u32 sq_entries;
__u32 cq_entries;
@@ -289,7 +296,9 @@
#define IORING_FEAT_CQE_SKIP (1U << 11)
#define IORING_FEAT_LINKED_FILE (1U << 12)
#define IORING_FEAT_REG_REG_RING (1U << 13)
-enum {
+#define IORING_FEAT_RECVSEND_BUNDLE (1U << 14)
+#define IORING_FEAT_MIN_TIMEOUT (1U << 15)
+enum io_uring_register_op {
IORING_REGISTER_BUFFERS = 0,
IORING_UNREGISTER_BUFFERS = 1,
IORING_REGISTER_FILES = 2,
@@ -319,10 +328,12 @@
IORING_REGISTER_PBUF_STATUS = 26,
IORING_REGISTER_NAPI = 27,
IORING_UNREGISTER_NAPI = 28,
+ IORING_REGISTER_CLOCK = 29,
+ IORING_REGISTER_CLONE_BUFFERS = 30,
IORING_REGISTER_LAST,
IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
};
-enum {
+enum io_wq_type {
IO_WQ_BOUND,
IO_WQ_UNBOUND,
};
@@ -377,6 +388,18 @@
__u8 resv;
__u32 resv2[3];
};
+struct io_uring_clock_register {
+ __u32 clockid;
+ __u32 __resv[3];
+};
+enum {
+ IORING_REGISTER_SRC_REGISTERED = 1,
+};
+struct io_uring_clone_buffers {
+ __u32 src_fd;
+ __u32 flags;
+ __u32 pad[6];
+};
struct io_uring_buf {
__u64 addr;
__u32 len;
@@ -394,8 +417,9 @@
__DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
};
};
-enum {
+enum io_uring_register_pbuf_ring_flags {
IOU_PBUF_RING_MMAP = 1,
+ IOU_PBUF_RING_INC = 2,
};
struct io_uring_buf_reg {
__u64 ring_addr;
@@ -415,7 +439,7 @@
__u8 pad[3];
__u64 resv;
};
-enum {
+enum io_uring_register_restriction_op {
IORING_RESTRICTION_REGISTER_OP = 0,
IORING_RESTRICTION_SQE_OP = 1,
IORING_RESTRICTION_SQE_FLAGS_ALLOWED = 2,
@@ -425,7 +449,7 @@
struct io_uring_getevents_arg {
__u64 sigmask;
__u32 sigmask_sz;
- __u32 pad;
+ __u32 min_wait_usec;
__u64 ts;
};
struct io_uring_sync_cancel_reg {
@@ -448,7 +472,7 @@
__u32 payloadlen;
__u32 flags;
};
-enum {
+enum io_uring_socket_op {
SOCKET_URING_OP_SIOCINQ = 0,
SOCKET_URING_OP_SIOCOUTQ,
SOCKET_URING_OP_GETSOCKOPT,
diff --git a/libc/kernel/uapi/linux/ioam6_iptunnel.h b/libc/kernel/uapi/linux/ioam6_iptunnel.h
index 34317fc..e1a0223 100644
--- a/libc/kernel/uapi/linux/ioam6_iptunnel.h
+++ b/libc/kernel/uapi/linux/ioam6_iptunnel.h
@@ -24,6 +24,7 @@
#define IOAM6_IPTUNNEL_FREQ_MAX 1000000
IOAM6_IPTUNNEL_FREQ_K,
IOAM6_IPTUNNEL_FREQ_N,
+ IOAM6_IPTUNNEL_SRC,
__IOAM6_IPTUNNEL_MAX,
};
#define IOAM6_IPTUNNEL_MAX (__IOAM6_IPTUNNEL_MAX - 1)
diff --git a/libc/kernel/uapi/linux/iommu.h b/libc/kernel/uapi/linux/iommu.h
deleted file mode 100644
index 3a7bf82..0000000
--- a/libc/kernel/uapi/linux/iommu.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This file is auto-generated. Modifications will be lost.
- *
- * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
- * for more information.
- */
-#ifndef _UAPI_IOMMU_H
-#define _UAPI_IOMMU_H
-#include <linux/types.h>
-#define IOMMU_FAULT_PERM_READ (1 << 0)
-#define IOMMU_FAULT_PERM_WRITE (1 << 1)
-#define IOMMU_FAULT_PERM_EXEC (1 << 2)
-#define IOMMU_FAULT_PERM_PRIV (1 << 3)
-enum iommu_fault_type {
- IOMMU_FAULT_DMA_UNRECOV = 1,
- IOMMU_FAULT_PAGE_REQ,
-};
-enum iommu_fault_reason {
- IOMMU_FAULT_REASON_UNKNOWN = 0,
- IOMMU_FAULT_REASON_PASID_FETCH,
- IOMMU_FAULT_REASON_BAD_PASID_ENTRY,
- IOMMU_FAULT_REASON_PASID_INVALID,
- IOMMU_FAULT_REASON_WALK_EABT,
- IOMMU_FAULT_REASON_PTE_FETCH,
- IOMMU_FAULT_REASON_PERMISSION,
- IOMMU_FAULT_REASON_ACCESS,
- IOMMU_FAULT_REASON_OOR_ADDRESS,
-};
-struct iommu_fault_unrecoverable {
- __u32 reason;
-#define IOMMU_FAULT_UNRECOV_PASID_VALID (1 << 0)
-#define IOMMU_FAULT_UNRECOV_ADDR_VALID (1 << 1)
-#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID (1 << 2)
- __u32 flags;
- __u32 pasid;
- __u32 perm;
- __u64 addr;
- __u64 fetch_addr;
-};
-struct iommu_fault_page_request {
-#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0)
-#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1)
-#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA (1 << 2)
-#define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 3)
- __u32 flags;
- __u32 pasid;
- __u32 grpid;
- __u32 perm;
- __u64 addr;
- __u64 private_data[2];
-};
-struct iommu_fault {
- __u32 type;
- __u32 padding;
- union {
- struct iommu_fault_unrecoverable event;
- struct iommu_fault_page_request prm;
- __u8 padding2[56];
- };
-};
-enum iommu_page_response_code {
- IOMMU_PAGE_RESP_SUCCESS = 0,
- IOMMU_PAGE_RESP_INVALID,
- IOMMU_PAGE_RESP_FAILURE,
-};
-struct iommu_page_response {
- __u32 argsz;
-#define IOMMU_PAGE_RESP_VERSION_1 1
- __u32 version;
-#define IOMMU_PAGE_RESP_PASID_VALID (1 << 0)
- __u32 flags;
- __u32 pasid;
- __u32 grpid;
- __u32 code;
-};
-#endif
diff --git a/libc/kernel/uapi/linux/iommufd.h b/libc/kernel/uapi/linux/iommufd.h
index 2570628..3bbcd40c6 100644
--- a/libc/kernel/uapi/linux/iommufd.h
+++ b/libc/kernel/uapi/linux/iommufd.h
@@ -6,25 +6,26 @@
*/
#ifndef _UAPI_IOMMUFD_H
#define _UAPI_IOMMUFD_H
-#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h>
#define IOMMUFD_TYPE (';')
enum {
IOMMUFD_CMD_BASE = 0x80,
IOMMUFD_CMD_DESTROY = IOMMUFD_CMD_BASE,
- IOMMUFD_CMD_IOAS_ALLOC,
- IOMMUFD_CMD_IOAS_ALLOW_IOVAS,
- IOMMUFD_CMD_IOAS_COPY,
- IOMMUFD_CMD_IOAS_IOVA_RANGES,
- IOMMUFD_CMD_IOAS_MAP,
- IOMMUFD_CMD_IOAS_UNMAP,
- IOMMUFD_CMD_OPTION,
- IOMMUFD_CMD_VFIO_IOAS,
- IOMMUFD_CMD_HWPT_ALLOC,
- IOMMUFD_CMD_GET_HW_INFO,
- IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING,
- IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP,
- IOMMUFD_CMD_HWPT_INVALIDATE,
+ IOMMUFD_CMD_IOAS_ALLOC = 0x81,
+ IOMMUFD_CMD_IOAS_ALLOW_IOVAS = 0x82,
+ IOMMUFD_CMD_IOAS_COPY = 0x83,
+ IOMMUFD_CMD_IOAS_IOVA_RANGES = 0x84,
+ IOMMUFD_CMD_IOAS_MAP = 0x85,
+ IOMMUFD_CMD_IOAS_UNMAP = 0x86,
+ IOMMUFD_CMD_OPTION = 0x87,
+ IOMMUFD_CMD_VFIO_IOAS = 0x88,
+ IOMMUFD_CMD_HWPT_ALLOC = 0x89,
+ IOMMUFD_CMD_GET_HW_INFO = 0x8a,
+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING = 0x8b,
+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c,
+ IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d,
+ IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e,
};
struct iommu_destroy {
__u32 size;
@@ -122,6 +123,7 @@
enum iommufd_hwpt_alloc_flags {
IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0,
IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1,
+ IOMMU_HWPT_FAULT_ID_VALID = 1 << 2,
};
enum iommu_hwpt_vtd_s1_flags {
IOMMU_VTD_S1_SRE = 1 << 0,
@@ -135,8 +137,8 @@
__u32 __reserved;
};
enum iommu_hwpt_data_type {
- IOMMU_HWPT_DATA_NONE,
- IOMMU_HWPT_DATA_VTD_S1,
+ IOMMU_HWPT_DATA_NONE = 0,
+ IOMMU_HWPT_DATA_VTD_S1 = 1,
};
struct iommu_hwpt_alloc {
__u32 size;
@@ -148,6 +150,8 @@
__u32 data_type;
__u32 data_len;
__aligned_u64 data_uptr;
+ __u32 fault_id;
+ __u32 __reserved2;
};
#define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC)
enum iommu_hw_info_vtd_flags {
@@ -160,8 +164,8 @@
__aligned_u64 ecap_reg;
};
enum iommu_hw_info_type {
- IOMMU_HW_INFO_TYPE_NONE,
- IOMMU_HW_INFO_TYPE_INTEL_VTD,
+ IOMMU_HW_INFO_TYPE_NONE = 0,
+ IOMMU_HW_INFO_TYPE_INTEL_VTD = 1,
};
enum iommufd_hw_capabilities {
IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0,
@@ -202,7 +206,7 @@
};
#define IOMMU_HWPT_GET_DIRTY_BITMAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP)
enum iommu_hwpt_invalidate_data_type {
- IOMMU_HWPT_INVALIDATE_DATA_VTD_S1,
+ IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0,
};
enum iommu_hwpt_vtd_s1_invalidate_flags {
IOMMU_VTD_INV_FLAGS_LEAF = 1 << 0,
@@ -223,4 +227,39 @@
__u32 __reserved;
};
#define IOMMU_HWPT_INVALIDATE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_INVALIDATE)
+enum iommu_hwpt_pgfault_flags {
+ IOMMU_PGFAULT_FLAGS_PASID_VALID = (1 << 0),
+ IOMMU_PGFAULT_FLAGS_LAST_PAGE = (1 << 1),
+};
+enum iommu_hwpt_pgfault_perm {
+ IOMMU_PGFAULT_PERM_READ = (1 << 0),
+ IOMMU_PGFAULT_PERM_WRITE = (1 << 1),
+ IOMMU_PGFAULT_PERM_EXEC = (1 << 2),
+ IOMMU_PGFAULT_PERM_PRIV = (1 << 3),
+};
+struct iommu_hwpt_pgfault {
+ __u32 flags;
+ __u32 dev_id;
+ __u32 pasid;
+ __u32 grpid;
+ __u32 perm;
+ __u64 addr;
+ __u32 length;
+ __u32 cookie;
+};
+enum iommufd_page_response_code {
+ IOMMUFD_PAGE_RESP_SUCCESS = 0,
+ IOMMUFD_PAGE_RESP_INVALID = 1,
+};
+struct iommu_hwpt_page_response {
+ __u32 cookie;
+ __u32 code;
+};
+struct iommu_fault_alloc {
+ __u32 size;
+ __u32 flags;
+ __u32 out_fault_id;
+ __u32 out_fault_fd;
+};
+#define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC)
#endif
diff --git a/libc/kernel/uapi/linux/kexec.h b/libc/kernel/uapi/linux/kexec.h
index c5c8623..d34f065 100644
--- a/libc/kernel/uapi/linux/kexec.h
+++ b/libc/kernel/uapi/linux/kexec.h
@@ -10,6 +10,7 @@
#define KEXEC_ON_CRASH 0x00000001
#define KEXEC_PRESERVE_CONTEXT 0x00000002
#define KEXEC_UPDATE_ELFCOREHDR 0x00000004
+#define KEXEC_CRASH_HOTPLUG_SUPPORT 0x00000008
#define KEXEC_ARCH_MASK 0xffff0000
#define KEXEC_FILE_UNLOAD 0x00000001
#define KEXEC_FILE_ON_CRASH 0x00000002
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 62c9872..8948a13 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -9,7 +9,7 @@
#include <drm/drm.h>
#include <linux/ioctl.h>
#define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 15
+#define KFD_IOCTL_MINOR_VERSION 17
struct kfd_ioctl_get_version_args {
__u32 major_version;
__u32 minor_version;
@@ -18,6 +18,7 @@
#define KFD_IOC_QUEUE_TYPE_SDMA 0x1
#define KFD_IOC_QUEUE_TYPE_COMPUTE_AQL 0x2
#define KFD_IOC_QUEUE_TYPE_SDMA_XGMI 0x3
+#define KFD_IOC_QUEUE_TYPE_SDMA_BY_ENG_ID 0x4
#define KFD_MAX_QUEUE_PERCENTAGE 100
#define KFD_MAX_QUEUE_PRIORITY 15
struct kfd_ioctl_create_queue_args {
@@ -36,6 +37,8 @@
__u64 ctx_save_restore_address;
__u32 ctx_save_restore_size;
__u32 ctl_stack_size;
+ __u32 sdma_engine_id;
+ __u32 pad;
};
struct kfd_ioctl_destroy_queue_args {
__u32 queue_id;
@@ -269,6 +272,7 @@
#define KFD_IOC_ALLOC_MEM_FLAGS_COHERENT (1 << 26)
#define KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED (1 << 25)
#define KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT (1 << 24)
+#define KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS (1 << 23)
struct kfd_ioctl_alloc_memory_of_gpu_args {
__u64 va_addr;
__u64 size;
@@ -357,6 +361,16 @@
__u32 gpuid;
__u32 anon_fd;
};
+#define KFD_EVENT_FMT_UPDATE_GPU_RESET(reset_seq_num,reset_cause) "%x %s\n", (reset_seq_num), (reset_cause)
+#define KFD_EVENT_FMT_THERMAL_THROTTLING(bitmask,counter) "%llx:%llx\n", (bitmask), (counter)
+#define KFD_EVENT_FMT_VMFAULT(pid,task_name) "%x:%s\n", (pid), (task_name)
+#define KFD_EVENT_FMT_PAGEFAULT_START(ns,pid,addr,node,rw) "%lld -%d @%lx(%x) %c\n", (ns), (pid), (addr), (node), (rw)
+#define KFD_EVENT_FMT_PAGEFAULT_END(ns,pid,addr,node,migrate_update) "%lld -%d @%lx(%x) %c\n", (ns), (pid), (addr), (node), (migrate_update)
+#define KFD_EVENT_FMT_MIGRATE_START(ns,pid,start,size,from,to,prefetch_loc,preferred_loc,migrate_trigger) "%lld -%d @%lx(%lx) %x->%x %x:%x %d\n", (ns), (pid), (start), (size), (from), (to), (prefetch_loc), (preferred_loc), (migrate_trigger)
+#define KFD_EVENT_FMT_MIGRATE_END(ns,pid,start,size,from,to,migrate_trigger) "%lld -%d @%lx(%lx) %x->%x %d\n", (ns), (pid), (start), (size), (from), (to), (migrate_trigger)
+#define KFD_EVENT_FMT_QUEUE_EVICTION(ns,pid,node,evict_trigger) "%lld -%d %x %d\n", (ns), (pid), (node), (evict_trigger)
+#define KFD_EVENT_FMT_QUEUE_RESTORE(ns,pid,node,rescheduled) "%lld -%d %x %c\n", (ns), (pid), (node), (rescheduled)
+#define KFD_EVENT_FMT_UNMAP_FROM_GPU(ns,pid,addr,size,node,unmap_trigger) "%lld -%d @%lx(%lx) %x %d\n", (ns), (pid), (addr), (size), (node), (unmap_trigger)
enum kfd_criu_op {
KFD_CRIU_OP_PROCESS_INFO,
KFD_CRIU_OP_CHECKPOINT,
@@ -465,6 +479,7 @@
};
enum kfd_dbg_trap_flags {
KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1,
+ KFD_DBG_TRAP_FLAG_SINGLE_ALU_OP = 2,
};
enum kfd_dbg_trap_exception_code {
EC_NONE = 0,
diff --git a/libc/kernel/uapi/linux/kfd_sysfs.h b/libc/kernel/uapi/linux/kfd_sysfs.h
index e538cf2..7771582 100644
--- a/libc/kernel/uapi/linux/kfd_sysfs.h
+++ b/libc/kernel/uapi/linux/kfd_sysfs.h
@@ -35,7 +35,8 @@
#define HSA_CAP_SVMAPI_SUPPORTED 0x08000000
#define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000
#define HSA_CAP_TRAP_DEBUG_FIRMWARE_SUPPORTED 0x20000000
-#define HSA_CAP_RESERVED 0xe00f8000
+#define HSA_CAP_TRAP_DEBUG_PRECISE_ALU_OPERATIONS_SUPPORTED 0x40000000
+#define HSA_CAP_RESERVED 0x800f8000
#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_MASK 0x0000000f
#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_SHIFT 0
#define HSA_DBG_WATCH_ADDR_MASK_HI_BIT_MASK 0x000003f0
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index ffaf5e6..297a09d 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -149,9 +149,10 @@
#define KVM_INTERNAL_ERROR_DELIVERY_EV 3
#define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4
#define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0)
+#define HINT_UNSAFE_IN_KVM(_symbol) _symbol
struct kvm_run {
__u8 request_interrupt_window;
- __u8 immediate_exit;
+ __u8 HINT_UNSAFE_IN_KVM(immediate_exit);
__u8 padding1[6];
__u32 exit_reason;
__u8 ready_for_interrupt_injection;
@@ -719,6 +720,9 @@
#define KVM_CAP_MEMORY_ATTRIBUTES 233
#define KVM_CAP_GUEST_MEMFD 234
#define KVM_CAP_VM_TYPES 235
+#define KVM_CAP_PRE_FAULT_MEMORY 236
+#define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
+#define KVM_CAP_X86_GUEST_MODE 238
struct kvm_irq_routing_irqchip {
__u32 irqchip;
__u32 pin;
@@ -1109,4 +1113,11 @@
__u64 flags;
__u64 reserved[6];
};
+#define KVM_PRE_FAULT_MEMORY _IOWR(KVMIO, 0xd5, struct kvm_pre_fault_memory)
+struct kvm_pre_fault_memory {
+ __u64 gpa;
+ __u64 size;
+ __u64 flags;
+ __u64 padding[5];
+};
#endif
diff --git a/libc/kernel/uapi/linux/landlock.h b/libc/kernel/uapi/linux/landlock.h
index 75d3037..8f83780 100644
--- a/libc/kernel/uapi/linux/landlock.h
+++ b/libc/kernel/uapi/linux/landlock.h
@@ -10,6 +10,7 @@
struct landlock_ruleset_attr {
__u64 handled_access_fs;
__u64 handled_access_net;
+ __u64 scoped;
};
#define LANDLOCK_CREATE_RULESET_VERSION (1U << 0)
enum landlock_rule_type {
@@ -39,6 +40,9 @@
#define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12)
#define LANDLOCK_ACCESS_FS_REFER (1ULL << 13)
#define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14)
+#define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15)
#define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0)
#define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1)
+#define LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET (1ULL << 0)
+#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
#endif
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index 289b7c5..0b5ba60 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -59,19 +59,6 @@
#define __UAPI_DEF_IN6_PKTINFO 1
#define __UAPI_DEF_IP6_MTUINFO 1
#endif
-#ifdef __NETIPX_IPX_H
-#define __UAPI_DEF_SOCKADDR_IPX 0
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 0
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0
-#define __UAPI_DEF_IPX_CONFIG_DATA 0
-#define __UAPI_DEF_IPX_ROUTE_DEF 0
-#else
-#define __UAPI_DEF_SOCKADDR_IPX 1
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
-#define __UAPI_DEF_IPX_CONFIG_DATA 1
-#define __UAPI_DEF_IPX_ROUTE_DEF 1
-#endif
#ifdef _SYS_XATTR_H
#define __UAPI_DEF_XATTR 0
#else
@@ -138,21 +125,6 @@
#ifndef __UAPI_DEF_IP6_MTUINFO
#define __UAPI_DEF_IP6_MTUINFO 1
#endif
-#ifndef __UAPI_DEF_SOCKADDR_IPX
-#define __UAPI_DEF_SOCKADDR_IPX 1
-#endif
-#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
-#endif
-#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
-#endif
-#ifndef __UAPI_DEF_IPX_CONFIG_DATA
-#define __UAPI_DEF_IPX_CONFIG_DATA 1
-#endif
-#ifndef __UAPI_DEF_IPX_ROUTE_DEF
-#define __UAPI_DEF_IPX_ROUTE_DEF 1
-#endif
#ifndef __UAPI_DEF_XATTR
#define __UAPI_DEF_XATTR 1
#endif
diff --git a/libc/kernel/uapi/linux/lsm.h b/libc/kernel/uapi/linux/lsm.h
index 3a3f152..b12ca64 100644
--- a/libc/kernel/uapi/linux/lsm.h
+++ b/libc/kernel/uapi/linux/lsm.h
@@ -30,6 +30,7 @@
#define LSM_ID_LANDLOCK 110
#define LSM_ID_IMA 111
#define LSM_ID_EVM 112
+#define LSM_ID_IPE 113
#define LSM_ATTR_UNDEF 0
#define LSM_ATTR_CURRENT 100
#define LSM_ATTR_EXEC 101
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 4d24726..5f2a2a2 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -41,6 +41,7 @@
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
#define FUSE_SUPER_MAGIC 0x65735546
+#define BCACHEFS_SUPER_MAGIC 0xca451a4e
#define MINIX_SUPER_MAGIC 0x137F
#define MINIX_SUPER_MAGIC2 0x138F
#define MINIX2_SUPER_MAGIC 0x2468
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 7b51b73..7a4d4db 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -15,6 +15,7 @@
#define MDIO_MMD_DTEXS 5
#define MDIO_MMD_TC 6
#define MDIO_MMD_AN 7
+#define MDIO_MMD_POWER_UNIT 13
#define MDIO_MMD_C22EXT 29
#define MDIO_MMD_VEND1 30
#define MDIO_MMD_VEND2 31
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index 230bfbb..cb36554 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -126,4 +126,11 @@
#define MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8 0x5001
#define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001
#define MEDIA_BUS_FMT_METADATA_FIXED 0x7001
+#define MEDIA_BUS_FMT_META_8 0x8001
+#define MEDIA_BUS_FMT_META_10 0x8002
+#define MEDIA_BUS_FMT_META_12 0x8003
+#define MEDIA_BUS_FMT_META_14 0x8004
+#define MEDIA_BUS_FMT_META_16 0x8005
+#define MEDIA_BUS_FMT_META_20 0x8006
+#define MEDIA_BUS_FMT_META_24 0x8007
#endif
diff --git a/libc/kernel/uapi/linux/media/raspberrypi/pisp_be_config.h b/libc/kernel/uapi/linux/media/raspberrypi/pisp_be_config.h
new file mode 100644
index 0000000..2e981ad
--- /dev/null
+++ b/libc/kernel/uapi/linux/media/raspberrypi/pisp_be_config.h
@@ -0,0 +1,418 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_PISP_BE_CONFIG_H_
+#define _UAPI_PISP_BE_CONFIG_H_
+#include <linux/types.h>
+#include "pisp_common.h"
+#define PISP_BACK_END_INPUT_ALIGN 4u
+#define PISP_BACK_END_COMPRESSED_ALIGN 8u
+#define PISP_BACK_END_OUTPUT_MIN_ALIGN 16u
+#define PISP_BACK_END_OUTPUT_MAX_ALIGN 64u
+#define PISP_BACK_END_MIN_TILE_WIDTH 16u
+#define PISP_BACK_END_MIN_TILE_HEIGHT 16u
+#define PISP_BACK_END_NUM_OUTPUTS 2
+#define PISP_BACK_END_HOG_OUTPUT 1
+#define PISP_BACK_END_NUM_TILES 64
+enum pisp_be_bayer_enable {
+ PISP_BE_BAYER_ENABLE_INPUT = 0x000001,
+ PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002,
+ PISP_BE_BAYER_ENABLE_DPC = 0x000004,
+ PISP_BE_BAYER_ENABLE_GEQ = 0x000008,
+ PISP_BE_BAYER_ENABLE_TDN_INPUT = 0x000010,
+ PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS = 0x000020,
+ PISP_BE_BAYER_ENABLE_TDN = 0x000040,
+ PISP_BE_BAYER_ENABLE_TDN_COMPRESS = 0x000080,
+ PISP_BE_BAYER_ENABLE_TDN_OUTPUT = 0x000100,
+ PISP_BE_BAYER_ENABLE_SDN = 0x000200,
+ PISP_BE_BAYER_ENABLE_BLC = 0x000400,
+ PISP_BE_BAYER_ENABLE_STITCH_INPUT = 0x000800,
+ PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS = 0x001000,
+ PISP_BE_BAYER_ENABLE_STITCH = 0x002000,
+ PISP_BE_BAYER_ENABLE_STITCH_COMPRESS = 0x004000,
+ PISP_BE_BAYER_ENABLE_STITCH_OUTPUT = 0x008000,
+ PISP_BE_BAYER_ENABLE_WBG = 0x010000,
+ PISP_BE_BAYER_ENABLE_CDN = 0x020000,
+ PISP_BE_BAYER_ENABLE_LSC = 0x040000,
+ PISP_BE_BAYER_ENABLE_TONEMAP = 0x080000,
+ PISP_BE_BAYER_ENABLE_CAC = 0x100000,
+ PISP_BE_BAYER_ENABLE_DEBIN = 0x200000,
+ PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000,
+};
+enum pisp_be_rgb_enable {
+ PISP_BE_RGB_ENABLE_INPUT = 0x000001,
+ PISP_BE_RGB_ENABLE_CCM = 0x000002,
+ PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004,
+ PISP_BE_RGB_ENABLE_YCBCR = 0x000008,
+ PISP_BE_RGB_ENABLE_FALSE_COLOUR = 0x000010,
+ PISP_BE_RGB_ENABLE_SHARPEN = 0x000020,
+ PISP_BE_RGB_ENABLE_YCBCR_INVERSE = 0x000080,
+ PISP_BE_RGB_ENABLE_GAMMA = 0x000100,
+ PISP_BE_RGB_ENABLE_CSC0 = 0x000200,
+ PISP_BE_RGB_ENABLE_CSC1 = 0x000400,
+ PISP_BE_RGB_ENABLE_DOWNSCALE0 = 0x001000,
+ PISP_BE_RGB_ENABLE_DOWNSCALE1 = 0x002000,
+ PISP_BE_RGB_ENABLE_RESAMPLE0 = 0x008000,
+ PISP_BE_RGB_ENABLE_RESAMPLE1 = 0x010000,
+ PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000,
+ PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000,
+ PISP_BE_RGB_ENABLE_HOG = 0x200000
+};
+#define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i))
+#define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i))
+#define PISP_BE_RGB_ENABLE_RESAMPLE(i) (PISP_BE_RGB_ENABLE_RESAMPLE0 << (i))
+#define PISP_BE_RGB_ENABLE_OUTPUT(i) (PISP_BE_RGB_ENABLE_OUTPUT0 << (i))
+enum pisp_be_dirty {
+ PISP_BE_DIRTY_GLOBAL = 0x0001,
+ PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002,
+ PISP_BE_DIRTY_CROP = 0x0004
+};
+struct pisp_be_global_config {
+ __u32 bayer_enables;
+ __u32 rgb_enables;
+ __u8 bayer_order;
+ __u8 pad[3];
+} __attribute__((packed));
+struct pisp_be_input_buffer_config {
+ __u32 addr[3][2];
+} __attribute__((packed));
+struct pisp_be_dpc_config {
+ __u8 coeff_level;
+ __u8 coeff_range;
+ __u8 pad;
+#define PISP_BE_DPC_FLAG_FOLDBACK 1
+ __u8 flags;
+} __attribute__((packed));
+struct pisp_be_geq_config {
+ __u16 offset;
+#define PISP_BE_GEQ_SHARPER (1U << 15)
+#define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
+ __u16 slope_sharper;
+ __u16 min;
+ __u16 max;
+} __attribute__((packed));
+struct pisp_be_tdn_input_buffer_config {
+ __u32 addr[2];
+} __attribute__((packed));
+struct pisp_be_tdn_config {
+ __u16 black_level;
+ __u16 ratio;
+ __u16 noise_constant;
+ __u16 noise_slope;
+ __u16 threshold;
+ __u8 reset;
+ __u8 pad;
+} __attribute__((packed));
+struct pisp_be_tdn_output_buffer_config {
+ __u32 addr[2];
+} __attribute__((packed));
+struct pisp_be_sdn_config {
+ __u16 black_level;
+ __u8 leakage;
+ __u8 pad;
+ __u16 noise_constant;
+ __u16 noise_slope;
+ __u16 noise_constant2;
+ __u16 noise_slope2;
+} __attribute__((packed));
+struct pisp_be_stitch_input_buffer_config {
+ __u32 addr[2];
+} __attribute__((packed));
+#define PISP_BE_STITCH_STREAMING_LONG 0x8000
+#define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff
+struct pisp_be_stitch_config {
+ __u16 threshold_lo;
+ __u8 threshold_diff_power;
+ __u8 pad;
+ __u16 exposure_ratio;
+ __u8 motion_threshold_256;
+ __u8 motion_threshold_recip;
+} __attribute__((packed));
+struct pisp_be_stitch_output_buffer_config {
+ __u32 addr[2];
+} __attribute__((packed));
+struct pisp_be_cdn_config {
+ __u16 thresh;
+ __u8 iir_strength;
+ __u8 g_adjust;
+} __attribute__((packed));
+#define PISP_BE_LSC_LOG_GRID_SIZE 5
+#define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE)
+#define PISP_BE_LSC_STEP_PRECISION 18
+struct pisp_be_lsc_config {
+ __u16 grid_step_x;
+ __u16 grid_step_y;
+#define PISP_BE_LSC_LUT_SIZE (PISP_BE_LSC_GRID_SIZE + 1)
+ __u32 lut_packed[PISP_BE_LSC_LUT_SIZE][PISP_BE_LSC_LUT_SIZE];
+} __attribute__((packed));
+struct pisp_be_lsc_extra {
+ __u16 offset_x;
+ __u16 offset_y;
+} __attribute__((packed));
+#define PISP_BE_CAC_LOG_GRID_SIZE 3
+#define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE)
+#define PISP_BE_CAC_STEP_PRECISION 20
+struct pisp_be_cac_config {
+ __u16 grid_step_x;
+ __u16 grid_step_y;
+#define PISP_BE_CAC_LUT_SIZE (PISP_BE_CAC_GRID_SIZE + 1)
+ __s8 lut[PISP_BE_CAC_LUT_SIZE][PISP_BE_CAC_LUT_SIZE][2][2];
+} __attribute__((packed));
+struct pisp_be_cac_extra {
+ __u16 offset_x;
+ __u16 offset_y;
+} __attribute__((packed));
+#define PISP_BE_DEBIN_NUM_COEFFS 4
+struct pisp_be_debin_config {
+ __s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS];
+ __s8 h_enable;
+ __s8 v_enable;
+ __s8 pad[2];
+} __attribute__((packed));
+#define PISP_BE_TONEMAP_LUT_SIZE 64
+struct pisp_be_tonemap_config {
+ __u16 detail_constant;
+ __u16 detail_slope;
+ __u16 iir_strength;
+ __u16 strength;
+ __u32 lut[PISP_BE_TONEMAP_LUT_SIZE];
+} __attribute__((packed));
+struct pisp_be_demosaic_config {
+ __u8 sharper;
+ __u8 fc_mode;
+ __u8 pad[2];
+} __attribute__((packed));
+struct pisp_be_ccm_config {
+ __s16 coeffs[9];
+ __u8 pad[2];
+ __s32 offsets[3];
+} __attribute__((packed));
+struct pisp_be_sat_control_config {
+ __u8 shift_r;
+ __u8 shift_g;
+ __u8 shift_b;
+ __u8 pad;
+} __attribute__((packed));
+struct pisp_be_false_colour_config {
+ __u8 distance;
+ __u8 pad[3];
+} __attribute__((packed));
+#define PISP_BE_SHARPEN_SIZE 5
+#define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9
+struct pisp_be_sharpen_config {
+ __s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+ __s8 pad0[3];
+ __s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+ __s8 pad1[3];
+ __s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+ __s8 pad2[3];
+ __s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+ __s8 pad3[3];
+ __s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+ __s8 pad4[3];
+ __u16 threshold_offset0;
+ __u16 threshold_slope0;
+ __u16 scale0;
+ __u16 pad5;
+ __u16 threshold_offset1;
+ __u16 threshold_slope1;
+ __u16 scale1;
+ __u16 pad6;
+ __u16 threshold_offset2;
+ __u16 threshold_slope2;
+ __u16 scale2;
+ __u16 pad7;
+ __u16 threshold_offset3;
+ __u16 threshold_slope3;
+ __u16 scale3;
+ __u16 pad8;
+ __u16 threshold_offset4;
+ __u16 threshold_slope4;
+ __u16 scale4;
+ __u16 pad9;
+ __u16 positive_strength;
+ __u16 positive_pre_limit;
+ __u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+ __u16 positive_limit;
+ __u16 negative_strength;
+ __u16 negative_pre_limit;
+ __u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+ __u16 negative_limit;
+ __u8 enables;
+ __u8 white;
+ __u8 black;
+ __u8 grey;
+} __attribute__((packed));
+struct pisp_be_sh_fc_combine_config {
+ __u8 y_factor;
+ __u8 c1_factor;
+ __u8 c2_factor;
+ __u8 pad;
+} __attribute__((packed));
+#define PISP_BE_GAMMA_LUT_SIZE 64
+struct pisp_be_gamma_config {
+ __u32 lut[PISP_BE_GAMMA_LUT_SIZE];
+} __attribute__((packed));
+struct pisp_be_crop_config {
+ __u16 offset_x, offset_y;
+ __u16 width, height;
+} __attribute__((packed));
+#define PISP_BE_RESAMPLE_FILTER_SIZE 96
+struct pisp_be_resample_config {
+ __u16 scale_factor_h, scale_factor_v;
+ __s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE];
+} __attribute__((packed));
+struct pisp_be_resample_extra {
+ __u16 scaled_width;
+ __u16 scaled_height;
+ __s16 initial_phase_h[3];
+ __s16 initial_phase_v[3];
+} __attribute__((packed));
+struct pisp_be_downscale_config {
+ __u16 scale_factor_h;
+ __u16 scale_factor_v;
+ __u16 scale_recip_h;
+ __u16 scale_recip_v;
+} __attribute__((packed));
+struct pisp_be_downscale_extra {
+ __u16 scaled_width;
+ __u16 scaled_height;
+} __attribute__((packed));
+struct pisp_be_hog_config {
+ __u8 compute_signed;
+ __u8 channel_mix[3];
+ __u32 stride;
+} __attribute__((packed));
+struct pisp_be_axi_config {
+ __u8 r_qos;
+ __u8 r_cache_prot;
+ __u8 w_qos;
+ __u8 w_cache_prot;
+} __attribute__((packed));
+enum pisp_be_transform {
+ PISP_BE_TRANSFORM_NONE = 0x0,
+ PISP_BE_TRANSFORM_HFLIP = 0x1,
+ PISP_BE_TRANSFORM_VFLIP = 0x2,
+ PISP_BE_TRANSFORM_ROT180 = (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP)
+};
+struct pisp_be_output_format_config {
+ struct pisp_image_format_config image;
+ __u8 transform;
+ __u8 pad[3];
+ __u16 lo;
+ __u16 hi;
+ __u16 lo2;
+ __u16 hi2;
+} __attribute__((packed));
+struct pisp_be_output_buffer_config {
+ __u32 addr[3][2];
+} __attribute__((packed));
+struct pisp_be_hog_buffer_config {
+ __u32 addr[2];
+} __attribute__((packed));
+struct pisp_be_config {
+ struct pisp_be_input_buffer_config input_buffer;
+ struct pisp_be_tdn_input_buffer_config tdn_input_buffer;
+ struct pisp_be_stitch_input_buffer_config stitch_input_buffer;
+ struct pisp_be_tdn_output_buffer_config tdn_output_buffer;
+ struct pisp_be_stitch_output_buffer_config stitch_output_buffer;
+ struct pisp_be_output_buffer_config output_buffer[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_hog_buffer_config hog_buffer;
+ struct pisp_be_global_config global;
+ struct pisp_image_format_config input_format;
+ struct pisp_decompress_config decompress;
+ struct pisp_be_dpc_config dpc;
+ struct pisp_be_geq_config geq;
+ struct pisp_image_format_config tdn_input_format;
+ struct pisp_decompress_config tdn_decompress;
+ struct pisp_be_tdn_config tdn;
+ struct pisp_compress_config tdn_compress;
+ struct pisp_image_format_config tdn_output_format;
+ struct pisp_be_sdn_config sdn;
+ struct pisp_bla_config blc;
+ struct pisp_compress_config stitch_compress;
+ struct pisp_image_format_config stitch_output_format;
+ struct pisp_image_format_config stitch_input_format;
+ struct pisp_decompress_config stitch_decompress;
+ struct pisp_be_stitch_config stitch;
+ struct pisp_be_lsc_config lsc;
+ struct pisp_wbg_config wbg;
+ struct pisp_be_cdn_config cdn;
+ struct pisp_be_cac_config cac;
+ struct pisp_be_debin_config debin;
+ struct pisp_be_tonemap_config tonemap;
+ struct pisp_be_demosaic_config demosaic;
+ struct pisp_be_ccm_config ccm;
+ struct pisp_be_sat_control_config sat_control;
+ struct pisp_be_ccm_config ycbcr;
+ struct pisp_be_sharpen_config sharpen;
+ struct pisp_be_false_colour_config false_colour;
+ struct pisp_be_sh_fc_combine_config sh_fc_combine;
+ struct pisp_be_ccm_config ycbcr_inverse;
+ struct pisp_be_gamma_config gamma;
+ struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_output_format_config output_format[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_hog_config hog;
+ struct pisp_be_axi_config axi;
+ struct pisp_be_lsc_extra lsc_extra;
+ struct pisp_be_cac_extra cac_extra;
+ struct pisp_be_downscale_extra downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_crop_config crop;
+ struct pisp_image_format_config hog_format;
+ __u32 dirty_flags_bayer;
+ __u32 dirty_flags_rgb;
+ __u32 dirty_flags_extra;
+} __attribute__((packed));
+enum pisp_tile_edge {
+ PISP_LEFT_EDGE = (1 << 0),
+ PISP_RIGHT_EDGE = (1 << 1),
+ PISP_TOP_EDGE = (1 << 2),
+ PISP_BOTTOM_EDGE = (1 << 3)
+};
+struct pisp_tile {
+ __u8 edge;
+ __u8 pad0[3];
+ __u32 input_addr_offset;
+ __u32 input_addr_offset2;
+ __u16 input_offset_x;
+ __u16 input_offset_y;
+ __u16 input_width;
+ __u16 input_height;
+ __u32 tdn_input_addr_offset;
+ __u32 tdn_output_addr_offset;
+ __u32 stitch_input_addr_offset;
+ __u32 stitch_output_addr_offset;
+ __u32 lsc_grid_offset_x;
+ __u32 lsc_grid_offset_y;
+ __u32 cac_grid_offset_x;
+ __u32 cac_grid_offset_y;
+ __u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+ __u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+ __u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+ __u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+ __u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 output_width[PISP_BACK_END_NUM_OUTPUTS];
+ __u16 output_height[PISP_BACK_END_NUM_OUTPUTS];
+ __u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS];
+ __u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS];
+ __u32 output_hog_addr_offset;
+} __attribute__((packed));
+struct pisp_be_tiles_config {
+ struct pisp_be_config config;
+ struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
+ __u32 num_tiles;
+} __attribute__((packed));
+#endif
diff --git a/libc/kernel/uapi/linux/media/raspberrypi/pisp_common.h b/libc/kernel/uapi/linux/media/raspberrypi/pisp_common.h
new file mode 100644
index 0000000..0e0b23f
--- /dev/null
+++ b/libc/kernel/uapi/linux/media/raspberrypi/pisp_common.h
@@ -0,0 +1,119 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_PISP_COMMON_H_
+#define _UAPI_PISP_COMMON_H_
+#include <linux/types.h>
+struct pisp_image_format_config {
+ __u16 width;
+ __u16 height;
+ __u32 format;
+ __s32 stride;
+ __s32 stride2;
+} __attribute__((packed));
+enum pisp_bayer_order {
+ PISP_BAYER_ORDER_RGGB = 0,
+ PISP_BAYER_ORDER_GBRG = 1,
+ PISP_BAYER_ORDER_BGGR = 2,
+ PISP_BAYER_ORDER_GRBG = 3,
+ PISP_BAYER_ORDER_GREYSCALE = 128
+};
+enum pisp_image_format {
+ PISP_IMAGE_FORMAT_BPS_8 = 0x00000000,
+ PISP_IMAGE_FORMAT_BPS_10 = 0x00000001,
+ PISP_IMAGE_FORMAT_BPS_12 = 0x00000002,
+ PISP_IMAGE_FORMAT_BPS_16 = 0x00000003,
+ PISP_IMAGE_FORMAT_BPS_MASK = 0x00000003,
+ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED = 0x00000000,
+ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR = 0x00000010,
+ PISP_IMAGE_FORMAT_PLANARITY_PLANAR = 0x00000020,
+ PISP_IMAGE_FORMAT_PLANARITY_MASK = 0x00000030,
+ PISP_IMAGE_FORMAT_SAMPLING_444 = 0x00000000,
+ PISP_IMAGE_FORMAT_SAMPLING_422 = 0x00000100,
+ PISP_IMAGE_FORMAT_SAMPLING_420 = 0x00000200,
+ PISP_IMAGE_FORMAT_SAMPLING_MASK = 0x00000300,
+ PISP_IMAGE_FORMAT_ORDER_NORMAL = 0x00000000,
+ PISP_IMAGE_FORMAT_ORDER_SWAPPED = 0x00001000,
+ PISP_IMAGE_FORMAT_SHIFT_0 = 0x00000000,
+ PISP_IMAGE_FORMAT_SHIFT_1 = 0x00010000,
+ PISP_IMAGE_FORMAT_SHIFT_2 = 0x00020000,
+ PISP_IMAGE_FORMAT_SHIFT_3 = 0x00030000,
+ PISP_IMAGE_FORMAT_SHIFT_4 = 0x00040000,
+ PISP_IMAGE_FORMAT_SHIFT_5 = 0x00050000,
+ PISP_IMAGE_FORMAT_SHIFT_6 = 0x00060000,
+ PISP_IMAGE_FORMAT_SHIFT_7 = 0x00070000,
+ PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000,
+ PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000,
+ PISP_IMAGE_FORMAT_BPP_32 = 0x00100000,
+ PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_3 = 0x03000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MASK = 0x03000000,
+ PISP_IMAGE_FORMAT_HOG_SIGNED = 0x04000000,
+ PISP_IMAGE_FORMAT_HOG_UNSIGNED = 0x08000000,
+ PISP_IMAGE_FORMAT_INTEGRAL_IMAGE = 0x10000000,
+ PISP_IMAGE_FORMAT_WALLPAPER_ROLL = 0x20000000,
+ PISP_IMAGE_FORMAT_THREE_CHANNEL = 0x40000000,
+ PISP_IMAGE_FORMAT_SINGLE_16 = PISP_IMAGE_FORMAT_BPS_16,
+ PISP_IMAGE_FORMAT_THREE_16 = PISP_IMAGE_FORMAT_BPS_16 | PISP_IMAGE_FORMAT_THREE_CHANNEL
+};
+#define PISP_IMAGE_FORMAT_BPS_8(fmt) (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8)
+#define PISP_IMAGE_FORMAT_BPS_10(fmt) (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10)
+#define PISP_IMAGE_FORMAT_BPS_12(fmt) (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12)
+#define PISP_IMAGE_FORMAT_BPS_16(fmt) (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16)
+#define PISP_IMAGE_FORMAT_BPS(fmt) (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8)
+#define PISP_IMAGE_FORMAT_SHIFT(fmt) (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1)
+#define PISP_IMAGE_FORMAT_THREE_CHANNEL(fmt) ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)
+#define PISP_IMAGE_FORMAT_SINGLE_CHANNEL(fmt) (! ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL))
+#define PISP_IMAGE_FORMAT_COMPRESSED(fmt) (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != PISP_IMAGE_FORMAT_UNCOMPRESSED)
+#define PISP_IMAGE_FORMAT_SAMPLING_444(fmt) (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == PISP_IMAGE_FORMAT_SAMPLING_444)
+#define PISP_IMAGE_FORMAT_SAMPLING_422(fmt) (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == PISP_IMAGE_FORMAT_SAMPLING_422)
+#define PISP_IMAGE_FORMAT_SAMPLING_420(fmt) (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == PISP_IMAGE_FORMAT_SAMPLING_420)
+#define PISP_IMAGE_FORMAT_ORDER_NORMAL(fmt) (! ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED))
+#define PISP_IMAGE_FORMAT_ORDER_SWAPPED(fmt) ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)
+#define PISP_IMAGE_FORMAT_INTERLEAVED(fmt) (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED)
+#define PISP_IMAGE_FORMAT_SEMIPLANAR(fmt) (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR)
+#define PISP_IMAGE_FORMAT_PLANAR(fmt) (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
+#define PISP_IMAGE_FORMAT_WALLPAPER(fmt) ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+#define PISP_IMAGE_FORMAT_BPP_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
+#define PISP_IMAGE_FORMAT_HOG(fmt) ((fmt) & (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
+#define PISP_WALLPAPER_WIDTH 128
+struct pisp_bla_config {
+ __u16 black_level_r;
+ __u16 black_level_gr;
+ __u16 black_level_gb;
+ __u16 black_level_b;
+ __u16 output_black_level;
+ __u8 pad[2];
+} __attribute__((packed));
+struct pisp_wbg_config {
+ __u16 gain_r;
+ __u16 gain_g;
+ __u16 gain_b;
+ __u8 pad[2];
+} __attribute__((packed));
+struct pisp_compress_config {
+ __u16 offset;
+ __u8 pad;
+ __u8 mode;
+} __attribute__((packed));
+struct pisp_decompress_config {
+ __u16 offset;
+ __u8 pad;
+ __u8 mode;
+} __attribute__((packed));
+enum pisp_axi_flags {
+ PISP_AXI_FLAG_ALIGN = 128,
+ PISP_AXI_FLAG_PAD = 64,
+ PISP_AXI_FLAG_PANIC = 32,
+};
+struct pisp_axi_config {
+ __u8 maxlen_flags;
+ __u8 cache_prot;
+ __u16 qos;
+} __attribute__((packed));
+#endif
diff --git a/libc/kernel/uapi/linux/mman.h b/libc/kernel/uapi/linux/mman.h
index cf1e978..f50b51c 100644
--- a/libc/kernel/uapi/linux/mman.h
+++ b/libc/kernel/uapi/linux/mman.h
@@ -18,6 +18,7 @@
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_SHARED_VALIDATE 0x03
+#define MAP_DROPPABLE 0x08
#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
#define MAP_HUGE_16KB HUGETLB_FLAG_ENCODE_16KB
diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h
index 1166a7a..c4278b5 100644
--- a/libc/kernel/uapi/linux/mount.h
+++ b/libc/kernel/uapi/linux/mount.h
@@ -90,7 +90,7 @@
#define MOUNT_ATTR_SIZE_VER0 32
struct statmount {
__u32 size;
- __u32 __spare1;
+ __u32 mnt_opts;
__u64 mask;
__u32 sb_dev_major;
__u32 sb_dev_minor;
@@ -108,7 +108,8 @@
__u64 propagate_from;
__u32 mnt_root;
__u32 mnt_point;
- __u64 __spare2[50];
+ __u64 mnt_ns_id;
+ __u64 __spare2[49];
char str[];
};
struct mnt_id_req {
@@ -116,13 +117,18 @@
__u32 spare;
__u64 mnt_id;
__u64 param;
+ __u64 mnt_ns_id;
};
#define MNT_ID_REQ_SIZE_VER0 24
+#define MNT_ID_REQ_SIZE_VER1 32
#define STATMOUNT_SB_BASIC 0x00000001U
#define STATMOUNT_MNT_BASIC 0x00000002U
#define STATMOUNT_PROPAGATE_FROM 0x00000004U
#define STATMOUNT_MNT_ROOT 0x00000008U
#define STATMOUNT_MNT_POINT 0x00000010U
#define STATMOUNT_FS_TYPE 0x00000020U
+#define STATMOUNT_MNT_NS_ID 0x00000040U
+#define STATMOUNT_MNT_OPTS 0x00000080U
#define LSMT_ROOT 0xffffffffffffffff
+#define LISTMOUNT_REVERSE (1 << 0)
#endif
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index 3c9ba5e..03d3691 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -53,6 +53,10 @@
__u64 mptcpi_bytes_received;
__u64 mptcpi_bytes_acked;
__u8 mptcpi_subflows_total;
+ __u8 reserved[3];
+ __u32 mptcpi_last_data_sent;
+ __u32 mptcpi_last_data_recv;
+ __u32 mptcpi_last_ack_recv;
};
#define MPTCP_RST_EUNSPEC 0
#define MPTCP_RST_EMPTCP 1
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index d47c28f..110220f 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -23,15 +23,19 @@
NBD_CMD_WRITE = 1,
NBD_CMD_DISC = 2,
NBD_CMD_FLUSH = 3,
- NBD_CMD_TRIM = 4
+ NBD_CMD_TRIM = 4,
+ NBD_CMD_WRITE_ZEROES = 6,
};
#define NBD_FLAG_HAS_FLAGS (1 << 0)
#define NBD_FLAG_READ_ONLY (1 << 1)
#define NBD_FLAG_SEND_FLUSH (1 << 2)
#define NBD_FLAG_SEND_FUA (1 << 3)
+#define NBD_FLAG_ROTATIONAL (1 << 4)
#define NBD_FLAG_SEND_TRIM (1 << 5)
+#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6)
#define NBD_FLAG_CAN_MULTI_CONN (1 << 8)
#define NBD_CMD_FLAG_FUA (1 << 16)
+#define NBD_CMD_FLAG_NO_HOLE (1 << 17)
#define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0)
#define NBD_CFLAG_DISCONNECT_ON_CLOSE (1 << 1)
#define NBD_REQUEST_MAGIC 0x25609513
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 9bbd309..b0df344 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -26,7 +26,8 @@
SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16),
- SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID_TCP,
+ SOF_TIMESTAMPING_OPT_RX_FILTER = (1 << 17),
+ SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_RX_FILTER,
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
};
#define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_ACK)
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
index cbfe26a..a7c5706 100644
--- a/libc/kernel/uapi/linux/netdev.h
+++ b/libc/kernel/uapi/linux/netdev.h
@@ -51,6 +51,7 @@
NETDEV_A_PAGE_POOL_INFLIGHT,
NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
NETDEV_A_PAGE_POOL_DETACH_TIME,
+ NETDEV_A_PAGE_POOL_DMABUF,
__NETDEV_A_PAGE_POOL_MAX,
NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1)
};
@@ -83,6 +84,7 @@
NETDEV_A_QUEUE_IFINDEX,
NETDEV_A_QUEUE_TYPE,
NETDEV_A_QUEUE_NAPI_ID,
+ NETDEV_A_QUEUE_DMABUF,
__NETDEV_A_QUEUE_MAX,
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
};
@@ -96,10 +98,40 @@
NETDEV_A_QSTATS_TX_PACKETS,
NETDEV_A_QSTATS_TX_BYTES,
NETDEV_A_QSTATS_RX_ALLOC_FAIL,
+ NETDEV_A_QSTATS_RX_HW_DROPS,
+ NETDEV_A_QSTATS_RX_HW_DROP_OVERRUNS,
+ NETDEV_A_QSTATS_RX_CSUM_COMPLETE,
+ NETDEV_A_QSTATS_RX_CSUM_UNNECESSARY,
+ NETDEV_A_QSTATS_RX_CSUM_NONE,
+ NETDEV_A_QSTATS_RX_CSUM_BAD,
+ NETDEV_A_QSTATS_RX_HW_GRO_PACKETS,
+ NETDEV_A_QSTATS_RX_HW_GRO_BYTES,
+ NETDEV_A_QSTATS_RX_HW_GRO_WIRE_PACKETS,
+ NETDEV_A_QSTATS_RX_HW_GRO_WIRE_BYTES,
+ NETDEV_A_QSTATS_RX_HW_DROP_RATELIMITS,
+ NETDEV_A_QSTATS_TX_HW_DROPS,
+ NETDEV_A_QSTATS_TX_HW_DROP_ERRORS,
+ NETDEV_A_QSTATS_TX_CSUM_NONE,
+ NETDEV_A_QSTATS_TX_NEEDS_CSUM,
+ NETDEV_A_QSTATS_TX_HW_GSO_PACKETS,
+ NETDEV_A_QSTATS_TX_HW_GSO_BYTES,
+ NETDEV_A_QSTATS_TX_HW_GSO_WIRE_PACKETS,
+ NETDEV_A_QSTATS_TX_HW_GSO_WIRE_BYTES,
+ NETDEV_A_QSTATS_TX_HW_DROP_RATELIMITS,
+ NETDEV_A_QSTATS_TX_STOP,
+ NETDEV_A_QSTATS_TX_WAKE,
__NETDEV_A_QSTATS_MAX,
NETDEV_A_QSTATS_MAX = (__NETDEV_A_QSTATS_MAX - 1)
};
enum {
+ NETDEV_A_DMABUF_IFINDEX = 1,
+ NETDEV_A_DMABUF_QUEUES,
+ NETDEV_A_DMABUF_FD,
+ NETDEV_A_DMABUF_ID,
+ __NETDEV_A_DMABUF_MAX,
+ NETDEV_A_DMABUF_MAX = (__NETDEV_A_DMABUF_MAX - 1)
+};
+enum {
NETDEV_CMD_DEV_GET = 1,
NETDEV_CMD_DEV_ADD_NTF,
NETDEV_CMD_DEV_DEL_NTF,
@@ -112,6 +144,7 @@
NETDEV_CMD_QUEUE_GET,
NETDEV_CMD_NAPI_GET,
NETDEV_CMD_QSTATS_GET,
+ NETDEV_CMD_BIND_RX,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 7922147..bfc6e25 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -695,7 +695,7 @@
__NFTA_SECMARK_MAX,
};
#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1)
-#define NFT_SECMARK_CTX_MAXLEN 256
+#define NFT_SECMARK_CTX_MAXLEN 4096
enum nft_reject_types {
NFT_REJECT_ICMP_UNREACH,
NFT_REJECT_TCP_RST,
diff --git a/libc/kernel/uapi/linux/nexthop.h b/libc/kernel/uapi/linux/nexthop.h
index 5726a66..2443c18 100644
--- a/libc/kernel/uapi/linux/nexthop.h
+++ b/libc/kernel/uapi/linux/nexthop.h
@@ -17,7 +17,7 @@
struct nexthop_grp {
__u32 id;
__u8 weight;
- __u8 resvd1;
+ __u8 weight_high;
__u16 resvd2;
};
enum {
@@ -28,6 +28,7 @@
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
#define NHA_OP_FLAG_DUMP_STATS BIT(0)
#define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
+#define NHA_OP_FLAG_RESP_GRP_RESVD_0 BIT(31)
enum {
NHA_UNSPEC,
NHA_ID,
diff --git a/libc/kernel/uapi/linux/nfs.h b/libc/kernel/uapi/linux/nfs.h
index 710e8ca..7b18f1f 100644
--- a/libc/kernel/uapi/linux/nfs.h
+++ b/libc/kernel/uapi/linux/nfs.h
@@ -47,7 +47,6 @@
NFSERR_NOSPC = 28,
NFSERR_ROFS = 30,
NFSERR_MLINK = 31,
- NFSERR_OPNOTSUPP = 45,
NFSERR_NAMETOOLONG = 63,
NFSERR_NOTEMPTY = 66,
NFSERR_DQUOT = 69,
diff --git a/libc/kernel/uapi/linux/nfs4.h b/libc/kernel/uapi/linux/nfs4.h
index 21f1103..6512901 100644
--- a/libc/kernel/uapi/linux/nfs4.h
+++ b/libc/kernel/uapi/linux/nfs4.h
@@ -34,6 +34,7 @@
#define NFS4_OPEN_RESULT_CONFIRM 0x0002
#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
#define NFS4_OPEN_RESULT_PRESERVE_UNLINKED 0x0008
+#define NFS4_OPEN_RESULT_NO_OPEN_STATEID 0x0010
#define NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK 0x0020
#define NFS4_SHARE_ACCESS_MASK 0x000F
#define NFS4_SHARE_ACCESS_READ 0x0001
@@ -52,6 +53,8 @@
#define NFS4_SHARE_WHEN_MASK 0xF0000
#define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000
#define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000
+#define NFS4_SHARE_WANT_DELEG_TIMESTAMPS 0x100000
+#define NFS4_SHARE_WANT_OPEN_XOR_DELEGATION 0x200000
#define NFS4_CDFC4_FORE 0x1
#define NFS4_CDFC4_BACK 0x2
#define NFS4_CDFC4_BOTH 0x3
diff --git a/libc/kernel/uapi/linux/nfsd_netlink.h b/libc/kernel/uapi/linux/nfsd_netlink.h
index dd3d570..bd3f02c 100644
--- a/libc/kernel/uapi/linux/nfsd_netlink.h
+++ b/libc/kernel/uapi/linux/nfsd_netlink.h
@@ -27,7 +27,52 @@
NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
};
enum {
+ NFSD_A_SERVER_THREADS = 1,
+ NFSD_A_SERVER_GRACETIME,
+ NFSD_A_SERVER_LEASETIME,
+ NFSD_A_SERVER_SCOPE,
+ __NFSD_A_SERVER_MAX,
+ NFSD_A_SERVER_MAX = (__NFSD_A_SERVER_MAX - 1)
+};
+enum {
+ NFSD_A_VERSION_MAJOR = 1,
+ NFSD_A_VERSION_MINOR,
+ NFSD_A_VERSION_ENABLED,
+ __NFSD_A_VERSION_MAX,
+ NFSD_A_VERSION_MAX = (__NFSD_A_VERSION_MAX - 1)
+};
+enum {
+ NFSD_A_SERVER_PROTO_VERSION = 1,
+ __NFSD_A_SERVER_PROTO_MAX,
+ NFSD_A_SERVER_PROTO_MAX = (__NFSD_A_SERVER_PROTO_MAX - 1)
+};
+enum {
+ NFSD_A_SOCK_ADDR = 1,
+ NFSD_A_SOCK_TRANSPORT_NAME,
+ __NFSD_A_SOCK_MAX,
+ NFSD_A_SOCK_MAX = (__NFSD_A_SOCK_MAX - 1)
+};
+enum {
+ NFSD_A_SERVER_SOCK_ADDR = 1,
+ __NFSD_A_SERVER_SOCK_MAX,
+ NFSD_A_SERVER_SOCK_MAX = (__NFSD_A_SERVER_SOCK_MAX - 1)
+};
+enum {
+ NFSD_A_POOL_MODE_MODE = 1,
+ NFSD_A_POOL_MODE_NPOOLS,
+ __NFSD_A_POOL_MODE_MAX,
+ NFSD_A_POOL_MODE_MAX = (__NFSD_A_POOL_MODE_MAX - 1)
+};
+enum {
NFSD_CMD_RPC_STATUS_GET = 1,
+ NFSD_CMD_THREADS_SET,
+ NFSD_CMD_THREADS_GET,
+ NFSD_CMD_VERSION_SET,
+ NFSD_CMD_VERSION_GET,
+ NFSD_CMD_LISTENER_SET,
+ NFSD_CMD_LISTENER_GET,
+ NFSD_CMD_POOL_MODE_SET,
+ NFSD_CMD_POOL_MODE_GET,
__NFSD_CMD_MAX,
NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index ddf2b3b..1bad2f2 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -528,6 +528,8 @@
NL80211_ATTR_MLO_TTLM_DLINK,
NL80211_ATTR_MLO_TTLM_ULINK,
NL80211_ATTR_ASSOC_SPP_AMSDU,
+ NL80211_ATTR_WIPHY_RADIOS,
+ NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -878,6 +880,7 @@
NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT,
NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT,
NL80211_FREQUENCY_ATTR_CAN_MONITOR,
+ NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP,
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
};
@@ -955,6 +958,7 @@
NL80211_RRF_DFS_CONCURRENT = 1 << 21,
NL80211_RRF_NO_6GHZ_VLP_CLIENT = 1 << 22,
NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1 << 23,
+ NL80211_RRF_ALLOW_6GHZ_VLP_AP = 1 << 24,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
@@ -1423,7 +1427,7 @@
NUM_NL80211_PLINK_STATES,
MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
};
-enum plink_actions {
+enum nl80211_plink_action {
NL80211_PLINK_ACTION_NO_ACTION,
NL80211_PLINK_ACTION_OPEN,
NL80211_PLINK_ACTION_BLOCK,
@@ -1973,4 +1977,19 @@
NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = 1 << 0,
NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
};
+enum nl80211_wiphy_radio_attrs {
+ __NL80211_WIPHY_RADIO_ATTR_INVALID,
+ NL80211_WIPHY_RADIO_ATTR_INDEX,
+ NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
+ NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
+ __NL80211_WIPHY_RADIO_ATTR_LAST,
+ NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
+};
+enum nl80211_wiphy_radio_freq_range {
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
+ NL80211_WIPHY_RADIO_FREQ_ATTR_START,
+ NL80211_WIPHY_RADIO_FREQ_ATTR_END,
+ __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
+ NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
+};
#endif
diff --git a/libc/kernel/uapi/linux/nsfs.h b/libc/kernel/uapi/linux/nsfs.h
index 61a5797..870afe7 100644
--- a/libc/kernel/uapi/linux/nsfs.h
+++ b/libc/kernel/uapi/linux/nsfs.h
@@ -7,9 +7,24 @@
#ifndef __LINUX_NSFS_H
#define __LINUX_NSFS_H
#include <linux/ioctl.h>
+#include <linux/types.h>
#define NSIO 0xb7
#define NS_GET_USERNS _IO(NSIO, 0x1)
#define NS_GET_PARENT _IO(NSIO, 0x2)
#define NS_GET_NSTYPE _IO(NSIO, 0x3)
#define NS_GET_OWNER_UID _IO(NSIO, 0x4)
+#define NS_GET_MNTNS_ID _IOR(NSIO, 0x5, __u64)
+#define NS_GET_PID_FROM_PIDNS _IOR(NSIO, 0x6, int)
+#define NS_GET_TGID_FROM_PIDNS _IOR(NSIO, 0x7, int)
+#define NS_GET_PID_IN_PIDNS _IOR(NSIO, 0x8, int)
+#define NS_GET_TGID_IN_PIDNS _IOR(NSIO, 0x9, int)
+struct mnt_ns_info {
+ __u32 size;
+ __u32 nr_mounts;
+ __u64 mnt_ns_id;
+};
+#define MNT_NS_INFO_SIZE_VER0 16
+#define NS_MNT_GET_INFO _IOR(NSIO, 10, struct mnt_ns_info)
+#define NS_MNT_GET_NEXT _IOR(NSIO, 11, struct mnt_ns_info)
+#define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info)
#endif
diff --git a/libc/kernel/uapi/linux/ntsync.h b/libc/kernel/uapi/linux/ntsync.h
new file mode 100644
index 0000000..857b31b
--- /dev/null
+++ b/libc/kernel/uapi/linux/ntsync.h
@@ -0,0 +1,17 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __LINUX_NTSYNC_H
+#define __LINUX_NTSYNC_H
+#include <linux/types.h>
+struct ntsync_sem_args {
+ __u32 sem;
+ __u32 count;
+ __u32 max;
+};
+#define NTSYNC_IOC_CREATE_SEM _IOWR('N', 0x80, struct ntsync_sem_args)
+#define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32)
+#endif
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index d45f4fa..98c8037 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -429,6 +429,13 @@
__OVS_CHECK_PKT_LEN_ATTR_MAX,
};
#define OVS_CHECK_PKT_LEN_ATTR_MAX (__OVS_CHECK_PKT_LEN_ATTR_MAX - 1)
+#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
+enum ovs_psample_attr {
+ OVS_PSAMPLE_ATTR_GROUP = 1,
+ OVS_PSAMPLE_ATTR_COOKIE,
+ __OVS_PSAMPLE_ATTR_MAX
+};
+#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
enum ovs_action_attr {
OVS_ACTION_ATTR_UNSPEC,
OVS_ACTION_ATTR_OUTPUT,
@@ -455,6 +462,7 @@
OVS_ACTION_ATTR_ADD_MPLS,
OVS_ACTION_ATTR_DEC_TTL,
OVS_ACTION_ATTR_DROP,
+ OVS_ACTION_ATTR_PSAMPLE,
__OVS_ACTION_ATTR_MAX,
};
#define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/papr_pdsm.h b/libc/kernel/uapi/linux/papr_pdsm.h
new file mode 100644
index 0000000..f466caa
--- /dev/null
+++ b/libc/kernel/uapi/linux/papr_pdsm.h
@@ -0,0 +1,64 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_POWERPC_PAPR_PDSM_H_
+#define _UAPI_ASM_POWERPC_PAPR_PDSM_H_
+#include <linux/types.h>
+#include <linux/ndctl.h>
+#define ND_PDSM_PAYLOAD_MAX_SIZE 184
+#define ND_PDSM_HDR_SIZE (sizeof(struct nd_pkg_pdsm) - ND_PDSM_PAYLOAD_MAX_SIZE)
+#define PAPR_PDSM_DIMM_HEALTHY 0
+#define PAPR_PDSM_DIMM_UNHEALTHY 1
+#define PAPR_PDSM_DIMM_CRITICAL 2
+#define PAPR_PDSM_DIMM_FATAL 3
+#define PDSM_DIMM_HEALTH_RUN_GAUGE_VALID 1
+#define PDSM_DIMM_DSC_VALID 2
+struct nd_papr_pdsm_health {
+ union {
+ struct {
+ __u32 extension_flags;
+ __u8 dimm_unarmed;
+ __u8 dimm_bad_shutdown;
+ __u8 dimm_bad_restore;
+ __u8 dimm_scrubbed;
+ __u8 dimm_locked;
+ __u8 dimm_encrypted;
+ __u16 dimm_health;
+ __u16 dimm_fuel_gauge;
+ __u64 dimm_dsc;
+ };
+ __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+ };
+};
+#define PDSM_SMART_INJECT_HEALTH_FATAL (1 << 0)
+#define PDSM_SMART_INJECT_BAD_SHUTDOWN (1 << 1)
+struct nd_papr_pdsm_smart_inject {
+ union {
+ struct {
+ __u32 flags;
+ __u8 fatal_enable;
+ __u8 unsafe_shutdown_enable;
+ };
+ __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+ };
+};
+enum papr_pdsm {
+ PAPR_PDSM_MIN = 0x0,
+ PAPR_PDSM_HEALTH,
+ PAPR_PDSM_SMART_INJECT,
+ PAPR_PDSM_MAX,
+};
+union nd_pdsm_payload {
+ struct nd_papr_pdsm_health health;
+ struct nd_papr_pdsm_smart_inject smart_inject;
+ __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+} __attribute__((__packed__));
+struct nd_pkg_pdsm {
+ __s32 cmd_status;
+ __u16 reserved[2];
+ union nd_pdsm_payload payload;
+} __attribute__((__packed__));
+#endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index e26392b..7083391 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -531,9 +531,11 @@
#define PCI_EXP_RTCTL_SENFEE 0x0002
#define PCI_EXP_RTCTL_SEFEE 0x0004
#define PCI_EXP_RTCTL_PMEIE 0x0008
-#define PCI_EXP_RTCTL_CRSSVE 0x0010
+#define PCI_EXP_RTCTL_RRS_SVE 0x0010
+#define PCI_EXP_RTCTL_CRSSVE PCI_EXP_RTCTL_RRS_SVE
#define PCI_EXP_RTCAP 0x1e
-#define PCI_EXP_RTCAP_CRSVIS 0x0001
+#define PCI_EXP_RTCAP_RRS_SV 0x0001
+#define PCI_EXP_RTCAP_CRSVIS PCI_EXP_RTCAP_RRS_SV
#define PCI_EXP_RTSTA 0x20
#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff
#define PCI_EXP_RTSTA_PME 0x00010000
@@ -626,6 +628,7 @@
#define PCI_EXT_CAP_ID_DVSEC 0x23
#define PCI_EXT_CAP_ID_DLF 0x25
#define PCI_EXT_CAP_ID_PL_16GT 0x26
+#define PCI_EXT_CAP_ID_NPEM 0x29
#define PCI_EXT_CAP_ID_PL_32GT 0x2A
#define PCI_EXT_CAP_ID_DOE 0x2E
#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE
@@ -944,6 +947,31 @@
#define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4
+#define PCI_NPEM_CAP 0x04
+#define PCI_NPEM_CAP_CAPABLE 0x00000001
+#define PCI_NPEM_CTRL 0x08
+#define PCI_NPEM_CTRL_ENABLE 0x00000001
+#define PCI_NPEM_CMD_RESET 0x00000002
+#define PCI_NPEM_IND_OK 0x00000004
+#define PCI_NPEM_IND_LOCATE 0x00000008
+#define PCI_NPEM_IND_FAIL 0x00000010
+#define PCI_NPEM_IND_REBUILD 0x00000020
+#define PCI_NPEM_IND_PFA 0x00000040
+#define PCI_NPEM_IND_HOTSPARE 0x00000080
+#define PCI_NPEM_IND_ICA 0x00000100
+#define PCI_NPEM_IND_IFA 0x00000200
+#define PCI_NPEM_IND_IDT 0x00000400
+#define PCI_NPEM_IND_DISABLED 0x00000800
+#define PCI_NPEM_IND_SPEC_0 0x01000000
+#define PCI_NPEM_IND_SPEC_1 0x02000000
+#define PCI_NPEM_IND_SPEC_2 0x04000000
+#define PCI_NPEM_IND_SPEC_3 0x08000000
+#define PCI_NPEM_IND_SPEC_4 0x10000000
+#define PCI_NPEM_IND_SPEC_5 0x20000000
+#define PCI_NPEM_IND_SPEC_6 0x40000000
+#define PCI_NPEM_IND_SPEC_7 0x80000000
+#define PCI_NPEM_STATUS 0x0c
+#define PCI_NPEM_STATUS_CC 0x00000001
#define PCI_DOE_CAP 0x04
#define PCI_DOE_CAP_INT_SUP 0x00000001
#define PCI_DOE_CAP_INT_MSG_NUM 0x00000ffe
@@ -963,7 +991,11 @@
#define PCI_DOE_DATA_OBJECT_HEADER_1_TYPE 0x00ff0000
#define PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH 0x0003ffff
#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX 0x000000ff
+#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_VER 0x0000ff00
#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID 0x0000ffff
#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL 0x00ff0000
#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX 0xff000000
+#define PCI_DVSEC_CXL_PORT 3
+#define PCI_DVSEC_CXL_PORT_CTL 0x0c
+#define PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR 0x00000001
#endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 16a1a2e..ec9b856 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -460,6 +460,8 @@
#define PERF_MEM_LVLNUM_L2 0x02
#define PERF_MEM_LVLNUM_L3 0x03
#define PERF_MEM_LVLNUM_L4 0x04
+#define PERF_MEM_LVLNUM_L2_MHB 0x05
+#define PERF_MEM_LVLNUM_MSC 0x06
#define PERF_MEM_LVLNUM_UNC 0x08
#define PERF_MEM_LVLNUM_CXL 0x09
#define PERF_MEM_LVLNUM_IO 0x0a
diff --git a/libc/kernel/uapi/linux/pidfd.h b/libc/kernel/uapi/linux/pidfd.h
index 082b4a0..9068727 100644
--- a/libc/kernel/uapi/linux/pidfd.h
+++ b/libc/kernel/uapi/linux/pidfd.h
@@ -8,9 +8,21 @@
#define _UAPI_LINUX_PIDFD_H
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/ioctl.h>
#define PIDFD_NONBLOCK O_NONBLOCK
#define PIDFD_THREAD O_EXCL
#define PIDFD_SIGNAL_THREAD (1UL << 0)
#define PIDFD_SIGNAL_THREAD_GROUP (1UL << 1)
#define PIDFD_SIGNAL_PROCESS_GROUP (1UL << 2)
+#define PIDFS_IOCTL_MAGIC 0xFF
+#define PIDFD_GET_CGROUP_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 1)
+#define PIDFD_GET_IPC_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 2)
+#define PIDFD_GET_MNT_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 3)
+#define PIDFD_GET_NET_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 4)
+#define PIDFD_GET_PID_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 5)
+#define PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 6)
+#define PIDFD_GET_TIME_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 7)
+#define PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 8)
+#define PIDFD_GET_USER_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 9)
+#define PIDFD_GET_UTS_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 10)
#endif
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index b402fa6..c5d8d79 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -179,7 +179,12 @@
int offmask;
};
struct tc_u32_sel {
- unsigned char flags;
+ /**
+ ** ANDROID FIX: Comment out TAG value to avoid C++ error about using
+ ** a type declared in an anonymous union. This is being fixed upstream
+ ** and should be corrected by the next kernel import.
+ */
+ __struct_group(/*tc_u32_sel_hdr*/, hdr,, unsigned char flags;
unsigned char offshift;
unsigned char nkeys;
__be16 offmask;
@@ -187,6 +192,7 @@
short offoff;
short hoff;
__be32 hmask;
+ );
struct tc_u32_key keys[];
};
struct tc_u32_mark {
@@ -419,6 +425,8 @@
TCA_FLOWER_KEY_CFM,
TCA_FLOWER_KEY_SPI,
TCA_FLOWER_KEY_SPI_MASK,
+ TCA_FLOWER_KEY_ENC_FLAGS,
+ TCA_FLOWER_KEY_ENC_FLAGS_MASK,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
@@ -437,6 +445,7 @@
TCA_FLOWER_KEY_ENC_OPTS_VXLAN,
TCA_FLOWER_KEY_ENC_OPTS_ERSPAN,
TCA_FLOWER_KEY_ENC_OPTS_GTP,
+ TCA_FLOWER_KEY_ENC_OPTS_PFCP,
__TCA_FLOWER_KEY_ENC_OPTS_MAX,
};
#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
@@ -471,6 +480,13 @@
};
#define TCA_FLOWER_KEY_ENC_OPT_GTP_MAX (__TCA_FLOWER_KEY_ENC_OPT_GTP_MAX - 1)
enum {
+ TCA_FLOWER_KEY_ENC_OPT_PFCP_UNSPEC,
+ TCA_FLOWER_KEY_ENC_OPT_PFCP_TYPE,
+ TCA_FLOWER_KEY_ENC_OPT_PFCP_SEID,
+ __TCA_FLOWER_KEY_ENC_OPT_PFCP_MAX,
+};
+#define TCA_FLOWER_KEY_ENC_OPT_PFCP_MAX (__TCA_FLOWER_KEY_ENC_OPT_PFCP_MAX - 1)
+enum {
TCA_FLOWER_KEY_MPLS_OPTS_UNSPEC,
TCA_FLOWER_KEY_MPLS_OPTS_LSE,
__TCA_FLOWER_KEY_MPLS_OPTS_MAX,
@@ -489,7 +505,13 @@
enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
+ TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM = (1 << 2),
+ TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT = (1 << 3),
+ TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM = (1 << 4),
+ TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT = (1 << 5),
+ __TCA_FLOWER_KEY_FLAGS_MAX,
};
+#define TCA_FLOWER_KEY_FLAGS_MAX (__TCA_FLOWER_KEY_FLAGS_MAX - 1)
enum {
TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
TCA_FLOWER_KEY_CFM_MD_LEVEL,
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 48e100b..136a10f 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -190,4 +190,21 @@
#define PR_RISCV_V_VSTATE_CTRL_CUR_MASK 0x3
#define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc
#define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f
+#define PR_RISCV_SET_ICACHE_FLUSH_CTX 71
+#define PR_RISCV_CTX_SW_FENCEI_ON 0
+#define PR_RISCV_CTX_SW_FENCEI_OFF 1
+#define PR_RISCV_SCOPE_PER_PROCESS 0
+#define PR_RISCV_SCOPE_PER_THREAD 1
+#define PR_PPC_GET_DEXCR 72
+#define PR_PPC_SET_DEXCR 73
+#define PR_PPC_DEXCR_SBHE 0
+#define PR_PPC_DEXCR_IBRTPD 1
+#define PR_PPC_DEXCR_SRAPD 2
+#define PR_PPC_DEXCR_NPHIE 3
+#define PR_PPC_DEXCR_CTRL_EDITABLE 0x1
+#define PR_PPC_DEXCR_CTRL_SET 0x2
+#define PR_PPC_DEXCR_CTRL_CLEAR 0x4
+#define PR_PPC_DEXCR_CTRL_SET_ONEXEC 0x8
+#define PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC 0x10
+#define PR_PPC_DEXCR_CTRL_MASK 0x1f
#endif
diff --git a/libc/kernel/uapi/linux/psample.h b/libc/kernel/uapi/linux/psample.h
index c82e76e..f9f979c 100644
--- a/libc/kernel/uapi/linux/psample.h
+++ b/libc/kernel/uapi/linux/psample.h
@@ -22,6 +22,8 @@
PSAMPLE_ATTR_LATENCY,
PSAMPLE_ATTR_TIMESTAMP,
PSAMPLE_ATTR_PROTO,
+ PSAMPLE_ATTR_USER_COOKIE,
+ PSAMPLE_ATTR_SAMPLE_PROBABILITY,
__PSAMPLE_ATTR_MAX
};
enum psample_command {
diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h
index 82fcbf1..7274081 100644
--- a/libc/kernel/uapi/linux/psp-sev.h
+++ b/libc/kernel/uapi/linux/psp-sev.h
@@ -20,6 +20,7 @@
SNP_PLATFORM_STATUS,
SNP_COMMIT,
SNP_SET_CONFIG,
+ SNP_VLEK_LOAD,
SEV_MAX,
};
typedef enum {
@@ -28,6 +29,7 @@
SEV_RET_INVALID_PLATFORM_STATE,
SEV_RET_INVALID_GUEST_STATE,
SEV_RET_INAVLID_CONFIG,
+ SEV_RET_INVALID_CONFIG = SEV_RET_INAVLID_CONFIG,
SEV_RET_INVALID_LEN,
SEV_RET_ALREADY_OWNED,
SEV_RET_INVALID_CERTIFICATE,
@@ -113,6 +115,15 @@
__u32 rsvd : 30;
__u8 rsvd1[52];
} __attribute__((__packed__));
+struct sev_user_data_snp_vlek_load {
+ __u32 len;
+ __u8 vlek_wrapped_version;
+ __u8 rsvd[3];
+ __u64 vlek_wrapped_address;
+} __attribute__((__packed__));
+struct sev_user_data_snp_wrapped_vlek_hashstick {
+ __u8 data[432];
+} __attribute__((__packed__));
struct sev_issue_cmd {
__u32 cmd;
__u64 data;
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index 5014936..88c6786 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -65,7 +65,8 @@
};
struct ptp_sys_offset_extended {
unsigned int n_samples;
- unsigned int rsv[3];
+ __kernel_clockid_t clockid;
+ unsigned int rsv[2];
struct ptp_clock_time ts[PTP_MAX_SAMPLES][3];
};
struct ptp_sys_offset_precise {
diff --git a/libc/kernel/uapi/linux/random.h b/libc/kernel/uapi/linux/random.h
index d1fd998..64f62d9 100644
--- a/libc/kernel/uapi/linux/random.h
+++ b/libc/kernel/uapi/linux/random.h
@@ -24,4 +24,10 @@
#define GRND_NONBLOCK 0x0001
#define GRND_RANDOM 0x0002
#define GRND_INSECURE 0x0004
+struct vgetrandom_opaque_params {
+ __u32 size_of_opaque_state;
+ __u32 mmap_prot;
+ __u32 mmap_flags;
+ __u32 reserved[13];
+};
#endif
diff --git a/libc/kernel/uapi/linux/rkisp1-config.h b/libc/kernel/uapi/linux/rkisp1-config.h
index d4206a0..d5cf92a 100644
--- a/libc/kernel/uapi/linux/rkisp1-config.h
+++ b/libc/kernel/uapi/linux/rkisp1-config.h
@@ -88,6 +88,7 @@
#define RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(n,v) ((v) << ((n) * 4 + 2))
#define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS 17
#define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS 6
+#define RKISP1_CIF_ISP_COMPAND_NUM_POINTS 64
#define RKISP1_CIF_ISP_STAT_AWB (1U << 0)
#define RKISP1_CIF_ISP_STAT_AUTOEXP (1U << 1)
#define RKISP1_CIF_ISP_STAT_AFM (1U << 2)
@@ -348,6 +349,17 @@
struct rkisp1_cif_isp_isp_meas_cfg meas;
struct rkisp1_cif_isp_isp_other_cfg others;
};
+struct rkisp1_cif_isp_compand_bls_config {
+ __u32 r;
+ __u32 gr;
+ __u32 gb;
+ __u32 b;
+};
+struct rkisp1_cif_isp_compand_curve_config {
+ __u8 px[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+ __u32 x[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+ __u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+};
struct rkisp1_cif_isp_awb_meas {
__u32 cnt;
__u8 mean_y_or_g;
@@ -388,4 +400,118 @@
__u32 frame_id;
struct rkisp1_cif_isp_stat params;
};
+enum rkisp1_ext_params_block_type {
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_IE,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
+};
+#define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE (1U << 0)
+#define RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE (1U << 1)
+struct rkisp1_ext_params_block_header {
+ __u16 type;
+ __u16 flags;
+ __u32 size;
+};
+struct rkisp1_ext_params_bls_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_bls_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpcc_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_dpcc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_sdg_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_sdg_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_lsc_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_lsc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_awb_gain_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_awb_gain_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_flt_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_flt_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_bdm_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_bdm_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_ctk_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_ctk_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_goc_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_goc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpf_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_dpf_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpf_strength_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_dpf_strength_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_cproc_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_cproc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_ie_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_ie_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_awb_meas_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_awb_meas_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_hst_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_hst_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_aec_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_aec_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_afc_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_afc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_compand_bls_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_compand_bls_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_compand_curve_config {
+ struct rkisp1_ext_params_block_header header;
+ struct rkisp1_cif_isp_compand_curve_config config;
+} __attribute__((aligned(8)));
+#define RKISP1_EXT_PARAMS_MAX_SIZE (sizeof(struct rkisp1_ext_params_bls_config) + sizeof(struct rkisp1_ext_params_dpcc_config) + sizeof(struct rkisp1_ext_params_sdg_config) + sizeof(struct rkisp1_ext_params_lsc_config) + sizeof(struct rkisp1_ext_params_awb_gain_config) + sizeof(struct rkisp1_ext_params_flt_config) + sizeof(struct rkisp1_ext_params_bdm_config) + sizeof(struct rkisp1_ext_params_ctk_config) + sizeof(struct rkisp1_ext_params_goc_config) + sizeof(struct rkisp1_ext_params_dpf_config) + sizeof(struct rkisp1_ext_params_dpf_strength_config) + sizeof(struct rkisp1_ext_params_cproc_config) + sizeof(struct rkisp1_ext_params_ie_config) + sizeof(struct rkisp1_ext_params_awb_meas_config) + sizeof(struct rkisp1_ext_params_hst_config) + sizeof(struct rkisp1_ext_params_aec_config) + sizeof(struct rkisp1_ext_params_afc_config) + sizeof(struct rkisp1_ext_params_compand_bls_config) + sizeof(struct rkisp1_ext_params_compand_curve_config) + sizeof(struct rkisp1_ext_params_compand_curve_config))
+enum rksip1_ext_param_buffer_version {
+ RKISP1_EXT_PARAM_BUFFER_V1 = 1,
+};
+struct rkisp1_ext_params_cfg {
+ __u32 version;
+ __u32 data_size;
+ __u8 data[RKISP1_EXT_PARAMS_MAX_SIZE];
+};
#endif
diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h
index ae914f7..eaeeee3 100644
--- a/libc/kernel/uapi/linux/sched.h
+++ b/libc/kernel/uapi/linux/sched.h
@@ -59,6 +59,7 @@
#define SCHED_BATCH 3
#define SCHED_IDLE 5
#define SCHED_DEADLINE 6
+#define SCHED_EXT 7
#define SCHED_RESET_ON_FORK 0x40000000
#define SCHED_FLAG_RESET_ON_FORK 0x01
#define SCHED_FLAG_RECLAIM 0x02
diff --git a/libc/kernel/uapi/linux/serio.h b/libc/kernel/uapi/linux/serio.h
index 424144e..0f0668f 100644
--- a/libc/kernel/uapi/linux/serio.h
+++ b/libc/kernel/uapi/linux/serio.h
@@ -66,4 +66,5 @@
#define SERIO_PULSE8_CEC 0x40
#define SERIO_RAINSHADOW_CEC 0x41
#define SERIO_FSIA6B 0x42
+#define SERIO_EXTRON_DA_HD_4K_PLUS 0x43
#endif
diff --git a/libc/kernel/uapi/linux/sev-guest.h b/libc/kernel/uapi/linux/sev-guest.h
index a822bed..a722641 100644
--- a/libc/kernel/uapi/linux/sev-guest.h
+++ b/libc/kernel/uapi/linux/sev-guest.h
@@ -51,6 +51,8 @@
#define SNP_GUEST_FW_ERR_MASK GENMASK_ULL(31, 0)
#define SNP_GUEST_VMM_ERR_SHIFT 32
#define SNP_GUEST_VMM_ERR(x) (((u64) x) << SNP_GUEST_VMM_ERR_SHIFT)
+#define SNP_GUEST_FW_ERR(x) ((x) & SNP_GUEST_FW_ERR_MASK)
+#define SNP_GUEST_ERR(vmm_err,fw_err) (SNP_GUEST_VMM_ERR(vmm_err) | SNP_GUEST_FW_ERR(fw_err))
#define SNP_GUEST_VMM_ERR_INVALID_LEN 1
#define SNP_GUEST_VMM_ERR_BUSY 2
#endif
diff --git a/libc/kernel/uapi/linux/smc.h b/libc/kernel/uapi/linux/smc.h
index 5e75fac..52a0da1 100644
--- a/libc/kernel/uapi/linux/smc.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -103,6 +103,8 @@
SMC_NLA_LGR_R_NET_COOKIE,
SMC_NLA_LGR_R_PAD,
SMC_NLA_LGR_R_BUF_TYPE,
+ SMC_NLA_LGR_R_SNDBUF_ALLOC,
+ SMC_NLA_LGR_R_RMB_ALLOC,
__SMC_NLA_LGR_R_MAX,
SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
};
@@ -134,6 +136,8 @@
SMC_NLA_LGR_D_V2_COMMON,
SMC_NLA_LGR_D_EXT_GID,
SMC_NLA_LGR_D_PEER_EXT_GID,
+ SMC_NLA_LGR_D_SNDBUF_ALLOC,
+ SMC_NLA_LGR_D_DMB_ALLOC,
__SMC_NLA_LGR_D_MAX,
SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
};
@@ -210,6 +214,8 @@
SMC_NLA_STATS_T_TX_BYTES,
SMC_NLA_STATS_T_RX_CNT,
SMC_NLA_STATS_T_TX_CNT,
+ SMC_NLA_STATS_T_RX_RMB_USAGE,
+ SMC_NLA_STATS_T_TX_RMB_USAGE,
__SMC_NLA_STATS_T_MAX,
SMC_NLA_STATS_T_MAX = __SMC_NLA_STATS_T_MAX - 1
};
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 2f4c65c..0f72302 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -289,6 +289,8 @@
LINUX_MIB_XFRMFWDHDRERROR,
LINUX_MIB_XFRMOUTSTATEINVALID,
LINUX_MIB_XFRMACQUIREERROR,
+ LINUX_MIB_XFRMOUTSTATEDIRERROR,
+ LINUX_MIB_XFRMINSTATEDIRERROR,
__LINUX_MIB_XFRMMAX
};
enum {
diff --git a/libc/kernel/uapi/linux/spi/spi.h b/libc/kernel/uapi/linux/spi/spi.h
index 45c45cd..d0ead4b 100644
--- a/libc/kernel/uapi/linux/spi/spi.h
+++ b/libc/kernel/uapi/linux/spi/spi.h
@@ -30,5 +30,6 @@
#define SPI_3WIRE_HIZ _BITUL(15)
#define SPI_RX_CPHA_FLIP _BITUL(16)
#define SPI_MOSI_IDLE_LOW _BITUL(17)
-#define SPI_MODE_USER_MASK (_BITUL(18) - 1)
+#define SPI_MOSI_IDLE_HIGH _BITUL(18)
+#define SPI_MODE_USER_MASK (_BITUL(19) - 1)
#endif
diff --git a/libc/kernel/uapi/linux/stat.h b/libc/kernel/uapi/linux/stat.h
index 9974f3e..aae9ed4 100644
--- a/libc/kernel/uapi/linux/stat.h
+++ b/libc/kernel/uapi/linux/stat.h
@@ -68,7 +68,12 @@
__u64 stx_mnt_id;
__u32 stx_dio_mem_align;
__u32 stx_dio_offset_align;
- __u64 __spare3[12];
+ __u64 stx_subvol;
+ __u32 stx_atomic_write_unit_min;
+ __u32 stx_atomic_write_unit_max;
+ __u32 stx_atomic_write_segments_max;
+ __u32 __spare1[1];
+ __u64 __spare3[9];
};
#define STATX_TYPE 0x00000001U
#define STATX_MODE 0x00000002U
@@ -86,6 +91,8 @@
#define STATX_MNT_ID 0x00001000U
#define STATX_DIOALIGN 0x00002000U
#define STATX_MNT_ID_UNIQUE 0x00004000U
+#define STATX_SUBVOL 0x00008000U
+#define STATX_WRITE_ATOMIC 0x00010000U
#define STATX__RESERVED 0x80000000U
#define STATX_ALL 0x00000fffU
#define STATX_ATTR_COMPRESSED 0x00000004
@@ -97,4 +104,5 @@
#define STATX_ATTR_MOUNT_ROOT 0x00002000
#define STATX_ATTR_VERITY 0x00100000
#define STATX_ATTR_DAX 0x00200000
+#define STATX_ATTR_WRITE_ATOMIC 0x00400000
#endif
diff --git a/libc/kernel/uapi/linux/stddef.h b/libc/kernel/uapi/linux/stddef.h
index aa3a694..dc37c6f 100644
--- a/libc/kernel/uapi/linux/stddef.h
+++ b/libc/kernel/uapi/linux/stddef.h
@@ -19,4 +19,10 @@
#ifndef __counted_by
#define __counted_by(m)
#endif
+#ifndef __counted_by_le
+#define __counted_by_le(m)
+#endif
+#ifndef __counted_by_be
+#define __counted_by_be(m)
+#endif
#endif
diff --git a/libc/kernel/uapi/linux/swab.h b/libc/kernel/uapi/linux/swab.h
index 6225a76..5d240e1 100644
--- a/libc/kernel/uapi/linux/swab.h
+++ b/libc/kernel/uapi/linux/swab.h
@@ -15,29 +15,14 @@
#define ___constant_swab64(x) ((__u64) ((((__u64) (x) & (__u64) 0x00000000000000ffULL) << 56) | (((__u64) (x) & (__u64) 0x000000000000ff00ULL) << 40) | (((__u64) (x) & (__u64) 0x0000000000ff0000ULL) << 24) | (((__u64) (x) & (__u64) 0x00000000ff000000ULL) << 8) | (((__u64) (x) & (__u64) 0x000000ff00000000ULL) >> 8) | (((__u64) (x) & (__u64) 0x0000ff0000000000ULL) >> 24) | (((__u64) (x) & (__u64) 0x00ff000000000000ULL) >> 40) | (((__u64) (x) & (__u64) 0xff00000000000000ULL) >> 56)))
#define ___constant_swahw32(x) ((__u32) ((((__u32) (x) & (__u32) 0x0000ffffUL) << 16) | (((__u32) (x) & (__u32) 0xffff0000UL) >> 16)))
#define ___constant_swahb32(x) ((__u32) ((((__u32) (x) & (__u32) 0x00ff00ffUL) << 8) | (((__u32) (x) & (__u32) 0xff00ff00UL) >> 8)))
-#ifdef __arch_swab16
-#else
-#endif
-#ifdef __arch_swab32
-#else
-#endif
-#ifdef __arch_swab64
-#elif defined(__SWAB_64_THRU_32__)
+#ifdef __SWAB_64_THRU_32__
#else
#endif
static inline __attribute__((__const__)) __u32 __fswahw32(__u32 val) {
-#ifdef __arch_swahw32
- return __arch_swahw32(val);
-#else
return ___constant_swahw32(val);
-#endif
}
static inline __attribute__((__const__)) __u32 __fswahb32(__u32 val) {
-#ifdef __arch_swahb32
- return __arch_swahb32(val);
-#else
return ___constant_swahb32(val);
-#endif
}
#define __swab16(x) (__u16) __builtin_bswap16((__u16) (x))
#define __swab32(x) (__u32) __builtin_bswap32((__u32) (x))
@@ -48,73 +33,33 @@
#define __swahw32(x) (__builtin_constant_p((__u32) (x)) ? ___constant_swahw32(x) : __fswahw32(x))
#define __swahb32(x) (__builtin_constant_p((__u32) (x)) ? ___constant_swahb32(x) : __fswahb32(x))
static __always_inline __u16 __swab16p(const __u16 * p) {
-#ifdef __arch_swab16p
- return __arch_swab16p(p);
-#else
return __swab16(* p);
-#endif
}
static __always_inline __u32 __swab32p(const __u32 * p) {
-#ifdef __arch_swab32p
- return __arch_swab32p(p);
-#else
return __swab32(* p);
-#endif
}
static __always_inline __u64 __swab64p(const __u64 * p) {
-#ifdef __arch_swab64p
- return __arch_swab64p(p);
-#else
return __swab64(* p);
-#endif
}
static inline __u32 __swahw32p(const __u32 * p) {
-#ifdef __arch_swahw32p
- return __arch_swahw32p(p);
-#else
return __swahw32(* p);
-#endif
}
static inline __u32 __swahb32p(const __u32 * p) {
-#ifdef __arch_swahb32p
- return __arch_swahb32p(p);
-#else
return __swahb32(* p);
-#endif
}
static inline void __swab16s(__u16 * p) {
-#ifdef __arch_swab16s
- __arch_swab16s(p);
-#else
* p = __swab16p(p);
-#endif
}
static __always_inline void __swab32s(__u32 * p) {
-#ifdef __arch_swab32s
- __arch_swab32s(p);
-#else
* p = __swab32p(p);
-#endif
}
static __always_inline void __swab64s(__u64 * p) {
-#ifdef __arch_swab64s
- __arch_swab64s(p);
-#else
* p = __swab64p(p);
-#endif
}
static inline void __swahw32s(__u32 * p) {
-#ifdef __arch_swahw32s
- __arch_swahw32s(p);
-#else
* p = __swahw32p(p);
-#endif
}
static inline void __swahb32s(__u32 * p) {
-#ifdef __arch_swahb32s
- __arch_swahb32s(p);
-#else
* p = __swahb32p(p);
-#endif
}
#endif
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index cb26f97..c71715c 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -71,6 +71,7 @@
#define TCP_AO_INFO 40
#define TCP_AO_GET_KEYS 41
#define TCP_AO_REPAIR 42
+#define TCP_IS_MPTCP 43
#define TCP_REPAIR_ON 1
#define TCP_REPAIR_OFF 0
#define TCP_REPAIR_OFF_NO_WP - 1
diff --git a/libc/kernel/uapi/linux/tcp_metrics.h b/libc/kernel/uapi/linux/tcp_metrics.h
index 931f50c..46ca141 100644
--- a/libc/kernel/uapi/linux/tcp_metrics.h
+++ b/libc/kernel/uapi/linux/tcp_metrics.h
@@ -4,8 +4,8 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#ifndef _LINUX_TCP_METRICS_H
-#define _LINUX_TCP_METRICS_H
+#ifndef _UAPI_LINUX_TCP_METRICS_H
+#define _UAPI_LINUX_TCP_METRICS_H
#include <linux/types.h>
#define TCP_METRICS_GENL_NAME "tcp_metrics"
#define TCP_METRICS_GENL_VERSION 0x1
@@ -21,6 +21,17 @@
};
#define TCP_METRIC_MAX (__TCP_METRIC_MAX - 1)
enum {
+ TCP_METRICS_A_METRICS_RTT = 1,
+ TCP_METRICS_A_METRICS_RTTVAR,
+ TCP_METRICS_A_METRICS_SSTHRESH,
+ TCP_METRICS_A_METRICS_CWND,
+ TCP_METRICS_A_METRICS_REODERING,
+ TCP_METRICS_A_METRICS_RTT_US,
+ TCP_METRICS_A_METRICS_RTTVAR_US,
+ __TCP_METRICS_A_METRICS_MAX
+};
+#define TCP_METRICS_A_METRICS_MAX (__TCP_METRICS_A_METRICS_MAX - 1)
+enum {
TCP_METRICS_ATTR_UNSPEC,
TCP_METRICS_ATTR_ADDR_IPV4,
TCP_METRICS_ATTR_ADDR_IPV6,
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
index d4772ee..6e4cff3 100644
--- a/libc/kernel/uapi/linux/tee.h
+++ b/libc/kernel/uapi/linux/tee.h
@@ -18,6 +18,7 @@
#define TEE_MEMREF_NULL (__u64) (- 1)
#define TEE_IMPL_ID_OPTEE 1
#define TEE_IMPL_ID_AMDTEE 2
+#define TEE_IMPL_ID_TSTEE 3
#define TEE_OPTEE_CAP_TZ (1 << 0)
struct tee_ioctl_version_data {
__u32 impl_id;
diff --git a/libc/kernel/uapi/linux/trace_mmap.h b/libc/kernel/uapi/linux/trace_mmap.h
new file mode 100644
index 0000000..e891a7e
--- /dev/null
+++ b/libc/kernel/uapi/linux/trace_mmap.h
@@ -0,0 +1,28 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _TRACE_MMAP_H_
+#define _TRACE_MMAP_H_
+#include <linux/types.h>
+struct trace_buffer_meta {
+ __u32 meta_page_size;
+ __u32 meta_struct_len;
+ __u32 subbuf_size;
+ __u32 nr_subbufs;
+ struct {
+ __u64 lost_events;
+ __u32 id;
+ __u32 read;
+ } reader;
+ __u64 flags;
+ __u64 entries;
+ __u64 overrun;
+ __u64 read;
+ __u64 Reserved1;
+ __u64 Reserved2;
+};
+#define TRACE_MMAP_IOCTL_GET_READER _IO('R', 0x20)
+#endif
diff --git a/libc/kernel/uapi/linux/uio.h b/libc/kernel/uapi/linux/uio.h
index 70d6962..3384309 100644
--- a/libc/kernel/uapi/linux/uio.h
+++ b/libc/kernel/uapi/linux/uio.h
@@ -12,6 +12,17 @@
void * iov_base;
__kernel_size_t iov_len;
};
+struct dmabuf_cmsg {
+ __u64 frag_offset;
+ __u32 frag_size;
+ __u32 frag_token;
+ __u32 dmabuf_id;
+ __u32 flags;
+};
+struct dmabuf_token {
+ __u32 token_start;
+ __u32 token_count;
+};
#define UIO_FASTIOV 8
#define UIO_MAXIOV 1024
#endif
diff --git a/libc/kernel/uapi/linux/um_timetravel.h b/libc/kernel/uapi/linux/um_timetravel.h
index 8706017..49eeb28 100644
--- a/libc/kernel/uapi/linux/um_timetravel.h
+++ b/libc/kernel/uapi/linux/um_timetravel.h
@@ -12,6 +12,15 @@
__u32 seq;
__u64 time;
};
+#define UM_TIMETRAVEL_MAX_FDS 2
+enum um_timetravel_shared_mem_fds {
+ UM_TIMETRAVEL_SHARED_MEMFD,
+ UM_TIMETRAVEL_SHARED_LOGFD,
+ UM_TIMETRAVEL_SHARED_MAX_FDS,
+};
+enum um_timetravel_start_ack {
+ UM_TIMETRAVEL_START_ACK_ID = 0xffff,
+};
enum um_timetravel_ops {
UM_TIMETRAVEL_ACK = 0,
UM_TIMETRAVEL_START = 1,
@@ -22,5 +31,36 @@
UM_TIMETRAVEL_RUN = 6,
UM_TIMETRAVEL_FREE_UNTIL = 7,
UM_TIMETRAVEL_GET_TOD = 8,
+ UM_TIMETRAVEL_BROADCAST = 9,
+};
+#define UM_TIMETRAVEL_SCHEDSHM_VERSION 2
+enum um_timetravel_schedshm_cap {
+ UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE = 0x1,
+};
+enum um_timetravel_schedshm_flags {
+ UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN = 0x1,
+};
+union um_timetravel_schedshm_client {
+ struct {
+ __u32 capa;
+ __u32 flags;
+ __u64 req_time;
+ __u64 name;
+ };
+ char reserve[128];
+};
+struct um_timetravel_schedshm {
+ union {
+ struct {
+ __u32 version;
+ __u32 len;
+ __u64 free_until;
+ __u64 current_time;
+ __u16 running_id;
+ __u16 max_clients;
+ };
+ char hdr[4096];
+ };
+ union um_timetravel_schedshm_client clients[];
};
#endif
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 6762773..c1121fb 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -119,6 +119,7 @@
#define USB_DT_DEVICE_CAPABILITY 0x10
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
#define USB_DT_WIRE_ADAPTER 0x21
+#define USB_DT_DFU_FUNCTIONAL 0x21
#define USB_DT_RPIPE 0x22
#define USB_DT_CS_RADIO_CONTROL 0x23
#define USB_DT_PIPE_USAGE 0x24
@@ -170,6 +171,7 @@
#define USB_CLASS_USB_TYPE_C_BRIDGE 0x12
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPEC 0xfe
+#define USB_SUBCLASS_DFU 0x01
#define USB_CLASS_VENDOR_SPEC 0xff
#define USB_SUBCLASS_VENDOR_SPEC 0xff
struct usb_config_descriptor {
diff --git a/libc/kernel/uapi/linux/usb/functionfs.h b/libc/kernel/uapi/linux/usb/functionfs.h
index 095e937..e838363 100644
--- a/libc/kernel/uapi/linux/usb/functionfs.h
+++ b/libc/kernel/uapi/linux/usb/functionfs.h
@@ -6,6 +6,7 @@
*/
#ifndef _UAPI__LINUX_FUNCTIONFS_H__
#define _UAPI__LINUX_FUNCTIONFS_H__
+#include <linux/const.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/usb/ch9.h>
@@ -32,6 +33,18 @@
__le16 wMaxPacketSize;
__u8 bInterval;
} __attribute__((packed));
+struct usb_dfu_functional_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bmAttributes;
+ __le16 wDetachTimeOut;
+ __le16 wTransferSize;
+ __le16 bcdDFUVersion;
+} __attribute__((packed));
+#define DFU_FUNC_ATT_CAN_DOWNLOAD _BITUL(0)
+#define DFU_FUNC_ATT_CAN_UPLOAD _BITUL(1)
+#define DFU_FUNC_ATT_MANIFEST_TOLERANT _BITUL(2)
+#define DFU_FUNC_ATT_WILL_DETACH _BITUL(3)
struct usb_functionfs_descs_head_v2 {
__le32 magic;
__le32 length;
diff --git a/libc/kernel/uapi/linux/usb/g_hid.h b/libc/kernel/uapi/linux/usb/g_hid.h
new file mode 100644
index 0000000..db50738
--- /dev/null
+++ b/libc/kernel/uapi/linux/usb/g_hid.h
@@ -0,0 +1,20 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __UAPI_LINUX_USB_G_HID_H
+#define __UAPI_LINUX_USB_G_HID_H
+#include <linux/types.h>
+#define MAX_REPORT_LENGTH 64
+struct usb_hidg_report {
+ __u8 report_id;
+ __u8 userspace_req;
+ __u16 length;
+ __u8 data[MAX_REPORT_LENGTH];
+ __u8 padding[4];
+};
+#define GADGET_HID_READ_GET_REPORT_ID _IOR('g', 0x41, __u8)
+#define GADGET_HID_WRITE_GET_REPORT _IOW('g', 0x42, struct usb_hidg_report)
+#endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 23158dc..f6ef26c 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -714,6 +714,7 @@
V4L2_MPEG_VIDEO_AV1_LEVEL_7_2 = 22,
V4L2_MPEG_VIDEO_AV1_LEVEL_7_3 = 23
};
+#define V4L2_CID_MPEG_VIDEO_AVERAGE_QP (V4L2_CID_CODEC_BASE + 657)
#define V4L2_CID_CODEC_CX2341X_BASE (V4L2_CTRL_CLASS_CODEC | 0x1000)
#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_CODEC_CX2341X_BASE + 0)
enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 9caaa47..b5a0c87 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -100,9 +100,10 @@
};
struct v4l2_subdev_routing {
__u32 which;
- __u32 num_routes;
+ __u32 len_routes;
__u64 routes;
- __u32 reserved[6];
+ __u32 num_routes;
+ __u32 reserved[11];
};
#define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1ULL << 0)
#define V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH (1ULL << 1)
diff --git a/libc/kernel/uapi/linux/vbox_vmmdev_types.h b/libc/kernel/uapi/linux/vbox_vmmdev_types.h
index 7123c02..cd0dcd9 100644
--- a/libc/kernel/uapi/linux/vbox_vmmdev_types.h
+++ b/libc/kernel/uapi/linux/vbox_vmmdev_types.h
@@ -177,6 +177,9 @@
__u32 flags;
__u16 offset_first_page;
__u16 page_count;
- __u64 pages[1];
+ union {
+ __u64 unused;
+ __DECLARE_FLEX_ARRAY(__u64, pages);
+ };
};
#endif
diff --git a/libc/kernel/uapi/linux/vdpa.h b/libc/kernel/uapi/linux/vdpa.h
index 462d579..a689f0d 100644
--- a/libc/kernel/uapi/linux/vdpa.h
+++ b/libc/kernel/uapi/linux/vdpa.h
@@ -17,6 +17,7 @@
VDPA_CMD_DEV_GET,
VDPA_CMD_DEV_CONFIG_GET,
VDPA_CMD_DEV_VSTATS_GET,
+ VDPA_CMD_DEV_ATTR_SET,
};
enum vdpa_attr {
VDPA_ATTR_UNSPEC,
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 1563f47..728b80a 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -4,8 +4,8 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#define LINUX_VERSION_CODE 395520
+#define LINUX_VERSION_CODE 396288
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
#define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 9
+#define LINUX_VERSION_PATCHLEVEL 12
#define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index ed91484..e49f5ea 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -173,6 +173,7 @@
#define V4L2_CAP_SDR_OUTPUT 0x00400000
#define V4L2_CAP_META_CAPTURE 0x00800000
#define V4L2_CAP_READWRITE 0x01000000
+#define V4L2_CAP_EDID 0x02000000
#define V4L2_CAP_STREAMING 0x04000000
#define V4L2_CAP_META_OUTPUT 0x08000000
#define V4L2_CAP_TOUCH 0x10000000
@@ -236,6 +237,8 @@
#define V4L2_PIX_FMT_RGBA1010102 v4l2_fourcc('R', 'A', '3', '0')
#define V4L2_PIX_FMT_ARGB2101010 v4l2_fourcc('A', 'R', '3', '0')
#define V4L2_PIX_FMT_BGR48_12 v4l2_fourcc('B', '3', '1', '2')
+#define V4L2_PIX_FMT_BGR48 v4l2_fourcc('B', 'G', 'R', '6')
+#define V4L2_PIX_FMT_RGB48 v4l2_fourcc('R', 'G', 'B', '6')
#define V4L2_PIX_FMT_ABGR64_12 v4l2_fourcc('B', '4', '1', '2')
#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
@@ -249,6 +252,8 @@
#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B')
#define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P')
#define V4L2_PIX_FMT_IPU3_Y10 v4l2_fourcc('i', 'p', '3', 'y')
+#define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P')
+#define V4L2_PIX_FMT_Y14P v4l2_fourcc('Y', '1', '4', 'P')
#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8')
#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ')
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V')
@@ -423,6 +428,16 @@
#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g')
#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G')
#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r')
+#define V4L2_PIX_FMT_PISP_COMP1_RGGB v4l2_fourcc('P', 'C', '1', 'R')
+#define V4L2_PIX_FMT_PISP_COMP1_GRBG v4l2_fourcc('P', 'C', '1', 'G')
+#define V4L2_PIX_FMT_PISP_COMP1_GBRG v4l2_fourcc('P', 'C', '1', 'g')
+#define V4L2_PIX_FMT_PISP_COMP1_BGGR v4l2_fourcc('P', 'C', '1', 'B')
+#define V4L2_PIX_FMT_PISP_COMP1_MONO v4l2_fourcc('P', 'C', '1', 'M')
+#define V4L2_PIX_FMT_PISP_COMP2_RGGB v4l2_fourcc('P', 'C', '2', 'R')
+#define V4L2_PIX_FMT_PISP_COMP2_GRBG v4l2_fourcc('P', 'C', '2', 'G')
+#define V4L2_PIX_FMT_PISP_COMP2_GBRG v4l2_fourcc('P', 'C', '2', 'g')
+#define V4L2_PIX_FMT_PISP_COMP2_BGGR v4l2_fourcc('P', 'C', '2', 'B')
+#define V4L2_PIX_FMT_PISP_COMP2_MONO v4l2_fourcc('P', 'C', '2', 'M')
#define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8')
#define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6')
#define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8')
@@ -442,6 +457,8 @@
#define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D')
#define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P')
#define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S')
+#define V4L2_META_FMT_RK_ISP1_EXT_PARAMS v4l2_fourcc('R', 'K', '1', 'E')
+#define V4L2_META_FMT_RPI_BE_CFG v4l2_fourcc('R', 'P', 'B', 'C')
#define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
#define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001
#define V4L2_PIX_FMT_FLAG_SET_CSC 0x00000002
@@ -464,6 +481,7 @@
#define V4L2_FMT_FLAG_CSC_YCBCR_ENC 0x0080
#define V4L2_FMT_FLAG_CSC_HSV_ENC V4L2_FMT_FLAG_CSC_YCBCR_ENC
#define V4L2_FMT_FLAG_CSC_QUANTIZATION 0x0100
+#define V4L2_FMT_FLAG_META_LINE_BASED 0x0200
enum v4l2_frmsizetypes {
V4L2_FRMSIZE_TYPE_DISCRETE = 1,
V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
@@ -563,6 +581,7 @@
#define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5)
#define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6)
#define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7)
+#define V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS (1 << 8)
struct v4l2_plane {
__u32 bytesused;
__u32 length;
@@ -936,7 +955,7 @@
struct v4l2_ctrl_hdr10_cll_info * p_hdr10_cll_info;
struct v4l2_ctrl_hdr10_mastering_display * p_hdr10_mastering_display;
void * ptr;
- };
+ } __attribute__((packed));
} __attribute__((packed));
struct v4l2_ext_controls {
union {
@@ -1311,6 +1330,9 @@
struct v4l2_meta_format {
__u32 dataformat;
__u32 buffersize;
+ __u32 width;
+ __u32 height;
+ __u32 bytesperline;
} __attribute__((packed));
struct v4l2_format {
__u32 type;
@@ -1435,6 +1457,12 @@
__u32 max_num_buffers;
__u32 reserved[5];
};
+struct v4l2_remove_buffers {
+ __u32 index;
+ __u32 count;
+ __u32 type;
+ __u32 reserved[13];
+};
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
@@ -1517,6 +1545,7 @@
#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band)
#define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info)
#define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl)
+#define VIDIOC_REMOVE_BUFS _IOWR('V', 104, struct v4l2_remove_buffers)
#define BASE_VIDIOC_PRIVATE 192
#define V4L2_PIX_FMT_HM12 V4L2_PIX_FMT_NV12_16L16
#define V4L2_PIX_FMT_SUNXI_TILED_NV12 V4L2_PIX_FMT_NV12_32L32
diff --git a/libc/kernel/uapi/linux/virtio_balloon.h b/libc/kernel/uapi/linux/virtio_balloon.h
index f37c148..3cf8807 100644
--- a/libc/kernel/uapi/linux/virtio_balloon.h
+++ b/libc/kernel/uapi/linux/virtio_balloon.h
@@ -38,8 +38,14 @@
#define VIRTIO_BALLOON_S_CACHES 7
#define VIRTIO_BALLOON_S_HTLB_PGALLOC 8
#define VIRTIO_BALLOON_S_HTLB_PGFAIL 9
-#define VIRTIO_BALLOON_S_NR 10
-#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { VIRTIO_BALLOON_S_NAMES_prefix "swap-in", VIRTIO_BALLOON_S_NAMES_prefix "swap-out", VIRTIO_BALLOON_S_NAMES_prefix "major-faults", VIRTIO_BALLOON_S_NAMES_prefix "minor-faults", VIRTIO_BALLOON_S_NAMES_prefix "free-memory", VIRTIO_BALLOON_S_NAMES_prefix "total-memory", VIRTIO_BALLOON_S_NAMES_prefix "available-memory", VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \
+#define VIRTIO_BALLOON_S_OOM_KILL 10
+#define VIRTIO_BALLOON_S_ALLOC_STALL 11
+#define VIRTIO_BALLOON_S_ASYNC_SCAN 12
+#define VIRTIO_BALLOON_S_DIRECT_SCAN 13
+#define VIRTIO_BALLOON_S_ASYNC_RECLAIM 14
+#define VIRTIO_BALLOON_S_DIRECT_RECLAIM 15
+#define VIRTIO_BALLOON_S_NR 16
+#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { VIRTIO_BALLOON_S_NAMES_prefix "swap-in", VIRTIO_BALLOON_S_NAMES_prefix "swap-out", VIRTIO_BALLOON_S_NAMES_prefix "major-faults", VIRTIO_BALLOON_S_NAMES_prefix "minor-faults", VIRTIO_BALLOON_S_NAMES_prefix "free-memory", VIRTIO_BALLOON_S_NAMES_prefix "total-memory", VIRTIO_BALLOON_S_NAMES_prefix "available-memory", VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures", VIRTIO_BALLOON_S_NAMES_prefix "oom-kills", VIRTIO_BALLOON_S_NAMES_prefix "alloc-stalls", VIRTIO_BALLOON_S_NAMES_prefix "async-scans", VIRTIO_BALLOON_S_NAMES_prefix "direct-scans", VIRTIO_BALLOON_S_NAMES_prefix "async-reclaims", VIRTIO_BALLOON_S_NAMES_prefix "direct-reclaims" \
}
#define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("")
struct virtio_balloon_stat {
diff --git a/libc/kernel/uapi/linux/virtio_bt.h b/libc/kernel/uapi/linux/virtio_bt.h
index 2b790ea..8799b66 100644
--- a/libc/kernel/uapi/linux/virtio_bt.h
+++ b/libc/kernel/uapi/linux/virtio_bt.h
@@ -13,7 +13,6 @@
#define VIRTIO_BT_F_CONFIG_V2 3
enum virtio_bt_config_type {
VIRTIO_BT_CONFIG_TYPE_PRIMARY = 0,
- VIRTIO_BT_CONFIG_TYPE_AMP = 1,
};
enum virtio_bt_config_vendor {
VIRTIO_BT_CONFIG_VENDOR_NONE = 0,
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
index c3f0fcc..bf35cf7 100644
--- a/libc/kernel/uapi/linux/virtio_gpu.h
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -195,6 +195,7 @@
#define VIRTIO_GPU_CAPSET_VIRGL 1
#define VIRTIO_GPU_CAPSET_VIRGL2 2
#define VIRTIO_GPU_CAPSET_VENUS 4
+#define VIRTIO_GPU_CAPSET_DRM 6
struct virtio_gpu_get_capset_info {
struct virtio_gpu_ctrl_hdr hdr;
__le32 capset_index;
diff --git a/libc/kernel/uapi/linux/virtio_mem.h b/libc/kernel/uapi/linux/virtio_mem.h
index e90853e..770623a 100644
--- a/libc/kernel/uapi/linux/virtio_mem.h
+++ b/libc/kernel/uapi/linux/virtio_mem.h
@@ -12,6 +12,7 @@
#include <linux/virtio_config.h>
#define VIRTIO_MEM_F_ACPI_PXM 0
#define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1
+#define VIRTIO_MEM_F_PERSISTENT_SUSPEND 2
#define VIRTIO_MEM_REQ_PLUG 0
#define VIRTIO_MEM_REQ_UNPLUG 1
#define VIRTIO_MEM_REQ_UNPLUG_ALL 2
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index 7573209..26ff301 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -33,6 +33,7 @@
#define VIRTIO_NET_F_GUEST_ANNOUNCE 21
#define VIRTIO_NET_F_MQ 22
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23
+#define VIRTIO_NET_F_DEVICE_STATS 50
#define VIRTIO_NET_F_VQ_NOTF_COAL 52
#define VIRTIO_NET_F_NOTF_COAL 53
#define VIRTIO_NET_F_GUEST_USO4 54
@@ -203,4 +204,103 @@
__le16 reserved;
struct virtio_net_ctrl_coal coal;
};
+#define VIRTIO_NET_CTRL_STATS 8
+#define VIRTIO_NET_CTRL_STATS_QUERY 0
+#define VIRTIO_NET_CTRL_STATS_GET 1
+struct virtio_net_stats_capabilities {
+#define VIRTIO_NET_STATS_TYPE_CVQ (1ULL << 32)
+#define VIRTIO_NET_STATS_TYPE_RX_BASIC (1ULL << 0)
+#define VIRTIO_NET_STATS_TYPE_RX_CSUM (1ULL << 1)
+#define VIRTIO_NET_STATS_TYPE_RX_GSO (1ULL << 2)
+#define VIRTIO_NET_STATS_TYPE_RX_SPEED (1ULL << 3)
+#define VIRTIO_NET_STATS_TYPE_TX_BASIC (1ULL << 16)
+#define VIRTIO_NET_STATS_TYPE_TX_CSUM (1ULL << 17)
+#define VIRTIO_NET_STATS_TYPE_TX_GSO (1ULL << 18)
+#define VIRTIO_NET_STATS_TYPE_TX_SPEED (1ULL << 19)
+ __le64 supported_stats_types[1];
+};
+struct virtio_net_ctrl_queue_stats {
+ struct {
+ __le16 vq_index;
+ __le16 reserved[3];
+ __le64 types_bitmap[1];
+ } stats[1];
+};
+struct virtio_net_stats_reply_hdr {
+#define VIRTIO_NET_STATS_TYPE_REPLY_CVQ 32
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_BASIC 0
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_CSUM 1
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_GSO 2
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_SPEED 3
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_BASIC 16
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_CSUM 17
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_GSO 18
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_SPEED 19
+ __u8 type;
+ __u8 reserved;
+ __le16 vq_index;
+ __le16 reserved1;
+ __le16 size;
+};
+struct virtio_net_stats_cvq {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 command_num;
+ __le64 ok_num;
+};
+struct virtio_net_stats_rx_basic {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 rx_notifications;
+ __le64 rx_packets;
+ __le64 rx_bytes;
+ __le64 rx_interrupts;
+ __le64 rx_drops;
+ __le64 rx_drop_overruns;
+};
+struct virtio_net_stats_tx_basic {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 tx_notifications;
+ __le64 tx_packets;
+ __le64 tx_bytes;
+ __le64 tx_interrupts;
+ __le64 tx_drops;
+ __le64 tx_drop_malformed;
+};
+struct virtio_net_stats_rx_csum {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 rx_csum_valid;
+ __le64 rx_needs_csum;
+ __le64 rx_csum_none;
+ __le64 rx_csum_bad;
+};
+struct virtio_net_stats_tx_csum {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 tx_csum_none;
+ __le64 tx_needs_csum;
+};
+struct virtio_net_stats_rx_gso {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 rx_gso_packets;
+ __le64 rx_gso_bytes;
+ __le64 rx_gso_packets_coalesced;
+ __le64 rx_gso_bytes_coalesced;
+};
+struct virtio_net_stats_tx_gso {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 tx_gso_packets;
+ __le64 tx_gso_bytes;
+ __le64 tx_gso_segments;
+ __le64 tx_gso_segments_bytes;
+ __le64 tx_gso_packets_noseg;
+ __le64 tx_gso_bytes_noseg;
+};
+struct virtio_net_stats_rx_speed {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 rx_ratelimit_packets;
+ __le64 rx_ratelimit_bytes;
+};
+struct virtio_net_stats_tx_speed {
+ struct virtio_net_stats_reply_hdr hdr;
+ __le64 tx_ratelimit_packets;
+ __le64 tx_ratelimit_bytes;
+};
#endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index e2f168d..9509efe 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -111,6 +111,10 @@
XFRM_POLICY_MASK = 3,
XFRM_POLICY_MAX = 3
};
+enum xfrm_sa_dir {
+ XFRM_SA_DIR_IN = 1,
+ XFRM_SA_DIR_OUT = 2
+};
enum {
XFRM_SHARE_ANY,
XFRM_SHARE_SESSION,
@@ -255,6 +259,8 @@
XFRMA_SET_MARK_MASK,
XFRMA_IF_ID,
XFRMA_MTIMER_THRESH,
+ XFRMA_SA_DIR,
+ XFRMA_NAT_KEEPALIVE_INTERVAL,
__XFRMA_MAX
#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK
#define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/zorro_ids.h b/libc/kernel/uapi/linux/zorro_ids.h
index f47c899..05239cd 100644
--- a/libc/kernel/uapi/linux/zorro_ids.h
+++ b/libc/kernel/uapi/linux/zorro_ids.h
@@ -354,6 +354,8 @@
#define ZORRO_MANUF_VMC 0x1389
#define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0)
#define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0)
+#define ZORRO_MANUF_CSLAB 0x1400
+#define ZORRO_PROD_CSLAB_WARP_1260 ZORRO_ID(CSLAB, 0x65, 0)
#define ZORRO_MANUF_INFORMATION 0x157C
#define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0)
#define ZORRO_MANUF_VORTEX 0x2017
diff --git a/libc/kernel/uapi/misc/mrvl_cn10k_dpi.h b/libc/kernel/uapi/misc/mrvl_cn10k_dpi.h
new file mode 100644
index 0000000..7d8671f
--- /dev/null
+++ b/libc/kernel/uapi/misc/mrvl_cn10k_dpi.h
@@ -0,0 +1,26 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __MRVL_CN10K_DPI_H__
+#define __MRVL_CN10K_DPI_H__
+#include <linux/types.h>
+#define DPI_MAX_ENGINES 6
+struct dpi_mps_mrrs_cfg {
+ __u16 max_read_req_sz;
+ __u16 max_payload_sz;
+ __u16 port;
+ __u16 reserved;
+};
+struct dpi_engine_cfg {
+ __u64 fifo_mask;
+ __u16 molr[DPI_MAX_ENGINES];
+ __u16 update_molr;
+ __u16 reserved;
+};
+#define DPI_MAGIC_NUM 0xB8
+#define DPI_MPS_MRRS_CFG _IOW(DPI_MAGIC_NUM, 1, struct dpi_mps_mrrs_cfg)
+#define DPI_ENGINE_CFG _IOW(DPI_MAGIC_NUM, 2, struct dpi_engine_cfg)
+#endif
diff --git a/libc/kernel/uapi/misc/pvpanic.h b/libc/kernel/uapi/misc/pvpanic.h
index bc421ae..8e1be62 100644
--- a/libc/kernel/uapi/misc/pvpanic.h
+++ b/libc/kernel/uapi/misc/pvpanic.h
@@ -6,6 +6,8 @@
*/
#ifndef __PVPANIC_H__
#define __PVPANIC_H__
-#define PVPANIC_PANICKED (1 << 0)
-#define PVPANIC_CRASH_LOADED (1 << 1)
+#include <linux/const.h>
+#define PVPANIC_PANICKED _BITUL(0)
+#define PVPANIC_CRASH_LOADED _BITUL(1)
+#define PVPANIC_SHUTDOWN _BITUL(2)
#endif
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 3dceafd..38bfb1b 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -18,7 +18,7 @@
BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED = 0x04ULL,
BNXT_RE_UCNTX_CMASK_DBR_PACING_ENABLED = 0x08ULL,
BNXT_RE_UCNTX_CMASK_POW2_DISABLED = 0x10ULL,
- BNXT_RE_COMP_MASK_UCNTX_HW_RETX_ENABLED = 0x40,
+ BNXT_RE_UCNTX_CMASK_MSN_TABLE_ENABLED = 0x40,
};
enum bnxt_re_wqe_mode {
BNXT_QPLIB_WQE_MODE_STATIC = 0x00,
@@ -27,6 +27,7 @@
};
enum {
BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT = 0x01,
+ BNXT_RE_COMP_MASK_REQ_UCNTX_VAR_WQE_SUPPORT = 0x02,
};
struct bnxt_re_uctx_req {
__aligned_u64 comp_mask;
@@ -66,10 +67,15 @@
struct bnxt_re_resize_cq_req {
__aligned_u64 cq_va;
};
+enum bnxt_re_qp_mask {
+ BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS = 0x1,
+};
struct bnxt_re_qp_req {
__aligned_u64 qpsva;
__aligned_u64 qprva;
__aligned_u64 qp_handle;
+ __aligned_u64 comp_mask;
+ __u32 sq_slots;
};
struct bnxt_re_qp_resp {
__u32 qpid;
@@ -79,8 +85,13 @@
__aligned_u64 srqva;
__aligned_u64 srq_handle;
};
+enum bnxt_re_srq_mask {
+ BNXT_RE_SRQ_TOGGLE_PAGE_SUPPORT = 0x1,
+};
struct bnxt_re_srq_resp {
__u32 srqid;
+ __u32 rsvd;
+ __aligned_u64 comp_mask;
};
enum bnxt_re_shpg_offt {
BNXT_RE_BEG_RESV_OFFT = 0x00,
diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h
index 2b30941..d4a9089 100644
--- a/libc/kernel/uapi/rdma/efa-abi.h
+++ b/libc/kernel/uapi/rdma/efa-abi.h
@@ -63,11 +63,16 @@
enum {
EFA_QP_DRIVER_TYPE_SRD = 0,
};
+enum {
+ EFA_CREATE_QP_WITH_UNSOLICITED_WRITE_RECV = 1 << 0,
+};
struct efa_ibv_create_qp {
__u32 comp_mask;
__u32 rq_ring_size;
__u32 sq_ring_size;
__u32 driver_qp_type;
+ __u16 flags;
+ __u8 reserved_90[6];
};
struct efa_ibv_create_qp_resp {
__u32 comp_mask;
@@ -95,6 +100,7 @@
EFA_QUERY_DEVICE_CAPS_CQ_WITH_SGID = 1 << 3,
EFA_QUERY_DEVICE_CAPS_DATA_POLLING_128 = 1 << 4,
EFA_QUERY_DEVICE_CAPS_RDMA_WRITE = 1 << 5,
+ EFA_QUERY_DEVICE_CAPS_UNSOLICITED_WRITE_RECV = 1 << 6,
};
struct efa_ibv_ex_query_device_resp {
__u32 comp_mask;
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index 5b0f700..b76e45c 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -68,6 +68,11 @@
__aligned_u64 cap_flags;
__aligned_u64 dwqe_mmap_key;
};
+struct hns_roce_ib_modify_qp_resp {
+ __u8 tc_mode;
+ __u8 priority;
+ __u8 reserved[6];
+};
enum {
HNS_ROCE_EXSGE_FLAGS = 1 << 0,
HNS_ROCE_RQ_INLINE_FLAGS = 1 << 1,
@@ -97,6 +102,7 @@
};
struct hns_roce_ib_create_ah_resp {
__u8 dmac[6];
- __u8 reserved[2];
+ __u8 priority;
+ __u8 tc_mode;
};
#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
index d774fba..5f5c426 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
@@ -8,8 +8,6 @@
#define IB_USER_IOCTL_CMDS_H
#define UVERBS_ID_NS_MASK 0xF000
#define UVERBS_ID_NS_SHIFT 12
-#define UVERBS_UDATA_DRIVER_DATA_NS 1
-#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_NS_SHIFT)
enum uverbs_default_objects {
UVERBS_OBJECT_DEVICE,
UVERBS_OBJECT_PD,
@@ -30,8 +28,10 @@
UVERBS_OBJECT_ASYNC_EVENT,
};
enum {
- UVERBS_ATTR_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
+ UVERBS_ID_DRIVER_NS = 1UL << UVERBS_ID_NS_SHIFT,
+ UVERBS_ATTR_UHW_IN = UVERBS_ID_DRIVER_NS,
UVERBS_ATTR_UHW_OUT,
+ UVERBS_ID_DRIVER_NS_WITH_UHW,
};
enum uverbs_methods_device {
UVERBS_METHOD_INVOKE_WRITE,
diff --git a/libc/kernel/uapi/rdma/mana-abi.h b/libc/kernel/uapi/rdma/mana-abi.h
index 73967b4..02bb061 100644
--- a/libc/kernel/uapi/rdma/mana-abi.h
+++ b/libc/kernel/uapi/rdma/mana-abi.h
@@ -9,8 +9,18 @@
#include <linux/types.h>
#include <rdma/ib_user_ioctl_verbs.h>
#define MANA_IB_UVERBS_ABI_VERSION 1
+enum mana_ib_create_cq_flags {
+ MANA_IB_CREATE_RNIC_CQ = 1 << 0,
+};
struct mana_ib_create_cq {
__aligned_u64 buf_addr;
+ __u16 flags;
+ __u16 reserved0;
+ __u32 reserved1;
+};
+struct mana_ib_create_cq_resp {
+ __u32 cqid;
+ __u32 reserved;
};
struct mana_ib_create_qp {
__aligned_u64 sq_buf_addr;
@@ -23,6 +33,13 @@
__u32 tx_vp_offset;
__u32 reserved;
};
+struct mana_ib_create_rc_qp {
+ __aligned_u64 queue_buf[4];
+ __u32 queue_size[4];
+};
+struct mana_ib_create_rc_qp_resp {
+ __u32 queue_id[4];
+};
struct mana_ib_create_wq {
__aligned_u64 wq_buf_addr;
__u32 wq_buf_size;
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 69d5250..2e61c71 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -201,6 +201,12 @@
enum mlx5_ib_device_query_context_attrs {
MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX = (1U << UVERBS_ID_NS_SHIFT),
};
+enum mlx5_ib_create_cq_attrs {
+ MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX = UVERBS_ID_DRIVER_NS_WITH_UHW,
+};
+enum mlx5_ib_reg_dmabuf_mr_attrs {
+ MLX5_IB_ATTR_REG_DMABUF_MR_ACCESS_FLAGS = (1U << UVERBS_ID_NS_SHIFT),
+};
#define MLX5_IB_DW_MATCH_PARAM 0xA0
struct mlx5_ib_match_params {
__u32 match_params[MLX5_IB_DW_MATCH_PARAM];
@@ -258,9 +264,13 @@
};
enum mlx5_ib_device_methods {
MLX5_IB_METHOD_QUERY_PORT = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH,
};
enum mlx5_ib_query_port_attrs {
MLX5_IB_ATTR_QUERY_PORT_PORT_NUM = (1U << UVERBS_ID_NS_SHIFT),
MLX5_IB_ATTR_QUERY_PORT,
};
+enum mlx5_ib_get_data_direct_sysfs_path_attrs {
+ MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH = (1U << UVERBS_ID_NS_SHIFT),
+};
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index f087ee8..3fe3c82 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -23,6 +23,9 @@
MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2 = 0x2,
MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL = 0x3,
};
+enum mlx5_ib_uapi_reg_dmabuf_flags {
+ MLX5_IB_UAPI_REG_DMABUF_ACCESS_DATA_DIRECT = 1 << 0,
+};
struct mlx5_ib_uapi_devx_async_cmd_hdr {
__aligned_u64 wr_id;
__u8 out_data[];
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index 2fe8c30..137b68f 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -17,6 +17,7 @@
enum {
RDMA_NL_GROUP_IWPM = 2,
RDMA_NL_GROUP_LS,
+ RDMA_NL_GROUP_NOTIFY,
RDMA_NL_NUM_GROUPS
};
#define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10)
@@ -199,6 +200,9 @@
RDMA_NLDEV_CMD_RES_SRQ_GET,
RDMA_NLDEV_CMD_STAT_GET_STATUS,
RDMA_NLDEV_CMD_RES_SRQ_GET_RAW,
+ RDMA_NLDEV_CMD_NEWDEV,
+ RDMA_NLDEV_CMD_DELDEV,
+ RDMA_NLDEV_CMD_MONITOR,
RDMA_NLDEV_NUM_OPS
};
enum rdma_nldev_print_type {
@@ -304,6 +308,13 @@
RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX,
RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC,
RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE,
+ RDMA_NLDEV_ATTR_DRIVER_DETAILS,
+ RDMA_NLDEV_ATTR_RES_SUBTYPE,
+ RDMA_NLDEV_ATTR_DEV_TYPE,
+ RDMA_NLDEV_ATTR_PARENT_NAME,
+ RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE,
+ RDMA_NLDEV_ATTR_EVENT_TYPE,
+ RDMA_NLDEV_SYS_ATTR_MONITOR_MODE,
RDMA_NLDEV_ATTR_MAX
};
enum rdma_nl_counter_mode {
@@ -316,4 +327,17 @@
RDMA_COUNTER_MASK_QP_TYPE = 1,
RDMA_COUNTER_MASK_PID = 1 << 1,
};
+enum rdma_nl_dev_type {
+ RDMA_DEVICE_TYPE_SMI = 1,
+};
+enum rdma_nl_name_assign_type {
+ RDMA_NAME_ASSIGN_TYPE_UNKNOWN = 0,
+ RDMA_NAME_ASSIGN_TYPE_USER = 1,
+};
+enum rdma_nl_notify_event_type {
+ RDMA_REGISTER_EVENT,
+ RDMA_UNREGISTER_EVENT,
+ RDMA_NETDEV_ATTACH_EVENT,
+ RDMA_NETDEV_DETACH_EVENT,
+};
#endif
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
index d98e8fa..fe3094e 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -144,7 +144,7 @@
};
struct mpi3mr_bsg_in_hdb_status {
__u8 num_hdb_types;
- __u8 rsvd1;
+ __u8 element_trigger_format;
__u16 rsvd2;
__u32 rsvd3;
struct mpi3mr_hdb_entry entry[1];
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index 7918528..83b38f1 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -7,7 +7,7 @@
#ifndef _UAPI__SOUND_ASEQUENCER_H
#define _UAPI__SOUND_ASEQUENCER_H
#include <sound/asound.h>
-#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 3)
+#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 4)
#define SNDRV_SEQ_EVENT_SYSTEM 0
#define SNDRV_SEQ_EVENT_RESULT 1
#define SNDRV_SEQ_EVENT_NOTE 5
@@ -298,6 +298,7 @@
#define SNDRV_SEQ_PORT_FLG_GIVEN_PORT (1 << 0)
#define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1 << 1)
#define SNDRV_SEQ_PORT_FLG_TIME_REAL (1 << 2)
+#define SNDRV_SEQ_PORT_FLG_IS_MIDI1 (1 << 3)
#define SNDRV_SEQ_PORT_DIR_UNKNOWN 0
#define SNDRV_SEQ_PORT_DIR_INPUT 1
#define SNDRV_SEQ_PORT_DIR_OUTPUT 2
@@ -343,7 +344,8 @@
int ppq;
unsigned int skew_value;
unsigned int skew_base;
- char reserved[24];
+ unsigned short tempo_base;
+ char reserved[22];
};
#define SNDRV_SEQ_TIMER_ALSA 0
#define SNDRV_SEQ_TIMER_MIDI_CLOCK 1
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index 8718b46..22e750d 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -53,7 +53,7 @@
#define SND_SOC_TPLG_MAGIC 0x41536F43
#define SND_SOC_TPLG_NUM_TEXTS 16
#define SND_SOC_TPLG_ABI_VERSION 0x5
-#define SND_SOC_TPLG_ABI_VERSION_MIN 0x4
+#define SND_SOC_TPLG_ABI_VERSION_MIN 0x5
#define SND_SOC_TPLG_TLV_SIZE 32
#define SND_SOC_TPLG_TYPE_MIXER 1
#define SND_SOC_TPLG_TYPE_BYTES 2
@@ -336,48 +336,4 @@
__le32 flags;
struct snd_soc_tplg_private priv;
} __attribute__((packed));
-struct snd_soc_tplg_manifest_v4 {
- __le32 size;
- __le32 control_elems;
- __le32 widget_elems;
- __le32 graph_elems;
- __le32 pcm_elems;
- __le32 dai_link_elems;
- struct snd_soc_tplg_private priv;
-} __attribute__((__packed__));
-struct snd_soc_tplg_stream_caps_v4 {
- __le32 size;
- char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- __le64 formats;
- __le32 rates;
- __le32 rate_min;
- __le32 rate_max;
- __le32 channels_min;
- __le32 channels_max;
- __le32 periods_min;
- __le32 periods_max;
- __le32 period_size_min;
- __le32 period_size_max;
- __le32 buffer_size_min;
- __le32 buffer_size_max;
-} __attribute__((__packed__));
-struct snd_soc_tplg_pcm_v4 {
- __le32 size;
- char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- __le32 pcm_id;
- __le32 dai_id;
- __le32 playback;
- __le32 capture;
- __le32 compress;
- struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX];
- __le32 num_streams;
- struct snd_soc_tplg_stream_caps_v4 caps[2];
-} __attribute__((__packed__));
-struct snd_soc_tplg_link_config_v4 {
- __le32 size;
- __le32 id;
- struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX];
- __le32 num_streams;
-} __attribute__((__packed__));
#endif
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index b608ed5..cbebef3 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -92,7 +92,7 @@
#define SNDRV_HWDEP_IOCTL_INFO _IOR('H', 0x01, struct snd_hwdep_info)
#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 17)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 18)
typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t;
enum {
@@ -263,7 +263,7 @@
unsigned char id[16];
unsigned short id16[8];
unsigned int id32[4];
-};
+} __attribute__((deprecated));
struct snd_pcm_info {
unsigned int device;
unsigned int subdevice;
@@ -276,7 +276,7 @@
int dev_subclass;
unsigned int subdevices_count;
unsigned int subdevices_avail;
- union snd_pcm_sync_id sync;
+ unsigned char pad1[16];
unsigned char reserved[64];
};
typedef int snd_pcm_hw_param_t;
@@ -324,7 +324,8 @@
unsigned int rate_num;
unsigned int rate_den;
snd_pcm_uframes_t fifo_size;
- unsigned char reserved[64];
+ unsigned char sync[16];
+ unsigned char reserved[48];
};
enum {
SNDRV_PCM_TSTAMP_NONE = 0,
@@ -675,7 +676,7 @@
#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
#define SNDRV_UMP_IOCTL_ENDPOINT_INFO _IOR('W', 0x40, struct snd_ump_endpoint_info)
#define SNDRV_UMP_IOCTL_BLOCK_INFO _IOR('W', 0x41, struct snd_ump_block_info)
-#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
+#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
enum {
SNDRV_TIMER_CLASS_NONE = - 1,
SNDRV_TIMER_CLASS_SLAVE = 0,
@@ -695,6 +696,7 @@
#define SNDRV_TIMER_GLOBAL_RTC 1
#define SNDRV_TIMER_GLOBAL_HPET 2
#define SNDRV_TIMER_GLOBAL_HRTIMER 3
+#define SNDRV_TIMER_GLOBAL_UDRIVEN 4
#define SNDRV_TIMER_FLG_SLAVE (1 << 0)
struct snd_timer_id {
int dev_class;
@@ -761,6 +763,12 @@
unsigned int queue;
unsigned char reserved[64];
};
+struct snd_timer_uinfo {
+ __u64 resolution;
+ int fd;
+ unsigned int id;
+ unsigned char reserved[16];
+};
#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
#define SNDRV_TIMER_IOCTL_TREAD_OLD _IOW('T', 0x02, int)
@@ -776,6 +784,8 @@
#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
#define SNDRV_TIMER_IOCTL_TREAD64 _IOW('T', 0xa4, int)
+#define SNDRV_TIMER_IOCTL_CREATE _IOWR('T', 0xa5, struct snd_timer_uinfo)
+#define SNDRV_TIMER_IOCTL_TRIGGER _IO('T', 0xa6)
#if __BITS_PER_LONG == 64
#define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD
#else
diff --git a/libc/kernel/uapi/sound/skl-tplg-interface.h b/libc/kernel/uapi/sound/skl-tplg-interface.h
index c620295..d613c7f 100644
--- a/libc/kernel/uapi/sound/skl-tplg-interface.h
+++ b/libc/kernel/uapi/sound/skl-tplg-interface.h
@@ -109,66 +109,4 @@
SKL_TYPE_TUPLE,
SKL_TYPE_DATA
};
-struct skl_dfw_v4_module_pin {
- __u16 module_id;
- __u16 instance_id;
-} __attribute__((__packed__));
-struct skl_dfw_v4_module_fmt {
- __u32 channels;
- __u32 freq;
- __u32 bit_depth;
- __u32 valid_bit_depth;
- __u32 ch_cfg;
- __u32 interleaving_style;
- __u32 sample_type;
- __u32 ch_map;
-} __attribute__((__packed__));
-struct skl_dfw_v4_module_caps {
- __u32 set_params : 2;
- __u32 rsvd : 30;
- __u32 param_id;
- __u32 caps_size;
- __u32 caps[HDA_SST_CFG_MAX];
-} __attribute__((__packed__));
-struct skl_dfw_v4_pipe {
- __u8 pipe_id;
- __u8 pipe_priority;
- __u16 conn_type : 4;
- __u16 rsvd : 4;
- __u16 memory_pages : 8;
-} __attribute__((__packed__));
-struct skl_dfw_v4_module {
- char uuid[SKL_UUID_STR_SZ];
- __u16 module_id;
- __u16 instance_id;
- __u32 max_mcps;
- __u32 mem_pages;
- __u32 obs;
- __u32 ibs;
- __u32 vbus_id;
- __u32 max_in_queue : 8;
- __u32 max_out_queue : 8;
- __u32 time_slot : 8;
- __u32 core_id : 4;
- __u32 rsvd1 : 4;
- __u32 module_type : 8;
- __u32 conn_type : 4;
- __u32 dev_type : 4;
- __u32 hw_conn_type : 4;
- __u32 rsvd2 : 12;
- __u32 params_fixup : 8;
- __u32 converter : 8;
- __u32 input_pin_type : 1;
- __u32 output_pin_type : 1;
- __u32 is_dynamic_in_pin : 1;
- __u32 is_dynamic_out_pin : 1;
- __u32 is_loadable : 1;
- __u32 rsvd3 : 11;
- struct skl_dfw_v4_pipe pipe;
- struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
- struct skl_dfw_v4_module_fmt out_fmt[MAX_OUT_QUEUE];
- struct skl_dfw_v4_module_pin in_pin[MAX_IN_QUEUE];
- struct skl_dfw_v4_module_pin out_pin[MAX_OUT_QUEUE];
- struct skl_dfw_v4_module_caps caps;
-} __attribute__((__packed__));
#endif
diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h
index fe1fe47..ed66131 100644
--- a/libc/kernel/uapi/sound/sof/abi.h
+++ b/libc/kernel/uapi/sound/sof/abi.h
@@ -9,7 +9,7 @@
#include <linux/types.h>
#define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 23
-#define SOF_ABI_PATCH 0
+#define SOF_ABI_PATCH 1
#define SOF_ABI_MAJOR_SHIFT 24
#define SOF_ABI_MAJOR_MASK 0xff
#define SOF_ABI_MINOR_SHIFT 12
diff --git a/libc/kernel/uapi/xen/privcmd.h b/libc/kernel/uapi/xen/privcmd.h
index 0597247..0874e4b 100644
--- a/libc/kernel/uapi/xen/privcmd.h
+++ b/libc/kernel/uapi/xen/privcmd.h
@@ -77,6 +77,10 @@
domid_t dom;
__u8 pad[2];
};
+struct privcmd_pcidev_get_gsi {
+ __u32 sbdf;
+ __u32 gsi;
+};
#define IOCTL_PRIVCMD_HYPERCALL _IOC(_IOC_NONE, 'P', 0, sizeof(struct privcmd_hypercall))
#define IOCTL_PRIVCMD_MMAP _IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
#define IOCTL_PRIVCMD_MMAPBATCH _IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
@@ -86,4 +90,5 @@
#define IOCTL_PRIVCMD_MMAP_RESOURCE _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))
#define IOCTL_PRIVCMD_IRQFD _IOW('P', 8, struct privcmd_irqfd)
#define IOCTL_PRIVCMD_IOEVENTFD _IOW('P', 9, struct privcmd_ioeventfd)
+#define IOCTL_PRIVCMD_PCIDEV_GET_GSI _IOC(_IOC_NONE, 'P', 10, sizeof(struct privcmd_pcidev_get_gsi))
#endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 2c8ec07..86dcc39 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -8,29 +8,29 @@
__atomic_swap; # arm
__b64_ntop;
__b64_pton;
- __cmsg_nxthdr; # introduced=21
- __connect; # arm x86 introduced=21
- __ctype_get_mb_cur_max; # introduced=21
+ __cmsg_nxthdr;
+ __connect; # arm x86
+ __ctype_get_mb_cur_max;
__cxa_atexit;
__cxa_finalize;
__cxa_thread_atexit_impl; # introduced=23
__dn_comp;
__dn_count_labels;
__dn_skipname;
- __epoll_pwait; # arm x86 introduced=21
+ __epoll_pwait; # arm x86
__errno;
- __exit; # arm x86 introduced=21
- __fadvise64; # x86 introduced=21
+ __exit; # arm x86
+ __fadvise64; # x86
__fbufsize; # introduced=23
__fcntl64; # arm x86
- __FD_CLR_chk; # introduced=21
- __FD_ISSET_chk; # introduced=21
- __FD_SET_chk; # introduced=21
- __fgets_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __FD_CLR_chk;
+ __FD_ISSET_chk;
+ __FD_SET_chk;
+ __fgets_chk;
__flbf; # introduced=23
__fp_nquery;
__fp_query;
- __fpclassify; # introduced=21
+ __fpclassify;
__fpclassifyd;
__fpclassifyf;
__fpclassifyl;
@@ -41,9 +41,9 @@
__fstatfs64; # arm x86
__fwritable; # introduced=23
__get_h_errno;
- __getcpu; # arm x86 introduced-arm=12 introduced-x86=12
+ __getcpu; # arm x86
__getcwd; # arm x86
- __getpid; # arm x86 introduced=21
+ __getpid; # arm x86
__getpriority; # arm x86
__gnu_basename; # introduced=23
__gnu_strerror_r; # introduced=23
@@ -55,24 +55,24 @@
__isinf;
__isinff;
__isinfl;
- __isnan; # introduced=21
- __isnanf; # introduced=21
+ __isnan;
+ __isnanf;
__isnanl;
__isnormal;
__isnormalf;
__isnormall;
__isthreaded; # arm x86 var
- __libc_current_sigrtmax; # introduced=21
- __libc_current_sigrtmin; # introduced=21
+ __libc_current_sigrtmax;
+ __libc_current_sigrtmin;
__libc_init;
__llseek; # arm x86
__loc_aton;
__loc_ntoa;
__memchr_chk; # introduced=23
- __memcpy_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __memmove_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __memcpy_chk;
+ __memmove_chk;
__memrchr_chk; # introduced=23
- __memset_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __memset_chk;
__mmap2; # arm x86
__ns_format_ttl; # arm x86 introduced=22
__ns_get16; # arm x86 introduced=22
@@ -96,9 +96,9 @@
__ns_skiprr; # arm x86 introduced=22
__ns_sprintrr; # arm x86 introduced=22
__ns_sprintrrf; # arm x86 introduced=22
- __open_2; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __open_2;
__openat; # arm x86
- __openat_2; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __openat_2;
__p_cdname;
__p_cdnname;
__p_class;
@@ -113,23 +113,23 @@
__p_type;
__p_type_syms; # var
__poll_chk; # introduced=23
- __ppoll; # arm x86 introduced=21
+ __ppoll; # arm x86
__ppoll_chk; # introduced=23
__ppoll64_chk; # introduced=28
__pread64_chk; # introduced=23
__pread_chk; # introduced=23
__progname; # var
- __pselect6; # arm x86 introduced=21
+ __pselect6; # arm x86
__pthread_cleanup_pop;
__pthread_cleanup_push;
__ptrace; # arm x86
__putlong;
__putshort;
- __read_chk; # introduced=21
+ __read_chk;
__readlink_chk; # introduced=23
__readlinkat_chk; # introduced=23
__reboot; # arm x86
- __recvfrom_chk; # introduced=21
+ __recvfrom_chk;
__register_atfork; # introduced=23
__res_close;
__res_dnok;
@@ -152,83 +152,83 @@
__res_send_setqhook;
__res_send_setrhook;
__rt_sigaction; # arm x86
- __rt_sigpending; # arm x86 introduced=21
+ __rt_sigpending; # arm x86
__rt_sigprocmask; # arm x86
- __rt_sigsuspend; # arm x86 introduced=21
+ __rt_sigsuspend; # arm x86
__rt_sigtimedwait; # arm x86
- __sched_cpualloc; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- __sched_cpucount; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- __sched_cpufree; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- __sched_getaffinity; # arm x86 introduced=12
+ __sched_cpualloc;
+ __sched_cpucount;
+ __sched_cpufree;
+ __sched_getaffinity; # arm x86
__set_thread_area; # x86
- __set_tid_address; # arm x86 introduced=21
+ __set_tid_address; # arm x86
__set_tls; # arm
__sF; # var
- __sigaction; # arm x86 introduced=21
- __snprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __socket; # arm x86 introduced=21
- __sprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __sigaction; # arm x86
+ __snprintf_chk;
+ __socket; # arm x86
+ __sprintf_chk;
__stack_chk_fail;
__stack_chk_guard; # var
__statfs64; # arm x86
- __stpcpy_chk; # introduced=21
- __stpncpy_chk; # introduced=21
- __stpncpy_chk2; # introduced=21
- __strcat_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strchr_chk; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- __strcpy_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strlcat_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strlcpy_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strlen_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strncat_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strncpy_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __strncpy_chk2; # introduced=21
- __strrchr_chk; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ __stpcpy_chk;
+ __stpncpy_chk;
+ __stpncpy_chk2;
+ __strcat_chk;
+ __strchr_chk;
+ __strcpy_chk;
+ __strlcat_chk;
+ __strlcpy_chk;
+ __strlen_chk;
+ __strncat_chk;
+ __strncpy_chk;
+ __strncpy_chk2;
+ __strrchr_chk;
__sym_ntop;
__sym_ntos;
__sym_ston;
__system_property_area_serial; # introduced=23
__system_property_find;
__system_property_find_nth;
- __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ __system_property_foreach;
__system_property_get;
__system_property_read;
- __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ __system_property_serial;
+ __system_property_set;
__timer_create; # arm x86
__timer_delete; # arm x86
__timer_getoverrun; # arm x86
__timer_gettime; # arm x86
__timer_settime; # arm x86
- __umask_chk; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- __vsnprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- __vsprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ __umask_chk;
+ __vsnprintf_chk;
+ __vsprintf_chk;
__waitid; # arm x86
_ctype_; # var
- _Exit; # introduced=21
+ _Exit;
_exit;
_flushlbf; # introduced=23
_getlong;
_getshort;
_longjmp;
- _resolv_delete_cache_for_net; # introduced=21
- _resolv_flush_cache_for_net; # introduced=21
- _resolv_set_nameservers_for_net; # introduced=21
+ _resolv_delete_cache_for_net;
+ _resolv_flush_cache_for_net;
+ _resolv_set_nameservers_for_net;
_setjmp;
- _tolower; # introduced=21
+ _tolower;
_tolower_tab_; # arm x86 var
- _toupper; # introduced=21
+ _toupper;
_toupper_tab_; # arm x86 var
abort;
- abs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ abs;
accept;
- accept4; # introduced=21
+ accept4;
access;
acct;
alarm;
alphasort;
- alphasort64; # introduced=21
- android_set_abort_message; # introduced=21
+ alphasort64;
+ android_set_abort_message;
arc4random;
arc4random_buf;
arc4random_uniform;
@@ -237,8 +237,8 @@
asctime64_r; # arm x86
asctime_r;
asprintf;
- at_quick_exit; # introduced=21
- atof; # introduced=21
+ at_quick_exit;
+ atof;
atoi;
atol;
atoll;
@@ -249,18 +249,18 @@
brk;
bsearch;
btowc;
- c16rtomb; # introduced=21
- c32rtomb; # introduced=21
+ c16rtomb;
+ c32rtomb;
cacheflush; # arm
calloc;
capget;
capset;
- cfgetispeed; # introduced=21
- cfgetospeed; # introduced=21
- cfmakeraw; # introduced=21
- cfsetispeed; # introduced=21
- cfsetospeed; # introduced=21
- cfsetspeed; # introduced=21
+ cfgetispeed;
+ cfgetospeed;
+ cfmakeraw;
+ cfsetispeed;
+ cfsetospeed;
+ cfsetspeed;
chdir;
chmod;
chown;
@@ -274,13 +274,13 @@
clock_gettime;
clock_nanosleep;
clock_settime;
- clone; # introduced-arm=9 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ clone;
close;
closedir;
closelog;
connect;
creat;
- creat64; # introduced=21
+ creat64;
ctime;
ctime64; # arm x86
ctime64_r; # arm x86
@@ -294,20 +294,20 @@
dirname_r; # arm x86
div;
dn_expand;
- dprintf; # introduced=21
+ dprintf;
drand48;
dup;
dup2;
- dup3; # introduced=21
- duplocale; # introduced=21
- endmntent; # introduced=21
+ dup3;
+ duplocale;
+ endmntent;
endservent;
endutent;
environ; # var
epoll_create;
- epoll_create1; # introduced=21
+ epoll_create1;
epoll_ctl;
- epoll_pwait; # introduced=21
+ epoll_pwait;
epoll_wait;
erand48;
err;
@@ -317,10 +317,10 @@
error_one_per_line; # var introduced=23
error_print_progname; # var introduced=23
errx;
- ether_aton; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- ether_aton_r; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- ether_ntoa; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- ether_ntoa_r; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ ether_aton;
+ ether_aton_r;
+ ether_ntoa;
+ ether_ntoa_r;
eventfd;
eventfd_read;
eventfd_write;
@@ -330,11 +330,11 @@
execv;
execve;
execvp;
- execvpe; # introduced=21
+ execvpe;
exit;
faccessat;
- fallocate; # introduced=21
- fallocate64; # introduced=21
+ fallocate;
+ fallocate64;
fchdir;
fchmod;
fchmodat;
@@ -351,7 +351,7 @@
ferror;
ferror_unlocked; # introduced=23
fflush;
- ffs; # introduced-arm=9 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ ffs;
fgetc;
fgetln;
fgetpos;
@@ -378,7 +378,7 @@
fread;
free;
freeaddrinfo;
- freelocale; # introduced=21
+ freelocale;
fremovexattr;
freopen;
fscanf;
@@ -387,30 +387,30 @@
fsetpos;
fsetxattr;
fstat;
- fstat64; # introduced=21
+ fstat64;
fstatat;
- fstatat64; # introduced=21
+ fstatat64;
fstatfs;
- fstatfs64; # introduced=21
- fstatvfs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- fstatvfs64; # introduced=21
+ fstatfs64;
+ fstatvfs;
+ fstatvfs64;
fsync;
ftell;
ftello;
ftok;
ftruncate;
- ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ ftruncate64;
ftrylockfile;
- fts_children; # introduced=21
- fts_close; # introduced=21
- fts_open; # introduced=21
- fts_read; # introduced=21
- fts_set; # introduced=21
- ftw; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- ftw64; # introduced=21
+ fts_children;
+ fts_close;
+ fts_open;
+ fts_read;
+ fts_set;
+ ftw;
+ ftw64;
funlockfile;
funopen;
- futimens; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ futimens;
fwide;
fwprintf;
fwrite;
@@ -421,13 +421,13 @@
get_nprocs_conf; # introduced=23
get_phys_pages; # introduced=23
getaddrinfo;
- getauxval; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ getauxval;
getc;
getc_unlocked;
getchar;
getchar_unlocked;
getcwd;
- getdelim; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ getdelim;
getegid;
getenv;
geteuid;
@@ -445,41 +445,41 @@
gethostent;
gethostname;
getitimer;
- getline; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ getline;
getlogin;
getmntent;
- getmntent_r; # introduced=21
+ getmntent_r;
getnameinfo;
getnetbyaddr;
getnetbyname;
getopt;
getopt_long;
getopt_long_only;
- getpagesize; # introduced=21
+ getpagesize;
getpeername;
getpgid;
getpgrp;
getpid;
getppid;
getpriority;
- getprogname; # introduced=21
+ getprogname;
getprotobyname;
getprotobynumber;
getpt;
getpwnam;
- getpwnam_r; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ getpwnam_r;
getpwuid;
- getpwuid_r; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ getpwuid_r;
getresgid;
getresuid;
getrlimit;
- getrlimit64; # introduced=21
+ getrlimit64;
getrusage;
gets;
getservbyname;
getservbyport;
getservent;
- getsid; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ getsid;
getsockname;
getsockopt;
gettid;
@@ -493,21 +493,21 @@
gmtime64; # arm x86
gmtime64_r; # arm x86
gmtime_r;
- grantpt; # introduced=21
+ grantpt;
herror;
hstrerror;
- htonl; # introduced=21
- htons; # introduced=21
+ htonl;
+ htons;
if_indextoname;
if_nametoindex;
- imaxabs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- imaxdiv; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ imaxabs;
+ imaxdiv;
inet_addr;
inet_aton;
- inet_lnaof; # introduced=21
- inet_makeaddr; # introduced=21
- inet_netof; # introduced=21
- inet_network; # introduced=21
+ inet_lnaof;
+ inet_makeaddr;
+ inet_netof;
+ inet_network;
inet_nsap_addr;
inet_nsap_ntoa;
inet_ntoa;
@@ -515,96 +515,96 @@
inet_pton;
init_module;
initgroups;
- initstate; # introduced=21
+ initstate;
inotify_add_watch;
inotify_init;
- inotify_init1; # introduced=21
+ inotify_init1;
inotify_rm_watch;
- insque; # introduced=21
+ insque;
ioctl;
isalnum;
- isalnum_l; # introduced=21
+ isalnum_l;
isalpha;
- isalpha_l; # introduced=21
+ isalpha_l;
isascii;
isatty;
isblank;
- isblank_l; # introduced=21
+ isblank_l;
iscntrl;
- iscntrl_l; # introduced=21
+ iscntrl_l;
isdigit;
- isdigit_l; # introduced=21
- isfinite; # introduced=21
- isfinitef; # introduced=21
- isfinitel; # introduced=21
+ isdigit_l;
+ isfinite;
+ isfinitef;
+ isfinitel;
isgraph;
- isgraph_l; # introduced=21
- isinf; # introduced=21
- isinff; # introduced=21
- isinfl; # introduced=21
+ isgraph_l;
+ isinf;
+ isinff;
+ isinfl;
islower;
- islower_l; # introduced=21
+ islower_l;
isnan;
isnanf;
- isnanl; # introduced=21
- isnormal; # introduced=21
- isnormalf; # introduced=21
- isnormall; # introduced=21
+ isnanl;
+ isnormal;
+ isnormalf;
+ isnormall;
isprint;
- isprint_l; # introduced=21
+ isprint_l;
ispunct;
- ispunct_l; # introduced=21
+ ispunct_l;
isspace;
- isspace_l; # introduced=21
+ isspace_l;
isupper;
- isupper_l; # introduced=21
+ isupper_l;
iswalnum;
- iswalnum_l; # introduced=21
+ iswalnum_l;
iswalpha;
- iswalpha_l; # introduced=21
- iswblank; # introduced=21
- iswblank_l; # introduced=21
+ iswalpha_l;
+ iswblank;
+ iswblank_l;
iswcntrl;
- iswcntrl_l; # introduced=21
+ iswcntrl_l;
iswctype;
- iswctype_l; # introduced=21
+ iswctype_l;
iswdigit;
- iswdigit_l; # introduced=21
+ iswdigit_l;
iswgraph;
- iswgraph_l; # introduced=21
+ iswgraph_l;
iswlower;
- iswlower_l; # introduced=21
+ iswlower_l;
iswprint;
- iswprint_l; # introduced=21
+ iswprint_l;
iswpunct;
- iswpunct_l; # introduced=21
+ iswpunct_l;
iswspace;
- iswspace_l; # introduced=21
+ iswspace_l;
iswupper;
- iswupper_l; # introduced=21
+ iswupper_l;
iswxdigit;
- iswxdigit_l; # introduced=21
+ iswxdigit_l;
isxdigit;
- isxdigit_l; # introduced=21
+ isxdigit_l;
jrand48;
kill;
killpg;
klogctl;
- labs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ labs;
lchown;
lcong48; # introduced=23
ldexp;
ldiv;
- lfind; # introduced=21
+ lfind;
lgetxattr;
link;
- linkat; # introduced=21
+ linkat;
listen;
listxattr;
- llabs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ llabs;
lldiv;
llistxattr;
- localeconv; # introduced=21
+ localeconv;
localtime;
localtime64; # arm x86
localtime64_r; # arm x86
@@ -613,26 +613,26 @@
longjmp;
lrand48;
lremovexattr;
- lsearch; # introduced=21
+ lsearch;
lseek;
lseek64;
lsetxattr;
lstat;
- lstat64; # introduced=21
+ lstat64;
madvise;
mallinfo;
malloc;
malloc_info; # introduced=23
- malloc_usable_size; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ malloc_usable_size;
mbrlen;
- mbrtoc16; # introduced=21
- mbrtoc32; # introduced=21
+ mbrtoc16;
+ mbrtoc32;
mbrtowc;
mbsinit;
- mbsnrtowcs; # introduced=21
+ mbsnrtowcs;
mbsrtowcs;
- mbstowcs; # introduced=21
- mbtowc; # introduced=21
+ mbstowcs;
+ mbtowc;
memalign;
memccpy;
memchr;
@@ -647,37 +647,37 @@
mkdir;
mkdirat;
mkdtemp;
- mkfifo; # introduced=21
+ mkfifo;
mkfifoat; # introduced=23
mknod;
- mknodat; # introduced=21
+ mknodat;
mkostemp; # introduced=23
mkostemp64; # introduced=23
mkostemps; # introduced=23
mkostemps64; # introduced=23
mkstemp;
- mkstemp64; # introduced=21
+ mkstemp64;
mkstemps;
mkstemps64; # introduced=23
mktemp;
mktime;
mktime64; # arm x86
mlock;
- mlockall; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ mlockall;
mmap;
- mmap64; # introduced=21
+ mmap64;
mount;
mprotect;
mrand48;
mremap;
msync;
munlock;
- munlockall; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
+ munlockall;
munmap;
nanosleep;
- newlocale; # introduced=21
- nftw; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- nftw64; # introduced=21
+ newlocale;
+ nftw;
+ nftw64;
nice;
nrand48;
ns_format_ttl; # arm64 x86_64 riscv64 introduced=22
@@ -703,14 +703,14 @@
ns_sprintrr; # arm64 x86_64 riscv64 introduced=22
ns_sprintrrf; # arm64 x86_64 riscv64 introduced=22
nsdispatch;
- ntohl; # introduced=21
- ntohs; # introduced=21
+ ntohl;
+ ntohs;
open;
- open64; # introduced=21
+ open64;
open_memstream; # introduced=23
open_wmemstream; # introduced=23
openat;
- openat64; # introduced=21
+ openat64;
opendir;
openlog;
openpty; # introduced=23
@@ -728,26 +728,26 @@
pipe2;
poll;
popen;
- posix_fadvise; # introduced=21
- posix_fadvise64; # introduced=21
- posix_fallocate; # introduced=21
- posix_fallocate64; # introduced=21
+ posix_fadvise;
+ posix_fadvise64;
+ posix_fallocate;
+ posix_fallocate64;
posix_madvise; # introduced=23
- posix_memalign; # introduced=17
- posix_openpt; # introduced=21
- ppoll; # introduced=21
+ posix_memalign;
+ posix_openpt;
+ ppoll;
prctl;
pread;
- pread64; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ pread64;
printf;
prlimit; # arm64 x86_64 riscv64
- prlimit64; # introduced=21
+ prlimit64;
process_vm_readv; # introduced=23
process_vm_writev; # introduced=23
pselect;
- psiginfo; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- psignal; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- pthread_atfork; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ psiginfo;
+ psignal;
+ pthread_atfork;
pthread_attr_destroy;
pthread_attr_getdetachstate;
pthread_attr_getguardsize;
@@ -770,15 +770,15 @@
pthread_cond_signal;
pthread_cond_timedwait;
pthread_cond_timedwait_monotonic; # arm x86
- pthread_cond_timedwait_monotonic_np; # introduced-arm=9 introduced-x86=9 introduced-arm64=28 introduced-x64_64=28
+ pthread_cond_timedwait_monotonic_np; # introduced-arm=9 introduced-x86=9 introduced-arm64=28 introduced-x64_64=28 introduced-riscv64=28
pthread_cond_timedwait_relative_np; # arm x86
pthread_cond_timeout_np; # arm x86
pthread_cond_wait;
pthread_condattr_destroy;
- pthread_condattr_getclock; # introduced=21
+ pthread_condattr_getclock;
pthread_condattr_getpshared;
pthread_condattr_init;
- pthread_condattr_setclock; # introduced=21
+ pthread_condattr_setclock;
pthread_condattr_setpshared;
pthread_create;
pthread_detach;
@@ -788,7 +788,7 @@
pthread_getcpuclockid;
pthread_getschedparam;
pthread_getspecific;
- pthread_gettid_np; # introduced=21
+ pthread_gettid_np;
pthread_join;
pthread_key_create;
pthread_key_delete;
@@ -797,7 +797,7 @@
pthread_mutex_init;
pthread_mutex_lock;
pthread_mutex_lock_timeout_np; # arm x86
- pthread_mutex_timedlock; # introduced=21
+ pthread_mutex_timedlock;
pthread_mutex_trylock;
pthread_mutex_unlock;
pthread_mutexattr_destroy;
@@ -840,30 +840,30 @@
putw; # arm x86
putwc;
putwchar;
- pvalloc; # arm x86 introduced=17
+ pvalloc; # arm x86
pwrite;
- pwrite64; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ pwrite64;
qsort;
- quick_exit; # introduced=21
+ quick_exit;
raise;
- rand; # introduced=21
- rand_r; # introduced=21
- random; # introduced=21
+ rand;
+ rand_r;
+ random;
read;
readahead;
readdir;
- readdir64; # introduced=21
- readdir64_r; # introduced=21
+ readdir64;
+ readdir64_r;
readdir_r;
readlink;
- readlinkat; # introduced=21
+ readlinkat;
readv;
realloc;
realpath;
reboot;
recv;
recvfrom;
- recvmmsg; # introduced=21
+ recvmmsg;
recvmsg;
regcomp;
regerror;
@@ -871,7 +871,7 @@
regfree;
remove;
removexattr;
- remque; # introduced=21
+ remque;
rename;
renameat;
res_init;
@@ -883,16 +883,16 @@
rmdir;
sbrk;
scandir;
- scandir64; # introduced=21
+ scandir64;
scanf;
sched_get_priority_max;
sched_get_priority_min;
- sched_getaffinity; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- sched_getcpu; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ sched_getaffinity;
+ sched_getcpu;
sched_getparam;
sched_getscheduler;
sched_rr_get_interval;
- sched_setaffinity; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ sched_setaffinity;
sched_setparam;
sched_setscheduler;
sched_yield;
@@ -911,8 +911,8 @@
sem_wait;
send;
sendfile;
- sendfile64; # introduced=21
- sendmmsg; # introduced=21
+ sendfile64;
+ sendmmsg;
sendmsg;
sendto;
setbuf;
@@ -920,8 +920,8 @@
setegid;
setenv;
seteuid;
- setfsgid; # introduced=21
- setfsuid; # introduced=21
+ setfsgid;
+ setfsuid;
setgid;
setgroups;
sethostname; # introduced=23
@@ -930,22 +930,22 @@
setlinebuf;
setlocale;
setlogmask;
- setmntent; # introduced=21
- setns; # introduced=21
+ setmntent;
+ setns;
setpgid;
setpgrp;
setpriority;
- setprogname; # introduced=21
+ setprogname;
setregid;
setresgid;
setresuid;
setreuid;
setrlimit;
- setrlimit64; # introduced=21
+ setrlimit64;
setservent;
setsid;
setsockopt;
- setstate; # introduced=21
+ setstate;
settimeofday;
setuid;
setutent;
@@ -953,22 +953,22 @@
setxattr;
shutdown;
sigaction;
- sigaddset; # introduced=21
+ sigaddset;
sigaltstack;
- sigblock; # arm x86 arm64 x86_64
- sigdelset; # introduced=21
- sigemptyset; # introduced=21
- sigfillset; # introduced=21
+ sigblock;
+ sigdelset;
+ sigemptyset;
+ sigfillset;
siginterrupt;
- sigismember; # introduced=21
- siglongjmp; # introduced-arm=9 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- signal; # introduced=21
- signalfd; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ sigismember;
+ siglongjmp;
+ signal;
+ signalfd;
sigpending;
sigprocmask;
sigqueue; # introduced=23
- sigsetjmp; # introduced-arm=9 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
- sigsetmask; # arm x86 arm64 x86_64
+ sigsetjmp;
+ sigsetmask;
sigsuspend;
sigtimedwait; # introduced=23
sigwait;
@@ -977,23 +977,23 @@
snprintf;
socket;
socketpair;
- splice; # introduced=21
+ splice;
sprintf;
- srand; # introduced=21
+ srand;
srand48;
- srandom; # introduced=21
+ srandom;
sscanf;
stat;
- stat64; # introduced=21
+ stat64;
statfs;
- statfs64; # introduced=21
- statvfs; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- statvfs64; # introduced=21
+ statfs64;
+ statvfs;
+ statvfs64;
stderr; # var introduced=23
stdin; # var introduced=23
stdout; # var introduced=23
- stpcpy; # introduced=21
- stpncpy; # introduced=21
+ stpcpy;
+ stpncpy;
strcasecmp;
strcasecmp_l; # introduced=23
strcasestr;
@@ -1001,7 +1001,7 @@
strchr;
strcmp;
strcoll;
- strcoll_l; # introduced=21
+ strcoll_l;
strcpy;
strcspn;
strdup;
@@ -1009,7 +1009,7 @@
strerror_l; # introduced=23
strerror_r;
strftime;
- strftime_l; # introduced=21
+ strftime_l;
strlcat;
strlcpy;
strlen;
@@ -1028,27 +1028,27 @@
strspn;
strstr;
strtod;
- strtof; # introduced=21
+ strtof;
strtoimax;
strtok;
strtok_r;
strtol;
- strtold; # introduced=21
- strtold_l; # introduced=21
+ strtold;
+ strtold_l;
strtoll;
- strtoll_l; # introduced=21
+ strtoll_l;
strtoul;
strtoull;
- strtoull_l; # introduced=21
+ strtoull_l;
strtoumax;
strxfrm;
- strxfrm_l; # introduced=21
- swapoff; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- swapon; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ strxfrm_l;
+ swapoff;
+ swapon;
swprintf;
swscanf;
symlink;
- symlinkat; # introduced=21
+ symlinkat;
sync;
sys_siglist; # var
sys_signame; # var
@@ -1057,54 +1057,54 @@
sysinfo;
syslog;
system;
- tcdrain; # introduced=21
- tcflow; # introduced=21
- tcflush; # introduced=21
- tcgetattr; # introduced=21
+ tcdrain;
+ tcflow;
+ tcflush;
+ tcgetattr;
tcgetpgrp;
- tcgetsid; # introduced=21
- tcsendbreak; # introduced=21
- tcsetattr; # introduced=21
+ tcgetsid;
+ tcsendbreak;
+ tcsetattr;
tcsetpgrp;
tdelete;
tdestroy;
- tee; # introduced=21
+ tee;
telldir; # introduced=23
tempnam;
tfind;
tgkill;
time;
- timegm; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ timegm;
timegm64; # arm x86
- timelocal; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ timelocal;
timelocal64; # arm x86
timer_create;
timer_delete;
timer_getoverrun;
timer_gettime;
timer_settime;
- timerfd_create; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- timerfd_gettime; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
- timerfd_settime; # introduced-arm=19 introduced-arm64=21 introduced-x86=19 introduced-x86_64=21
+ timerfd_create;
+ timerfd_gettime;
+ timerfd_settime;
times;
timezone; # var
tmpfile;
tmpnam;
toascii;
tolower;
- tolower_l; # introduced=21
+ tolower_l;
toupper;
- toupper_l; # introduced=21
+ toupper_l;
towlower;
- towlower_l; # introduced=21
+ towlower_l;
towupper;
- towupper_l; # introduced=21
+ towupper_l;
truncate;
- truncate64; # introduced=21
+ truncate64;
tsearch;
ttyname;
ttyname_r;
- twalk; # introduced=21
+ twalk;
tzname; # var
tzset;
umask;
@@ -1117,16 +1117,16 @@
unlinkat;
unlockpt;
unsetenv;
- unshare; # introduced-arm=17 introduced-arm64=21 introduced-x86=17 introduced-x86_64=21
- uselocale; # introduced=21
+ unshare;
+ uselocale;
usleep;
utime;
- utimensat; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
+ utimensat;
utimes;
utmpname;
valloc; # arm x86
vasprintf;
- vdprintf; # introduced=21
+ vdprintf;
verr;
verrx;
vfdprintf; # arm x86 versioned=28
@@ -1134,22 +1134,22 @@
vfprintf;
vfscanf;
vfwprintf;
- vfwscanf; # introduced=21
- vmsplice; # introduced=21
+ vfwscanf;
+ vmsplice;
vprintf;
vscanf;
vsnprintf;
vsprintf;
vsscanf;
vswprintf;
- vswscanf; # introduced=21
+ vswscanf;
vsyslog;
vwarn;
vwarnx;
vwprintf;
- vwscanf; # introduced=21
+ vwscanf;
wait;
- wait4; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ wait4;
waitid;
waitpid;
warn;
@@ -1163,7 +1163,7 @@
wcschr;
wcscmp;
wcscoll;
- wcscoll_l; # introduced=21
+ wcscoll_l;
wcscpy;
wcscspn;
wcsdup;
@@ -1177,33 +1177,33 @@
wcsncmp;
wcsncpy;
wcsnlen;
- wcsnrtombs; # introduced=21
+ wcsnrtombs;
wcspbrk;
wcsrchr;
wcsrtombs;
wcsspn;
wcsstr;
wcstod;
- wcstof; # introduced=21
- wcstoimax; # introduced=21
+ wcstof;
+ wcstoimax;
wcstok;
wcstol;
- wcstold; # introduced=21
- wcstold_l; # introduced=21
- wcstoll; # introduced=21
- wcstoll_l; # introduced=21
- wcstombs; # introduced=21
+ wcstold;
+ wcstold_l;
+ wcstoll;
+ wcstoll_l;
+ wcstombs;
wcstoul;
- wcstoull; # introduced=21
- wcstoull_l; # introduced=21
- wcstoumax; # introduced=21
+ wcstoull;
+ wcstoull_l;
+ wcstoumax;
wcswidth;
wcsxfrm;
- wcsxfrm_l; # introduced=21
+ wcsxfrm_l;
wctob;
- wctomb; # introduced=21
+ wctomb;
wctype;
- wctype_l; # introduced=21
+ wctype_l;
wcwidth;
wmemchr;
wmemcmp;
@@ -1341,7 +1341,7 @@
wctrans_l; # introduced=26
} LIBC_N;
-LIBC_P { # introduced=P
+LIBC_P { # introduced=28
global:
__freading;
__free_hook;
@@ -1442,7 +1442,7 @@
wcstoul_l;
} LIBC_O;
-LIBC_Q { # introduced=Q
+LIBC_Q { # introduced=29
global:
___tls_get_addr; # x86
__aeabi_read_tp; # arm
@@ -1478,7 +1478,7 @@
android_mallopt; # apex llndk
} LIBC_P;
-LIBC_R { # introduced=R
+LIBC_R { # introduced=30
global:
__mempcpy_chk;
__tls_get_addr; # arm64
@@ -1548,7 +1548,7 @@
_Unwind_VRS_Set; # arm
} LIBC_Q;
-LIBC_S { # introduced=S
+LIBC_S { # introduced=31
global:
__libc_get_static_tls_bounds;
__libc_register_thread_exit_callback;
@@ -1563,7 +1563,7 @@
process_madvise;
} LIBC_R;
-LIBC_T { # introduced=Tiramisu
+LIBC_T { # introduced=33
global:
backtrace;
backtrace_symbols;
@@ -1574,7 +1574,7 @@
pwritev64v2;
} LIBC_S;
-LIBC_U { # introduced=UpsideDownCake
+LIBC_U { # introduced=34
global:
__freadahead;
close_range;
@@ -1584,7 +1584,7 @@
posix_spawn_file_actions_addfchdir_np;
} LIBC_T;
-LIBC_V { # introduced=VanillaIceCream
+LIBC_V { # introduced=35
global:
android_crash_detail_register;
android_crash_detail_unregister;
@@ -1608,6 +1608,17 @@
__system_properties_zygote_reload; # apex
} LIBC_U;
+LIBC_36 { # introduced=36
+ global:
+ lchmod;
+ mseal;
+ pthread_getaffinity_np;
+ pthread_setaffinity_np;
+ qsort_r;
+ sig2str;
+ str2sig;
+} LIBC_V;
+
LIBC_PRIVATE {
global:
__accept4; # arm x86
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 3828c28..5d61801 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -79,6 +79,10 @@
"libmemunreachable",
],
+ whole_static_libs: [
+ "libmemory_trace",
+ ],
+
shared_libs: [
"libunwindstack",
],
diff --git a/libm/fenv-access.h b/libc/malloc_debug/Nanotime.h
similarity index 82%
rename from libm/fenv-access.h
rename to libc/malloc_debug/Nanotime.h
index 7acb34d..d7c3f60 100644
--- a/libm/fenv-access.h
+++ b/libc/malloc_debug/Nanotime.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,11 @@
#pragma once
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
-#endif
+#include <stdint.h>
+#include <time.h>
+
+static inline __always_inline uint64_t Nanotime() {
+ struct timespec t = {};
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
+}
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 79e051b..f832f03 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -39,76 +39,23 @@
#include <mutex>
#include <android-base/stringprintf.h>
+#include <memory_trace/MemoryTrace.h>
#include "Config.h"
#include "DebugData.h"
+#include "Nanotime.h"
#include "RecordData.h"
#include "debug_disable.h"
#include "debug_log.h"
-RecordEntry::RecordEntry() : tid_(gettid()) {
-}
-
-bool ThreadCompleteEntry::Write(int fd) const {
- return dprintf(fd, "%d: thread_done 0x0\n", tid_) > 0;
-}
-
-AllocEntry::AllocEntry(void* pointer, uint64_t start_ns, uint64_t end_ns)
- : pointer_(pointer), start_ns_(start_ns), end_ns_(end_ns) {}
-
-MallocEntry::MallocEntry(void* pointer, size_t size, uint64_t start_ns, uint64_t end_ns)
- : AllocEntry(pointer, start_ns, end_ns), size_(size) {}
-
-bool MallocEntry::Write(int fd) const {
- return dprintf(fd, "%d: malloc %p %zu %" PRIu64 " %" PRIu64 "\n", tid_, pointer_, size_,
- start_ns_, end_ns_) > 0;
-}
-
-FreeEntry::FreeEntry(void* pointer, uint64_t start_ns, uint64_t end_ns)
- : AllocEntry(pointer, start_ns, end_ns) {}
-
-bool FreeEntry::Write(int fd) const {
- return dprintf(fd, "%d: free %p %" PRIu64 " %" PRIu64 "\n", tid_, pointer_, start_ns_, end_ns_) >
- 0;
-}
-
-CallocEntry::CallocEntry(void* pointer, size_t nmemb, size_t size, uint64_t start_ns,
- uint64_t end_ns)
- : MallocEntry(pointer, size, start_ns, end_ns), nmemb_(nmemb) {}
-
-bool CallocEntry::Write(int fd) const {
- return dprintf(fd, "%d: calloc %p %zu %zu %" PRIu64 " %" PRIu64 "\n", tid_, pointer_, nmemb_,
- size_, start_ns_, end_ns_) > 0;
-}
-
-ReallocEntry::ReallocEntry(void* pointer, size_t size, void* old_pointer, uint64_t start_ns,
- uint64_t end_ns)
- : MallocEntry(pointer, size, start_ns, end_ns), old_pointer_(old_pointer) {}
-
-bool ReallocEntry::Write(int fd) const {
- return dprintf(fd, "%d: realloc %p %p %zu %" PRIu64 " %" PRIu64 "\n", tid_, pointer_,
- old_pointer_, size_, start_ns_, end_ns_) > 0;
-}
-
-// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
-MemalignEntry::MemalignEntry(void* pointer, size_t size, size_t alignment, uint64_t start_ns,
- uint64_t end_ns)
- : MallocEntry(pointer, size, start_ns, end_ns), alignment_(alignment) {}
-
-bool MemalignEntry::Write(int fd) const {
- return dprintf(fd, "%d: memalign %p %zu %zu %" PRIu64 " %" PRIu64 "\n", tid_, pointer_,
- alignment_, size_, start_ns_, end_ns_) > 0;
-}
-
struct ThreadData {
- ThreadData(RecordData* record_data, ThreadCompleteEntry* entry)
- : record_data(record_data), entry(entry) {}
- RecordData* record_data;
- ThreadCompleteEntry* entry;
+ ThreadData(RecordData* record_data) : record_data(record_data) {}
+
+ RecordData* record_data = nullptr;
size_t count = 0;
};
-static void ThreadKeyDelete(void* data) {
+void RecordData::ThreadKeyDelete(void* data) {
ThreadData* thread_data = reinterpret_cast<ThreadData*>(data);
thread_data->count++;
@@ -117,7 +64,11 @@
if (thread_data->count == 4) {
ScopedDisableDebugCalls disable;
- thread_data->record_data->AddEntryOnly(thread_data->entry);
+ memory_trace::Entry* entry = thread_data->record_data->InternalReserveEntry();
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{
+ .tid = gettid(), .type = memory_trace::THREAD_DONE, .end_ns = Nanotime()};
+ }
delete thread_data;
} else {
pthread_setspecific(thread_data->record_data->key(), data);
@@ -159,7 +110,12 @@
}
for (size_t i = 0; i < cur_index_; i++) {
- if (!entries_[i]->Write(dump_fd)) {
+ if (entries_[i].type == memory_trace::UNKNOWN) {
+ // This can happen if an entry was reserved but not filled in due to some
+ // type of error during the operation.
+ continue;
+ }
+ if (!memory_trace::WriteEntryToFd(dump_fd, entries_[i])) {
error_log("Failed to write record alloc information: %s", strerror(errno));
break;
}
@@ -201,25 +157,26 @@
pthread_key_delete(key_);
}
-void RecordData::AddEntryOnly(const RecordEntry* entry) {
+memory_trace::Entry* RecordData::InternalReserveEntry() {
std::lock_guard<std::mutex> entries_lock(entries_lock_);
if (cur_index_ == entries_.size()) {
- // Maxed out, throw the entry away.
- return;
+ return nullptr;
}
- entries_[cur_index_++].reset(entry);
- if (cur_index_ == entries_.size()) {
+ memory_trace::Entry* entry = &entries_[cur_index_];
+ entry->type = memory_trace::UNKNOWN;
+ if (++cur_index_ == entries_.size()) {
info_log("Maximum number of records added, all new operations will be dropped.");
}
+ return entry;
}
-void RecordData::AddEntry(const RecordEntry* entry) {
+memory_trace::Entry* RecordData::ReserveEntry() {
void* data = pthread_getspecific(key_);
if (data == nullptr) {
- ThreadData* thread_data = new ThreadData(this, new ThreadCompleteEntry());
+ ThreadData* thread_data = new ThreadData(this);
pthread_setspecific(key_, thread_data);
}
- AddEntryOnly(entry);
+ return InternalReserveEntry();
}
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 7efa1f7..ce71da1 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -39,117 +39,9 @@
#include <string>
#include <vector>
+#include <memory_trace/MemoryTrace.h>
#include <platform/bionic/macros.h>
-class RecordEntry {
- public:
- RecordEntry();
- virtual ~RecordEntry() = default;
-
- virtual bool Write(int fd) const = 0;
-
- protected:
- pid_t tid_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordEntry);
-};
-
-class ThreadCompleteEntry : public RecordEntry {
- public:
- ThreadCompleteEntry() = default;
- virtual ~ThreadCompleteEntry() = default;
-
- bool Write(int fd) const override;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
-};
-
-class AllocEntry : public RecordEntry {
- public:
- explicit AllocEntry(void* pointer, uint64_t st, uint64_t et);
- virtual ~AllocEntry() = default;
-
- protected:
- void* pointer_;
-
- // The start/end time of this operation.
- uint64_t start_ns_;
- uint64_t end_ns_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(AllocEntry);
-};
-
-class MallocEntry : public AllocEntry {
- public:
- MallocEntry(void* pointer, size_t size, uint64_t st, uint64_t et);
- virtual ~MallocEntry() = default;
-
- bool Write(int fd) const override;
-
- protected:
- size_t size_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(MallocEntry);
-};
-
-class FreeEntry : public AllocEntry {
- public:
- explicit FreeEntry(void* pointer, uint64_t st, uint64_t et);
- virtual ~FreeEntry() = default;
-
- bool Write(int fd) const override;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
-};
-
-class CallocEntry : public MallocEntry {
- public:
- CallocEntry(void* pointer, size_t nmemb, size_t size, uint64_t st, uint64_t et);
- virtual ~CallocEntry() = default;
-
- bool Write(int fd) const override;
-
- protected:
- size_t nmemb_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(CallocEntry);
-};
-
-class ReallocEntry : public MallocEntry {
- public:
- ReallocEntry(void* pointer, size_t size, void* old_pointer, uint64_t st, uint64_t et);
- virtual ~ReallocEntry() = default;
-
- bool Write(int fd) const override;
-
- protected:
- void* old_pointer_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
-};
-
-// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
-class MemalignEntry : public MallocEntry {
- public:
- MemalignEntry(void* pointer, size_t size, size_t alignment, uint64_t st, uint64_t et);
- virtual ~MemalignEntry() = default;
-
- bool Write(int fd) const override;
-
- protected:
- size_t alignment_;
-
- private:
- BIONIC_DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
-};
-
class Config;
class RecordData {
@@ -159,8 +51,7 @@
bool Initialize(const Config& config);
- void AddEntry(const RecordEntry* entry);
- void AddEntryOnly(const RecordEntry* entry);
+ memory_trace::Entry* ReserveEntry();
const std::string& file() { return file_; }
pthread_key_t key() { return key_; }
@@ -171,12 +62,16 @@
static void WriteData(int, siginfo_t*, void*);
static RecordData* record_obj_;
+ static void ThreadKeyDelete(void* data);
+
void WriteEntries();
void WriteEntries(const std::string& file);
+ memory_trace::Entry* InternalReserveEntry();
+
std::mutex entries_lock_;
pthread_key_t key_;
- std::vector<std::unique_ptr<const RecordEntry>> entries_;
+ std::vector<memory_trace::Entry> entries_;
size_t cur_index_;
std::string file_;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 3743852..fce6c24 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -54,6 +54,7 @@
#include "Config.h"
#include "DebugData.h"
#include "LogAllocatorStats.h"
+#include "Nanotime.h"
#include "Unreachable.h"
#include "UnwindBacktrace.h"
#include "backtrace.h"
@@ -70,12 +71,6 @@
const MallocDispatch* g_dispatch;
-static inline __always_inline uint64_t Nanotime() {
- struct timespec t = {};
- clock_gettime(CLOCK_MONOTONIC, &t);
- return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
-}
-
namespace {
// A TimedResult contains the result of from malloc end_ns al. functions and the
// start/end timestamps.
@@ -595,11 +590,22 @@
ScopedDisableDebugCalls disable;
ScopedBacktraceSignalBlocker blocked;
+ memory_trace::Entry* entry = nullptr;
+ if (g_debug->config().options() & RECORD_ALLOCS) {
+ // In order to preserve the order of operations, reserve the entry before
+ // performing the operation.
+ entry = g_debug->record->ReserveEntry();
+ }
+
TimedResult result = InternalMalloc(size);
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(new MallocEntry(result.getValue<void*>(), size,
- result.GetStartTimeNS(), result.GetEndTimeNS()));
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::MALLOC,
+ .ptr = reinterpret_cast<uint64_t>(result.getValue<void*>()),
+ .size = size,
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
return result.getValue<void*>();
@@ -684,11 +690,21 @@
return;
}
+ memory_trace::Entry* entry = nullptr;
+ if (g_debug->config().options() & RECORD_ALLOCS) {
+ // In order to preserve the order of operations, reserve the entry before
+ // performing the operation.
+ entry = g_debug->record->ReserveEntry();
+ }
+
TimedResult result = InternalFree(pointer);
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(
- new FreeEntry(pointer, result.GetStartTimeNS(), result.GetEndTimeNS()));
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::FREE,
+ .ptr = reinterpret_cast<uint64_t>(pointer),
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
}
@@ -711,6 +727,13 @@
return nullptr;
}
+ memory_trace::Entry* entry = nullptr;
+ if (g_debug->config().options() & RECORD_ALLOCS) {
+ // In order to preserve the order of operations, reserve the entry before
+ // performing the operation.
+ entry = g_debug->record->ReserveEntry();
+ }
+
TimedResult result;
void* pointer;
if (g_debug->HeaderEnabled()) {
@@ -758,22 +781,29 @@
pointer = result.getValue<void*>();
}
- if (pointer != nullptr) {
- if (g_debug->TrackPointers()) {
- PointerData::Add(pointer, bytes);
- }
+ if (pointer == nullptr) {
+ return nullptr;
+ }
- if (g_debug->config().options() & FILL_ON_ALLOC) {
- size_t bytes = InternalMallocUsableSize(pointer);
- size_t fill_bytes = g_debug->config().fill_on_alloc_bytes();
- bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
- memset(pointer, g_debug->config().fill_alloc_value(), bytes);
- }
+ if (g_debug->TrackPointers()) {
+ PointerData::Add(pointer, bytes);
+ }
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(new MemalignEntry(pointer, bytes, alignment,
- result.GetStartTimeNS(), result.GetEndTimeNS()));
- }
+ if (g_debug->config().options() & FILL_ON_ALLOC) {
+ size_t bytes = InternalMallocUsableSize(pointer);
+ size_t fill_bytes = g_debug->config().fill_on_alloc_bytes();
+ bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+ memset(pointer, g_debug->config().fill_alloc_value(), bytes);
+ }
+
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::MEMALIGN,
+ .ptr = reinterpret_cast<uint64_t>(pointer),
+ .size = bytes,
+ .u.align = alignment,
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
return pointer;
@@ -789,13 +819,25 @@
ScopedDisableDebugCalls disable;
ScopedBacktraceSignalBlocker blocked;
+ memory_trace::Entry* entry = nullptr;
+ if (g_debug->config().options() & RECORD_ALLOCS) {
+ // In order to preserve the order of operations, reserve the entry before
+ // performing the operation.
+ entry = g_debug->record->ReserveEntry();
+ }
+
if (pointer == nullptr) {
TimedResult result = InternalMalloc(bytes);
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(new ReallocEntry(result.getValue<void*>(), bytes, nullptr,
- result.GetStartTimeNS(), result.GetEndTimeNS()));
- }
pointer = result.getValue<void*>();
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::REALLOC,
+ .ptr = reinterpret_cast<uint64_t>(pointer),
+ .size = bytes,
+ .u.old_ptr = 0,
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
+ }
return pointer;
}
@@ -806,9 +848,14 @@
if (bytes == 0) {
TimedResult result = InternalFree(pointer);
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(new ReallocEntry(nullptr, bytes, pointer, result.GetStartTimeNS(),
- result.GetEndTimeNS()));
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::REALLOC,
+ .ptr = 0,
+ .size = 0,
+ .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
return nullptr;
@@ -904,9 +951,14 @@
}
}
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(new ReallocEntry(new_pointer, bytes, pointer, result.GetStartTimeNS(),
- result.GetEndTimeNS()));
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::REALLOC,
+ .ptr = reinterpret_cast<uint64_t>(new_pointer),
+ .size = bytes,
+ .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
return new_pointer;
@@ -945,6 +997,13 @@
return nullptr;
}
+ memory_trace::Entry* entry = nullptr;
+ if (g_debug->config().options() & RECORD_ALLOCS) {
+ // In order to preserve the order of operations, reserve the entry before
+ // performing the operation.
+ entry = g_debug->record->ReserveEntry();
+ }
+
void* pointer;
TimedResult result;
if (g_debug->HeaderEnabled()) {
@@ -961,9 +1020,14 @@
pointer = result.getValue<void*>();
}
- if (g_debug->config().options() & RECORD_ALLOCS) {
- g_debug->record->AddEntry(
- new CallocEntry(pointer, nmemb, bytes, result.GetStartTimeNS(), result.GetEndTimeNS()));
+ if (entry != nullptr) {
+ *entry = memory_trace::Entry{.tid = gettid(),
+ .type = memory_trace::CALLOC,
+ .ptr = reinterpret_cast<uint64_t>(pointer),
+ .size = bytes,
+ .u.n_elements = nmemb,
+ .start_ns = result.GetStartTimeNS(),
+ .end_ns = result.GetEndTimeNS()};
}
if (pointer != nullptr && g_debug->TrackPointers()) {
@@ -1062,18 +1126,20 @@
void debug_malloc_disable() {
ScopedConcurrentLock lock;
- g_dispatch->malloc_disable();
if (g_debug->pointer) {
+ // Acquire the pointer locks first, otherwise, the code can be holding
+ // the allocation lock and deadlock trying to acquire a pointer lock.
g_debug->pointer->PrepareFork();
}
+ g_dispatch->malloc_disable();
}
void debug_malloc_enable() {
ScopedConcurrentLock lock;
+ g_dispatch->malloc_enable();
if (g_debug->pointer) {
g_debug->pointer->PostForkParent();
}
- g_dispatch->malloc_enable();
}
ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t max_frames) {
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index d7a7a4f..080242c 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -57,6 +57,12 @@
#include <bionic/malloc.h>
#include <tests/utils.h>
+// exported from bionic
+__BEGIN_DECLS
+extern void malloc_disable();
+extern void malloc_enable();
+__END_DECLS
+
// All DISABLED_ tests are designed to be executed after malloc debug
// is enabled. These tests don't run be default, and are executed
// by wrappers that will enable various malloc debug features.
@@ -788,3 +794,34 @@
unexpected_log_strings_.push_back("Timed out waiting for ");
Exec("MallocTests.DISABLED_malloc_and_backtrace_deadlock", "verbose verify_pointers", 0);
}
+
+// Creates two threads: one that calls malloc_disable() and malloc_enable() in a loop and
+// the other that performs a bunch of allocations.
+TEST(MallocTests, DISABLED_malloc_disable_deadlock) {
+ std::atomic_bool running(true);
+
+ std::thread t1([&] {
+ while (running) {
+ malloc_disable();
+ malloc_enable();
+ }
+ });
+
+ std::thread t2([&] {
+ while (running) {
+ void* p = malloc(100);
+ free(p);
+ }
+ });
+
+ // let the threads run for a while, then tell them to stop and wait for shutdown
+ std::this_thread::sleep_for(std::chrono::seconds(5));
+
+ running = false;
+ t1.join();
+ t2.join();
+}
+
+TEST_F(MallocDebugSystemTest, malloc_disable_deadlock) {
+ Exec("MallocTests.DISABLED_malloc_disable_deadlock", "verbose backtrace");
+}
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 93268c1..c4af3b9 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -16,6 +16,7 @@
#pragma once
+#include <stddef.h>
#include <stdint.h>
#define BIONIC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
@@ -31,24 +32,6 @@
? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
: (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value)))))
-static constexpr uintptr_t align_down(uintptr_t p, size_t align) {
- return p & ~(align - 1);
-}
-
-static constexpr uintptr_t align_up(uintptr_t p, size_t align) {
- return (p + align - 1) & ~(align - 1);
-}
-
-template <typename T>
-static inline T* _Nonnull align_down(T* _Nonnull p, size_t align) {
- return reinterpret_cast<T*>(align_down(reinterpret_cast<uintptr_t>(p), align));
-}
-
-template <typename T>
-static inline T* _Nonnull align_up(T* _Nonnull p, size_t align) {
- return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
-}
-
#if defined(__arm__)
#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined r14")
#elif defined(__aarch64__)
@@ -97,3 +80,26 @@
static inline T* _Nonnull untag_address(T* _Nonnull p) {
return reinterpret_cast<T*>(untag_address(reinterpret_cast<uintptr_t>(p)));
}
+
+// MTE globals protects internal and external global variables. One of the main
+// things that MTE globals does is force all global variable accesses to go
+// through the GOT. In the linker though, some global variables are accessed (or
+// address-taken) prior to relocations being processed. Because relocations
+// haven't run yet, the GOT entry hasn't been populated, and this leads to
+// crashes. Thus, any globals used by the linker prior to relocation should be
+// annotated with this attribute, which suppresses tagging of this global
+// variable, restoring the pc-relative address computation.
+//
+// A way to find global variables that need this attribute is to build the
+// linker/libc with `SANITIZE_TARGET=memtag_globals`, push them onto a device
+// (it doesn't have to be MTE capable), and then run an executable using
+// LD_LIBRARY_PATH and using the linker in interpreter mode (e.g.
+// `LD_LIBRARY_PATH=/data/tmp/ /data/tmp/linker64 /data/tmp/my_binary`). A
+// good heuristic is that the global variable is in a file that should be
+// compiled with `-ffreestanding` (but there are global variables there that
+// don't need this attribute).
+#if __has_feature(memtag_globals)
+#define BIONIC_USED_BEFORE_LINKER_RELOCATES __attribute__((no_sanitize("memtag")))
+#else // __has_feature(memtag_globals)
+#define BIONIC_USED_BEFORE_LINKER_RELOCATES
+#endif // __has_feature(memtag_globals)
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index 98b3d27..610cb45 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -28,6 +28,7 @@
#pragma once
+#include <stddef.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -49,6 +50,36 @@
return supported;
}
+inline void* get_tagged_address(const void* ptr) {
+#if defined(__aarch64__)
+ if (mte_supported()) {
+ __asm__ __volatile__(".arch_extension mte; ldg %0, [%0]" : "+r"(ptr));
+ }
+#endif // aarch64
+ return const_cast<void*>(ptr);
+}
+
+// Inserts a random tag tag to `ptr`, using any of the set lower 16 bits in
+// `mask` to exclude the corresponding tag from being generated. Note: This does
+// not tag memory. This generates a pointer to be used with set_memory_tag.
+inline void* insert_random_tag(const void* ptr, __attribute__((unused)) uint64_t mask = 0) {
+#if defined(__aarch64__)
+ if (mte_supported() && ptr) {
+ __asm__ __volatile__(".arch_extension mte; irg %0, %0, %1" : "+r"(ptr) : "r"(mask));
+ }
+#endif // aarch64
+ return const_cast<void*>(ptr);
+}
+
+// Stores the address tag in `ptr` to memory, at `ptr`.
+inline void set_memory_tag(__attribute__((unused)) void* ptr) {
+#if defined(__aarch64__)
+ if (mte_supported()) {
+ __asm__ __volatile__(".arch_extension mte; stg %0, [%0]" : "+r"(ptr));
+ }
+#endif // aarch64
+}
+
#ifdef __aarch64__
class ScopedDisableMTE {
size_t prev_tco_;
@@ -86,6 +117,12 @@
return ptr | ((1ULL << size_cls) << 56ULL);
}
+inline void stack_mte_free_ringbuffer(uintptr_t stack_mte_tls) {
+ size_t size = stack_mte_ringbuffer_size_from_pointer(stack_mte_tls);
+ void* ptr = reinterpret_cast<void*>(stack_mte_tls & ((1ULL << 56ULL) - 1ULL));
+ munmap(ptr, size);
+}
+
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.
diff --git a/libc/platform/bionic/reserved_signals.h b/libc/platform/bionic/reserved_signals.h
index dab58af..1c7076b 100644
--- a/libc/platform/bionic/reserved_signals.h
+++ b/libc/platform/bionic/reserved_signals.h
@@ -44,16 +44,25 @@
// 38 (__SIGRTMIN + 6) heapprofd ART managed heap dumps
// 39 (__SIGRTMIN + 7) fdtrack
// 40 (__SIGRTMIN + 8) android_run_on_all_threads (bionic/pthread_internal.cpp)
+// 41 (__SIGRTMIN + 9) re-enable MTE on thread
#define BIONIC_SIGNAL_POSIX_TIMERS (__SIGRTMIN + 0)
#define BIONIC_SIGNAL_BACKTRACE (__SIGRTMIN + 1)
#define BIONIC_SIGNAL_DEBUGGER (__SIGRTMIN + 3)
#define BIONIC_SIGNAL_PROFILER (__SIGRTMIN + 4)
+// When used for the dumping a heap dump, BIONIC_SIGNAL_ART_PROFILER is always handled
+// gracefully without crashing.
+// In debuggerd, we crash the process with this signal to indicate to init that
+// a process has been terminated by an MTEAERR SEGV. This works because there is
+// no other reason a process could have terminated with this signal.
+// This is to work around the limitation of that it is not possible to get the
+// si_code that terminated a process.
#define BIONIC_SIGNAL_ART_PROFILER (__SIGRTMIN + 6)
#define BIONIC_SIGNAL_FDTRACK (__SIGRTMIN + 7)
#define BIONIC_SIGNAL_RUN_ON_ALL_THREADS (__SIGRTMIN + 8)
+#define BIONIC_ENABLE_MTE (__SIGRTMIN + 9)
-#define __SIGRT_RESERVED 9
+#define __SIGRT_RESERVED 10
static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigset, int how) {
int (*block)(sigset64_t*, int);
int (*unblock)(sigset64_t*, int);
@@ -83,5 +92,6 @@
unblock(&sigset, __SIGRTMIN + 6);
unblock(&sigset, __SIGRTMIN + 7);
unblock(&sigset, __SIGRTMIN + 8);
+ unblock(&sigset, __SIGRTMIN + 9);
return sigset;
}
diff --git a/libc/private/CFIShadow.h b/libc/private/CFIShadow.h
index cbdf0f7..b40c063 100644
--- a/libc/private/CFIShadow.h
+++ b/libc/private/CFIShadow.h
@@ -40,7 +40,7 @@
// below) are interpreted as follows.
//
// For an address P and corresponding shadow value V, the address of __cfi_check is calculated as
-// align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity)
+// __builtin_align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity)
//
// Special shadow values:
// 0 = kInvalidShadow, this memory range has no valid CFI targets.
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
index bd67d74..7accdb3 100644
--- a/libc/private/CachedProperty.h
+++ b/libc/private/CachedProperty.h
@@ -29,9 +29,7 @@
#pragma once
#include <string.h>
-
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
+#include <sys/system_properties.h>
// Cached system property lookup. For code that needs to read the same property multiple times,
// this class helps optimize those lookups.
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index ee28d69..e1f655a 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -29,7 +29,7 @@
// constituents for easy access.
class KernelArgumentBlock {
public:
- explicit KernelArgumentBlock(void* raw_args) {
+ __attribute__((no_sanitize("hwaddress"))) explicit KernelArgumentBlock(void* raw_args) {
uintptr_t* args = reinterpret_cast<uintptr_t*>(raw_args);
argc = static_cast<int>(*args);
argv = reinterpret_cast<char**>(args + 1);
@@ -48,7 +48,7 @@
// Similar to ::getauxval but doesn't require the libc global variables to be set up,
// so it's safe to call this really early on.
- unsigned long getauxval(unsigned long type) {
+ __attribute__((no_sanitize("hwaddress"))) unsigned long getauxval(unsigned long type) {
for (ElfW(auxv_t)* v = auxv; v->a_type != AT_NULL; ++v) {
if (v->a_type == type) {
return v->a_un.a_val;
diff --git a/libc/private/bionic_asm_arm.h b/libc/private/bionic_asm_arm.h
index d8381d3..9ca5f38 100644
--- a/libc/private/bionic_asm_arm.h
+++ b/libc/private/bionic_asm_arm.h
@@ -37,7 +37,7 @@
#pragma once
-#define __bionic_asm_align 0
+#define __bionic_asm_align 64
#undef __bionic_asm_custom_entry
#undef __bionic_asm_custom_end
diff --git a/libc/private/bionic_asm_arm64.h b/libc/private/bionic_asm_arm64.h
index ffc7181..1e907a1 100644
--- a/libc/private/bionic_asm_arm64.h
+++ b/libc/private/bionic_asm_arm64.h
@@ -37,7 +37,7 @@
#pragma once
-#define __bionic_asm_align 16
+#define __bionic_asm_align 64
#undef __bionic_asm_function_type
#define __bionic_asm_function_type %function
diff --git a/libc/private/bionic_constants.h b/libc/private/bionic_constants.h
index 6274fe2..ce484d8 100644
--- a/libc/private/bionic_constants.h
+++ b/libc/private/bionic_constants.h
@@ -16,6 +16,7 @@
#pragma once
+#define US_PER_S 1'000'000LL
#define NS_PER_S 1'000'000'000LL
// Size of the shadow call stack. This can be small because these stacks only
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index a1bebda..cd6dca9 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -157,6 +157,10 @@
};
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
+__LIBC_HIDDEN__ bool __libc_mte_enabled();
+__LIBC_HIDDEN__ void __libc_init_mte(const memtag_dynamic_entries_t*, const void*, size_t,
+ uintptr_t);
+__LIBC_HIDDEN__ void __libc_init_mte_stack(void*);
__LIBC_HIDDEN__ void __libc_init_fdsan();
__LIBC_HIDDEN__ void __libc_init_fdtrack();
__LIBC_HIDDEN__ void __libc_init_profiling_handlers();
diff --git a/libc/private/bionic_ifuncs.h b/libc/private/bionic_ifuncs.h
index e6b349a..b31c903 100644
--- a/libc/private/bionic_ifuncs.h
+++ b/libc/private/bionic_ifuncs.h
@@ -31,6 +31,8 @@
#include <stdint.h>
#include <sys/ifunc.h>
+#include <private/bionic_call_ifunc_resolver.h>
+
#if defined(__aarch64__)
#define IFUNC_ARGS (uint64_t hwcap __attribute__((unused)), \
__ifunc_arg_t* arg __attribute__((unused)))
@@ -40,14 +42,6 @@
#define IFUNC_ARGS ()
#endif
-// We can't have HWASAN enabled in resolvers because they may be called before HWASAN is
-// initialized.
-#define DEFINE_IFUNC_FOR(name) \
- name##_func name __attribute__((ifunc(#name "_resolver"))); \
- __attribute__((visibility("hidden"))) \
- __attribute__((no_sanitize("hwaddress"))) \
- name##_func* name##_resolver IFUNC_ARGS
-
#define DECLARE_FUNC(type, name) \
__attribute__((visibility("hidden"))) \
type name
@@ -56,3 +50,137 @@
DECLARE_FUNC(type, name); \
return name; \
}
+
+#if defined(BIONIC_DYNAMIC_DISPATCH)
+
+// We can't have HWASAN enabled in resolvers because they may be called before
+// HWASAN is initialized.
+#define DEFINE_IFUNC_FOR(name) \
+ name##_func_t name __attribute__((ifunc(#name "_resolver"))); \
+ __attribute__((visibility("hidden"))) \
+ __attribute__((no_sanitize("hwaddress"))) name##_func_t* name##_resolver IFUNC_ARGS
+
+#define DEFINE_STATIC_SHIM(x)
+
+#elif defined(BIONIC_STATIC_DISPATCH)
+
+#define DEFINE_IFUNC_FOR(name) \
+ name##_func_t* name##_resolver IFUNC_ARGS; \
+ __attribute__((visibility("hidden"))) \
+ __attribute__((no_sanitize("hwaddress"))) name##_func_t* name##_resolver IFUNC_ARGS
+
+#define DEFINE_STATIC_SHIM(x) x
+
+#define FORWARD(name) \
+ static name##_func_t* fn = reinterpret_cast<name##_func_t*>( \
+ __bionic_call_ifunc_resolver(reinterpret_cast<ElfW(Addr)>(name##_resolver))); \
+ return fn
+
+#else
+#error neither dynamic nor static dispatch?!
+#endif
+
+typedef void* memchr_func_t(const void*, int, size_t);
+#define MEMCHR_SHIM() \
+ DEFINE_STATIC_SHIM(void* memchr(const void* src, int ch, size_t n) { \
+ FORWARD(memchr)(src, ch, n); \
+ })
+
+typedef int memcmp_func_t(const void*, const void*, size_t);
+#define MEMCMP_SHIM() \
+ DEFINE_STATIC_SHIM(int memcmp(const void* lhs, const void* rhs, size_t n) { \
+ FORWARD(memcmp)(lhs, rhs, n); \
+ })
+
+typedef void* memcpy_func_t(void*, const void*, size_t);
+#define MEMCPY_SHIM() \
+ DEFINE_STATIC_SHIM(void* memcpy(void* dst, const void* src, size_t n) { \
+ FORWARD(memcpy)(dst, src, n); \
+ })
+
+typedef void* memmove_func_t(void*, const void*, size_t);
+#define MEMMOVE_SHIM() \
+ DEFINE_STATIC_SHIM(void* memmove(void* dst, const void* src, size_t n) { \
+ FORWARD(memmove)(dst, src, n); \
+ })
+
+typedef int memrchr_func_t(const void*, int, size_t);
+#define MEMRCHR_SHIM() \
+ DEFINE_STATIC_SHIM(int memrchr(const void* src, int ch, size_t n) { \
+ FORWARD(memrchr)(src, ch, n); \
+ })
+
+typedef void* memset_func_t(void*, int, size_t);
+#define MEMSET_SHIM() \
+ DEFINE_STATIC_SHIM(void* memset(void* dst, int ch, size_t n) { FORWARD(memset)(dst, ch, n); })
+
+typedef void* __memset_chk_func_t(void*, int, size_t, size_t);
+#define __MEMSET_CHK_SHIM() \
+ DEFINE_STATIC_SHIM(void* __memset_chk(void* dst, int ch, size_t n, size_t n2) { \
+ FORWARD(__memset_chk)(dst, ch, n, n2); \
+ })
+
+typedef char* stpcpy_func_t(char*, const char*);
+#define STPCPY_SHIM() \
+ DEFINE_STATIC_SHIM(char* stpcpy(char* dst, const char* src) { FORWARD(stpcpy)(dst, src); })
+
+typedef char* strcat_func_t(char*, const char*);
+#define STRCAT_SHIM() \
+ DEFINE_STATIC_SHIM(char* strcat(char* dst, const char* src) { FORWARD(strcat)(dst, src); })
+
+typedef char* __strcat_chk_func_t(char*, const char*, size_t);
+#define __STRCAT_CHK_SHIM() \
+ DEFINE_STATIC_SHIM(char* __strcat_chk(char* dst, const char* src, size_t dst_buf_size) { \
+ FORWARD(__strcat_chk)(dst, src, dst_buf_size); \
+ })
+
+typedef char* strchr_func_t(const char*, int);
+#define STRCHR_SHIM() \
+ DEFINE_STATIC_SHIM(char* strchr(const char* src, int ch) { FORWARD(strchr)(src, ch); })
+
+typedef char* strchrnul_func_t(const char*, int);
+#define STRCHRNUL_SHIM() \
+ DEFINE_STATIC_SHIM(char* strchrnul(const char* src, int ch) { FORWARD(strchrnul)(src, ch); })
+
+typedef int strcmp_func_t(const char*, const char*);
+#define STRCMP_SHIM() \
+ DEFINE_STATIC_SHIM(int strcmp(char* lhs, const char* rhs) { FORWARD(strcmp)(lhs, rhs); })
+
+typedef char* strcpy_func_t(char*, const char*);
+#define STRCPY_SHIM() \
+ DEFINE_STATIC_SHIM(char* strcpy(char* dst, const char* src) { FORWARD(strcpy)(dst, src); })
+
+typedef char* __strcpy_chk_func_t(char*, const char*, size_t);
+#define __STRCPY_CHK_SHIM() \
+ DEFINE_STATIC_SHIM(char* __strcpy_chk(char* dst, const char* src, size_t dst_len) { \
+ FORWARD(__strcpy_chk)(dst, src, dst_len); \
+ })
+
+typedef size_t strlen_func_t(const char*);
+#define STRLEN_SHIM() DEFINE_STATIC_SHIM(size_t strlen(const char* s) { FORWARD(strlen)(s); })
+
+typedef char* strncat_func_t(char*, const char*, size_t);
+#define STRNCAT_SHIM() \
+ DEFINE_STATIC_SHIM(char* strncat(char* dst, const char* src, size_t n) { \
+ FORWARD(strncat)(dst, src, n); \
+ })
+
+typedef int strncmp_func_t(const char*, const char*, size_t);
+#define STRNCMP_SHIM() \
+ DEFINE_STATIC_SHIM(int strncmp(const char* lhs, const char* rhs, size_t n) { \
+ FORWARD(strncmp)(lhs, rhs, n); \
+ })
+
+typedef char* strncpy_func_t(char*, const char*, size_t);
+#define STRNCPY_SHIM() \
+ DEFINE_STATIC_SHIM(char* strncpy(char* dst, const char* src, size_t n) { \
+ FORWARD(strncpy)(dst, src, n); \
+ })
+
+typedef size_t strnlen_func_t(const char*, size_t);
+#define STRNLEN_SHIM() \
+ DEFINE_STATIC_SHIM(size_t strnlen(const char* s, size_t n) { FORWARD(strnlen)(s, n); })
+
+typedef char* strrchr_func_t(const char*, int);
+#define STRRCHR_SHIM() \
+ DEFINE_STATIC_SHIM(char* strrchr(const char* src, int ch) { FORWARD(strrchr)(src, ch); })
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 8ed4939..d0c6d5e 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -46,7 +46,7 @@
public:
void init(bool process_shared) {
- atomic_init(&state, Unlocked);
+ atomic_store_explicit(&state, Unlocked, memory_order_relaxed);
this->process_shared = process_shared;
}
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 0e5f861..fb85775 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -38,11 +38,11 @@
(rv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE || \
rv == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE)
-static inline __wur bool mbstate_is_initial(const mbstate_t* ps) {
+static inline __nodiscard bool mbstate_is_initial(const mbstate_t* ps) {
return *(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0;
}
-static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
+static inline __nodiscard size_t mbstate_bytes_so_far(const mbstate_t* ps) {
return
(ps->__seq[2] != 0) ? 3 :
(ps->__seq[1] != 0) ? 2 :
@@ -53,7 +53,7 @@
ps->__seq[i] = static_cast<uint8_t>(byte);
}
-static inline __wur uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
+static inline __nodiscard uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
return ps->__seq[n];
}
@@ -61,13 +61,13 @@
*(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
}
-static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
+static inline __nodiscard size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
errno = _errno;
mbstate_reset(ps);
return BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE;
}
-static inline __wur size_t mbstate_reset_and_return(size_t _return, mbstate_t* ps) {
+static inline __nodiscard size_t mbstate_reset_and_return(size_t _return, mbstate_t* ps) {
mbstate_reset(ps);
return _return;
}
diff --git a/libc/private/bionic_time_conversions.h b/libc/private/bionic_time_conversions.h
index c6b3c78..ce7de0d 100644
--- a/libc/private/bionic_time_conversions.h
+++ b/libc/private/bionic_time_conversions.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _BIONIC_TIME_CONVERSIONS_H
-#define _BIONIC_TIME_CONVERSIONS_H
+#pragma once
#include <errno.h>
#include <time.h>
@@ -35,20 +34,21 @@
#include "private/bionic_constants.h"
-__BEGIN_DECLS
+bool timespec_from_timeval(timespec& ts, const timeval& tv);
+void timespec_from_ms(timespec& ts, const int ms);
-__LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv);
-__LIBC_HIDDEN__ void timespec_from_ms(timespec& ts, const int ms);
+void timeval_from_timespec(timeval& tv, const timespec& ts);
-__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
+void monotonic_time_from_realtime_time(timespec& monotonic_time, const timespec& realtime_time);
+void realtime_time_from_monotonic_time(timespec& realtime_time, const timespec& monotonic_time);
-__LIBC_HIDDEN__ void monotonic_time_from_realtime_time(timespec& monotonic_time,
- const timespec& realtime_time);
+static inline int64_t to_ns(const timespec& ts) {
+ return ts.tv_sec * NS_PER_S + ts.tv_nsec;
+}
-__LIBC_HIDDEN__ void realtime_time_from_monotonic_time(timespec& realtime_time,
- const timespec& monotonic_time);
-
-__END_DECLS
+static inline int64_t to_us(const timeval& tv) {
+ return tv.tv_sec * US_PER_S + tv.tv_usec;
+}
static inline int check_timespec(const timespec* ts, bool null_allowed) {
if (null_allowed && ts == nullptr) {
@@ -76,5 +76,3 @@
}
}
#endif
-
-#endif
diff --git a/libc/private/bsd_sys_param.h b/libc/private/bsd_sys_param.h
deleted file mode 100644
index ab54aa0..0000000
--- a/libc/private/bsd_sys_param.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <inttypes.h>
-
-/* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */
-#define ALIGNBYTES (sizeof(uintptr_t) - 1)
-#define ALIGN(p) ((__BIONIC_CAST(reinterpret_cast, uintptr_t, p) + ALIGNBYTES) & ~ALIGNBYTES)
diff --git a/libc/private/icu.h b/libc/private/icu.h
index a671e98..8e4aa80 100644
--- a/libc/private/icu.h
+++ b/libc/private/icu.h
@@ -80,7 +80,8 @@
int8_t __icu_charType(wint_t wc);
int32_t __icu_getIntPropertyValue(wint_t wc, UProperty property);
-bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int));
+
+typedef UBool (*u_hasBinaryProperty_t)(UChar32, UProperty);
void* __find_icu_symbol(const char* symbol_name);
diff --git a/libc/stdio/fmemopen.cpp b/libc/stdio/fmemopen.cpp
index 6e333ba..f069da4 100644
--- a/libc/stdio/fmemopen.cpp
+++ b/libc/stdio/fmemopen.cpp
@@ -33,8 +33,8 @@
#include "local.h"
-// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html
-// and http://man7.org/linux/man-pages/man3/fmemopen.3.html for documentation.
+// See https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fmemopen.html
+// and https://man7.org/linux/man-pages/man3/fmemopen.3.html for documentation.
struct fmemopen_cookie {
char* buf;
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 62efea1..a60468e 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -51,11 +51,7 @@
struct __sbuf {
unsigned char* _base;
-#if defined(__LP64__)
size_t _size;
-#else
- int _size;
-#endif
};
struct __sFILE {
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
index 702f8d3..653bba2 100644
--- a/libc/stdio/printf_common.h
+++ b/libc/stdio/printf_common.h
@@ -85,6 +85,10 @@
// Helper function for `fprintf to unbuffered unix file': creates a
// temporary buffer. We only work on write-only files; this avoids
// worries about ungetc buffers and so forth.
+//
+// We prevent inlining because this massively increases the printf()
+// family's stack usage to support a rare case.
+__attribute__((__noinline__))
static int __sbprintf(FILE* fp, const CHAR_TYPE* fmt, va_list ap) {
FILE fake;
struct __sfileext fakeext;
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index f18cd81..a5f2f81 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -58,8 +58,6 @@
#include "private/bionic_fortify.h"
#include "private/thread_private.h"
-#include "private/bsd_sys_param.h" // For ALIGN/ALIGNBYTES.
-
#define NDYNAMIC 10 /* add ten more whenever necessary */
#define PRINTF_IMPL(expr) \
@@ -135,12 +133,14 @@
};
static glue* moreglue(int n) {
- char* data = new char[sizeof(glue) + ALIGNBYTES + n * sizeof(FILE) + n * sizeof(__sfileext)];
+ char* data = new char[sizeof(glue) +
+ alignof(FILE) + n * sizeof(FILE) +
+ alignof(__sfileext) + n * sizeof(__sfileext)];
if (data == nullptr) return nullptr;
glue* g = reinterpret_cast<glue*>(data);
- FILE* p = reinterpret_cast<FILE*>(ALIGN(data + sizeof(*g)));
- __sfileext* pext = reinterpret_cast<__sfileext*>(ALIGN(data + sizeof(*g)) + n * sizeof(FILE));
+ FILE* p = reinterpret_cast<FILE*>(__builtin_align_up(g + 1, alignof(FILE)));
+ __sfileext* pext = reinterpret_cast<__sfileext*>(__builtin_align_up(p + n, alignof(__sfileext)));
g->next = nullptr;
g->niobs = n;
g->iobs = p;
@@ -1079,6 +1079,26 @@
return __sflush(fp);
}
+int fpurge(FILE* fp) {
+ CHECK_FP(fp);
+
+ ScopedFileLock sfl(fp);
+
+ if (fp->_flags == 0) {
+ // Already freed!
+ errno = EBADF;
+ return EOF;
+ }
+
+ if (HASUB(fp)) FREEUB(fp);
+ WCIO_FREE(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
+ return 0;
+}
+__strong_alias(__fpurge, fpurge);
+
size_t fread(void* buf, size_t size, size_t count, FILE* fp) {
CHECK_FP(fp);
ScopedFileLock sfl(fp);
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index 99a8af7..3eb2f33 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -59,10 +59,6 @@
return (fp->_flags & __SLBF) != 0;
}
-void __fpurge(FILE* fp) {
- fpurge(fp);
-}
-
size_t __fpending(FILE* fp) {
return fp->_p - fp->_bf._base;
}
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index e0509aa..354317c 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -43,7 +43,7 @@
#define PRINT(ptr, len) \
do { \
- iovp->iov_base = (ptr); \
+ iovp->iov_base = (void*)(ptr); \
iovp->iov_len = (len); \
uio.uio_resid += (len); \
iovp++; \
@@ -125,10 +125,10 @@
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
- static CHAR_TYPE blanks[PADSIZE] = {
+ static const CHAR_TYPE blanks[PADSIZE] = {
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
};
- static CHAR_TYPE zeroes[PADSIZE] = {
+ static const CHAR_TYPE zeroes[PADSIZE] = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
};
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index 72f973c..89e889e 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -128,10 +128,10 @@
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
- static CHAR_TYPE blanks[PADSIZE] = {
+ static const CHAR_TYPE blanks[PADSIZE] = {
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
};
- static CHAR_TYPE zeroes[PADSIZE] = {
+ static const CHAR_TYPE zeroes[PADSIZE] = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
};
diff --git a/libc/system_properties/Android.bp b/libc/system_properties/Android.bp
index 16ea73f..e2fce34 100644
--- a/libc/system_properties/Android.bp
+++ b/libc/system_properties/Android.bp
@@ -58,27 +58,10 @@
],
}
-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 {
+cc_defaults {
name: "large_system_property_node_defaults",
- soong_config_variables: {
- large_system_property_node: {
- cflags: ["-DLARGE_SYSTEM_PROPERTY_NODE=1"]
- }
- }
+ cflags: select(release_flag("RELEASE_LARGE_SYSTEM_PROPERTY_NODE"), {
+ true: ["-DLARGE_SYSTEM_PROPERTY_NODE=1"],
+ default: [],
+ }),
}
diff --git a/libc/system_properties/include/system_properties/prop_area.h b/libc/system_properties/include/system_properties/prop_area.h
index 187ff75..089cf52 100644
--- a/libc/system_properties/include/system_properties/prop_area.h
+++ b/libc/system_properties/include/system_properties/prop_area.h
@@ -102,7 +102,7 @@
}
prop_area(const uint32_t magic, const uint32_t version) : magic_(magic), version_(version) {
- atomic_init(&serial_, 0u);
+ atomic_store_explicit(&serial_, 0u, memory_order_relaxed);
memset(reserved_, 0, sizeof(reserved_));
// Allocate enough space for the root node.
bytes_used_ = sizeof(prop_trie_node);
diff --git a/libc/system_properties/prop_info.cpp b/libc/system_properties/prop_info.cpp
index c3bf177..499b36a 100644
--- a/libc/system_properties/prop_info.cpp
+++ b/libc/system_properties/prop_info.cpp
@@ -38,7 +38,7 @@
prop_info::prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen) {
memcpy(this->name, name, namelen);
this->name[namelen] = '\0';
- atomic_init(&this->serial, valuelen << 24);
+ atomic_store_explicit(&this->serial, valuelen << 24, memory_order_relaxed);
memcpy(this->value, value, valuelen);
this->value[valuelen] = '\0';
}
@@ -48,7 +48,7 @@
this->name[namelen] = '\0';
auto error_value_len = sizeof(kLongLegacyError) - 1;
- atomic_init(&this->serial, error_value_len << 24 | kLongFlag);
+ atomic_store_explicit(&this->serial, error_value_len << 24 | kLongFlag, memory_order_relaxed);
memcpy(this->long_property.error_message, kLongLegacyError, sizeof(kLongLegacyError));
this->long_property.offset = long_offset;
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index ae7881e..20160c9 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -68,8 +68,8 @@
#define FIELD_TM_YDAY (1 << 3)
#define FIELD_TM_YEAR (1 << 4)
-static char gmt[] = { "GMT" };
-static char utc[] = { "UTC" };
+static const char gmt[] = { "GMT" };
+static const char utc[] = { "UTC" };
/* RFC-822/RFC-2822 */
static const char * const nast[5] = {
"EST", "CST", "MST", "PST", "\0\0\0"
@@ -97,6 +97,7 @@
return(_strptime(buf, fmt, tm, 1));
}
DEF_WEAK(strptime);
+__strong_alias(strptime_l, strptime);
static char *
_strptime(const char *buf, const char *fmt, struct tm *tm, int initialize)
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/qsort_r.c b/libc/upstream-freebsd/lib/libc/stdlib/qsort_r.c
new file mode 100644
index 0000000..b382b40
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/stdlib/qsort_r.c
@@ -0,0 +1,6 @@
+/*
+ * This file is in the public domain. Originally written by Garrett
+ * A. Wollman.
+ */
+#define I_AM_QSORT_R
+#include "qsort.c"
diff --git a/libc/upstream-netbsd/lib/libc/regex/utils.h b/libc/upstream-netbsd/lib/libc/regex/utils.h
index 972f555..8650dd4 100644
--- a/libc/upstream-netbsd/lib/libc/regex/utils.h
+++ b/libc/upstream-netbsd/lib/libc/regex/utils.h
@@ -63,6 +63,7 @@
/* utility definitions */
#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */
+#undef INFINITY // Android-added: avoid collision with C23 <float.h> INFINITY (via <limits.h>)
#define INFINITY (DUPMAX + 1)
#define NC_MAX (CHAR_MAX - CHAR_MIN + 1)
diff --git a/libc/upstream-netbsd/lib/libc/stdlib/bsearch.c b/libc/upstream-netbsd/lib/libc/stdlib/bsearch.c
deleted file mode 100644
index e48fe85..0000000
--- a/libc/upstream-netbsd/lib/libc/stdlib/bsearch.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $NetBSD: bsearch.c,v 1.16 2022/05/31 08:43:14 andvar Exp $ */
-
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)bsearch.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: bsearch.c,v 1.16 2022/05/31 08:43:14 andvar Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/*
- * Perform a binary search.
- *
- * The code below is a bit sneaky. After a comparison fails, we
- * divide the work in half by moving either left or right. If lim
- * is odd, moving left simply involves halving lim: e.g., when lim
- * is 5 we look at item 2, so we change lim to 2 so that we will
- * look at items 0 & 1. If lim is even, the same applies. If lim
- * is odd, moving right again involves halving lim, this time moving
- * the base up one item past p: e.g., when lim is 5 we change base
- * to item 3 and make lim 2 so that we will look at items 3 and 4.
- * If lim is even, however, we have to shrink it by one before
- * halving: e.g., when lim is 4, we still looked at item 2, so we
- * have to make lim 3, then halve, obtaining 1, so that we will only
- * look at item 3.
- */
-void *
-bsearch(const void *key, const void *base0, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *))
-{
- const char *base = base0;
- size_t lim;
- int cmp;
- const void *p;
-
- _DIAGASSERT(key != NULL);
- _DIAGASSERT(base0 != NULL || nmemb == 0);
- _DIAGASSERT(compar != NULL);
-
- for (lim = nmemb; lim != 0; lim >>= 1) {
- p = base + (lim >> 1) * size;
- cmp = (*compar)(key, p);
- if (cmp == 0)
- return __UNCONST(p);
- if (cmp > 0) { /* key > p: move right */
- base = (const char *)p + size;
- lim--;
- } /* else move left */
- }
- return (NULL);
-}
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index cbc52b5..ac6840a 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -25,8 +25,6 @@
#include <sys/random.h> // For getentropy.
-#include "private/bsd_sys_param.h"
-
#define __BEGIN_HIDDEN_DECLS _Pragma("GCC visibility push(hidden)")
#define __END_HIDDEN_DECLS _Pragma("GCC visibility pop")
diff --git a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
index ff6b26e..3ec0222 100644
--- a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
+++ b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
@@ -46,11 +46,11 @@
*
* Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008
* as described in;
- * http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html
+ * https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/fnmatch.html
*
* Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
* from chapter 2. "Shell Command Language"
- * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
+ * https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_18_13
* where; 1. A bracket expression starting with an unquoted <circumflex> '^'
* character CONTINUES to specify a non-matching list; 2. an explicit <period> '.'
* in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading
@@ -61,7 +61,7 @@
*
* Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
* from chapter 9, "Regular Expressions"
- * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
+ * https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/basedefs/V1_chap09.html#tag_09_03_05
* with no support for collating symbols, equivalence class expressions or
* character class expressions. A partial range expression with a leading
* hyphen following a valid range expression will match only the ordinary
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fpurge.c b/libc/upstream-openbsd/lib/libc/stdio/fpurge.c
deleted file mode 100644
index 8dd8a91..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fpurge.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $OpenBSD: fpurge.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * fpurge: like fflush, but without writing anything: leave the
- * given FILE's buffer empty.
- */
-int
-fpurge(FILE *fp)
-{
- FLOCKFILE(fp);
- if (!fp->_flags) {
- FUNLOCKFILE(fp);
- errno = EBADF;
- return(EOF);
- }
-
- if (HASUB(fp))
- FREEUB(fp);
- WCIO_FREE(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
- FUNLOCKFILE(fp);
- return (0);
-}
-DEF_WEAK(fpurge);
diff --git a/libc/upstream-openbsd/lib/libc/string/memchr.c b/libc/upstream-openbsd/lib/libc/string/memchr.c
deleted file mode 100644
index a6a4bd6..0000000
--- a/libc/upstream-openbsd/lib/libc/string/memchr.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $OpenBSD: memchr.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-void *
-memchr(const void *s, int c, size_t n)
-{
- if (n != 0) {
- const unsigned char *p = s;
-
- do {
- if (*p++ == (unsigned char)c)
- return ((void *)(p - 1));
- } while (--n != 0);
- }
- return (NULL);
-}
-DEF_STRONG(memchr);
diff --git a/libc/upstream-openbsd/lib/libc/string/memrchr.c b/libc/upstream-openbsd/lib/libc/string/memrchr.c
deleted file mode 100644
index e123bc1..0000000
--- a/libc/upstream-openbsd/lib/libc/string/memrchr.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $OpenBSD: memrchr.c,v 1.4 2019/01/25 00:19:25 millert Exp $ */
-
-/*
- * Copyright (c) 2007 Todd C. Miller <millert@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <string.h>
-
-/*
- * Reverse memchr()
- * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
- */
-void *
-memrchr(const void *s, int c, size_t n)
-{
- const unsigned char *cp;
-
- if (n != 0) {
- cp = (unsigned char *)s + n;
- do {
- if (*(--cp) == (unsigned char)c)
- return((void *)cp);
- } while (--n != 0);
- }
- return(NULL);
-}
-DEF_WEAK(memrchr);
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcat.c b/libc/upstream-openbsd/lib/libc/string/strlcat.c
deleted file mode 100644
index aa3db7ab..0000000
--- a/libc/upstream-openbsd/lib/libc/string/strlcat.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */
-
-/*
- * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Appends src to string dst of size dsize (unlike strncat, dsize is the
- * full size of dst, not space left). At most dsize-1 characters
- * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
- * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
- * If retval >= dsize, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t dsize)
-{
- const char *odst = dst;
- const char *osrc = src;
- size_t n = dsize;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end. */
- while (n-- != 0 && *dst != '\0')
- dst++;
- dlen = dst - odst;
- n = dsize - dlen;
-
- if (n-- == 0)
- return(dlen + strlen(src));
- while (*src != '\0') {
- if (n != 0) {
- *dst++ = *src;
- n--;
- }
- src++;
- }
- *dst = '\0';
-
- return(dlen + (src - osrc)); /* count does not include NUL */
-}
-DEF_WEAK(strlcat);
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcpy.c b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
deleted file mode 100644
index 7e3b9ae..0000000
--- a/libc/upstream-openbsd/lib/libc/string/strlcpy.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */
-
-/*
- * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy string src to buffer dst of size dsize. At most dsize-1
- * chars will be copied. Always NUL terminates (unless dsize == 0).
- * Returns strlen(src); if retval >= dsize, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t dsize)
-{
- const char *osrc = src;
- size_t nleft = dsize;
-
- /* Copy as many bytes as will fit. */
- if (nleft != 0) {
- while (--nleft != 0) {
- if ((*dst++ = *src++) == '\0')
- break;
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src. */
- if (nleft == 0) {
- if (dsize != 0)
- *dst = '\0'; /* NUL-terminate dst */
- while (*src++)
- ;
- }
-
- return(src - osrc - 1); /* count does not include NUL */
-}
-DEF_WEAK(strlcpy);
diff --git a/libc/versioner-dependencies/arm/kernel_uapi_asm-arm b/libc/versioner-dependencies/arm/kernel_uapi_asm-arm
deleted file mode 120000
index 3c7584d..0000000
--- a/libc/versioner-dependencies/arm/kernel_uapi_asm-arm
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/asm-arm
\ No newline at end of file
diff --git a/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64 b/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64
deleted file mode 120000
index 7ee6fd2..0000000
--- a/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/asm-arm64
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/clang-builtins b/libc/versioner-dependencies/common/clang-builtins
deleted file mode 120000
index 148dd2b..0000000
--- a/libc/versioner-dependencies/common/clang-builtins
+++ /dev/null
@@ -1 +0,0 @@
-../../../../prebuilts/clang-tools/linux-x86/clang-headers
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/kernel_android_uapi b/libc/versioner-dependencies/common/kernel_android_uapi
deleted file mode 120000
index fd78315..0000000
--- a/libc/versioner-dependencies/common/kernel_android_uapi
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/android/uapi/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/kernel_uapi b/libc/versioner-dependencies/common/kernel_uapi
deleted file mode 120000
index d5cb8ee..0000000
--- a/libc/versioner-dependencies/common/kernel_uapi
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64 b/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64
deleted file mode 120000
index 61353cb..0000000
--- a/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/asm-riscv/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86/kernel_uapi_asm-x86 b/libc/versioner-dependencies/x86/kernel_uapi_asm-x86
deleted file mode 120000
index 1b7a73d..0000000
--- a/libc/versioner-dependencies/x86/kernel_uapi_asm-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/asm-x86/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86 b/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86
deleted file mode 120000
index 1b7a73d..0000000
--- a/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../kernel/uapi/asm-x86/
\ No newline at end of file
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 1bbd902..205c454 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -60,6 +60,8 @@
native_bridge_supported: true,
static_ndk_lib: true,
+ export_include_dirs: ["include_private"],
+
defaults: [
"linux_bionic_supported",
"bug_24465209_workaround",
@@ -123,7 +125,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
}
@@ -170,7 +171,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
}
diff --git a/libdl/NOTICE b/libdl/NOTICE
index fce0104..80038fc 100644
--- a/libdl/NOTICE
+++ b/libdl/NOTICE
@@ -30,3 +30,19 @@
-------------------------------------------------------------------
+Copyright (C) 2024 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
diff --git a/libdl/include_private/android/dlext_private.h b/libdl/include_private/android/dlext_private.h
new file mode 100644
index 0000000..fda1086
--- /dev/null
+++ b/libdl/include_private/android/dlext_private.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// TODO: libdl has several private extensions, but they have not all moved into a standard
+// private header.
+
+/**
+ * Set whether to load libraries in app compat mode.
+ *
+ * Any library which is not 16 KB aligned on a 4 KB aligned
+ * will be loaded in a special mode, which may load some R-only
+ * code as RW, in order to increase compatibility.
+ *
+ * \param enable_app_compat whether the mode is enabled for additional
+ * library loads.
+ */
+void android_set_16kb_appcompat_mode(bool enable_app_compat);
+
+__END_DECLS
diff --git a/libdl/libdl_android.cpp b/libdl/libdl_android.cpp
index 47a164a..f0959eb 100644
--- a/libdl/libdl_android.cpp
+++ b/libdl/libdl_android.cpp
@@ -59,6 +59,9 @@
__attribute__((__weak__, visibility("default")))
struct android_namespace_t* __loader_android_get_exported_namespace(const char* name);
+__attribute__((__weak__, visibility("default"))) void __loader_android_set_16kb_appcompat_mode(
+ bool enable_app_compat);
+
// Proxy calls to bionic loader
__attribute__((__weak__))
void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
@@ -115,4 +118,8 @@
return __loader_android_get_exported_namespace(name);
}
+__attribute__((__weak__)) void android_set_16kb_appcompat_mode(bool enable_app_compat) {
+ __loader_android_set_16kb_appcompat_mode(enable_app_compat);
+}
+
} // extern "C"
diff --git a/libdl/libdl_android.map.txt b/libdl/libdl_android.map.txt
index 7afcd9c..efbc841 100644
--- a/libdl/libdl_android.map.txt
+++ b/libdl/libdl_android.map.txt
@@ -24,6 +24,7 @@
android_init_anonymous_namespace; # apex
android_link_namespaces; # apex
android_set_application_target_sdk_version; # apex
+ android_set_16kb_appcompat_mode; #apex
local:
*;
};
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 8adc342..e096f9a 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -55,8 +55,8 @@
uintptr_t addr = reinterpret_cast<uintptr_t>(Ptr);
// The aligned range of [0, kShadowAlign) uses a single shadow element, therefore all pointers in
// this range must get the same aligned_addr below. This matches CFIShadowWriter::Add; not the
- // same as align_up().
- uintptr_t aligned_addr = align_down(addr, CFIShadow::kShadowAlign) + CFIShadow::kShadowAlign;
+ // same as just __builtin_align_up().
+ uintptr_t aligned_addr = __builtin_align_down(addr, CFIShadow::kShadowAlign) + CFIShadow::kShadowAlign;
uintptr_t p = aligned_addr - (static_cast<uintptr_t>(v - CFIShadow::kRegularShadowMin)
<< CFIShadow::kCfiCheckGranularity);
#ifdef __arm__
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 3627c84..e446f56 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -269,8 +269,10 @@
if (fatal) {
// Find the most common stack.
size_t max = 0;
+ size_t total = 0;
StackInfo* stack = nullptr;
for (size_t i = 0; i < stacks.count; ++i) {
+ total += stacks.data[i].count;
if (stacks.data[i].count > max) {
stack = &stacks.data[i];
max = stack->count;
@@ -287,7 +289,7 @@
char* p = buf;
p += async_safe_format_buffer(buf, sizeof(buf),
"aborting due to fd leak: see \"open files\" in the tombstone; "
- "most common stack (%zu/%zu) is\n", max, stacks.count);
+ "most common stack (%zu/%zu) is\n", max, total);
for (size_t i = 0; i < stack->stack_depth; ++i) {
ssize_t bytes_left = buf + sizeof(buf) - p;
diff --git a/libm/Android.bp b/libm/Android.bp
index 00d90a0..ee86959 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -161,8 +161,6 @@
"upstream-freebsd/lib/msun/src/s_nextafterf.c",
"upstream-freebsd/lib/msun/src/s_remquo.c",
"upstream-freebsd/lib/msun/src/s_remquof.c",
- "upstream-freebsd/lib/msun/src/s_rint.c",
- "upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/s_round.c",
"upstream-freebsd/lib/msun/src/s_roundf.c",
"upstream-freebsd/lib/msun/src/s_scalbln.c",
@@ -179,17 +177,15 @@
"upstream-freebsd/lib/msun/src/s_tanh.c",
"upstream-freebsd/lib/msun/src/s_tanhf.c",
"upstream-freebsd/lib/msun/src/s_tgammaf.c",
- "upstream-freebsd/lib/msun/src/s_trunc.c",
- "upstream-freebsd/lib/msun/src/s_truncf.c",
"upstream-freebsd/lib/msun/src/w_cabs.c",
"upstream-freebsd/lib/msun/src/w_cabsf.c",
"upstream-freebsd/lib/msun/src/w_cabsl.c",
"upstream-freebsd/lib/msun/src/w_drem.c",
"upstream-freebsd/lib/msun/src/w_dremf.c",
- // The FreeBSD complex functions appear to be better, but they're incomplete.
- // We take the FreeBSD implementations when they exist, but fill out the rest
- // of <complex.h> from NetBSD...
+ // The FreeBSD complex function implementations appear to be better
+ // than the other BSDs', but they're incomplete. We take the FreeBSD
+ // implementations when they exist, but fill out the rest from NetBSD...
"upstream-netbsd/lib/libm/complex/ccoshl.c",
"upstream-netbsd/lib/libm/complex/ccosl.c",
"upstream-netbsd/lib/libm/complex/cephes_subrl.c",
@@ -275,10 +271,23 @@
arch: {
arm: {
srcs: [
- "arm/fenv.c",
- "upstream-freebsd/lib/msun/src/s_ceil.c",
- "upstream-freebsd/lib/msun/src/s_ceilf.c",
+ "fenv-arm.c",
],
+ armv7_a_neon: {
+ // armv7 arm32 has no instructions to implement these as
+ // builtins, so we build the portable implementations for armv7,
+ // because the NDK still supports armv7.
+ srcs: [
+ "upstream-freebsd/lib/msun/src/s_ceil.c",
+ "upstream-freebsd/lib/msun/src/s_ceilf.c",
+ "upstream-freebsd/lib/msun/src/s_floor.c",
+ "upstream-freebsd/lib/msun/src/s_floorf.c",
+ "upstream-freebsd/lib/msun/src/s_rint.c",
+ "upstream-freebsd/lib/msun/src/s_rintf.c",
+ "upstream-freebsd/lib/msun/src/s_trunc.c",
+ "upstream-freebsd/lib/msun/src/s_truncf.c",
+ ],
+ },
instruction_set: "arm",
version_script: ":libm.arm.map",
no_libcrt: true,
@@ -292,7 +301,7 @@
arm64: {
srcs: [
- "arm64/fenv.c",
+ "fenv-arm64.c",
],
exclude_srcs: [
"upstream-freebsd/lib/msun/src/s_fma.c",
@@ -309,19 +318,15 @@
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_lround.c",
"upstream-freebsd/lib/msun/src/s_lroundf.c",
- "upstream-freebsd/lib/msun/src/s_rint.c",
- "upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/s_round.c",
"upstream-freebsd/lib/msun/src/s_roundf.c",
- "upstream-freebsd/lib/msun/src/s_trunc.c",
- "upstream-freebsd/lib/msun/src/s_truncf.c",
],
version_script: ":libm.arm64.map",
},
riscv64: {
srcs: [
- "riscv64/fenv.c",
+ "fenv-riscv64.c",
],
exclude_srcs: [
@@ -339,31 +344,22 @@
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_lround.c",
"upstream-freebsd/lib/msun/src/s_lroundf.c",
- "upstream-freebsd/lib/msun/src/s_rint.c",
- "upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/s_round.c",
"upstream-freebsd/lib/msun/src/s_roundf.c",
- "upstream-freebsd/lib/msun/src/s_trunc.c",
- "upstream-freebsd/lib/msun/src/s_truncf.c",
],
version_script: ":libm.riscv64.map",
},
x86: {
srcs: [
- "i387/fenv.c",
- "x86/lrint.S",
- "x86/lrintf.S",
+ "fenv-x86.c",
],
exclude_srcs: [
+ "upstream-freebsd/lib/msun/src/s_llrint.c",
+ "upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
- "upstream-freebsd/lib/msun/src/s_rint.c",
- "upstream-freebsd/lib/msun/src/s_rintf.c",
- "upstream-freebsd/lib/msun/src/s_trunc.c",
- "upstream-freebsd/lib/msun/src/s_truncf.c",
],
- local_include_dirs: ["i387"],
// 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"],
@@ -372,19 +368,13 @@
x86_64: {
srcs: [
- "amd64/fenv.c",
- "x86_64/lrint.S",
- "x86_64/lrintf.S",
+ "fenv-x86_64.c",
],
exclude_srcs: [
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
- "upstream-freebsd/lib/msun/src/s_rint.c",
- "upstream-freebsd/lib/msun/src/s_rintf.c",
- "upstream-freebsd/lib/msun/src/s_trunc.c",
- "upstream-freebsd/lib/msun/src/s_truncf.c",
],
version_script: ":libm.x86_64.map",
},
@@ -396,10 +386,7 @@
],
cflags: [
- "-D_BSD_SOURCE",
- "-DFLT_EVAL_METHOD=0",
"-include freebsd-compat.h",
- "-include fenv-access.h",
"-fno-builtin",
"-fno-math-errno",
"-Wall",
@@ -448,7 +435,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
@@ -503,6 +489,8 @@
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
}
+// Because of a historical accidnt, ldexp() is in libc,
+// even though ldexpf() and ldexpl() are in libm.
filegroup {
name: "libc_ldexp_srcs",
srcs: ["upstream-freebsd/lib/msun/src/s_scalbn.c"],
diff --git a/libm/NOTICE b/libm/NOTICE
index 3c0e783..bcdce54 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -244,34 +244,6 @@
-------------------------------------------------------------------
-Copyright (C) 2021 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (C) 2022 The Android Open Source Project
All rights reserved.
@@ -540,36 +512,6 @@
-------------------------------------------------------------------
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (c) 2017 Steven G. Kargl
All rights reserved.
@@ -622,17 +564,6 @@
-------------------------------------------------------------------
-From: @(#)s_ilogb.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.
-
--------------------------------------------------------------------
-
SPDX-License-Identifier: BSD-2-Clause
Copyright (c) 2003, Steven G. Kargl
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 41e145b..97db425 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -18,13 +18,12 @@
#include "fpmath.h"
-double fabs(double x) { return __builtin_fabs(x); }
-float fabsf(float x) { return __builtin_fabsf(x); }
-long double fabsl(long double x) { return __builtin_fabsl(x); }
-
-#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
-float ceilf(float x) { return __builtin_ceilf(x); }
+#if defined(__arm__) && (__ARM_ARCH <= 7)
+// armv7 arm32 has no instructions to implement these builtins,
+// so we include the msun source in the .bp file instead.
+#else
double ceil(double x) { return __builtin_ceil(x); }
+float ceilf(float x) { return __builtin_ceilf(x); }
#if defined(__ILP32__)
__weak_reference(ceil, ceill);
#endif
@@ -34,21 +33,16 @@
float copysignf(float x, float y) { return __builtin_copysignf(x, y); }
long double copysignl(long double x, long double y) { return __builtin_copysignl(x, y); }
-#if defined(__arm__) && (__ARM_ARCH < 8)
-// armv8 arm32 has a single-instruction implementation for these, but
-// armv7 arm32 doesn't, so __builtin_ doesn't work for arm32.
-#include "math_private.h"
-namespace s_floor {
-#include "upstream-freebsd/lib/msun/src/s_floor.c"
-}
-namespace s_floorf {
-#include "upstream-freebsd/lib/msun/src/s_floorf.c"
-}
-float floorf(float x) { return s_floorf::floorf(x); }
-double floor(double x) { return s_floor::floor(x); }
+double fabs(double x) { return __builtin_fabs(x); }
+float fabsf(float x) { return __builtin_fabsf(x); }
+long double fabsl(long double x) { return __builtin_fabsl(x); }
+
+#if defined(__arm__) && (__ARM_ARCH <= 7)
+// armv7 arm32 has no instructions to implement these builtins,
+// so we include the msun source in the .bp file instead.
#else
-float floorf(float x) { return __builtin_floorf(x); }
double floor(double x) { return __builtin_floor(x); }
+float floorf(float x) { return __builtin_floorf(x); }
#if defined(__ILP32__)
__weak_reference(floor, floorl);
#endif
@@ -65,7 +59,7 @@
double fmin(double x, double y) { return __builtin_fmin(x, y); }
#endif
-#if defined(__aarch64__) || defined(__riscv)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
long lrint(double x) { return __builtin_lrint(x); }
long lrintf(float x) { return __builtin_lrintf(x); }
long long llrint(double x) { return __builtin_llrint(x); }
@@ -79,28 +73,34 @@
long long llroundf(float x) { return __builtin_llroundf(x); }
#endif
-#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
-float rintf(float x) { return __builtin_rintf(x); }
+#if defined(__arm__) && (__ARM_ARCH <= 7)
+// armv7 arm32 has no instructions to implement these builtins,
+// so we include the msun source in the .bp file instead.
+#else
double rint(double x) { return __builtin_rint(x); }
+float rintf(float x) { return __builtin_rintf(x); }
#if defined(__ILP32__)
__weak_reference(rint, rintl);
#endif
#endif
#if defined(__aarch64__) || defined(__riscv)
-float roundf(float x) { return __builtin_roundf(x); }
double round(double x) { return __builtin_round(x); }
+float roundf(float x) { return __builtin_roundf(x); }
#endif
-float sqrtf(float x) { return __builtin_sqrtf(x); }
double sqrt(double x) { return __builtin_sqrt(x); }
+float sqrtf(float x) { return __builtin_sqrtf(x); }
#if defined(__ILP32__)
__weak_reference(sqrt, sqrtl);
#endif
-#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
-float truncf(float x) { return __builtin_truncf(x); }
+#if defined(__arm__) && (__ARM_ARCH <= 7)
+// armv7 arm32 has no instructions to implement these builtins,
+// so we include the msun source in the .bp file instead.
+#else
double trunc(double x) { return __builtin_trunc(x); }
+float truncf(float x) { return __builtin_truncf(x); }
#if defined(__ILP32__)
__weak_reference(trunc, truncl);
#endif
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index 5f9b980..68492bc 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -29,9 +29,7 @@
long double fminl(long double a1, long double a2) { return fmin(a1, a2); }
int ilogbl(long double a1) { return ilogb(a1); }
long long llrintl(long double a1) { return llrint(a1); }
-#if !defined(__i386__) // x86 has an assembler lrint/lrintl.
long lrintl(long double a1) { return lrint(a1); }
-#endif
long long llroundl(long double a1) { return llround(a1); }
long lroundl(long double a1) { return lround(a1); }
long double modfl(long double a1, long double* a2) { double i; double f = modf(a1, &i); *a2 = i; return f; }
diff --git a/libm/arm/fenv.c b/libm/fenv-arm.c
similarity index 100%
rename from libm/arm/fenv.c
rename to libm/fenv-arm.c
diff --git a/libm/arm64/fenv.c b/libm/fenv-arm64.c
similarity index 100%
rename from libm/arm64/fenv.c
rename to libm/fenv-arm64.c
diff --git a/libm/riscv64/fenv.c b/libm/fenv-riscv64.c
similarity index 100%
rename from libm/riscv64/fenv.c
rename to libm/fenv-riscv64.c
diff --git a/libm/i387/fenv.c b/libm/fenv-x86.c
similarity index 100%
rename from libm/i387/fenv.c
rename to libm/fenv-x86.c
diff --git a/libm/amd64/fenv.c b/libm/fenv-x86_64.c
similarity index 100%
rename from libm/amd64/fenv.c
rename to libm/fenv-x86_64.c
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index a3c7cd4..9555ff9 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -16,9 +16,12 @@
#pragma once
+// Since we're implementing all the extensions,
+// we need to make sure we get all their declarations when we include <math.h>.
+#define _BSD_SOURCE
+
// Some FreeBSD source includes <complex.h> and assumes <math.h> from that.
#include <math.h>
-#include <float.h>
#define __weak_reference(sym,alias) \
__asm__(".weak " #alias); \
diff --git a/libm/libm.map.txt b/libm/libm.map.txt
index a931b93..b9a0db2 100644
--- a/libm/libm.map.txt
+++ b/libm/libm.map.txt
@@ -8,23 +8,23 @@
acosf;
acosh;
acoshf;
- acoshl; # introduced=21
- acosl; # introduced=21
+ acoshl;
+ acosl;
asin;
asinf;
asinh;
asinhf;
- asinhl; # introduced=21
- asinl; # introduced=21
+ asinhl;
+ asinl;
atan;
atan2;
atan2f;
- atan2l; # introduced=21
+ atan2l;
atanf;
atanh;
atanhf;
- atanhl; # introduced=21
- atanl; # introduced=21
+ atanhl;
+ atanl;
cabs; # introduced=23
cabsf; # introduced=23
cabsl; # introduced-arm=21 introduced-arm64=23 introduced-x86=21 introduced-x86_64=23
@@ -45,7 +45,7 @@
catanhf; # introduced=23
cbrt;
cbrtf;
- cbrtl; # introduced=21
+ cbrtl;
ccos; # introduced=23
ccosf; # introduced=23
ccosh; # introduced=23
@@ -68,8 +68,8 @@
cosf;
cosh;
coshf;
- coshl; # introduced=21
- cosl; # introduced=21
+ coshl;
+ cosl;
cproj; # introduced=23
cprojf; # introduced=23
cprojl; # introduced-arm=21 introduced-arm64=23 introduced-x86=21 introduced-x86_64=23
@@ -92,38 +92,38 @@
erf;
erfc;
erfcf;
- erfcl; # introduced=21
+ erfcl;
erff;
- erfl; # introduced=21
+ erfl;
exp;
exp2;
exp2f;
- exp2l; # introduced=21
+ exp2l;
expf;
- expl; # introduced=21
+ expl;
expm1;
expm1f;
- expm1l; # introduced=21
+ expm1l;
fabs;
fabsf;
fabsl;
fdim;
fdimf;
fdiml;
- feclearexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fedisableexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- feenableexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fegetenv; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fegetexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fegetexceptflag; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fegetround; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- feholdexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- feraiseexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fesetenv; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fesetexceptflag; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fesetround; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- fetestexcept; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- feupdateenv; # introduced-arm=21 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
+ feclearexcept;
+ fedisableexcept;
+ feenableexcept;
+ fegetenv;
+ fegetexcept;
+ fegetexceptflag;
+ fegetround;
+ feholdexcept;
+ feraiseexcept;
+ fesetenv;
+ fesetexceptflag;
+ fesetround;
+ fetestexcept;
+ feupdateenv;
finite;
finitef;
floor;
@@ -131,7 +131,7 @@
floorl;
fma;
fmaf;
- fmal; # introduced=21
+ fmal;
fmax;
fmaxf;
fmaxl;
@@ -140,17 +140,17 @@
fminl;
fmod;
fmodf;
- fmodl; # introduced=21
+ fmodl;
frexp;
frexpf;
- frexpl; # introduced=21
+ frexpl;
gamma;
gamma_r;
gammaf;
gammaf_r;
hypot;
hypotf;
- hypotl; # introduced=21
+ hypotl;
ilogb;
ilogbf;
ilogbl;
@@ -166,77 +166,77 @@
lgamma_r;
lgammaf;
lgammaf_r;
- lgammal; # introduced=21
+ lgammal;
lgammal_r; # introduced=23
llrint;
llrintf;
- llrintl; # introduced=21
+ llrintl;
llround;
llroundf;
llroundl;
log;
log10;
log10f;
- log10l; # introduced=21
+ log10l;
log1p;
log1pf;
- log1pl; # introduced=21
- log2; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- log2f; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- log2l; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ log1pl;
+ log2;
+ log2f;
+ log2l;
logb;
logbf;
- logbl; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ logbl;
logf;
- logl; # introduced=21
+ logl;
lrint;
lrintf;
- lrintl; # introduced=21
+ lrintl;
lround;
lroundf;
lroundl;
modf;
modff;
- modfl; # introduced=21
- nan; # introduced-arm=13 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- nanf; # introduced-arm=13 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- nanl; # introduced-arm=13 introduced-arm64=21 introduced-x86=13 introduced-x86_64=21
+ modfl;
+ nan;
+ nanf;
+ nanl;
nearbyint;
nearbyintf;
- nearbyintl; # introduced=21
+ nearbyintl;
nextafter;
nextafterf;
- nextafterl; # introduced=21
- nexttoward; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ nextafterl;
+ nexttoward;
nexttowardf;
- nexttowardl; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ nexttowardl;
pow;
powf;
- powl; # introduced=21
+ powl;
remainder;
remainderf;
- remainderl; # introduced=21
+ remainderl;
remquo;
remquof;
- remquol; # introduced=21
+ remquol;
rint;
rintf;
- rintl; # introduced=21
+ rintl;
round;
roundf;
roundl;
scalb;
scalbf;
- scalbln; # introduced-arm=9 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- scalblnf; # introduced-arm=9 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
- scalblnl; # introduced-arm=9 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21
+ scalbln;
+ scalblnf;
+ scalblnl;
scalbn;
scalbnf;
scalbnl;
signgam; # var
significand;
significandf;
- significandl; # introduced=21
+ significandl;
sin;
sincos;
sincosf;
@@ -244,20 +244,20 @@
sinf;
sinh;
sinhf;
- sinhl; # introduced=21
- sinl; # introduced=21
+ sinhl;
+ sinl;
sqrt;
sqrtf;
- sqrtl; # introduced=21
+ sqrtl;
tan;
tanf;
tanh;
tanhf;
- tanhl; # introduced=21
- tanl; # introduced=21
+ tanhl;
+ tanl;
tgamma;
- tgammaf; # introduced-arm=13 introduced-arm64=21 introduced-x86=9 introduced-x86_64=21
- tgammal; # introduced=21
+ tgammaf;
+ tgammal;
trunc;
truncf;
truncl;
@@ -271,7 +271,7 @@
*;
};
-LIBC_O { # introduced=O
+LIBC_O { # introduced=26
global:
cacoshl;
cacosl;
diff --git a/libm/significandl.c b/libm/significandl.c
index c5d7dd4..b672110 100644
--- a/libm/significandl.c
+++ b/libm/significandl.c
@@ -22,11 +22,13 @@
* 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 <math.h>
+// This function is only in glibc.
+// musl and NetBSD/OpenBSD just have the double and float variants,
+// while FreeBSD and iOS/macOS have none.
long double significandl(long double x) {
return scalbnl(x, -ilogbl(x));
}
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
index c667293..44cd519 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
@@ -29,10 +29,6 @@
* SUCH DAMAGE.
*/
-/* @(#)exp.c 8.1 (Berkeley) 6/4/93 */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* EXP(X)
* RETURN THE EXPONENTIAL OF X
* DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
index 9d09ac7..a82140b 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
@@ -29,10 +29,6 @@
* SUCH DAMAGE.
*/
-/* @(#)log.c 8.2 (Berkeley) 11/30/93 */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* Table-driven natural logarithm.
*
* This code was derived, with minor modifications, from:
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
index 493ced3..8369477 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
@@ -42,10 +42,6 @@
* porting to other precisions.
*/
-/* @(#)gamma.c 8.1 (Berkeley) 6/4/93 */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/ld128/e_lgammal_r.c b/libm/upstream-freebsd/lib/msun/ld128/e_lgammal_r.c
index 53d3af1..f8079b7 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/e_lgammal_r.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/e_lgammal_r.c
@@ -1,4 +1,3 @@
-/* @(#)e_lgamma_r.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_lgamma_r.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/ld128/e_powl.c b/libm/upstream-freebsd/lib/msun/ld128/e_powl.c
index 12b92a1..f5a993c 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/e_powl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/e_powl.c
@@ -59,9 +59,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/ld128/e_rem_pio2l.h b/libm/upstream-freebsd/lib/msun/ld128/e_rem_pio2l.h
index fcef399..0ea1a70 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/e_rem_pio2l.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/e_rem_pio2l.h
@@ -1,4 +1,3 @@
-/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -13,9 +12,6 @@
* Optimized by Bruce D. Evans.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* ld128 version of __ieee754_rem_pio2l(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
@@ -58,7 +54,7 @@
pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */
pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
-static inline __always_inline int
+static __always_inline int
__ieee754_rem_pio2l(long double x, long double *y)
{
union IEEEl2bits u,u1;
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
index 3ba767b..75aef7b 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "invtrig.h"
/*
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
index 3f505c5..4876be8 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
@@ -24,8 +24,6 @@
* 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 <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c b/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
index 422357b..c756266 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
@@ -1,4 +1,3 @@
-/* From: @(#)k_cos.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ld128 version of k_cos.c. See ../src/k_cos.c for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
index 3faf7a7..86811dd 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
@@ -30,9 +30,6 @@
* Optimized by Bruce D. Evans.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ld128 version of k_expl.h. See ../ld80/s_expl.c for most comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_sinl.c b/libm/upstream-freebsd/lib/msun/ld128/k_sinl.c
index 09472d6..f2b17ba 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_sinl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_sinl.c
@@ -1,4 +1,3 @@
-/* From: @(#)k_sin.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ld128 version of k_sin.c. See ../src/k_sin.c for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_tanl.c b/libm/upstream-freebsd/lib/msun/ld128/k_tanl.c
index d7ec0b9..8aff0d1 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_tanl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_tanl.c
@@ -1,5 +1,3 @@
-/* From: @(#)k_tan.c 1.5 04/04/22 SMI */
-
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
@@ -11,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ld128 version of k_tan.c. See ../src/k_tan.c for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_erfl.c b/libm/upstream-freebsd/lib/msun/ld128/s_erfl.c
index e29c969..227c31f 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_erfl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_erfl.c
@@ -1,4 +1,3 @@
-/* @(#)s_erf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See s_erf.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
index bcbdc5f..249cb4c 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <stdint.h>
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
index 0274a8f..e1358e2 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
@@ -28,9 +28,6 @@
* Optimized by Bruce D. Evans.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ld128 version of s_expl.c. See ../ld80/s_expl.c for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
index bc53884..e9133ec 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/**
* Implementation of the natural logarithm of x for 128-bit format.
*
@@ -447,7 +444,7 @@
#endif
#ifdef STRUCT_RETURN
-static inline __always_inline void
+static __always_inline void
k_logl(long double x, struct ld *rp)
#else
long double
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
index cde3f18..b90d024 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
@@ -24,8 +24,6 @@
* 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>
diff --git a/libm/upstream-freebsd/lib/msun/src/catrig.c b/libm/upstream-freebsd/lib/msun/src/catrig.c
index 82061b5..45af164 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrig.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrig.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/catrigf.c b/libm/upstream-freebsd/lib/msun/src/catrigf.c
index fb4a6bf..da90629 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrigf.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrigf.c
@@ -40,9 +40,6 @@
* a few comments on the right of declarations remain.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/catrigl.c b/libm/upstream-freebsd/lib/msun/src/catrigl.c
index e66f87a..faf9d29 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrigl.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrigl.c
@@ -39,9 +39,6 @@
* a few comments on the right of declarations remain.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acos.c b/libm/upstream-freebsd/lib/msun/src/e_acos.c
index 6623355..af51fe1 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acos.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acos.c
@@ -1,5 +1,4 @@
-/* @(#)e_acos.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* acos(x)
* Method :
* acos(x) = pi/2 - asin(x)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosf.c b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
index 64f1c5a..ede552e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
@@ -25,11 +22,17 @@
pio2_hi = 1.5707962513e+00; /* 0x3fc90fda */
static volatile float
pio2_lo = 7.5497894159e-08; /* 0x33a22168 */
+
+/*
+ * The coefficients for the rational approximation were generated over
+ * 0x1p-12f <= x <= 0.5f. The maximum error satisfies log2(e) < -30.084.
+ */
static const float
-pS0 = 1.6666586697e-01,
-pS1 = -4.2743422091e-02,
-pS2 = -8.6563630030e-03,
-qS1 = -7.0662963390e-01;
+pS0 = 1.66666672e-01f, /* 0x3e2aaaab */
+pS1 = -1.19510300e-01f, /* 0xbdf4c1d1 */
+pS2 = 5.47002675e-03f, /* 0x3bb33de9 */
+qS1 = -1.16706085e+00f, /* 0xbf956240 */
+qS2 = 2.90115148e-01f; /* 0x3e9489f9 */
float
acosf(float x)
@@ -49,13 +52,13 @@
if(ix<=0x32800000) return pio2_hi+pio2_lo;/*if|x|<2**-26*/
z = x*x;
p = z*(pS0+z*(pS1+z*pS2));
- q = one+z*qS1;
+ q = one+z*(qS1+z*qS2);
r = p/q;
return pio2_hi - (x - (pio2_lo-x*r));
} else if (hx<0) { /* x < -0.5 */
z = (one+x)*(float)0.5;
p = z*(pS0+z*(pS1+z*pS2));
- q = one+z*qS1;
+ q = one+z*(qS1+z*qS2);
s = sqrtf(z);
r = p/q;
w = r*s-pio2_lo;
@@ -69,7 +72,7 @@
SET_FLOAT_WORD(df,idf&0xfffff000);
c = (z-df*df)/(s+df);
p = z*(pS0+z*(pS1+z*pS2));
- q = one+z*qS1;
+ q = one+z*(qS1+z*qS2);
r = p/q;
w = r*s+c;
return (float)2.0*(df+w);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosh.c b/libm/upstream-freebsd/lib/msun/src/e_acosh.c
index 7947995..0e5640b 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosh.c
@@ -1,5 +1,4 @@
-/* @(#)e_acosh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* acosh(x)
* Method :
* Based on
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acoshf.c b/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
index 781ccf2..b6fbd2c 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acoshl.c b/libm/upstream-freebsd/lib/msun/src/e_acoshl.c
index b9f3aed..6bfa624 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acoshl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acoshl.c
@@ -1,6 +1,5 @@
/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36Z das */
-/* @(#)e_acosh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -13,9 +12,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_acosh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosl.c b/libm/upstream-freebsd/lib/msun/src/e_acosl.c
index d33c8fe..2098143 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosl.c
@@ -1,5 +1,4 @@
-/* @(#)e_acos.c 1.3 95/01/18 */
/* FreeBSD: head/lib/msun/src/e_acos.c 176451 2008-02-22 02:30:36Z das */
/*
* ====================================================
@@ -12,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See comments in e_acos.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_asin.c b/libm/upstream-freebsd/lib/msun/src/e_asin.c
index fa180ab..530bf79 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asin.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asin.c
@@ -1,5 +1,4 @@
-/* @(#)e_asin.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* asin(x)
* Method :
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
diff --git a/libm/upstream-freebsd/lib/msun/src/e_asinf.c b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
index db4b9b6..8d1aca2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asinf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
@@ -13,20 +13,23 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
static const float
one = 1.0000000000e+00, /* 0x3F800000 */
-huge = 1.000e+30,
- /* coefficient for R(x^2) */
-pS0 = 1.6666586697e-01,
-pS1 = -4.2743422091e-02,
-pS2 = -8.6563630030e-03,
-qS1 = -7.0662963390e-01;
+huge = 1.000e+30;
+
+/*
+ * The coefficients for the rational approximation were generated over
+ * 0x1p-12f <= x <= 0.5f. The maximum error satisfies log2(e) < -30.084.
+ */
+static const float
+pS0 = 1.66666672e-01f, /* 0x3e2aaaab */
+pS1 = -1.19510300e-01f, /* 0xbdf4c1d1 */
+pS2 = 5.47002675e-03f, /* 0x3bb33de9 */
+qS1 = -1.16706085e+00f, /* 0xbf956240 */
+qS2 = 2.90115148e-01f; /* 0x3e9489f9 */
static const double
pio2 = 1.570796326794896558e+00;
@@ -49,7 +52,7 @@
}
t = x*x;
p = t*(pS0+t*(pS1+t*pS2));
- q = one+t*qS1;
+ q = one+t*(qS1+t*qS2);
w = p/q;
return x+x*w;
}
@@ -57,7 +60,7 @@
w = one-fabsf(x);
t = w*(float)0.5;
p = t*(pS0+t*(pS1+t*pS2));
- q = one+t*qS1;
+ q = one+t*(qS1+t*qS2);
s = sqrt(t);
w = p/q;
t = pio2-2.0*(s+s*w);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_asinl.c b/libm/upstream-freebsd/lib/msun/src/e_asinl.c
index a85765f..bb2320e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asinl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asinl.c
@@ -1,5 +1,4 @@
-/* @(#)e_asin.c 1.3 95/01/18 */
/* FreeBSD: head/lib/msun/src/e_asin.c 176451 2008-02-22 02:30:36Z das */
/*
* ====================================================
@@ -12,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See comments in e_asin.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atan2.c b/libm/upstream-freebsd/lib/msun/src/e_atan2.c
index 0b2e721..ab5fc72 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atan2.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atan2.c
@@ -1,5 +1,4 @@
-/* @(#)e_atan2.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atan2f.c b/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
index 4ea001d..408f364 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atan2l.c b/libm/upstream-freebsd/lib/msun/src/e_atan2l.c
index 94ebdec..a27fd3e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atan2l.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atan2l.c
@@ -1,5 +1,4 @@
-/* @(#)e_atan2.c 1.3 95/01/18 */
/* FreeBSD: head/lib/msun/src/e_atan2.c 176451 2008-02-22 02:30:36Z das */
/*
* ====================================================
@@ -13,9 +12,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See comments in e_atan2.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atanh.c b/libm/upstream-freebsd/lib/msun/src/e_atanh.c
index 41f3bca..0cc0b92 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atanh.c
@@ -1,5 +1,4 @@
-/* @(#)e_atanh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* atanh(x)
* Method :
* 1.Reduced x to positive by atanh(-x) = -atanh(x)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atanhf.c b/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
index 46643be..a2d6b69 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atanhl.c b/libm/upstream-freebsd/lib/msun/src/e_atanhl.c
index 11d56ea..cb70727 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atanhl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atanhl.c
@@ -1,6 +1,5 @@
/* from: FreeBSD: head/lib/msun/src/e_atanh.c 176451 2008-02-22 02:30:36Z das */
-/* @(#)e_atanh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -13,9 +12,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_atanh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_cosh.c b/libm/upstream-freebsd/lib/msun/src/e_cosh.c
index 071663e..5c3614e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_cosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_cosh.c
@@ -1,5 +1,4 @@
-/* @(#)e_cosh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* cosh(x)
* Method :
* mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
diff --git a/libm/upstream-freebsd/lib/msun/src/e_coshf.c b/libm/upstream-freebsd/lib/msun/src/e_coshf.c
index 1673315..40443b8 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_coshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_coshf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_coshl.c b/libm/upstream-freebsd/lib/msun/src/e_coshl.c
index 4e3b283..efb5094 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_coshl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_coshl.c
@@ -11,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_cosh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_fmod.c b/libm/upstream-freebsd/lib/msun/src/e_fmod.c
index 6d5f533..77afd11 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_fmod.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_fmod.c
@@ -1,5 +1,4 @@
-/* @(#)e_fmod.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* fmod(x,y)
* Return x mod y in exact arithmetic
diff --git a/libm/upstream-freebsd/lib/msun/src/e_fmodf.c b/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
index 3cef921..a7d1a0c 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* fmodf(x,y)
* Return x mod y in exact arithmetic
diff --git a/libm/upstream-freebsd/lib/msun/src/e_fmodl.c b/libm/upstream-freebsd/lib/msun/src/e_fmodl.c
index ad3bcc3..d5997e1 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_fmodl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_fmodl.c
@@ -1,4 +1,3 @@
-/* @(#)e_fmod.c 1.3 95/01/18 */
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <stdint.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gamma.c b/libm/upstream-freebsd/lib/msun/src/e_gamma.c
index a13f3e2..43541ad 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gamma.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gamma.c
@@ -1,5 +1,4 @@
-/* @(#)e_gamma.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* gamma(x)
* Return the logarithm of the Gamma function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c b/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
index 2d996ca..f317ae4 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
@@ -1,5 +1,4 @@
-/* @(#)e_gamma_r.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* gamma_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gammaf.c b/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
index 563c148..98da571 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* gammaf(x)
* Return the logarithm of the Gamma function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c b/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
index d7fc2db..ae80c1b 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* gammaf_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypot.c b/libm/upstream-freebsd/lib/msun/src/e_hypot.c
index 8e3f931..a291af5 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypot.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypot.c
@@ -1,5 +1,4 @@
-/* @(#)e_hypot.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* hypot(x,y)
*
* Method :
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypotf.c b/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
index a3b8c86..e45486e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypotl.c b/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
index fc43538..d8e060a 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
@@ -1,4 +1,3 @@
-/* From: @(#)e_hypot.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* long double version of hypot(). See e_hypot.c for most comments. */
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0.c b/libm/upstream-freebsd/lib/msun/src/e_j0.c
index c43ab69..b19661c 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0.c
@@ -1,4 +1,3 @@
-/* @(#)e_j0.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* j0(x), y0(x)
* Bessel function of the first and second kinds of order zero.
* Method -- j0(x):
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0f.c b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
index 290be04..de04a9f 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_j0.c for complete comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1.c b/libm/upstream-freebsd/lib/msun/src/e_j1.c
index ee3f6fc..06a74b0 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1.c
@@ -1,4 +1,3 @@
-/* @(#)e_j1.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* j1(x), y1(x)
* Bessel function of the first and second kinds of order zero.
* Method -- j1(x):
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1f.c b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
index e1f4498..28cee8e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_j1.c for complete comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jn.c b/libm/upstream-freebsd/lib/msun/src/e_jn.c
index 6b876ce..0a71566 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jn.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jn.c
@@ -1,4 +1,3 @@
-/* @(#)e_jn.c 1.4 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* jn(n, x), yn(n, x)
* floating point Bessel's function of the 1st and 2nd kind
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jnf.c b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
index ba58622..b55eaf5 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jnf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_jn.c for complete comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgamma.c b/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
index 9c4a30e..46e7c25 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
@@ -1,5 +1,4 @@
-/* @(#)e_lgamma.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* lgamma(x)
* Return the logarithm of the Gamma function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
index c020b63..30edd65 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
@@ -1,4 +1,3 @@
-/* @(#)e_lgamma_r.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* lgamma_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c b/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
index 00a816c..cc34e44 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* lgammaf(x)
* Return the logarithm of the Gamma function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c b/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
index fdd2321..3f863ce 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
@@ -14,9 +14,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgammal.c b/libm/upstream-freebsd/lib/msun/src/e_lgammal.c
index ebc2fc7..51e3216 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgammal.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgammal.c
@@ -1,4 +1,3 @@
-/* @(#)e_lgamma.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log10.c b/libm/upstream-freebsd/lib/msun/src/e_log10.c
index 595c238..3647fb0 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log10.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log10.c
@@ -1,5 +1,4 @@
-/* @(#)e_log10.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* Return the base 10 logarithm of x. See e_log.c and k_log.h for most
* comments.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log10f.c b/libm/upstream-freebsd/lib/msun/src/e_log10f.c
index d0c3a53..ee01d6f 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log10f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log10f.c
@@ -9,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* Float version of e_log10.c. See the latter for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/src/e_rem_pio2.c b/libm/upstream-freebsd/lib/msun/src/e_rem_pio2.c
index 47b6513..16a57a0 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_rem_pio2.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_rem_pio2.c
@@ -1,5 +1,4 @@
-/* @(#)e_rem_pio2.c 1.4 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -13,9 +12,6 @@
* Optimized by Bruce D. Evans.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* __ieee754_rem_pio2(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
@@ -49,7 +45,7 @@
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
#ifdef INLINE_REM_PIO2
-static __inline __always_inline
+static __always_inline
#endif
int
__ieee754_rem_pio2(double x, double *y)
@@ -166,7 +162,7 @@
/* set z = scalbn(|x|,ilogb(x)-23) */
GET_LOW_WORD(low,x);
e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */
- INSERT_WORDS(z, ix - ((int32_t)(e0<<20)), low);
+ INSERT_WORDS(z, ix - ((int32_t)((u_int32_t)e0<<20)), low);
for(i=0;i<2;i++) {
tx[i] = (double)((int32_t)(z));
z = (z-tx[i])*two24;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_rem_pio2f.c b/libm/upstream-freebsd/lib/msun/src/e_rem_pio2f.c
index 597f613..84cd9bf 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_rem_pio2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_rem_pio2f.c
@@ -14,9 +14,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* __ieee754_rem_pio2f(x,y)
*
* return the remainder of x rem pi/2 in *y
@@ -41,7 +38,7 @@
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
#ifdef INLINE_REM_PIO2F
-static __inline __always_inline
+static __always_inline
#endif
int
__ieee754_rem_pio2f(float x, double *y)
@@ -70,7 +67,7 @@
}
/* set z = scalbn(|x|,ilogb(|x|)-23) */
e0 = (ix>>23)-150; /* e0 = ilogb(|x|)-23; */
- SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23)));
+ SET_FLOAT_WORD(z, ix - ((int32_t)((u_int32_t)e0<<23)));
tx[0] = z;
n = __kernel_rem_pio2(tx,ty,e0,1,0);
if(hx<0) {*y = -ty[0]; return -n;}
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainder.c b/libm/upstream-freebsd/lib/msun/src/e_remainder.c
index 13156d8..a5fb714 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainder.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainder.c
@@ -1,5 +1,4 @@
-/* @(#)e_remainder.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* remainder(x,p)
* Return :
* returns x REM p = x - [x/p]*p as if in infinite
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainderf.c b/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
index e0dcfd1..4a6ff63 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
index 2295673..7a681cd 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
long double
diff --git a/libm/upstream-freebsd/lib/msun/src/e_scalb.c b/libm/upstream-freebsd/lib/msun/src/e_scalb.c
index 84a6893..28d2ae6 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_scalb.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_scalb.c
@@ -1,5 +1,4 @@
-/* @(#)e_scalb.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* scalb(x, fn) is provide for
* passing various standard test suite. One
diff --git a/libm/upstream-freebsd/lib/msun/src/e_scalbf.c b/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
index 28483a5..557a5a0 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sinh.c b/libm/upstream-freebsd/lib/msun/src/e_sinh.c
index 9fe8999..5eec75e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sinh.c
@@ -1,5 +1,4 @@
-/* @(#)e_sinh.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* sinh(x)
* Method :
* mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sinhf.c b/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
index 082beb1..e9fe732 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sinhl.c b/libm/upstream-freebsd/lib/msun/src/e_sinhl.c
index 38d3df1..cf481b2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sinhl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sinhl.c
@@ -11,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See e_sinh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
index 67c777f..a785536 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <fenv.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/k_cos.c b/libm/upstream-freebsd/lib/msun/src/k_cos.c
index c4702e6..2eb5e04 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_cos.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_cos.c
@@ -1,5 +1,4 @@
-/* @(#)k_cos.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* __kernel_cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
diff --git a/libm/upstream-freebsd/lib/msun/src/k_cosf.c b/libm/upstream-freebsd/lib/msun/src/k_cosf.c
index f7a2c0a..934c1c7 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_cosf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_cosf.c
@@ -14,11 +14,6 @@
* ====================================================
*/
-#ifndef INLINE_KERNEL_COSDF
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/k_exp.c b/libm/upstream-freebsd/lib/msun/src/k_exp.c
index 1b86cd6..383616d 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_exp.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_exp.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/k_expf.c b/libm/upstream-freebsd/lib/msun/src/k_expf.c
index 7071632..2af0c6d 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_expf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_expf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/k_log.h b/libm/upstream-freebsd/lib/msun/src/k_log.h
index aaff8bd..da8f008 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_log.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_log.h
@@ -1,5 +1,4 @@
-/* @(#)e_log.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* k_log1p(f):
* Return log(1+f) - f for 1+f in ~[sqrt(2)/2, sqrt(2)].
diff --git a/libm/upstream-freebsd/lib/msun/src/k_logf.h b/libm/upstream-freebsd/lib/msun/src/k_logf.h
index 71c547e..72b6751 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_logf.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_logf.h
@@ -9,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* Float version of k_log.h. See the latter for most comments.
*/
diff --git a/libm/upstream-freebsd/lib/msun/src/k_rem_pio2.c b/libm/upstream-freebsd/lib/msun/src/k_rem_pio2.c
index 0a717f7..3d49d14 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_rem_pio2.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_rem_pio2.c
@@ -1,5 +1,4 @@
-/* @(#)k_rem_pio2.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* __kernel_rem_pio2(x,y,e0,nx,prec)
* double x[],y[]; int e0,nx,prec;
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sin.c b/libm/upstream-freebsd/lib/msun/src/k_sin.c
index 12ee8c1..5b97d86 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sin.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_sin.c
@@ -1,5 +1,4 @@
-/* @(#)k_sin.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* __kernel_sin( x, y, iy)
* kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sincos.h b/libm/upstream-freebsd/lib/msun/src/k_sincos.h
index 6f03be2..796e72a 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sincos.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_sincos.h
@@ -11,9 +11,6 @@
* k_sin.c and k_cos.c merged by Steven G. Kargl.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
static const double
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sincosf.h b/libm/upstream-freebsd/lib/msun/src/k_sincosf.h
index 073986d..f031016 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sincosf.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_sincosf.h
@@ -11,9 +11,6 @@
* k_sinf.c and k_cosf.c merged by Steven G. Kargl.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
static const double
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sincosl.h b/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
index 6425f14..cf8536c 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
@@ -12,9 +12,6 @@
* k_sinl.c and k_cosl.c merged by Steven G. Kargl
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#if LDBL_MANT_DIG == 64 /* ld80 version of k_sincosl.c. */
#if defined(__amd64__) || defined(__i386__)
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sinf.c b/libm/upstream-freebsd/lib/msun/src/k_sinf.c
index 0841759..ebebd96 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sinf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_sinf.c
@@ -14,11 +14,6 @@
* ====================================================
*/
-#ifndef INLINE_KERNEL_SINDF
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/k_tan.c b/libm/upstream-freebsd/lib/msun/src/k_tan.c
index 2e86c3b..92f30a6 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_tan.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_tan.c
@@ -1,5 +1,3 @@
-/* @(#)k_tan.c 1.5 04/04/22 SMI */
-
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
@@ -10,10 +8,6 @@
* ====================================================
*/
-/* INDENT OFF */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* __kernel_tan( x, y, k )
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_tanf.c b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
index 5be1445..83bfad9 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_tanf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
@@ -13,11 +13,6 @@
* ====================================================
*/
-#ifndef INLINE_KERNEL_TANDF
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/math_private.h b/libm/upstream-freebsd/lib/msun/src/math_private.h
index a55d97a..1595f90 100644
--- a/libm/upstream-freebsd/lib/msun/src/math_private.h
+++ b/libm/upstream-freebsd/lib/msun/src/math_private.h
@@ -10,8 +10,6 @@
*/
/*
- * from: @(#)fdlibm.h 5.1 93/09/24
- * $FreeBSD$
*/
#ifndef _MATH_PRIVATE_H_
@@ -407,7 +405,7 @@
* any extra precision into the type of 'a' -- 'a' should have type float_t,
* double_t or long double. b's type should be no larger than 'a's type.
* Callers should use these types with scopes as large as possible, to
- * reduce their own extra-precision and efficiciency problems. In
+ * reduce their own extra-precision and efficiency problems. In
* particular, they shouldn't convert back and forth just to call here.
*/
#ifdef DEBUG
diff --git a/libm/upstream-freebsd/lib/msun/src/s_asinh.c b/libm/upstream-freebsd/lib/msun/src/s_asinh.c
index a1b9169..daebf21 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_asinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_asinh.c
@@ -1,4 +1,3 @@
-/* @(#)s_asinh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* asinh(x)
* Method :
* Based on
diff --git a/libm/upstream-freebsd/lib/msun/src/s_asinhf.c b/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
index 72bcefe..4e622d5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_asinhl.c b/libm/upstream-freebsd/lib/msun/src/s_asinhl.c
index ba28f59..b939fae 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_asinhl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_asinhl.c
@@ -1,6 +1,5 @@
/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36Z das */
-/* @(#)s_asinh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See s_asinh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_atan.c b/libm/upstream-freebsd/lib/msun/src/s_atan.c
index 566f5dc..bff8b5c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_atan.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_atan.c
@@ -1,4 +1,3 @@
-/* @(#)s_atan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* atan(x)
* Method
* 1. Reduce x to positive by atan(x) = -atan(-x).
diff --git a/libm/upstream-freebsd/lib/msun/src/s_atanf.c b/libm/upstream-freebsd/lib/msun/src/s_atanf.c
index b3a371f..2c38014 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_atanf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_atanf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_atanl.c b/libm/upstream-freebsd/lib/msun/src/s_atanl.c
index ff29c3c..d9e6174 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_atanl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_atanl.c
@@ -1,4 +1,3 @@
-/* @(#)s_atan.c 5.1 93/09/24 */
/* FreeBSD: head/lib/msun/src/s_atan.c 176451 2008-02-22 02:30:36Z das */
/*
* ====================================================
@@ -11,9 +10,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See comments in s_atan.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_carg.c b/libm/upstream-freebsd/lib/msun/src/s_carg.c
index f203198..ea7edfd 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_carg.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_carg.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargf.c b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
index 6ea487c..25ab65e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargl.c b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
index ba39438..8a1a108 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
index 4353d34..6bf8424 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
@@ -1,4 +1,3 @@
-/* @(#)s_cbrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
* Optimized by Bruce D. Evans.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrtf.c b/libm/upstream-freebsd/lib/msun/src/s_cbrtf.c
index 454f974..a225d3e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrtf.c
@@ -14,9 +14,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
index b15c96e..f1950e2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
@@ -14,9 +14,6 @@
* and David A. Schultz.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
index 0fd9206..3d46c99 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
@@ -38,9 +38,6 @@
* must satisfy both cosh(conj(z)) == conj(cosh(z)) and cosh(-z) == cosh(z).
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
index 2db8403..aeb2dec 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
@@ -30,9 +30,6 @@
* Float version of ccosh(). See s_ccosh.c for details.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ceil.c b/libm/upstream-freebsd/lib/msun/src/s_ceil.c
index 929f813..e6699bc 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ceil.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ceil.c
@@ -1,4 +1,3 @@
-/* @(#)s_ceil.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ceil(x)
* Return x rounded toward -inf to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ceilf.c b/libm/upstream-freebsd/lib/msun/src/s_ceilf.c
index 23bfe04..cc19afa 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ceilf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ceilf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ceill.c b/libm/upstream-freebsd/lib/msun/src/s_ceill.c
index 2d1045f..ded36c1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ceill.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ceill.c
@@ -7,13 +7,8 @@
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
- *
- * From: @(#)s_ceil.c 5.1 93/09/24
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* ceill(x)
* Return x rounded toward -inf to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexp.c b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
index 8db763d..0151768 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
index 7247301..a6c0c99 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimag.c b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
index 0b14fd7..5779b2a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimag.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
index 42a1efd..ca2bdf2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
index 9707bc3..3986430 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_clog.c b/libm/upstream-freebsd/lib/msun/src/s_clog.c
index 8150fa7..2129890 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_clog.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_clog.c
@@ -24,9 +24,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_clogf.c b/libm/upstream-freebsd/lib/msun/src/s_clogf.c
index 19a9445..2204e1e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_clogf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_clogf.c
@@ -24,9 +24,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_clogl.c b/libm/upstream-freebsd/lib/msun/src/s_clogl.c
index e59a137..075bdb4 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_clogl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_clogl.c
@@ -24,9 +24,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#ifdef __i386__
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conj.c b/libm/upstream-freebsd/lib/msun/src/s_conj.c
index a83abd8..1203ba6 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conj.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjf.c b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
index f9eb146..9720998 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjl.c b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
index 4b86f2e..ef084f4 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cos.c b/libm/upstream-freebsd/lib/msun/src/s_cos.c
index 29804f4..44ecad9 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cos.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cos.c
@@ -1,4 +1,3 @@
-/* @(#)s_cos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* cos(x)
* Return cosine function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cosl.c b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
index 6f0b36f..32fc8b2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* Limited testing on pseudorandom numbers drawn within [-2e8:4e8] shows
* an accuracy of <= 0.7412 ULP.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cpow.c b/libm/upstream-freebsd/lib/msun/src/s_cpow.c
index cdc57bd..b887db5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cpow.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cpow.c
@@ -43,9 +43,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cpowf.c b/libm/upstream-freebsd/lib/msun/src/s_cpowf.c
index aeb773b..1442910 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cpowf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cpowf.c
@@ -43,9 +43,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cpowl.c b/libm/upstream-freebsd/lib/msun/src/s_cpowl.c
index 5d43b55..39797ca 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cpowl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cpowl.c
@@ -43,9 +43,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cproj.c b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
index 5b0d4ed..9eebb45 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cproj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
index 0d76e75..13d90ba 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
index 7fc35d2..083b5fa 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creal.c b/libm/upstream-freebsd/lib/msun/src/s_creal.c
index 5c8734e..b3a82f0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creal.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_crealf.c b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
index a93421f..36fc115 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_crealf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creall.c b/libm/upstream-freebsd/lib/msun/src/s_creall.c
index b4eb9ef..b56143a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creall.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creall.c
@@ -24,8 +24,6 @@
* 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 <complex.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinh.c b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
index b3928ce..e7ed10e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
@@ -38,9 +38,6 @@
* must satisfy both sinh(conj(z)) == conj(sinh(z)) and sinh(-z) == -sinh(z).
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
index a8d6f2d..c439275 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
@@ -30,9 +30,6 @@
* Float version of csinh(). See s_csinh.c for details.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
index d96c344..c40b5a6 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
index e3ef4d0..b572451 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
index d564133..0f375f3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
index aa4e10c..6904363 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
@@ -65,9 +65,6 @@
* precision. I also handle large x differently.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
index e9ebe4f..551e143 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
@@ -30,9 +30,6 @@
* Hyperbolic tangent of a complex argument z. See s_ctanh.c for details.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_erf.c b/libm/upstream-freebsd/lib/msun/src/s_erf.c
index ab2dc19..a9de122 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_erf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_erf.c
@@ -1,4 +1,3 @@
-/* @(#)s_erf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* double erf(double x)
* double erfc(double x)
* x
diff --git a/libm/upstream-freebsd/lib/msun/src/s_erff.c b/libm/upstream-freebsd/lib/msun/src/s_erff.c
index d6cfbd2..6c8f406 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_erff.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_erff.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_expm1.c b/libm/upstream-freebsd/lib/msun/src/s_expm1.c
index 844f103..cdc225e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_expm1.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_expm1.c
@@ -1,4 +1,3 @@
-/* @(#)s_expm1.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* expm1(x)
* Returns exp(x)-1, the exponential of x minus 1.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_expm1f.c b/libm/upstream-freebsd/lib/msun/src/s_expm1f.c
index b47daac..6887bf2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_expm1f.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_expm1f.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fdim.c b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
index b81dbac..4f56ee4 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fdim.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#define DECL(type, fn) \
diff --git a/libm/upstream-freebsd/lib/msun/src/s_finite.c b/libm/upstream-freebsd/lib/msun/src/s_finite.c
index 4c51352..a3fd599 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_finite.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_finite.c
@@ -1,4 +1,3 @@
-/* @(#)s_finite.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* finite(x) returns 1 is x is finite, else 0;
* no branching!
diff --git a/libm/upstream-freebsd/lib/msun/src/s_finitef.c b/libm/upstream-freebsd/lib/msun/src/s_finitef.c
index c62239e..9a4a876 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_finitef.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_finitef.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* finitef(x) returns 1 is x is finite, else 0;
* no branching!
diff --git a/libm/upstream-freebsd/lib/msun/src/s_floor.c b/libm/upstream-freebsd/lib/msun/src/s_floor.c
index 65f696a..7ca65b1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_floor.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_floor.c
@@ -1,4 +1,3 @@
-/* @(#)s_floor.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* floor(x)
* Return x rounded toward -inf to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_floorf.c b/libm/upstream-freebsd/lib/msun/src/s_floorf.c
index 6b510de..d497157 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_floorf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_floorf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* floorf(x)
* Return x rounded toward -inf to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_floorl.c b/libm/upstream-freebsd/lib/msun/src/s_floorl.c
index 6cec3e7..3b54cab 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_floorl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_floorl.c
@@ -7,13 +7,8 @@
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
- *
- * From: @(#)s_floor.c 5.1 93/09/24
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* floorl(x)
* Return x rounded toward -inf to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fma.c b/libm/upstream-freebsd/lib/msun/src/s_fma.c
index 2fd7075..23a8449 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fma.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fma.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <fenv.h>
#include <float.h>
#include <math.h>
@@ -225,17 +222,17 @@
case FE_TONEAREST:
return (z);
case FE_TOWARDZERO:
- if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
+ if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0))
return (z);
else
return (nextafter(z, 0));
case FE_DOWNWARD:
- if (x > 0.0 ^ y < 0.0)
+ if ((x > 0.0) ^ (y < 0.0))
return (z);
else
return (nextafter(z, -INFINITY));
default: /* FE_UPWARD */
- if (x > 0.0 ^ y < 0.0)
+ if ((x > 0.0) ^ (y < 0.0))
return (nextafter(z, INFINITY));
else
return (z);
@@ -247,7 +244,7 @@
zs = copysign(DBL_MIN, zs);
fesetround(FE_TONEAREST);
- /* work around clang bug 8100 */
+ /* work around clang issue #8472 */
volatile double vxs = xs;
/*
@@ -263,14 +260,14 @@
spread = ex + ey;
- if (r.hi == 0.0) {
+ if (r.hi == 0.0 && xy.lo == 0) {
/*
* When the addends cancel to 0, ensure that the result has
* the correct sign.
*/
fesetround(oround);
volatile double vzs = zs; /* XXX gcc CSE bug workaround */
- return (xy.hi + vzs + ldexp(xy.lo, spread));
+ return (xy.hi + vzs);
}
if (oround != FE_TONEAREST) {
@@ -279,7 +276,7 @@
* rounding modes.
*/
fesetround(oround);
- /* work around clang bug 8100 */
+ /* work around clang issue #8472 */
volatile double vrlo = r.lo;
adj = vrlo + xy.lo;
return (ldexp(r.hi + adj, spread));
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
index ae979cb..5f3d5d1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <fenv.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmal.c b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
index a0622a2..2fca206 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <fenv.h>
#include <float.h>
#include <math.h>
@@ -206,17 +203,17 @@
case FE_TONEAREST:
return (z);
case FE_TOWARDZERO:
- if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
+ if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0))
return (z);
else
return (nextafterl(z, 0));
case FE_DOWNWARD:
- if (x > 0.0 ^ y < 0.0)
+ if ((x > 0.0) ^ (y < 0.0))
return (z);
else
return (nextafterl(z, -INFINITY));
default: /* FE_UPWARD */
- if (x > 0.0 ^ y < 0.0)
+ if ((x > 0.0) ^ (y < 0.0))
return (nextafterl(z, INFINITY));
else
return (z);
@@ -228,7 +225,7 @@
zs = copysignl(LDBL_MIN, zs);
fesetround(FE_TONEAREST);
- /* work around clang bug 8100 */
+ /* work around clang issue #8472 */
volatile long double vxs = xs;
/*
@@ -244,14 +241,14 @@
spread = ex + ey;
- if (r.hi == 0.0) {
+ if (r.hi == 0.0 && xy.lo == 0) {
/*
* When the addends cancel to 0, ensure that the result has
* the correct sign.
*/
fesetround(oround);
volatile long double vzs = zs; /* XXX gcc CSE bug workaround */
- return (xy.hi + vzs + ldexpl(xy.lo, spread));
+ return (xy.hi + vzs);
}
if (oround != FE_TONEAREST) {
@@ -260,7 +257,7 @@
* rounding modes.
*/
fesetround(oround);
- /* work around clang bug 8100 */
+ /* work around clang issue #8472 */
volatile long double vrlo = r.lo;
adj = vrlo + xy.lo;
return (ldexpl(r.hi + adj, spread));
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmax.c b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
index 42bd11c..5d437fc 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmax.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
index 10667d3..1572572 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#include "fpmath.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
index bf42587..73e2a4b 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#include "fpmath.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmin.c b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
index e79071d..a349e5d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmin.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminf.c b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
index 19ffd42..5c2537e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#include "fpmath.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminl.c b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
index c906f1d..7ac17e3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#include "fpmath.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_frexp.c b/libm/upstream-freebsd/lib/msun/src/s_frexp.c
index 318a991..90aea67 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_frexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_frexp.c
@@ -1,4 +1,3 @@
-/* @(#)s_frexp.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* for non-zero x
* x = frexp(arg,&exp);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_frexpf.c b/libm/upstream-freebsd/lib/msun/src/s_frexpf.c
index 5a7c486..bca27b5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_frexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_frexpf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
index 7101615..32f1264 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
@@ -24,8 +24,6 @@
* 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 <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ilogb.c b/libm/upstream-freebsd/lib/msun/src/s_ilogb.c
index a930bc9..27e0bbb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ilogb.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ilogb.c
@@ -1,4 +1,3 @@
-/* @(#)s_ilogb.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* ilogb(double x)
* return the binary exponent of non-zero x
* ilogb(0) = FP_ILOGB0
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ilogbf.c b/libm/upstream-freebsd/lib/msun/src/s_ilogbf.c
index 93fe295..e0f8fee 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ilogbf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ilogbf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <limits.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ilogbl.c b/libm/upstream-freebsd/lib/msun/src/s_ilogbl.c
index 3211f44..4d8fb8f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ilogbl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ilogbl.c
@@ -1,5 +1,4 @@
/*
- * From: @(#)s_ilogb.c 5.1 93/09/24
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <limits.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llrint.c b/libm/upstream-freebsd/lib/msun/src/s_llrint.c
index 7c959ec..5e27603 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llrint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llrint.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type double
#define roundit rint
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llrintf.c b/libm/upstream-freebsd/lib/msun/src/s_llrintf.c
index 7ec6015..b117f7c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llrintf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llrintf.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type float
#define roundit rintf
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llrintl.c b/libm/upstream-freebsd/lib/msun/src/s_llrintl.c
index 6ef8375..82f4529 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llrintl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llrintl.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type long double
#define roundit rintl
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llround.c b/libm/upstream-freebsd/lib/msun/src/s_llround.c
index 827dfc1..3983ce1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llround.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llround.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type double
#define roundit round
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llroundf.c b/libm/upstream-freebsd/lib/msun/src/s_llroundf.c
index c037a18..827d915 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llroundf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llroundf.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type float
#define roundit roundf
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_llroundl.c b/libm/upstream-freebsd/lib/msun/src/s_llroundl.c
index 02c44eb..40cad84 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_llroundl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_llroundl.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type long double
#define roundit roundl
#define dtype long long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_log1p.c b/libm/upstream-freebsd/lib/msun/src/s_log1p.c
index 3cc77bd..7131bea 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_log1p.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_log1p.c
@@ -1,4 +1,3 @@
-/* @(#)s_log1p.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* double log1p(double x)
*
* Method :
diff --git a/libm/upstream-freebsd/lib/msun/src/s_log1pf.c b/libm/upstream-freebsd/lib/msun/src/s_log1pf.c
index df04c67..dad567b 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_log1pf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_log1pf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_logb.c b/libm/upstream-freebsd/lib/msun/src/s_logb.c
index a47e354..ec777fd 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_logb.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_logb.c
@@ -1,4 +1,3 @@
-/* @(#)s_logb.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* double logb(x)
* IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_logbf.c b/libm/upstream-freebsd/lib/msun/src/s_logbf.c
index 3ab190d..0416a9c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_logbf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_logbf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_logbl.c b/libm/upstream-freebsd/lib/msun/src/s_logbl.c
index ee1a91f..1641dfb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_logbl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_logbl.c
@@ -1,5 +1,4 @@
/*
- * From: @(#)s_ilogb.c 5.1 93/09/24
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <limits.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lrint.c b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
index be00cbb..b1e9654 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lrint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
@@ -26,12 +26,10 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <fenv.h>
#include <math.h>
#ifndef type
-__FBSDID("$FreeBSD$");
#define type double
#define roundit rint
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lrintf.c b/libm/upstream-freebsd/lib/msun/src/s_lrintf.c
index a757ded..1c040e8 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lrintf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lrintf.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type float
#define roundit rintf
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lrintl.c b/libm/upstream-freebsd/lib/msun/src/s_lrintl.c
index 497b442..91614e8 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lrintl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lrintl.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type long double
#define roundit rintl
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lround.c b/libm/upstream-freebsd/lib/msun/src/s_lround.c
index 00f4b95..ae2f5ce 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lround.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lround.c
@@ -26,13 +26,11 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/limits.h>
#include <fenv.h>
#include <math.h>
#ifndef type
-__FBSDID("$FreeBSD$");
#define type double
#define roundit round
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lroundf.c b/libm/upstream-freebsd/lib/msun/src/s_lroundf.c
index e24fe7f..86e63cc 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lroundf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lroundf.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type float
#define roundit roundf
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lroundl.c b/libm/upstream-freebsd/lib/msun/src/s_lroundl.c
index e410827..57a2e90 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lroundl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lroundl.c
@@ -1,6 +1,3 @@
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#define type long double
#define roundit roundl
#define dtype long
diff --git a/libm/upstream-freebsd/lib/msun/src/s_modf.c b/libm/upstream-freebsd/lib/msun/src/s_modf.c
index ab13191..6ee2d5a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_modf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_modf.c
@@ -1,4 +1,3 @@
-/* @(#)s_modf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,10 +9,6 @@
* ====================================================
*/
-#ifndef lint
-static char rcsid[] = "$FreeBSD$";
-#endif
-
/*
* modf(double x, double *iptr)
* return fraction part of x, and return x's integral part in *iptr.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_modff.c b/libm/upstream-freebsd/lib/msun/src/s_modff.c
index 062259c..39f6c1c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_modff.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_modff.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_modfl.c b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
index 8e5c4d3..32470eb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_modfl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
@@ -34,8 +34,6 @@
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
- *
- * $FreeBSD$
*/
#include <float.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nan.c b/libm/upstream-freebsd/lib/msun/src/s_nan.c
index 1345f22..d129a55 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nan.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nan.c
@@ -24,8 +24,6 @@
* 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/endian.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
index ae6ffde..3dcaf98 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <fenv.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nextafter.c b/libm/upstream-freebsd/lib/msun/src/s_nextafter.c
index 52dd21c..1b394e5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nextafter.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nextafter.c
@@ -1,4 +1,3 @@
-/* @(#)s_nextafter.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* IEEE functions
* nextafter(x,y)
* return the next machine floating-point number of x in the
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nextafterf.c b/libm/upstream-freebsd/lib/msun/src/s_nextafterf.c
index 96e21ef..418b126 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nextafterf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nextafterf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nextafterl.c b/libm/upstream-freebsd/lib/msun/src/s_nextafterl.c
index 9c61a43..fe5a010 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nextafterl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nextafterl.c
@@ -1,4 +1,3 @@
-/* @(#)s_nextafter.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* IEEE functions
* nextafter(x,y)
* return the next machine floating-point number of x in the
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nexttoward.c b/libm/upstream-freebsd/lib/msun/src/s_nexttoward.c
index b2a50d3..5482dc2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nexttoward.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nexttoward.c
@@ -1,4 +1,3 @@
-/* @(#)s_nextafter.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* We assume that a long double has a 15-bit exponent. On systems
* where long double is the same as double, nexttoward() is an alias
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nexttowardf.c b/libm/upstream-freebsd/lib/msun/src/s_nexttowardf.c
index 9ddfff9..05c89f4 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nexttowardf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nexttowardf.c
@@ -9,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "fpmath.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_remquo.c b/libm/upstream-freebsd/lib/msun/src/s_remquo.c
index 6a111df..206d290 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_remquo.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_remquo.c
@@ -1,4 +1,3 @@
-/* @(#)e_fmod.c 1.3 95/01/18 */
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_remquof.c b/libm/upstream-freebsd/lib/msun/src/s_remquof.c
index f4c1016..9cd1485 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_remquof.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_remquof.c
@@ -1,4 +1,3 @@
-/* @(#)e_fmod.c 1.3 95/01/18 */
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_remquol.c b/libm/upstream-freebsd/lib/msun/src/s_remquol.c
index a9f5813..0dadcea 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_remquol.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_remquol.c
@@ -1,4 +1,3 @@
-/* @(#)e_fmod.c 1.3 95/01/18 */
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <stdint.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_rint.c b/libm/upstream-freebsd/lib/msun/src/s_rint.c
index c56f8fb..d82a9d0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_rint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_rint.c
@@ -1,4 +1,3 @@
-/* @(#)s_rint.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* rint(x)
* Return x rounded to integral value according to the prevailing
diff --git a/libm/upstream-freebsd/lib/msun/src/s_rintf.c b/libm/upstream-freebsd/lib/msun/src/s_rintf.c
index f8743a4..3f0cb90 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_rintf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_rintf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <stdint.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_rintl.c b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
index 790edbc..72c9cab 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_rintl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_round.c b/libm/upstream-freebsd/lib/msun/src/s_round.c
index a112bc5..c1b55f5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_round.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_round.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundf.c b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
index bb6f77c..7c09e09 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundl.c b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
index 9e85423..bc5dfe5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
index e8c6377..42e4669 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
#define NMAX 65536
diff --git a/libm/upstream-freebsd/lib/msun/src/s_significand.c b/libm/upstream-freebsd/lib/msun/src/s_significand.c
index eed80ec..62571bb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_significand.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_significand.c
@@ -1,4 +1,3 @@
-/* @(#)s_signif.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* significand(x) computes just
* scalb(x, (double) -ilogb(x)),
diff --git a/libm/upstream-freebsd/lib/msun/src/s_significandf.c b/libm/upstream-freebsd/lib/msun/src/s_significandf.c
index b33ab7b..3cdaa4d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_significandf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_significandf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sin.c b/libm/upstream-freebsd/lib/msun/src/s_sin.c
index 17ea846..614bcc2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sin.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sin.c
@@ -1,4 +1,3 @@
-/* @(#)s_sin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* sin(x)
* Return sine function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sincos.c b/libm/upstream-freebsd/lib/msun/src/s_sincos.c
index 85e8d74..4e819ea 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sincos.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sincos.c
@@ -12,9 +12,6 @@
* algorithms are contained in the original files.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sincosl.c b/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
index 3dd3457..7fb69aa 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
@@ -26,9 +26,6 @@
* s_sinl.c and s_cosl.c merged by Steven G. Kargl.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinl.c b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
index c5ee106..d0b7b34 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sinl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tan.c b/libm/upstream-freebsd/lib/msun/src/s_tan.c
index 196c27e..20b9516 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tan.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tan.c
@@ -1,4 +1,3 @@
-/* @(#)s_tan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* tan(x)
* Return tangent function of x.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanf.c b/libm/upstream-freebsd/lib/msun/src/s_tanf.c
index 4fe8c17..2462f96 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanf.c
@@ -14,9 +14,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <float.h>
#include "math.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanh.c b/libm/upstream-freebsd/lib/msun/src/s_tanh.c
index 6d26c69..cc8daed 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanh.c
@@ -1,4 +1,3 @@
-/* @(#)s_tanh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/* Tanh(x)
* Return the Hyperbolic Tangent of x
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanhf.c b/libm/upstream-freebsd/lib/msun/src/s_tanhf.c
index f537be4..e56813a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanhf.c
@@ -13,9 +13,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "math.h"
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanhl.c b/libm/upstream-freebsd/lib/msun/src/s_tanhl.c
index b753186..3285b9a 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanhl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanhl.c
@@ -1,6 +1,5 @@
/* from: FreeBSD: head/lib/msun/src/s_tanhl.c XXX */
-/* @(#)s_tanh.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -12,9 +11,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* See s_tanh.c for complete comments.
*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanl.c b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
index c21e38d..3736477 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* Limited testing on pseudorandom numbers drawn within [0:4e8] shows
* an accuracy of <= 1.5 ULP where 247024 values of x out of 40 million
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
index 6cbd356..9fa9df9 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <math.h>
/*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_trunc.c b/libm/upstream-freebsd/lib/msun/src/s_trunc.c
index 63a6753..3ec59f2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_trunc.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_trunc.c
@@ -1,4 +1,3 @@
-/* @(#)s_floor.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* trunc(x)
* Return x rounded toward 0 to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_truncf.c b/libm/upstream-freebsd/lib/msun/src/s_truncf.c
index 384eaee..3f4db30 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_truncf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_truncf.c
@@ -1,4 +1,3 @@
-/* @(#)s_floor.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,9 +9,6 @@
* ====================================================
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* truncf(x)
* Return x rounded toward 0 to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/s_truncl.c b/libm/upstream-freebsd/lib/msun/src/s_truncl.c
index 9e2b511..81e794d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_truncl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_truncl.c
@@ -7,13 +7,8 @@
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
- *
- * From: @(#)s_floor.c 5.1 93/09/24
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* truncl(x)
* Return x rounded toward 0 to integral value
diff --git a/libm/upstream-freebsd/lib/msun/src/w_cabs.c b/libm/upstream-freebsd/lib/msun/src/w_cabs.c
index 543b858..4986461 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_cabs.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_cabs.c
@@ -5,9 +5,6 @@
* Placed into the Public Domain, 1994.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <float.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/w_cabsf.c b/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
index b5065c8..aedbdef 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
@@ -5,11 +5,6 @@
* Placed into the Public Domain, 1994.
*/
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
#include <complex.h>
#include <math.h>
#include "math_private.h"
diff --git a/libm/upstream-freebsd/lib/msun/src/w_cabsl.c b/libm/upstream-freebsd/lib/msun/src/w_cabsl.c
index b715e0c..1539944 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_cabsl.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_cabsl.c
@@ -7,9 +7,6 @@
* Modified by Steven G. Kargl for the long double type.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <complex.h>
#include <math.h>
diff --git a/libm/upstream-freebsd/lib/msun/src/w_dremf.c b/libm/upstream-freebsd/lib/msun/src/w_dremf.c
index 4bfcff2..18df078 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_dremf.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_dremf.c
@@ -4,7 +4,6 @@
* Written by J.T. Conklin, <jtc@wimsey.com>
* Placed into the Public Domain, 1994.
*/
-/* $FreeBSD$ */
#include "math.h"
#include "math_private.h"
diff --git a/libm/x86/lrint.S b/libm/x86/lrint.S
deleted file mode 100644
index df26b30..0000000
--- a/libm/x86/lrint.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-ENTRY(lrint)
- // LP32 sizeof(long) == 4.
- movsd 0x4(%esp),%xmm0
- cvtsd2si %xmm0, %eax
- ret
-END(lrint)
-
-// LP32 sizeof(long double) == sizeof(double).
-ALIAS_SYMBOL(lrintl, lrint);
diff --git a/libm/x86/lrintf.S b/libm/x86/lrintf.S
deleted file mode 100644
index d2dae03..0000000
--- a/libm/x86/lrintf.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-ENTRY(lrintf)
- // LP32 sizeof(long) == 4.
- movss 0x4(%esp),%xmm0
- cvtss2si %xmm0, %eax
- ret
-END(lrintf)
diff --git a/libm/x86_64/lrint.S b/libm/x86_64/lrint.S
deleted file mode 100644
index d678761..0000000
--- a/libm/x86_64/lrint.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-ENTRY(lrint)
- // LP64 sizeof(long) == 8.
- cvtsd2si %xmm0, %rax
- ret
-END(lrint)
-
-// LP64 sizeof(long long) == sizeof(long).
-ALIAS_SYMBOL(llrint, lrint);
diff --git a/libm/x86_64/lrintf.S b/libm/x86_64/lrintf.S
deleted file mode 100644
index 3d3acfb..0000000
--- a/libm/x86_64/lrintf.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright (c) 2014, Intel Corporation
-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.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-ENTRY(lrintf)
- // LP64 sizeof(long) == 8.
- cvtss2si %xmm0, %rax
- ret
-END(lrintf)
-
-// LP64 sizeof(long long) == sizeof(long).
-ALIAS_SYMBOL(llrintf, lrintf);
diff --git a/linker/Android.bp b/linker/Android.bp
index d82e687..8300f01 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -108,6 +108,12 @@
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
+
+ sanitize: {
+ // Supporting memtag_globals in the linker would be tricky,
+ // because it relocates itself very early.
+ memtag_globals: false,
+ },
}
// ========================================================
@@ -184,6 +190,7 @@
"linker_mapped_file_fragment.cpp",
"linker_note_gnu_property.cpp",
"linker_phdr.cpp",
+ "linker_phdr_16kib_compat.cpp",
"linker_relocate.cpp",
"linker_sdk_versions.cpp",
"linker_soinfo.cpp",
@@ -343,11 +350,10 @@
// linker[_asan][64] binary
// ========================================================
-cc_binary {
- name: "linker",
+cc_defaults {
+ name: "linker_binary_defaults",
defaults: [
"linker_bin_template",
- "linux_bionic_supported",
"linker_version_script_overlay",
],
@@ -369,8 +375,6 @@
compile_multilib: "both",
- recovery_available: true,
- vendor_ramdisk_available: true,
apex_available: [
"//apex_available:platform",
"com.android.runtime",
@@ -394,10 +398,26 @@
},
afdo: true,
+}
- // FIXME: Workaround compat issue with obfuscation libraries.
- // http://b/352456802
- lto_O0: true,
+cc_binary {
+ name: "linker",
+ defaults: [
+ "linux_bionic_supported",
+ "linker_binary_defaults",
+ ],
+
+ vendor_ramdisk_available: true,
+}
+
+cc_binary {
+ name: "linker.recovery",
+ defaults: [
+ "linker_binary_defaults",
+ ],
+
+ recovery: true,
+ stem: "linker",
}
// ========================================================
@@ -497,6 +517,7 @@
"linker_mapped_file_fragment.cpp",
"linker_sdk_versions.cpp",
"linker_dlwarning.cpp",
+ "linker_phdr_16kib_compat.cpp"
],
static_libs: [
@@ -538,3 +559,32 @@
},
},
}
+
+cc_fuzz {
+ name: "ElfReader_fuzzer",
+ srcs: [
+ "ElfReader_fuzzer.cpp",
+ "linker.cpp",
+ "linker_block_allocator.cpp",
+ "linker_debug.cpp",
+ "linker_dlwarning.cpp",
+ "linker_globals.cpp",
+ "linker_mapped_file_fragment.cpp",
+ "linker_phdr.cpp",
+ "linker_phdr_16kib_compat.cpp",
+ "linker_sdk_versions.cpp",
+ "linker_utils.cpp",
+ ":elf_note_sources",
+ ],
+ static_libs: [
+ "libasync_safe",
+ "libbase",
+ "libziparchive",
+ ],
+ include_dirs: ["bionic/libc"],
+ // TODO: use all the architectures' files.
+ // We'll either need to give them unique names across architectures,
+ // or change soong to preserve subdirectories in `corpus:`,
+ // and maybe also the [deprecated] LLVM fuzzer infrastructure?
+ corpus: [":bionic_prebuilt_test_elf_files_arm64"],
+}
diff --git a/libm/fenv-access.h b/linker/ElfReader_fuzzer.cpp
similarity index 73%
copy from libm/fenv-access.h
copy to linker/ElfReader_fuzzer.cpp
index 7acb34d..a23132b 100644
--- a/libm/fenv-access.h
+++ b/linker/ElfReader_fuzzer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,21 @@
* SUCH DAMAGE.
*/
-#pragma once
+#include "linker_phdr.h"
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
-#endif
+#include <stddef.h>
+#include <stdint.h>
+
+#include <android-base/file.h>
+
+// See current fuzz coverage here:
+// https://android-coverage.googleplex.com/fuzz_targets/ElfReader_fuzzer/index.html
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ TemporaryFile tf;
+ android::base::WriteFully(tf.fd, data, size);
+
+ ElfReader er;
+ er.Read(tf.path, tf.fd, 0, size);
+ return 0;
+}
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index fee19f4..f811d6d 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -89,6 +89,7 @@
const void* caller_addr) __LINKER_PUBLIC__;
void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
+void __loader_android_set_16kb_appcompat_mode(bool enable_app_compat) __LINKER_PUBLIC__;
libc_shared_globals* __loader_shared_globals() __LINKER_PUBLIC__;
#if defined(__arm__)
_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
@@ -301,6 +302,11 @@
decrement_dso_handle_reference_counter(dso_handle);
}
+void __loader_android_set_16kb_appcompat_mode(bool enable_app_compat) {
+ ScopedPthreadMutexLocker locker(&g_dl_mutex);
+ set_16kb_appcompat_mode(enable_app_compat);
+}
+
libc_shared_globals* __loader_shared_globals() {
return __libc_shared_globals();
}
@@ -331,6 +337,7 @@
__libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_;
__libdl_info->gnu_bucket_ = linker_si.gnu_bucket_;
__libdl_info->gnu_chain_ = linker_si.gnu_chain_;
+ __libdl_info->memtag_dynamic_entries_ = linker_si.memtag_dynamic_entries_;
__libdl_info->ref_count_ = 1;
__libdl_info->strtab_size_ = linker_si.strtab_size_;
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
index 1c03106..c938a16 100644
--- a/linker/ld_android.cpp
+++ b/linker/ld_android.cpp
@@ -55,6 +55,7 @@
__strong_alias(__loader_add_thread_local_dtor, __internal_linker_error);
__strong_alias(__loader_remove_thread_local_dtor, __internal_linker_error);
__strong_alias(__loader_shared_globals, __internal_linker_error);
+__strong_alias(__loader_android_set_16kb_appcompat_mode, __internal_linker_error);
#if defined(__arm__)
__strong_alias(__loader_dl_unwind_find_exidx, __internal_linker_error);
#endif
diff --git a/linker/linker.arm.map b/linker/linker.arm.map
index b805cd6..edfa249 100644
--- a/linker/linker.arm.map
+++ b/linker/linker.arm.map
@@ -25,6 +25,7 @@
__loader_shared_globals;
rtld_db_dlactivity;
__loader_android_handle_signal;
+ __loader_android_set_16kb_appcompat_mode;
local:
*;
};
diff --git a/linker/linker.cpp b/linker/linker.cpp
index e13d37d..8f78915 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -51,6 +51,7 @@
#include <android-base/scopeguard.h>
#include <async_safe/log.h>
#include <bionic/pthread_internal.h>
+#include <platform/bionic/mte.h>
// Private C library headers.
@@ -316,7 +317,7 @@
async_safe_fatal("library name \"%s\" too long", name);
}
- TRACE("name %s: allocating soinfo for ns=%p", name, ns);
+ LD_DEBUG(any, "name %s: allocating soinfo for ns=%p", name, ns);
soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
file_offset, rtld_flags);
@@ -326,7 +327,7 @@
si->generate_handle();
ns->add_soinfo(si);
- TRACE("name %s: allocated soinfo @ %p", name, si);
+ LD_DEBUG(any, "name %s: allocated soinfo @ %p", name, si);
return si;
}
@@ -349,7 +350,7 @@
munmap(reinterpret_cast<void*>(si->get_gap_start()), si->get_gap_size());
}
- TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
+ LD_DEBUG(any, "name %s: freeing soinfo @ %p", si->get_realpath(), si);
if (!solist_remove_soinfo(si)) {
async_safe_fatal("soinfo=%p is not in soinfo_list (double unload?)", si);
@@ -387,7 +388,7 @@
auto length = readlink(proc_self_fd, buf, sizeof(buf));
if (length == -1) {
if (!is_first_stage_init()) {
- PRINT("readlink(\"%s\") failed: %s [fd=%d]", proc_self_fd, strerror(errno), fd);
+ DL_WARN("readlink(\"%s\" [fd=%d]) failed: %m", proc_self_fd, fd);
}
return false;
}
@@ -640,6 +641,11 @@
si_->set_gap_start(elf_reader.gap_start());
si_->set_gap_size(elf_reader.gap_size());
si_->set_should_pad_segments(elf_reader.should_pad_segments());
+ si_->set_should_use_16kib_app_compat(elf_reader.should_use_16kib_app_compat());
+ if (si_->should_use_16kib_app_compat()) {
+ si_->set_compat_relro_start(elf_reader.compat_relro_start());
+ si_->set_compat_relro_size(elf_reader.compat_relro_size());
+ }
return true;
}
@@ -818,8 +824,8 @@
}
if (s != nullptr) {
- TRACE_TYPE(LOOKUP, "%s s->st_value = %p, found->base = %p",
- name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
+ LD_DEBUG(lookup, "%s s->st_value = %p, found->base = %p",
+ name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
}
return s;
@@ -923,7 +929,7 @@
}
const char* const path = normalized_path.c_str();
- TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
+ LD_DEBUG(any, "Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
// Treat an '!/' separator inside a path as the separator between the name
// of the zip file on disk and the subdirectory to search within it.
@@ -936,7 +942,7 @@
char buf[512];
if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
- PRINT("Warning: ignoring very long library path: %s", path);
+ DL_WARN("ignoring very long library path: %s", path);
return -1;
}
@@ -976,8 +982,8 @@
*realpath += separator;
} else {
if (!is_first_stage_init()) {
- PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
- normalized_path.c_str());
+ DL_WARN("unable to get realpath for the library \"%s\". Will use given path.",
+ normalized_path.c_str());
}
*realpath = normalized_path;
}
@@ -988,7 +994,7 @@
static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) {
int n = async_safe_format_buffer(buf, buf_size, "%s/%s", path, name);
if (n < 0 || n >= static_cast<int>(buf_size)) {
- PRINT("Warning: ignoring very long library path: %s/%s", path, name);
+ DL_WARN("ignoring very long library path: %s/%s", path, name);
return false;
}
@@ -1009,8 +1015,7 @@
*file_offset = 0;
if (!realpath_fd(fd, realpath)) {
if (!is_first_stage_init()) {
- PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
- path);
+ DL_WARN("unable to get realpath for the library \"%s\". Will use given path.", path);
}
*realpath = path;
}
@@ -1043,7 +1048,7 @@
ZipArchiveCache* zip_archive_cache,
const char* name, soinfo *needed_by,
off64_t* file_offset, std::string* realpath) {
- TRACE("[ opening %s from namespace %s ]", name, ns->get_name());
+ LD_DEBUG(any, "[ opening %s from namespace %s ]", name, ns->get_name());
// If the name contains a slash, we should attempt to open it directly and not search the paths.
if (strchr(name, '/') != nullptr) {
@@ -1185,7 +1190,7 @@
struct stat file_stat;
if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
- DL_OPEN_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
+ DL_OPEN_ERR("unable to stat file for the library \"%s\": %m", name);
return false;
}
if (file_offset >= file_stat.st_size) {
@@ -1215,7 +1220,7 @@
struct statfs fs_stat;
if (TEMP_FAILURE_RETRY(fstatfs(task->get_fd(), &fs_stat)) != 0) {
- DL_OPEN_ERR("unable to fstatfs file for the library \"%s\": %s", name, strerror(errno));
+ DL_OPEN_ERR("unable to fstatfs file for the library \"%s\": %m", name);
return false;
}
@@ -1249,15 +1254,15 @@
// do not print this if a library is in the list of shared libraries for linked namespaces
if (!maybe_accessible_via_namespace_links(ns, name)) {
- PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
- " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
- " permitted_paths=\"%s\"]",
- name, realpath.c_str(),
- needed_or_dlopened_by,
- ns->get_name(),
- android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
- android::base::Join(ns->get_default_library_paths(), ':').c_str(),
- android::base::Join(ns->get_permitted_paths(), ':').c_str());
+ DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
+ " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
+ " permitted_paths=\"%s\"]",
+ name, realpath.c_str(),
+ needed_or_dlopened_by,
+ ns->get_name(),
+ android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
+ android::base::Join(ns->get_default_library_paths(), ':').c_str(),
+ android::base::Join(ns->get_permitted_paths(), ':').c_str());
}
return false;
}
@@ -1330,10 +1335,9 @@
std::string realpath;
if (!realpath_fd(extinfo->library_fd, &realpath)) {
if (!is_first_stage_init()) {
- PRINT(
- "warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
- "Will use given name.",
- name);
+ DL_WARN("unable to get realpath for the library \"%s\" by extinfo->library_fd. "
+ "Will use given name.",
+ name);
}
realpath = name;
}
@@ -1474,8 +1478,8 @@
// Library might still be loaded, the accurate detection
// of this fact is done by load_library.
- TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder... ]",
- task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
+ LD_DEBUG(any, "[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder... ]",
+ task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags,
true /* search_linked_namespaces */)) {
@@ -1694,16 +1698,24 @@
}
}
+ // The WebView loader uses RELRO sharing in order to promote page sharing of the large RELRO
+ // segment, as it's full of C++ vtables. Because MTE globals, by default, applies random tags to
+ // each global variable, the RELRO segment is polluted and unique for each process. In order to
+ // allow sharing, but still provide some protection, we use deterministic global tagging schemes
+ // for DSOs that are loaded through android_dlopen_ext, such as those loaded by WebView.
+ bool dlext_use_relro =
+ extinfo && extinfo->flags & (ANDROID_DLEXT_WRITE_RELRO | ANDROID_DLEXT_USE_RELRO);
+
// Step 3: pre-link all DT_NEEDED libraries in breadth first order.
bool any_memtag_stack = false;
for (auto&& task : load_tasks) {
soinfo* si = task->get_soinfo();
- if (!si->is_linked() && !si->prelink_image()) {
+ if (!si->is_linked() && !si->prelink_image(dlext_use_relro)) {
return false;
}
// si->memtag_stack() needs to be called after si->prelink_image() which populates
// the dynamic section.
- if (si->has_min_version(7) && si->memtag_stack()) {
+ if (si->memtag_stack()) {
any_memtag_stack = true;
LD_LOG(kLogDlopen,
"... load_library requesting stack MTE for: realpath=\"%s\", soname=\"%s\"",
@@ -1717,7 +1729,7 @@
} else {
// find_library is used by the initial linking step, so we communicate that we
// want memtag_stack enabled to __libc_init_mte.
- __libc_shared_globals()->initial_memtag_stack = true;
+ __libc_shared_globals()->initial_memtag_stack_abi = true;
}
}
@@ -1906,8 +1918,8 @@
if (si->has_min_version(0)) {
soinfo* child = nullptr;
while ((child = si->get_children().pop_front()) != nullptr) {
- TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
- child->get_realpath(), child);
+ LD_DEBUG(any, "%s@%p needs to unload %s@%p", si->get_realpath(), si,
+ child->get_realpath(), child);
child->get_parents().remove(si);
@@ -2197,10 +2209,10 @@
if (file_exists(translated_name_holder.c_str())) {
soinfo* si = nullptr;
if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
- PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
- translated_name_holder.c_str());
+ DL_WARN("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
+ translated_name_holder.c_str());
} else {
- PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ DL_WARN("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
translated_name = translated_name_holder.c_str();
}
}
@@ -2217,10 +2229,10 @@
if (!translated_name_holder.empty() && file_exists(translated_name_holder.c_str())) {
soinfo* si = nullptr;
if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
- PRINT("linker_hwasan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
- translated_name_holder.c_str());
+ DL_WARN("linker_hwasan dlopen NOT translating \"%s\" -> \"%s\": library already loaded",
+ name, translated_name_holder.c_str());
} else {
- PRINT("linker_hwasan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ DL_WARN("linker_hwasan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
translated_name = translated_name_holder.c_str();
}
}
@@ -2358,7 +2370,7 @@
void* tls_block = get_tls_block_for_this_thread(tls_module, /*should_alloc=*/true);
*symbol = static_cast<char*>(tls_block) + sym->st_value;
} else {
- *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
+ *symbol = get_tagged_address(reinterpret_cast<void*>(found->resolve_symbol_address(sym)));
}
failure_guard.Disable();
LD_LOG(kLogDlsym,
@@ -2589,8 +2601,8 @@
if (g_is_ldd) return 0;
ElfW(Addr) ifunc_addr = __bionic_call_ifunc_resolver(resolver_addr);
- TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
- reinterpret_cast<void *>(resolver_addr), reinterpret_cast<void*>(ifunc_addr));
+ LD_DEBUG(calls, "ifunc_resolver@%p returned %p",
+ reinterpret_cast<void *>(resolver_addr), reinterpret_cast<void*>(ifunc_addr));
return ifunc_addr;
}
@@ -2788,15 +2800,25 @@
return true;
}
-static void apply_relr_reloc(ElfW(Addr) offset, ElfW(Addr) load_bias) {
- ElfW(Addr) address = offset + load_bias;
- *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
+static void apply_relr_reloc(ElfW(Addr) offset, ElfW(Addr) load_bias, bool has_memtag_globals) {
+ ElfW(Addr) destination = offset + load_bias;
+ if (!has_memtag_globals) {
+ *reinterpret_cast<ElfW(Addr)*>(destination) += load_bias;
+ return;
+ }
+
+ ElfW(Addr)* tagged_destination =
+ reinterpret_cast<ElfW(Addr)*>(get_tagged_address(reinterpret_cast<void*>(destination)));
+ ElfW(Addr) tagged_value = reinterpret_cast<ElfW(Addr)>(
+ get_tagged_address(reinterpret_cast<void*>(*tagged_destination + load_bias)));
+ *tagged_destination = tagged_value;
}
// Process relocations in SHT_RELR section (experimental).
// Details of the encoding are described in this post:
// https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
-bool relocate_relr(const ElfW(Relr)* begin, const ElfW(Relr)* end, ElfW(Addr) load_bias) {
+bool relocate_relr(const ElfW(Relr) * begin, const ElfW(Relr) * end, ElfW(Addr) load_bias,
+ bool has_memtag_globals) {
constexpr size_t wordsize = sizeof(ElfW(Addr));
ElfW(Addr) base = 0;
@@ -2807,7 +2829,7 @@
if ((entry&1) == 0) {
// Even entry: encodes the offset for next relocation.
offset = static_cast<ElfW(Addr)>(entry);
- apply_relr_reloc(offset, load_bias);
+ apply_relr_reloc(offset, load_bias, has_memtag_globals);
// Set base offset for subsequent bitmap entries.
base = offset + wordsize;
continue;
@@ -2818,7 +2840,7 @@
while (entry != 0) {
entry >>= 1;
if ((entry&1) != 0) {
- apply_relr_reloc(offset, load_bias);
+ apply_relr_reloc(offset, load_bias, has_memtag_globals);
}
offset += wordsize;
}
@@ -2833,7 +2855,7 @@
// An empty list of soinfos
static soinfo_list_t g_empty_list;
-bool soinfo::prelink_image() {
+bool soinfo::prelink_image(bool dlext_use_relro) {
if (flags_ & FLAG_PRELINKED) return true;
/* Extract dynamic section */
ElfW(Word) dynamic_flags = 0;
@@ -2842,8 +2864,8 @@
/* We can't log anything until the linker is relocated */
bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
if (!relocating_linker) {
- INFO("[ Linking \"%s\" ]", get_realpath());
- DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
+ LD_DEBUG(any, "[ Linking \"%s\" ]", get_realpath());
+ LD_DEBUG(any, "si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
}
if (dynamic == nullptr) {
@@ -2853,7 +2875,7 @@
return false;
} else {
if (!relocating_linker) {
- DEBUG("dynamic = %p", dynamic);
+ LD_DEBUG(dynamic, "dynamic section @%p", dynamic);
}
}
@@ -2883,8 +2905,8 @@
// source: http://www.sco.com/developers/gabi/1998-04-29/ch5.dynamic.html
uint32_t needed_count = 0;
for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
- DEBUG("d = %p, d[0](tag) = %p d[1](val) = %p",
- d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
+ LD_DEBUG(dynamic, "dynamic entry @%p: d_tag=%p, d_val=%p",
+ d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
switch (d->d_tag) {
case DT_SONAME:
// this is parsed after we have strtab initialized (see below).
@@ -3098,17 +3120,17 @@
case DT_INIT:
init_func_ = reinterpret_cast<linker_ctor_function_t>(load_bias + d->d_un.d_ptr);
- DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
+ LD_DEBUG(dynamic, "%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
break;
case DT_FINI:
fini_func_ = reinterpret_cast<linker_dtor_function_t>(load_bias + d->d_un.d_ptr);
- DEBUG("%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
+ LD_DEBUG(dynamic, "%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
break;
case DT_INIT_ARRAY:
init_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
- DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
+ LD_DEBUG(dynamic, "%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
break;
case DT_INIT_ARRAYSZ:
@@ -3117,7 +3139,7 @@
case DT_FINI_ARRAY:
fini_array_ = reinterpret_cast<linker_dtor_function_t*>(load_bias + d->d_un.d_ptr);
- DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
+ LD_DEBUG(dynamic, "%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
break;
case DT_FINI_ARRAYSZ:
@@ -3126,7 +3148,7 @@
case DT_PREINIT_ARRAY:
preinit_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
- DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
+ LD_DEBUG(dynamic, "%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
break;
case DT_PREINIT_ARRAYSZ:
@@ -3266,8 +3288,8 @@
}
}
- DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
- reinterpret_cast<void*>(base), strtab_, symtab_);
+ LD_DEBUG(dynamic, "si->base = %p, si->strtab = %p, si->symtab = %p",
+ reinterpret_cast<void*>(base), strtab_, symtab_);
// Validity checks.
if (relocating_linker && needed_count != 0) {
@@ -3322,6 +3344,18 @@
// it each time we look up a symbol with a version.
if (!validate_verdef_section(this)) return false;
+ // MTE globals requires remapping data segments with PROT_MTE as anonymous mappings, because file
+ // based mappings may not be backed by tag-capable memory (see "MAP_ANONYMOUS" on
+ // https://www.kernel.org/doc/html/latest/arch/arm64/memory-tagging-extension.html). This is only
+ // done if the binary has MTE globals (evidenced by the dynamic table entries), as it destroys
+ // page sharing. It's also only done on devices that support MTE, because the act of remapping
+ // pages is unnecessary on non-MTE devices (where we might still run MTE-globals enabled code).
+ if (should_tag_memtag_globals() &&
+ remap_memtag_globals_segments(phdr, phnum, base) == 0) {
+ tag_globals(dlext_use_relro);
+ protect_memtag_globals_ro_segments(phdr, phnum, base);
+ }
+
flags_ |= FLAG_PRELINKED;
return true;
}
@@ -3363,25 +3397,26 @@
"\"%s\" has text relocations",
get_realpath());
add_dlwarning(get_realpath(), "text relocations");
- if (phdr_table_unprotect_segments(phdr, phnum, load_bias, should_pad_segments_) < 0) {
- DL_ERR("can't unprotect loadable segments for \"%s\": %s", get_realpath(), strerror(errno));
+ if (phdr_table_unprotect_segments(phdr, phnum, load_bias, should_pad_segments_,
+ should_use_16kib_app_compat_) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %m", get_realpath());
return false;
}
}
#endif
- if (!relocate(lookup_list)) {
+ if (this != solist_get_vdso() && !relocate(lookup_list)) {
return false;
}
- DEBUG("[ finished linking %s ]", get_realpath());
+ LD_DEBUG(any, "[ finished linking %s ]", get_realpath());
#if !defined(__LP64__)
if (has_text_relocations) {
// All relocations are done, we can protect our segments back to read-only.
- if (phdr_table_protect_segments(phdr, phnum, load_bias, should_pad_segments_) < 0) {
- DL_ERR("can't protect segments for \"%s\": %s",
- get_realpath(), strerror(errno));
+ if (phdr_table_protect_segments(phdr, phnum, load_bias, should_pad_segments_,
+ should_use_16kib_app_compat_) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %m", get_realpath());
return false;
}
}
@@ -3393,19 +3428,24 @@
return false;
}
+ if (should_tag_memtag_globals()) {
+ std::list<std::string>* vma_names_ptr = vma_names();
+ // should_tag_memtag_globals -> __aarch64__ -> vma_names() != nullptr
+ CHECK(vma_names_ptr);
+ name_memtag_globals_segments(phdr, phnum, base, get_realpath(), vma_names_ptr);
+ }
+
/* Handle serializing/sharing the RELRO segment */
if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd, relro_fd_offset) < 0) {
- DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
- get_realpath(), strerror(errno));
+ DL_ERR("failed serializing GNU RELRO section for \"%s\": %m", get_realpath());
return false;
}
} else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
extinfo->relro_fd, relro_fd_offset) < 0) {
- DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
- get_realpath(), strerror(errno));
+ DL_ERR("failed mapping GNU RELRO section for \"%s\": %m", get_realpath());
return false;
}
}
@@ -3417,14 +3457,70 @@
}
bool soinfo::protect_relro() {
- if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias, should_pad_segments_) < 0) {
- DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
- get_realpath(), strerror(errno));
- return false;
+ if (should_use_16kib_app_compat_) {
+ if (phdr_table_protect_gnu_relro_16kib_compat(compat_relro_start_, compat_relro_size_) < 0) {
+ DL_ERR("can't enable COMPAT GNU RELRO protection for \"%s\": %s", get_realpath(),
+ strerror(errno));
+ return false;
+ }
+ } else {
+ if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias, should_pad_segments_,
+ should_use_16kib_app_compat_) < 0) {
+ DL_ERR("can't enable GNU RELRO protection for \"%s\": %m", get_realpath());
+ return false;
+ }
}
return true;
}
+// https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#global-variable-tagging
+void soinfo::tag_globals(bool dlext_use_relro) {
+ if (is_linked()) return;
+ if (flags_ & FLAG_GLOBALS_TAGGED) return;
+ flags_ |= FLAG_GLOBALS_TAGGED;
+
+ constexpr size_t kTagGranuleSize = 16;
+ const uint8_t* descriptor_stream = reinterpret_cast<const uint8_t*>(memtag_globals());
+
+ if (memtag_globalssz() == 0) {
+ DL_ERR("Invalid memtag descriptor pool size: %zu", memtag_globalssz());
+ }
+
+ uint64_t addr = load_bias;
+ uleb128_decoder decoder(descriptor_stream, memtag_globalssz());
+ // Don't ever generate tag zero, to easily distinguish between tagged and
+ // untagged globals in register/tag dumps.
+ uint64_t last_tag_mask = 1;
+ uint64_t last_tag = 1;
+ constexpr uint64_t kDistanceReservedBits = 3;
+
+ while (decoder.has_bytes()) {
+ uint64_t value = decoder.pop_front();
+ uint64_t distance = (value >> kDistanceReservedBits) * kTagGranuleSize;
+ uint64_t ngranules = value & ((1 << kDistanceReservedBits) - 1);
+ if (ngranules == 0) {
+ ngranules = decoder.pop_front() + 1;
+ }
+
+ addr += distance;
+ void* tagged_addr;
+ if (dlext_use_relro) {
+ tagged_addr = reinterpret_cast<void*>(addr | (last_tag++ << 56));
+ if (last_tag > (1 << kTagGranuleSize)) last_tag = 1;
+ } else {
+ tagged_addr = insert_random_tag(reinterpret_cast<void*>(addr), last_tag_mask);
+ uint64_t tag = (reinterpret_cast<uint64_t>(tagged_addr) >> 56) & 0x0f;
+ last_tag_mask = 1 | (1 << tag);
+ }
+
+ for (size_t k = 0; k < ngranules; k++) {
+ auto* granule = static_cast<uint8_t*>(tagged_addr) + k * kTagGranuleSize;
+ set_memory_tag(static_cast<void*>(granule));
+ }
+ addr += ngranules * kTagGranuleSize;
+ }
+}
+
static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan, bool is_hwasan) {
g_default_namespace.set_isolated(false);
auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : (
@@ -3560,7 +3656,7 @@
{
std::string ld_config_file_path = get_ld_config_file_path(executable_path);
- INFO("[ Reading linker config \"%s\" ]", ld_config_file_path.c_str());
+ LD_DEBUG(any, "[ Reading linker config \"%s\" ]", ld_config_file_path.c_str());
ScopedTrace trace(("linker config " + ld_config_file_path).c_str());
std::string error_msg;
if (!Config::read_binary_config(ld_config_file_path.c_str(), executable_path, g_is_asan, g_is_hwasan,
diff --git a/linker/linker.generic.map b/linker/linker.generic.map
index 4d7f236..2beae65 100644
--- a/linker/linker.generic.map
+++ b/linker/linker.generic.map
@@ -24,6 +24,7 @@
__loader_shared_globals;
rtld_db_dlactivity;
__loader_android_handle_signal;
+ __loader_android_set_16kb_appcompat_mode;
local:
*;
};
diff --git a/linker/linker.h b/linker/linker.h
index ac2222d..7afa0d7 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -108,6 +108,9 @@
bool get_transparent_hugepages_supported();
+void set_16kb_appcompat_mode(bool enable_app_compat);
+bool get_16kb_appcompat_mode();
+
enum {
/* A regular namespace is the namespace with a custom search path that does
* not impose any restrictions on the location of native libraries.
@@ -179,7 +182,8 @@
int get_application_target_sdk_version();
ElfW(Versym) find_verdef_version_index(const soinfo* si, const version_info* vi);
bool validate_verdef_section(const soinfo* si);
-bool relocate_relr(const ElfW(Relr)* begin, const ElfW(Relr)* end, ElfW(Addr) load_bias);
+bool relocate_relr(const ElfW(Relr) * begin, const ElfW(Relr) * end, ElfW(Addr) load_bias,
+ bool has_memtag_globals);
struct platform_properties {
#if defined(__aarch64__)
diff --git a/linker/linker_auxv.cpp b/linker/linker_auxv.cpp
index 95413a0..23025f7 100644
--- a/linker/linker_auxv.cpp
+++ b/linker/linker_auxv.cpp
@@ -61,10 +61,14 @@
case AT_HWCAP2: return "AT_HWCAP2";
case AT_RSEQ_FEATURE_SIZE: return "AT_RSEQ_FEATURE_SIZE";
case AT_RSEQ_ALIGN: return "AT_RSEQ_ALIGN";
+ case AT_HWCAP3: return "AT_HWCAP3";
+ case AT_HWCAP4: return "AT_HWCAP4";
case AT_EXECFN: return "AT_EXECFN";
case AT_SYSINFO_EHDR: return "AT_SYSINFO_EHDR";
-#if defined(AT_MINSIGSTKSZ)
case AT_MINSIGSTKSZ: return "AT_MINSIGSTKSZ";
+#if defined(AT_VECTOR_SIZE_ARCH)
+ // AT_VECTOR_SIZE_ARCH isn't a value: it's the number of architecture-specific
+ // values that exist for the current architecture, so not relevant here.
#endif
#if defined(AT_SYSINFO)
case AT_SYSINFO: return "AT_SYSINFO";
@@ -114,6 +118,8 @@
case AT_FLAGS:
case AT_HWCAP:
case AT_HWCAP2:
+ case AT_HWCAP3:
+ case AT_HWCAP4:
async_safe_format_fd(STDOUT_FILENO, "%-20s %#lb\n", name, value);
break;
case AT_EXECFN:
diff --git a/linker/linker_cfi.cpp b/linker/linker_cfi.cpp
index 247a25d..92ec53e 100644
--- a/linker/linker_cfi.cpp
+++ b/linker/linker_cfi.cpp
@@ -166,13 +166,13 @@
}
uintptr_t cfi_check = soinfo_find_cfi_check(si);
if (cfi_check == 0) {
- INFO("[ CFI add 0x%zx + 0x%zx %s ]", static_cast<uintptr_t>(si->base),
+ LD_DEBUG(cfi, "[ CFI add 0x%zx + 0x%zx %s ]", static_cast<uintptr_t>(si->base),
static_cast<uintptr_t>(si->size), si->get_soname());
AddUnchecked(si->base, si->base + si->size);
return true;
}
- INFO("[ CFI add 0x%zx + 0x%zx %s: 0x%zx ]", static_cast<uintptr_t>(si->base),
+ LD_DEBUG(cfi, "[ CFI add 0x%zx + 0x%zx %s: 0x%zx ]", static_cast<uintptr_t>(si->base),
static_cast<uintptr_t>(si->size), si->get_soname(), cfi_check);
#ifdef __arm__
// Require Thumb encoding.
@@ -263,8 +263,8 @@
void CFIShadowWriter::BeforeUnload(soinfo* si) {
if (shadow_start == nullptr) return;
if (si->base == 0 || si->size == 0) return;
- INFO("[ CFI remove 0x%zx + 0x%zx: %s ]", static_cast<uintptr_t>(si->base),
- static_cast<uintptr_t>(si->size), si->get_soname());
+ LD_DEBUG(cfi, "[ CFI remove 0x%zx + 0x%zx: %s ]", static_cast<uintptr_t>(si->base),
+ static_cast<uintptr_t>(si->size), si->get_soname());
AddInvalid(si->base, si->base + si->size);
FixupVmaName();
}
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 70430b8..35a93fc 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -46,9 +46,6 @@
#include <string>
#include <unordered_map>
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-
class ConfigParser {
public:
enum {
@@ -254,11 +251,8 @@
// the failure with INFO rather than DL_WARN. e.g. A binary in
// /data/local/tmp may attempt to stat /postinstall. See
// http://b/120996057.
- INFO("%s:%zd: warning: path \"%s\" couldn't be resolved: %s",
- ld_config_file_path,
- cp.lineno(),
- value.c_str(),
- strerror(errno));
+ LD_DEBUG(any, "%s:%zd: warning: path \"%s\" couldn't be resolved: %m",
+ ld_config_file_path, cp.lineno(), value.c_str());
resolved_path = value;
}
@@ -269,7 +263,7 @@
}
}
- INFO("[ Using config section \"%s\" ]", section_name.c_str());
+ LD_DEBUG(any, "[ Using config section \"%s\" ]", section_name.c_str());
// skip everything until we meet a correct section
while (true) {
diff --git a/linker/linker_debug.cpp b/linker/linker_debug.cpp
index b0aae79..430a151 100644
--- a/linker/linker_debug.cpp
+++ b/linker/linker_debug.cpp
@@ -30,18 +30,76 @@
#include <unistd.h>
-void linker_log_va_list(int prio __unused, const char* fmt, va_list ap) {
-#if LINKER_DEBUG_TO_LOG
- async_safe_format_log_va_list(5 - prio, "linker", fmt, ap);
-#else
- async_safe_format_fd_va_list(STDOUT_FILENO, fmt, ap);
- write(STDOUT_FILENO, "\n", 1);
-#endif
+#include <android-base/strings.h>
+
+LinkerDebugConfig g_linker_debug_config;
+
+void init_LD_DEBUG(const std::string& value) {
+ if (value.empty()) return;
+ std::vector<std::string> options = android::base::Split(value, ",");
+ for (const auto& o : options) {
+ if (o == "calls") g_linker_debug_config.calls = true;
+ else if (o == "cfi") g_linker_debug_config.cfi = true;
+ else if (o == "dynamic") g_linker_debug_config.dynamic = true;
+ else if (o == "lookup") g_linker_debug_config.lookup = true;
+ else if (o == "props") g_linker_debug_config.props = true;
+ else if (o == "reloc") g_linker_debug_config.reloc = true;
+ else if (o == "statistics") g_linker_debug_config.statistics = true;
+ else if (o == "timing") g_linker_debug_config.timing = true;
+ else if (o == "all") {
+ g_linker_debug_config.calls = true;
+ g_linker_debug_config.cfi = true;
+ g_linker_debug_config.dynamic = true;
+ g_linker_debug_config.lookup = true;
+ g_linker_debug_config.props = true;
+ g_linker_debug_config.reloc = true;
+ g_linker_debug_config.statistics = true;
+ g_linker_debug_config.timing = true;
+ } else {
+ __linker_error("$LD_DEBUG is a comma-separated list of:\n"
+ "\n"
+ " calls ctors/dtors/ifuncs\n"
+ " cfi control flow integrity messages\n"
+ " dynamic dynamic section processing\n"
+ " lookup symbol lookup\n"
+ " props ELF property processing\n"
+ " reloc relocation resolution\n"
+ " statistics relocation statistics\n"
+ " timing timing information\n"
+ "\n"
+ "or 'all' for all of the above.\n");
+ }
+ }
+ if (g_linker_debug_config.calls || g_linker_debug_config.cfi ||
+ g_linker_debug_config.dynamic || g_linker_debug_config.lookup ||
+ g_linker_debug_config.props || g_linker_debug_config.reloc ||
+ g_linker_debug_config.statistics || g_linker_debug_config.timing) {
+ g_linker_debug_config.any = true;
+ }
}
-void linker_log(int prio, const char* fmt, ...) {
+static void linker_log_va_list(int prio, const char* fmt, va_list ap) {
+ va_list ap2;
+ va_copy(ap2, ap);
+ async_safe_format_log_va_list(prio, "linker", fmt, ap2);
+ va_end(ap2);
+
+ async_safe_format_fd_va_list(STDERR_FILENO, fmt, ap);
+ write(STDERR_FILENO, "\n", 1);
+}
+
+void __linker_log(int prio, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
linker_log_va_list(prio, fmt, ap);
va_end(ap);
}
+
+void __linker_error(const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ linker_log_va_list(ANDROID_LOG_FATAL, fmt, ap);
+ va_end(ap);
+
+ _exit(EXIT_FAILURE);
+}
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 477b009..e5f17c4 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -28,59 +28,45 @@
#pragma once
-// You can increase the verbosity of debug traces by defining the LD_DEBUG
-// environment variable to a numeric value from 0 to 2 (corresponding to
-// INFO, TRACE, and DEBUG calls in the source). This will only
-// affect new processes being launched.
-
-// By default, traces are sent to logcat, with the "linker" tag. You can
-// change this to go to stdout instead by setting the definition of
-// LINKER_DEBUG_TO_LOG to 0.
-#define LINKER_DEBUG_TO_LOG 1
-
-#define TRACE_DEBUG 1
-#define DO_TRACE_LOOKUP 1
-#define DO_TRACE_RELO 1
-#define DO_TRACE_IFUNC 1
-#define TIMING 0
-#define STATS 0
-
-/*********************************************************************
- * You shouldn't need to modify anything below unless you are adding
- * more debugging information.
- *
- * To enable/disable specific debug options, change the defines above
- *********************************************************************/
-
#include <stdarg.h>
#include <unistd.h>
+#include <string>
+
#include <async_safe/log.h>
#include <async_safe/CHECK.h>
-#define LINKER_VERBOSITY_PRINT (-1)
-#define LINKER_VERBOSITY_INFO 0
-#define LINKER_VERBOSITY_TRACE 1
-#define LINKER_VERBOSITY_DEBUG 2
+struct LinkerDebugConfig {
+ // Set automatically if any of the more specific options are set.
+ bool any;
-__LIBC_HIDDEN__ extern int g_ld_debug_verbosity;
+ // Messages relating to calling ctors/dtors/ifuncs.
+ bool calls;
+ // Messages relating to CFI.
+ bool cfi;
+ // Messages relating to the dynamic section.
+ bool dynamic;
+ // Messages relating to symbol lookup.
+ bool lookup;
+ // Messages relating to relocation processing.
+ bool reloc;
+ // Messages relating to ELF properties.
+ bool props;
+ // TODO: "config" and "zip" seem likely to want to be separate?
-__LIBC_HIDDEN__ void linker_log_va_list(int prio, const char* fmt, va_list ap);
-__LIBC_HIDDEN__ void linker_log(int prio, const char* fmt, ...) __printflike(2, 3);
+ bool timing;
+ bool statistics;
+};
-#define _PRINTVF(v, x...) \
- do { \
- if (g_ld_debug_verbosity > (v)) linker_log((v), x); \
- } while (0)
+extern LinkerDebugConfig g_linker_debug_config;
-#define PRINT(x...) _PRINTVF(LINKER_VERBOSITY_PRINT, x)
-#define INFO(x...) _PRINTVF(LINKER_VERBOSITY_INFO, x)
-#define TRACE(x...) _PRINTVF(LINKER_VERBOSITY_TRACE, x)
+__LIBC_HIDDEN__ void init_LD_DEBUG(const std::string& value);
+__LIBC_HIDDEN__ void __linker_log(int prio, const char* fmt, ...) __printflike(2, 3);
+__LIBC_HIDDEN__ void __linker_error(const char* fmt, ...) __printflike(1, 2);
-#if TRACE_DEBUG
-#define DEBUG(x...) _PRINTVF(LINKER_VERBOSITY_DEBUG, "DEBUG: " x)
-#else /* !TRACE_DEBUG */
-#define DEBUG(x...) do {} while (0)
-#endif /* TRACE_DEBUG */
-
-#define TRACE_TYPE(t, x...) do { if (DO_TRACE_##t) { TRACE(x); } } while (0)
+#define LD_DEBUG(what, x...) \
+ do { \
+ if (g_linker_debug_config.what) { \
+ __linker_log(ANDROID_LOG_INFO, x); \
+ } \
+ } while (false)
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index 0cb7ca9..2bfdccd 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -54,7 +54,7 @@
#define DL_ERR_AND_LOG(fmt, x...) \
do { \
DL_ERR(fmt, ##x); \
- PRINT(fmt, ##x); \
+ __linker_log(ANDROID_LOG_ERROR, fmt, ##x); \
} while (false)
#define DL_OPEN_ERR(fmt, x...) \
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 2b230a8..f65f82d 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -46,6 +46,7 @@
#include "linker_tls.h"
#include "linker_utils.h"
+#include "platform/bionic/macros.h"
#include "private/KernelArgumentBlock.h"
#include "private/bionic_call_ifunc_resolver.h"
#include "private/bionic_globals.h"
@@ -71,7 +72,13 @@
static void set_bss_vma_name(soinfo* si);
void __libc_init_mte(const memtag_dynamic_entries_t* memtag_dynamic_entries, const void* phdr_start,
- size_t phdr_count, uintptr_t load_bias, void* stack_top);
+ size_t phdr_count, uintptr_t load_bias);
+
+void __libc_init_mte_stack(void* stack_top);
+
+static void __linker_cannot_link(const char* argv0) {
+ __linker_error("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+}
// These should be preserved static to avoid emitting
// RELATIVE relocations for the part of the code running
@@ -100,7 +107,7 @@
if (trav == nullptr) {
// si was not in solist
- PRINT("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
+ DL_WARN("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
return false;
}
@@ -128,7 +135,6 @@
}
bool g_is_ldd;
-int g_ld_debug_verbosity;
static std::vector<std::string> g_ld_preload_names;
@@ -167,22 +173,21 @@
return;
}
- soinfo* si = soinfo_alloc(&g_default_namespace, "[vdso]", nullptr, 0, 0);
+ vdso = soinfo_alloc(&g_default_namespace, "[vdso]", nullptr, 0, 0);
- si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
- si->phnum = ehdr_vdso->e_phnum;
- si->base = reinterpret_cast<ElfW(Addr)>(ehdr_vdso);
- si->size = phdr_table_get_load_size(si->phdr, si->phnum);
- si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
+ vdso->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
+ vdso->phnum = ehdr_vdso->e_phnum;
+ vdso->base = reinterpret_cast<ElfW(Addr)>(ehdr_vdso);
+ vdso->size = phdr_table_get_load_size(vdso->phdr, vdso->phnum);
+ vdso->load_bias = get_elf_exec_load_bias(ehdr_vdso);
- si->prelink_image();
- si->link_image(SymbolLookupList(si), si, nullptr, nullptr);
- // prevents accidental unloads...
- si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE);
- si->set_linked();
- si->call_constructors();
+ if (!vdso->prelink_image() || !vdso->link_image(SymbolLookupList(vdso), vdso, nullptr, nullptr)) {
+ __linker_cannot_link(g_argv[0]);
+ }
- vdso = si;
+ // Prevent accidental unloads...
+ vdso->set_dt_flags_1(vdso->get_dt_flags_1() | DF_1_NODELETE);
+ vdso->set_linked();
}
// Initializes an soinfo's link_map_head field using other fields from the
@@ -216,8 +221,7 @@
if (TEMP_FAILURE_RETRY(stat(exe_path, &result.file_stat) == -1)) {
// Fallback to argv[0] for the case where /proc isn't available
if (TEMP_FAILURE_RETRY(stat(arg_path, &result.file_stat) == -1)) {
- async_safe_fatal("unable to stat either \"/proc/self/exe\" or \"%s\": %s",
- arg_path, strerror(errno));
+ async_safe_fatal("unable to stat either \"/proc/self/exe\" or \"%s\": %m", arg_path);
}
exe_path = arg_path;
}
@@ -233,33 +237,6 @@
return result;
}
-#if defined(__LP64__)
-static char kFallbackLinkerPath[] = "/system/bin/linker64";
-#else
-static char kFallbackLinkerPath[] = "/system/bin/linker";
-#endif
-
-__printflike(1, 2)
-static void __linker_error(const char* fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- async_safe_format_fd_va_list(STDERR_FILENO, fmt, ap);
- va_end(ap);
-
- va_start(ap, fmt);
- async_safe_format_log_va_list(ANDROID_LOG_FATAL, "linker", fmt, ap);
- va_end(ap);
-
- _exit(EXIT_FAILURE);
-}
-
-static void __linker_cannot_link(const char* argv0) {
- __linker_error("CANNOT LINK EXECUTABLE \"%s\": %s\n",
- argv0,
- linker_get_error_buffer());
-}
-
// Load an executable. Normally the kernel has already loaded the executable when the linker
// starts. The linker can be invoked directly on an executable, though, and then the linker must
// load it. This function doesn't load dependencies or resolve relocations.
@@ -267,26 +244,26 @@
ExecutableInfo result = {};
if (orig_path[0] != '/') {
- __linker_error("error: expected absolute path: \"%s\"\n", orig_path);
+ __linker_error("error: expected absolute path: \"%s\"", orig_path);
}
off64_t file_offset;
android::base::unique_fd fd(open_executable(orig_path, &file_offset, &result.path));
if (fd.get() == -1) {
- __linker_error("error: unable to open file \"%s\"\n", orig_path);
+ __linker_error("error: unable to open file \"%s\"", orig_path);
}
if (TEMP_FAILURE_RETRY(fstat(fd.get(), &result.file_stat)) == -1) {
- __linker_error("error: unable to stat \"%s\": %s\n", result.path.c_str(), strerror(errno));
+ __linker_error("error: unable to stat \"%s\": %m", result.path.c_str());
}
ElfReader elf_reader;
if (!elf_reader.Read(result.path.c_str(), fd.get(), file_offset, result.file_stat.st_size)) {
- __linker_error("error: %s\n", linker_get_error_buffer());
+ __linker_error("error: %s", linker_get_error_buffer());
}
address_space_params address_space;
if (!elf_reader.Load(&address_space)) {
- __linker_error("error: %s\n", linker_get_error_buffer());
+ __linker_error("error: %s", linker_get_error_buffer());
}
result.phdr = elf_reader.loaded_phdr();
@@ -306,10 +283,8 @@
static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load) {
ProtectedDataGuard guard;
-#if TIMING
- struct timeval t0, t1;
- gettimeofday(&t0, 0);
-#endif
+ timeval t0, t1;
+ gettimeofday(&t0, nullptr);
// Sanitize the environment.
__libc_init_AT_SECURE(args.envp);
@@ -327,17 +302,11 @@
// Enable debugging logs?
const char* LD_DEBUG = getenv("LD_DEBUG");
- if (LD_DEBUG != nullptr) {
- g_ld_debug_verbosity = atoi(LD_DEBUG);
- }
+ if (LD_DEBUG != nullptr) init_LD_DEBUG(LD_DEBUG);
if (getenv("LD_SHOW_AUXV") != nullptr) ld_show_auxv(args.auxv);
-#if defined(__LP64__)
- INFO("[ Android dynamic linker (64-bit) ]");
-#else
- INFO("[ Android dynamic linker (32-bit) ]");
-#endif
+ LD_DEBUG(any, "[ Android dynamic linker (" ABI_STRING ") ]");
// These should have been sanitized by __libc_init_AT_SECURE, but the test
// doesn't cost us anything.
@@ -346,18 +315,18 @@
if (!getauxval(AT_SECURE)) {
ldpath_env = getenv("LD_LIBRARY_PATH");
if (ldpath_env != nullptr) {
- INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
+ LD_DEBUG(any, "[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
}
ldpreload_env = getenv("LD_PRELOAD");
if (ldpreload_env != nullptr) {
- INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
+ LD_DEBUG(any, "[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
}
}
const ExecutableInfo exe_info = exe_to_load ? load_executable(exe_to_load) :
get_executable_info(args.argv[0]);
- INFO("[ Linking executable \"%s\" ]", exe_info.path.c_str());
+ LD_DEBUG(any, "[ Linking executable \"%s\" ]", exe_info.path.c_str());
// Initialize the main exe's soinfo.
soinfo* si = soinfo_alloc(&g_default_namespace,
@@ -388,21 +357,28 @@
if (interp == nullptr) {
// This case can happen if the linker attempts to execute itself
// (e.g. "linker64 /system/bin/linker64").
- interp = kFallbackLinkerPath;
+#if defined(__LP64__)
+#define DEFAULT_INTERP "/system/bin/linker64"
+#else
+#define DEFAULT_INTERP "/system/bin/linker"
+#endif
+ interp = DEFAULT_INTERP;
}
solinker->set_realpath(interp);
init_link_map_head(*solinker);
#if defined(__aarch64__)
+ __libc_init_mte(somain->memtag_dynamic_entries(), somain->phdr, somain->phnum, somain->load_bias);
+
if (exe_to_load == nullptr) {
// Kernel does not add PROT_BTI to executable pages of the loaded ELF.
// Apply appropriate protections here if it is needed.
auto note_gnu_property = GnuPropertySection(somain);
if (note_gnu_property.IsBTICompatible() &&
- (phdr_table_protect_segments(somain->phdr, somain->phnum, somain->load_bias,
- somain->should_pad_segments(), ¬e_gnu_property) < 0)) {
- __linker_error("error: can't protect segments for \"%s\": %s", exe_info.path.c_str(),
- strerror(errno));
+ (phdr_table_protect_segments(
+ somain->phdr, somain->phnum, somain->load_bias, somain->should_pad_segments(),
+ somain->should_use_16kib_app_compat(), ¬e_gnu_property) < 0)) {
+ __linker_error("error: can't protect segments for \"%s\": %m", exe_info.path.c_str());
}
}
#endif
@@ -427,7 +403,7 @@
// and the NDK no longer supports earlier API levels.
if (elf_hdr->e_type != ET_DYN) {
__linker_error("error: %s: Android only supports position-independent "
- "executables (-fPIE)\n", exe_info.path.c_str());
+ "executables (-fPIE)", exe_info.path.c_str());
}
// Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
@@ -494,8 +470,7 @@
#if defined(__aarch64__)
// This has to happen after the find_libraries, which will have collected any possible
// libraries that request memtag_stack in the dynamic section.
- __libc_init_mte(somain->memtag_dynamic_entries(), somain->phdr, somain->phnum, somain->load_bias,
- args.argv);
+ __libc_init_mte_stack(args.argv);
#endif
linker_finalize_static_tls();
@@ -506,27 +481,22 @@
si->call_pre_init_constructors();
si->call_constructors();
-#if TIMING
- gettimeofday(&t1, nullptr);
- PRINT("LINKER TIME: %s: %d microseconds", g_argv[0],
- static_cast<int>(((static_cast<long long>(t1.tv_sec) * 1000000LL) +
- static_cast<long long>(t1.tv_usec)) -
- ((static_cast<long long>(t0.tv_sec) * 1000000LL) +
- static_cast<long long>(t0.tv_usec))));
-#endif
-#if STATS
- print_linker_stats();
-#endif
-#if TIMING || STATS
- fflush(stdout);
-#endif
+ if (g_linker_debug_config.timing) {
+ gettimeofday(&t1, nullptr);
+ long long t0_us = (t0.tv_sec * 1000000LL) + t0.tv_usec;
+ long long t1_us = (t1.tv_sec * 1000000LL) + t1.tv_usec;
+ LD_DEBUG(timing, "LINKER TIME: %s: %lld microseconds", g_argv[0], t1_us - t0_us);
+ }
+ if (g_linker_debug_config.statistics) {
+ print_linker_stats();
+ }
// We are about to hand control over to the executable loaded. We don't want
// to leave dirty pages behind unnecessarily.
purge_unused_memory();
ElfW(Addr) entry = exe_info.entry_point;
- TRACE("[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(entry));
+ LD_DEBUG(any, "[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(entry));
return entry;
}
@@ -659,8 +629,13 @@
// Apply RELR relocations first so that the GOT is initialized for ifunc
// resolvers.
if (relr && relrsz) {
+ // Nothing has tagged the memtag globals here, so it is pointless either
+ // way to handle them, the tags will be zero anyway.
+ // That is moot though, because the linker does not use memtag_globals
+ // in the first place.
relocate_relr(reinterpret_cast<ElfW(Relr*)>(ehdr + relr),
- reinterpret_cast<ElfW(Relr*)>(ehdr + relr + relrsz), ehdr);
+ reinterpret_cast<ElfW(Relr*)>(ehdr + relr + relrsz), ehdr,
+ /*has_memtag_globals=*/ false);
}
if (pltrel && pltrelsz) {
call_ifunc_resolvers_for_section(reinterpret_cast<RelType*>(ehdr + pltrel),
@@ -680,6 +655,16 @@
}
}
+// Remapping MTE globals segments happens before the linker relocates itself, and so can't use
+// memcpy() from string.h. This function is compiled with -ffreestanding.
+void linker_memcpy(void* dst, const void* src, size_t n) {
+ char* dst_bytes = reinterpret_cast<char*>(dst);
+ const char* src_bytes = reinterpret_cast<const char*>(src);
+ for (size_t i = 0; i < n; ++i) {
+ dst_bytes[i] = src_bytes[i];
+ }
+}
+
// Detect an attempt to run the linker on itself. e.g.:
// /system/bin/linker64 /system/bin/linker64
// Use priority-1 to run this constructor before other constructors.
@@ -695,7 +680,7 @@
// fallback.
__libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
#endif
- __linker_error("error: linker cannot load itself\n");
+ __linker_error("error: linker cannot load itself");
}
static ElfW(Addr) __attribute__((noinline))
@@ -757,6 +742,8 @@
tmp_linker_so.set_linker_flag();
if (!tmp_linker_so.prelink_image()) __linker_cannot_link(args.argv[0]);
+ // There is special logic in soinfo::relocate to avoid duplicating the
+ // relocations we did in relocate_linker().
if (!tmp_linker_so.link_image(SymbolLookupList(&tmp_linker_so), &tmp_linker_so, nullptr, nullptr)) __linker_cannot_link(args.argv[0]);
return __linker_init_post_relocation(args, tmp_linker_so);
@@ -843,7 +830,7 @@
ElfW(Addr) start_address = linker_main(args, exe_to_load);
- INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
+ LD_DEBUG(any, "[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
// Return the address that the calling assembly stub should jump to.
return start_address;
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 724f43c..ffbcf0f 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -70,3 +70,5 @@
soinfo* solist_get_head();
soinfo* solist_get_somain();
soinfo* solist_get_vdso();
+
+void linker_memcpy(void* dst, const void* src, size_t n);
diff --git a/linker/linker_note_gnu_property.cpp b/linker/linker_note_gnu_property.cpp
index be1aebc..d221b8d 100644
--- a/linker/linker_note_gnu_property.cpp
+++ b/linker/linker_note_gnu_property.cpp
@@ -62,7 +62,7 @@
continue;
}
- TRACE("\"%s\" PT_GNU_PROPERTY: found at segment index %zu", name, i);
+ LD_DEBUG(props, "\"%s\" PT_GNU_PROPERTY: found at segment index %zu", name, i);
// Check segment size.
if (phdr[i].p_memsz < sizeof(ElfW(NhdrGNUProperty))) {
@@ -90,7 +90,7 @@
}
}
- TRACE("\"%s\" PT_GNU_PROPERTY: not found", name);
+ LD_DEBUG(props, "\"%s\" PT_GNU_PROPERTY: not found", name);
return nullptr;
}
@@ -122,7 +122,7 @@
// The total length of the program property array is in _bytes_.
ElfW(Word) offset = 0;
while (offset < note_nhdr->nhdr.n_descsz) {
- DEBUG("\"%s\" .note.gnu.property: processing at offset 0x%x", name, offset);
+ LD_DEBUG(props, "\"%s\" .note.gnu.property: processing at offset 0x%x", name, offset);
// At least the "header" part must fit.
// The ABI doesn't say that pr_datasz can't be 0.
@@ -137,7 +137,7 @@
// Loop on program property array.
const ElfW(Prop)* property = reinterpret_cast<const ElfW(Prop)*>(¬e_nhdr->n_desc[offset]);
const ElfW(Word) property_size =
- align_up(sizeof(ElfW(Prop)) + property->pr_datasz, sizeof(ElfW(Addr)));
+ __builtin_align_up(sizeof(ElfW(Prop)) + property->pr_datasz, sizeof(ElfW(Addr)));
if ((note_nhdr->nhdr.n_descsz - offset) < property_size) {
DL_ERR_AND_LOG(
"\"%s\" .note.gnu.property: property descriptor size is "
@@ -161,14 +161,14 @@
const ElfW(Word) flags = *reinterpret_cast<const ElfW(Word)*>(&property->pr_data[0]);
properties_.bti_compatible = (flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) != 0;
if (properties_.bti_compatible) {
- INFO("[ BTI compatible: \"%s\" ]", name);
+ LD_DEBUG(props, "[ BTI compatible: \"%s\" ]", name);
}
break;
}
#endif
default:
- DEBUG("\"%s\" .note.gnu.property: found property pr_type %u pr_datasz 0x%x", name,
- property->pr_type, property->pr_datasz);
+ LD_DEBUG(props, "\"%s\" .note.gnu.property: found property pr_type %u pr_datasz 0x%x",
+ name, property->pr_type, property->pr_datasz);
break;
}
diff --git a/linker/linker_note_gnu_property_test.cpp b/linker/linker_note_gnu_property_test.cpp
index 41fc47b..2a5eddc 100644
--- a/linker/linker_note_gnu_property_test.cpp
+++ b/linker/linker_note_gnu_property_test.cpp
@@ -107,7 +107,7 @@
template <typename T>
bool push(ElfW(Word) pr_type, ElfW(Word) pr_datasz, const T* pr_data) {
// Must be aligned.
- const uintptr_t addition = align_up(pr_datasz, sizeof(ElfW(Addr)));
+ const uintptr_t addition = __builtin_align_up(pr_datasz, sizeof(ElfW(Addr)));
if ((offset() + addition) > kMaxSectionSize) {
return false;
}
@@ -137,18 +137,18 @@
dump_member("entries ", entries);
if (entries > 0) {
std::cout << " raw data:";
- const uintptr_t offset = note->nhdr.n_descsz + 16;
- for (uintptr_t offs = 16; offs < offset; ++offs) {
+ const uintptr_t end = note->nhdr.n_descsz + 16;
+ for (uintptr_t offset = 16; offset < end; ++offset) {
std::cout << std::hex;
- if ((offs % 8) == 0) {
+ if ((offset % 8) == 0) {
std::cout << "\n ";
}
- auto value = static_cast<unsigned>(section[offs]);
+ auto value = static_cast<unsigned>(section[offset]);
std::cout << " ";
if (value < 0x10) {
std::cout << "0";
}
- std::cout << static_cast<unsigned>(section[offs]);
+ std::cout << static_cast<unsigned>(section[offset]);
}
std::cout << std::dec << "\n";
}
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index b9229ca..1e36f5e 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -37,9 +37,12 @@
#include <unistd.h>
#include "linker.h"
+#include "linker_debug.h"
#include "linker_dlwarning.h"
#include "linker_globals.h"
-#include "linker_debug.h"
+#include "linker_logger.h"
+#include "linker_main.h"
+#include "linker_soinfo.h"
#include "linker_utils.h"
#include "private/bionic_asm_note.h"
@@ -47,6 +50,7 @@
#include "private/elf_note.h"
#include <android-base/file.h>
+#include <android-base/properties.h>
static int GetTargetElfMachine() {
#if defined(__arm__)
@@ -139,11 +143,6 @@
**/
-#define MAYBE_MAP_FLAG(x, from, to) (((x) & (from)) ? (to) : 0)
-#define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
- MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
- MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
-
static const size_t kPageSize = page_size();
/*
@@ -160,8 +159,8 @@
ElfReader::ElfReader()
: did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
- strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
- mapped_by_caller_(false) {
+ strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), max_align_(0), min_align_(0),
+ loaded_phdr_(nullptr), mapped_by_caller_(false) {
}
bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
@@ -176,12 +175,22 @@
if (ReadElfHeader() &&
VerifyElfHeader() &&
ReadProgramHeaders() &&
+ CheckProgramHeaderAlignment() &&
ReadSectionHeaders() &&
ReadDynamicSection() &&
ReadPadSegmentNote()) {
did_read_ = true;
}
+ if (kPageSize == 16*1024 && min_align_ == 4096) {
+ // This prop needs to be read on 16KiB devices for each ELF where min_palign is 4KiB.
+ // It cannot be cached since the developer may toggle app compat on/off.
+ // This check will be removed once app compat is made the default on 16KiB devices.
+ should_use_16kib_app_compat_ =
+ ::android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false) ||
+ get_16kb_appcompat_mode();
+ }
+
return did_read_;
}
@@ -197,8 +206,9 @@
#if defined(__aarch64__)
// For Armv8.5-A loaded executable segments may require PROT_BTI.
if (note_gnu_property_.IsBTICompatible()) {
- did_load_ = (phdr_table_protect_segments(phdr_table_, phdr_num_, load_bias_,
- should_pad_segments_, ¬e_gnu_property_) == 0);
+ did_load_ =
+ (phdr_table_protect_segments(phdr_table_, phdr_num_, load_bias_, should_pad_segments_,
+ should_use_16kib_app_compat_, ¬e_gnu_property_) == 0);
}
#endif
}
@@ -363,7 +373,7 @@
}
if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
- DL_ERR("\"%s\" phdr mmap failed: %s", name_.c_str(), strerror(errno));
+ DL_ERR("\"%s\" phdr mmap failed: %m", name_.c_str());
return false;
}
@@ -389,7 +399,7 @@
}
if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
- DL_ERR("\"%s\" shdr mmap failed: %s", name_.c_str(), strerror(errno));
+ DL_ERR("\"%s\" shdr mmap failed: %m", name_.c_str());
return false;
}
@@ -482,7 +492,7 @@
}
if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
- DL_ERR("\"%s\" dynamic section mmap failed: %s", name_.c_str(), strerror(errno));
+ DL_ERR("\"%s\" dynamic section mmap failed: %m", name_.c_str());
return false;
}
@@ -495,7 +505,7 @@
}
if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
- DL_ERR("\"%s\" strtab section mmap failed: %s", name_.c_str(), strerror(errno));
+ DL_ERR("\"%s\" strtab section mmap failed: %m", name_.c_str());
return false;
}
@@ -553,30 +563,26 @@
return max_vaddr - min_vaddr;
}
-// Returns the maximum p_align associated with a loadable segment in the ELF
-// program header table. Used to determine whether the file should be loaded at
-// a specific virtual address alignment for use with huge pages.
-size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count) {
- size_t maximum_alignment = page_size();
+bool ElfReader::CheckProgramHeaderAlignment() {
+ max_align_ = min_align_ = page_size();
- for (size_t i = 0; i < phdr_count; ++i) {
- const ElfW(Phdr)* phdr = &phdr_table[i];
+ for (size_t i = 0; i < phdr_num_; ++i) {
+ const ElfW(Phdr)* phdr = &phdr_table_[i];
// p_align must be 0, 1, or a positive, integral power of two.
if (phdr->p_type != PT_LOAD || ((phdr->p_align & (phdr->p_align - 1)) != 0)) {
+ // TODO: reject ELF files with bad p_align values.
continue;
}
- if (phdr->p_align > maximum_alignment) {
- maximum_alignment = phdr->p_align;
+ max_align_ = std::max(max_align_, static_cast<size_t>(phdr->p_align));
+
+ if (phdr->p_align > 1) {
+ min_align_ = std::min(min_align_, static_cast<size_t>(phdr->p_align));
}
}
-#if defined(__LP64__)
- return maximum_alignment;
-#else
- return page_size();
-#endif
+ return true;
}
// Reserve a virtual address range such that if it's limits were extended to the next 2**align
@@ -597,24 +603,23 @@
// Minimum alignment of shared library gap. For efficiency, this should match the second level
// page size of the platform.
#if defined(__LP64__)
- constexpr size_t kGapAlignment = 1ul << 21; // 2MB
-#else
- constexpr size_t kGapAlignment = 0;
+ constexpr size_t kGapAlignment = 2 * 1024 * 1024;
#endif
// Maximum gap size, in the units of kGapAlignment.
constexpr size_t kMaxGapUnits = 32;
// Allocate enough space so that the end of the desired region aligned up is still inside the
// mapping.
- size_t mmap_size = align_up(size, mapping_align) + mapping_align - page_size();
+ size_t mmap_size = __builtin_align_up(size, mapping_align) + mapping_align - page_size();
uint8_t* mmap_ptr =
reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
return nullptr;
}
size_t gap_size = 0;
- size_t first_byte = reinterpret_cast<size_t>(align_up(mmap_ptr, mapping_align));
- size_t last_byte = reinterpret_cast<size_t>(align_down(mmap_ptr + mmap_size, mapping_align) - 1);
- if (kGapAlignment && first_byte / kGapAlignment != last_byte / kGapAlignment) {
+ size_t first_byte = reinterpret_cast<size_t>(__builtin_align_up(mmap_ptr, mapping_align));
+ size_t last_byte = reinterpret_cast<size_t>(__builtin_align_down(mmap_ptr + mmap_size, mapping_align) - 1);
+#if defined(__LP64__)
+ if (first_byte / kGapAlignment != last_byte / kGapAlignment) {
// This library crosses a 2MB boundary and will fragment a new huge page.
// Lets take advantage of that and insert a random number of inaccessible huge pages before that
// to improve address randomization and make it harder to locate this library code by probing.
@@ -622,23 +627,24 @@
mapping_align = std::max(mapping_align, kGapAlignment);
gap_size =
kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
- mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - page_size();
+ mmap_size = __builtin_align_up(size + gap_size, mapping_align) + mapping_align - page_size();
mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
if (mmap_ptr == MAP_FAILED) {
return nullptr;
}
}
+#endif
- uint8_t *gap_end, *gap_start;
+ uint8_t* gap_end = mmap_ptr + mmap_size;
+#if defined(__LP64__)
if (gap_size) {
- gap_end = align_down(mmap_ptr + mmap_size, kGapAlignment);
- gap_start = gap_end - gap_size;
- } else {
- gap_start = gap_end = mmap_ptr + mmap_size;
+ gap_end = __builtin_align_down(gap_end, kGapAlignment);
}
+#endif
+ uint8_t* gap_start = gap_end - gap_size;
- uint8_t* first = align_up(mmap_ptr, mapping_align);
- uint8_t* last = align_down(gap_start, mapping_align) - size;
+ uint8_t* first = __builtin_align_up(mmap_ptr, mapping_align);
+ uint8_t* last = __builtin_align_down(gap_start, mapping_align) - size;
// arc4random* is not available in first stage init because /dev/urandom hasn't yet been
// created. Don't randomize then.
@@ -668,6 +674,13 @@
return false;
}
+ if (should_use_16kib_app_compat_) {
+ // Reserve additional space for aligning the permission boundary in compat loading
+ // Up to kPageSize-kCompatPageSize additional space is needed, but reservation
+ // is done with mmap which gives kPageSize multiple-sized reservations.
+ load_size_ += kPageSize;
+ }
+
uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
void* start;
@@ -679,10 +692,9 @@
}
size_t start_alignment = page_size();
if (get_transparent_hugepages_supported() && get_application_target_sdk_version() >= 31) {
- size_t maximum_alignment = phdr_table_get_maximum_alignment(phdr_table_, phdr_num_);
// Limit alignment to PMD size as other alignments reduce the number of
// bits available for ASLR for no benefit.
- start_alignment = maximum_alignment == kPmdSize ? kPmdSize : page_size();
+ start_alignment = max_align_ == kPmdSize ? kPmdSize : page_size();
}
start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, start_alignment, &gap_start_,
&gap_size_);
@@ -703,13 +715,21 @@
load_start_ = start;
load_bias_ = reinterpret_cast<uint8_t*>(start) - addr;
+
+ if (should_use_16kib_app_compat_) {
+ // In compat mode make the initial mapping RW since the ELF contents will be read
+ // into it; instead of mapped over it.
+ mprotect(reinterpret_cast<void*>(start), load_size_, PROT_READ | PROT_WRITE);
+ }
+
return true;
}
/*
- * Returns true if the kernel supports page size migration, else false.
+ * Returns true if the kernel supports page size migration for this process.
*/
bool page_size_migration_supported() {
+#if defined(__LP64__)
static bool pgsize_migration_enabled = []() {
std::string enabled;
if (!android::base::ReadFileToString("/sys/kernel/mm/pgsize_migration/enabled", &enabled)) {
@@ -718,6 +738,9 @@
return enabled.find("1") != std::string::npos;
}();
return pgsize_migration_enabled;
+#else
+ return false;
+#endif
}
// Find the ELF note of type NT_ANDROID_TYPE_PAD_SEGMENT and check that the desc value is 1.
@@ -786,8 +809,15 @@
}
static inline void _extend_load_segment_vma(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- size_t phdr_idx, ElfW(Addr)* p_memsz,
- ElfW(Addr)* p_filesz, bool should_pad_segments) {
+ size_t phdr_idx, ElfW(Addr)* p_memsz,
+ ElfW(Addr)* p_filesz, bool should_pad_segments,
+ bool should_use_16kib_app_compat) {
+ // NOTE: Segment extension is only applicable where the ELF's max-page-size > runtime page size;
+ // to save kernel VMA slab memory. 16KiB compat mode is the exact opposite scenario.
+ if (should_use_16kib_app_compat) {
+ return;
+ }
+
const ElfW(Phdr)* phdr = &phdr_table[phdr_idx];
const ElfW(Phdr)* next = nullptr;
size_t next_idx = phdr_idx + 1;
@@ -829,7 +859,146 @@
*p_filesz += extend;
}
+bool ElfReader::MapSegment(size_t seg_idx, size_t len) {
+ const ElfW(Phdr)* phdr = &phdr_table_[seg_idx];
+
+ void* start = reinterpret_cast<void*>(page_start(phdr->p_vaddr + load_bias_));
+
+ // The ELF could be being loaded directly from a zipped APK,
+ // the zip offset must be added to find the segment offset.
+ const ElfW(Addr) offset = file_offset_ + page_start(phdr->p_offset);
+
+ int prot = PFLAGS_TO_PROT(phdr->p_flags);
+
+ void* seg_addr = mmap64(start, len, prot, MAP_FIXED | MAP_PRIVATE, fd_, offset);
+
+ if (seg_addr == MAP_FAILED) {
+ DL_ERR("couldn't map \"%s\" segment %zd: %m", name_.c_str(), seg_idx);
+ return false;
+ }
+
+ // Mark segments as huge page eligible if they meet the requirements
+ if ((phdr->p_flags & PF_X) && phdr->p_align == kPmdSize &&
+ get_transparent_hugepages_supported()) {
+ madvise(seg_addr, len, MADV_HUGEPAGE);
+ }
+
+ return true;
+}
+
+void ElfReader::ZeroFillSegment(const ElfW(Phdr)* phdr) {
+ // NOTE: In 16KiB app compat mode, the ELF mapping is anonymous, meaning that
+ // RW segments are COW-ed from the kernel's zero page. So there is no need to
+ // explicitly zero-fill until the last page's limit.
+ if (should_use_16kib_app_compat_) {
+ return;
+ }
+
+ ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
+ uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
+
+ // If the segment is writable, and does not end on a page boundary,
+ // zero-fill it until the page limit.
+ //
+ // Do not attempt to zero the extended region past the first partial page,
+ // since doing so may:
+ // 1) Result in a SIGBUS, as the region is not backed by the underlying
+ // file.
+ // 2) Break the COW backing, faulting in new anon pages for a region
+ // that will not be used.
+ if ((phdr->p_flags & PF_W) != 0 && page_offset(unextended_seg_file_end) > 0) {
+ memset(reinterpret_cast<void*>(unextended_seg_file_end), 0,
+ kPageSize - page_offset(unextended_seg_file_end));
+ }
+}
+
+void ElfReader::DropPaddingPages(const ElfW(Phdr)* phdr, uint64_t seg_file_end) {
+ // NOTE: Padding pages are only applicable where the ELF's max-page-size > runtime page size;
+ // 16KiB compat mode is the exact opposite scenario.
+ if (should_use_16kib_app_compat_) {
+ return;
+ }
+
+ ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
+ uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
+
+ uint64_t pad_start = page_end(unextended_seg_file_end);
+ uint64_t pad_end = page_end(seg_file_end);
+ CHECK(pad_start <= pad_end);
+
+ uint64_t pad_len = pad_end - pad_start;
+ if (pad_len == 0 || !page_size_migration_supported()) {
+ return;
+ }
+
+ // Pages may be brought in due to readahead.
+ // Drop the padding (zero) pages, to avoid reclaim work later.
+ //
+ // NOTE: The madvise() here is special, as it also serves to hint to the
+ // kernel the portion of the LOAD segment that is padding.
+ //
+ // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
+ // [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
+ if (madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
+ DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
+ name_.c_str(), pad_start, pad_len);
+ }
+}
+
+bool ElfReader::MapBssSection(const ElfW(Phdr)* phdr, ElfW(Addr) seg_page_end,
+ ElfW(Addr) seg_file_end) {
+ // NOTE: We do not need to handle .bss in 16KiB compat mode since the mapping
+ // reservation is anonymous and RW to begin with.
+ if (should_use_16kib_app_compat_) {
+ return true;
+ }
+
+ // seg_file_end is now the first page address after the file content.
+ seg_file_end = page_end(seg_file_end);
+
+ if (seg_page_end <= seg_file_end) {
+ return true;
+ }
+
+ // If seg_page_end is larger than seg_file_end, we need to zero
+ // anything between them. This is done by using a private anonymous
+ // map for all extra pages
+ size_t zeromap_size = seg_page_end - seg_file_end;
+ void* zeromap =
+ mmap(reinterpret_cast<void*>(seg_file_end), zeromap_size, PFLAGS_TO_PROT(phdr->p_flags),
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (zeromap == MAP_FAILED) {
+ DL_ERR("couldn't map .bss section for \"%s\": %m", name_.c_str());
+ return false;
+ }
+
+ // Set the VMA name using prctl
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
+
+ return true;
+}
+
bool ElfReader::LoadSegments() {
+ // NOTE: The compat(legacy) page size (4096) must be used when aligning
+ // the 4KiB segments for loading in compat mode. The larger 16KiB page size
+ // will lead to overwriting adjacent segments since the ELF's segment(s)
+ // are not 16KiB aligned.
+ size_t seg_align = should_use_16kib_app_compat_ ? kCompatPageSize : kPageSize;
+
+ // Only enforce this on 16 KB systems with app compat disabled.
+ // Apps may rely on undefined behavior here on 4 KB systems,
+ // which is the norm before this change is introduced
+ if (kPageSize >= 16384 && min_align_ < kPageSize && !should_use_16kib_app_compat_) {
+ DL_ERR("\"%s\" program alignment (%zu) cannot be smaller than system page size (%zu)",
+ name_.c_str(), min_align_, kPageSize);
+ return false;
+ }
+
+ if (!Setup16KiBAppCompat()) {
+ DL_ERR("\"%s\" failed to setup 16KiB App Compat", name_.c_str());
+ return false;
+ }
+
for (size_t i = 0; i < phdr_num_; ++i) {
const ElfW(Phdr)* phdr = &phdr_table_[i];
@@ -839,14 +1008,14 @@
ElfW(Addr) p_memsz = phdr->p_memsz;
ElfW(Addr) p_filesz = phdr->p_filesz;
- _extend_load_segment_vma(phdr_table_, phdr_num_, i, &p_memsz, &p_filesz, should_pad_segments_);
+ _extend_load_segment_vma(phdr_table_, phdr_num_, i, &p_memsz, &p_filesz, should_pad_segments_,
+ should_use_16kib_app_compat_);
// Segment addresses in memory.
ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
ElfW(Addr) seg_end = seg_start + p_memsz;
- ElfW(Addr) seg_page_start = page_start(seg_start);
- ElfW(Addr) seg_page_end = page_end(seg_end);
+ ElfW(Addr) seg_page_end = __builtin_align_up(seg_end, seg_align);
ElfW(Addr) seg_file_end = seg_start + p_filesz;
@@ -854,7 +1023,7 @@
ElfW(Addr) file_start = phdr->p_offset;
ElfW(Addr) file_end = file_start + p_filesz;
- ElfW(Addr) file_page_start = page_start(file_start);
+ ElfW(Addr) file_page_start = __builtin_align_down(file_start, seg_align);
ElfW(Addr) file_length = file_end - file_page_start;
if (file_size_ <= 0) {
@@ -886,79 +1055,24 @@
add_dlwarning(name_.c_str(), "W+E load segments");
}
- void* seg_addr = mmap64(reinterpret_cast<void*>(seg_page_start),
- file_length,
- prot,
- MAP_FIXED|MAP_PRIVATE,
- fd_,
- file_offset_ + file_page_start);
- if (seg_addr == MAP_FAILED) {
- DL_ERR("couldn't map \"%s\" segment %zd: %s", name_.c_str(), i, strerror(errno));
- return false;
- }
-
- // Mark segments as huge page eligible if they meet the requirements
- // (executable and PMD aligned).
- if ((phdr->p_flags & PF_X) && phdr->p_align == kPmdSize &&
- get_transparent_hugepages_supported()) {
- madvise(seg_addr, file_length, MADV_HUGEPAGE);
+ // Pass the file_length, since it may have been extended by _extend_load_segment_vma().
+ if (should_use_16kib_app_compat_) {
+ if (!CompatMapSegment(i, file_length)) {
+ return false;
+ }
+ } else {
+ if (!MapSegment(i, file_length)) {
+ return false;
+ }
}
}
- // if the segment is writable, and does not end on a page boundary,
- // zero-fill it until the page limit.
- //
- // Do not attempt to zero the extended region past the first partial page,
- // since doing so may:
- // 1) Result in a SIGBUS, as the region is not backed by the underlying
- // file.
- // 2) Break the COW backing, faulting in new anon pages for a region
- // that will not be used.
+ ZeroFillSegment(phdr);
- uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
- if ((phdr->p_flags & PF_W) != 0 && page_offset(unextended_seg_file_end) > 0) {
- memset(reinterpret_cast<void*>(unextended_seg_file_end), 0,
- kPageSize - page_offset(unextended_seg_file_end));
- }
+ DropPaddingPages(phdr, seg_file_end);
- // Pages may be brought in due to readahead.
- // Drop the padding (zero) pages, to avoid reclaim work later.
- //
- // NOTE: The madvise() here is special, as it also serves to hint to the
- // kernel the portion of the LOAD segment that is padding.
- //
- // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
- // [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
- uint64_t pad_start = page_end(unextended_seg_file_end);
- uint64_t pad_end = page_end(seg_file_end);
- CHECK(pad_start <= pad_end);
- uint64_t pad_len = pad_end - pad_start;
- if (page_size_migration_supported() && pad_len > 0 &&
- madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
- DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
- name_.c_str(), pad_start, pad_len);
- }
-
- seg_file_end = page_end(seg_file_end);
-
- // seg_file_end is now the first page address after the file
- // content. If seg_end is larger, we need to zero anything
- // between them. This is done by using a private anonymous
- // map for all extra pages.
- if (seg_page_end > seg_file_end) {
- size_t zeromap_size = seg_page_end - seg_file_end;
- void* zeromap = mmap(reinterpret_cast<void*>(seg_file_end),
- zeromap_size,
- PFLAGS_TO_PROT(phdr->p_flags),
- MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
- -1,
- 0);
- if (zeromap == MAP_FAILED) {
- DL_ERR("couldn't zero fill \"%s\" gap: %s", name_.c_str(), strerror(errno));
- return false;
- }
-
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
+ if (!MapBssSection(phdr, seg_page_end, seg_file_end)) {
+ return false;
}
}
return true;
@@ -970,7 +1084,7 @@
*/
static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, int extra_prot_flags,
- bool should_pad_segments) {
+ bool should_pad_segments, bool should_use_16kib_app_compat) {
for (size_t i = 0; i < phdr_count; ++i) {
const ElfW(Phdr)* phdr = &phdr_table[i];
@@ -980,7 +1094,8 @@
ElfW(Addr) p_memsz = phdr->p_memsz;
ElfW(Addr) p_filesz = phdr->p_filesz;
- _extend_load_segment_vma(phdr_table, phdr_count, i, &p_memsz, &p_filesz, should_pad_segments);
+ _extend_load_segment_vma(phdr_table, phdr_count, i, &p_memsz, &p_filesz, should_pad_segments,
+ should_use_16kib_app_compat);
ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr + load_bias);
ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + p_memsz + load_bias);
@@ -1019,12 +1134,14 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* should_pad_segments -> Are segments extended to avoid gaps in the memory map
+ * should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
* prop -> GnuPropertySection or nullptr
* Return:
* 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat,
const GnuPropertySection* prop __unused) {
int prot = 0;
#if defined(__aarch64__)
@@ -1032,7 +1149,127 @@
prot |= PROT_BTI;
}
#endif
- return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, prot, should_pad_segments);
+ return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, prot, should_pad_segments,
+ should_use_16kib_app_compat);
+}
+
+static bool segment_needs_memtag_globals_remapping(const ElfW(Phdr) * phdr) {
+ // For now, MTE globals is only supported on writeable data segments.
+ return phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_X) && (phdr->p_flags & PF_W);
+}
+
+/* When MTE globals are requested by the binary, and when the hardware supports
+ * it, remap the executable's PT_LOAD data pages to have PROT_MTE.
+ *
+ * Returns 0 on success, -1 on failure (error code in errno).
+ */
+int remap_memtag_globals_segments(const ElfW(Phdr) * phdr_table __unused,
+ size_t phdr_count __unused, ElfW(Addr) load_bias __unused) {
+#if defined(__aarch64__)
+ for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
+ if (!segment_needs_memtag_globals_remapping(phdr)) {
+ continue;
+ }
+
+ uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ size_t seg_page_aligned_size = seg_page_end - seg_page_start;
+
+ int prot = PFLAGS_TO_PROT(phdr->p_flags);
+ // For anonymous private mappings, it may be possible to simply mprotect()
+ // the PROT_MTE flag over the top. For file-based mappings, this will fail,
+ // and we'll need to fall back. We also allow PROT_WRITE here to allow
+ // writing memory tags (in `soinfo::tag_globals()`), and set these sections
+ // back to read-only after tags are applied (similar to RELRO).
+ prot |= PROT_MTE;
+ if (mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
+ prot | PROT_WRITE) == 0) {
+ continue;
+ }
+
+ void* mapping_copy = mmap(nullptr, seg_page_aligned_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ linker_memcpy(mapping_copy, reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size);
+
+ void* seg_addr = mmap(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
+ prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (seg_addr == MAP_FAILED) return -1;
+
+ linker_memcpy(seg_addr, mapping_copy, seg_page_aligned_size);
+ munmap(mapping_copy, seg_page_aligned_size);
+ }
+#endif // defined(__aarch64__)
+ return 0;
+}
+
+void protect_memtag_globals_ro_segments(const ElfW(Phdr) * phdr_table __unused,
+ size_t phdr_count __unused, ElfW(Addr) load_bias __unused) {
+#if defined(__aarch64__)
+ for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
+ int prot = PFLAGS_TO_PROT(phdr->p_flags);
+ if (!segment_needs_memtag_globals_remapping(phdr) || (prot & PROT_WRITE)) {
+ continue;
+ }
+
+ prot |= PROT_MTE;
+
+ uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ size_t seg_page_aligned_size = seg_page_end - seg_page_start;
+ mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size, prot);
+ }
+#endif // defined(__aarch64__)
+}
+
+void name_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, const char* soname,
+ std::list<std::string>* vma_names) {
+ for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
+ if (!segment_needs_memtag_globals_remapping(phdr)) {
+ continue;
+ }
+
+ uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
+ uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
+ size_t seg_page_aligned_size = seg_page_end - seg_page_start;
+
+ // For file-based mappings that we're now forcing to be anonymous mappings, set the VMA name to
+ // make debugging easier.
+ // Once we are targeting only devices that run kernel 5.10 or newer (and thus include
+ // https://android-review.git.corp.google.com/c/kernel/common/+/1934723 which causes the
+ // VMA_ANON_NAME to be copied into the kernel), we can get rid of the storage here.
+ // For now, that is not the case:
+ // https://source.android.com/docs/core/architecture/kernel/android-common#compatibility-matrix
+ constexpr int kVmaNameLimit = 80;
+ std::string& vma_name = vma_names->emplace_back(kVmaNameLimit, '\0');
+ int full_vma_length =
+ async_safe_format_buffer(vma_name.data(), kVmaNameLimit, "mt:%s+%" PRIxPTR, soname,
+ page_start(phdr->p_vaddr)) +
+ /* include the null terminator */ 1;
+ // There's an upper limit of 80 characters, including the null terminator, in the anonymous VMA
+ // name. If we run over that limit, we end up truncating the segment offset and parts of the
+ // DSO's name, starting on the right hand side of the basename. Because the basename is the most
+ // important thing, chop off the soname from the left hand side first.
+ //
+ // Example (with '#' as the null terminator):
+ // - "mt:/data/nativetest64/bionic-unit-tests/bionic-loader-test-libs/libdlext_test.so+e000#"
+ // is a `full_vma_length` == 86.
+ //
+ // We need to left-truncate (86 - 80) 6 characters from the soname, plus the
+ // `vma_truncation_prefix`, so 9 characters total.
+ if (full_vma_length > kVmaNameLimit) {
+ const char vma_truncation_prefix[] = "...";
+ int soname_truncated_bytes =
+ full_vma_length - kVmaNameLimit + sizeof(vma_truncation_prefix) - 1;
+ async_safe_format_buffer(vma_name.data(), kVmaNameLimit, "mt:%s%s+%" PRIxPTR,
+ vma_truncation_prefix, soname + soname_truncated_bytes,
+ page_start(phdr->p_vaddr));
+ }
+ if (prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<void*>(seg_page_start),
+ seg_page_aligned_size, vma_name.data()) != 0) {
+ DL_WARN("Failed to rename memtag global segment: %m");
+ }
+ }
}
/* Change the protection of all loaded segments in memory to writable.
@@ -1049,20 +1286,22 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* should_pad_segments -> Are segments extended to avoid gaps in the memory map
+ * should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
* Return:
* 0 on success, -1 on failure (error code in errno).
*/
-int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table,
- size_t phdr_count, ElfW(Addr) load_bias,
- bool should_pad_segments) {
+int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat) {
return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, PROT_WRITE,
- should_pad_segments);
+ should_pad_segments, should_use_16kib_app_compat);
}
static inline void _extend_gnu_relro_prot_end(const ElfW(Phdr)* relro_phdr,
const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, ElfW(Addr)* seg_page_end,
- bool should_pad_segments) {
+ bool should_pad_segments,
+ bool should_use_16kib_app_compat) {
// Find the index and phdr of the LOAD containing the GNU_RELRO segment
for (size_t index = 0; index < phdr_count; ++index) {
const ElfW(Phdr)* phdr = &phdr_table[index];
@@ -1110,7 +1349,7 @@
// mprotect will only RO protect a part of the extended RW LOAD segment, which
// will leave an extra split RW VMA (the gap).
_extend_load_segment_vma(phdr_table, phdr_count, index, &p_memsz, &p_filesz,
- should_pad_segments);
+ should_pad_segments, should_use_16kib_app_compat);
*seg_page_end = page_end(phdr->p_vaddr + p_memsz + load_bias);
return;
@@ -1123,7 +1362,8 @@
*/
static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, int prot_flags,
- bool should_pad_segments) {
+ bool should_pad_segments,
+ bool should_use_16kib_app_compat) {
const ElfW(Phdr)* phdr = phdr_table;
const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
@@ -1151,7 +1391,7 @@
ElfW(Addr) seg_page_start = page_start(phdr->p_vaddr) + load_bias;
ElfW(Addr) seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
_extend_gnu_relro_prot_end(phdr, phdr_table, phdr_count, load_bias, &seg_page_end,
- should_pad_segments);
+ should_pad_segments, should_use_16kib_app_compat);
int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
seg_page_end - seg_page_start,
@@ -1177,13 +1417,29 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* should_pad_segments -> Were segments extended to avoid gaps in the memory map
+ * should_use_16kib_app_compat -> Is the ELF being loaded in 16KiB app compat mode.
* Return:
* 0 on success, -1 on failure (error code in errno).
*/
int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, bool should_pad_segments) {
+ ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat) {
return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ,
- should_pad_segments);
+ should_pad_segments, should_use_16kib_app_compat);
+}
+
+/*
+ * Apply RX protection to the compat relro region of the ELF being loaded in
+ * 16KiB compat mode.
+ *
+ * Input:
+ * start -> start address of the compat relro region.
+ * size -> size of the compat relro region in bytes.
+ * Return:
+ * 0 on success, -1 on failure (error code in errno).
+ */
+int phdr_table_protect_gnu_relro_16kib_compat(ElfW(Addr) start, ElfW(Addr) size) {
+ return mprotect(reinterpret_cast<void*>(start), size, PROT_READ | PROT_EXEC);
}
/* Serialize the GNU relro segments to the given file descriptor. This can be
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index aab9018..3b68528 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -39,6 +39,15 @@
#include "linker_mapped_file_fragment.h"
#include "linker_note_gnu_property.h"
+#include <list>
+
+#define MAYBE_MAP_FLAG(x, from, to) (((x) & (from)) ? (to) : 0)
+#define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
+ MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
+ MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
+
+static constexpr size_t kCompatPageSize = 0x1000;
+
class ElfReader {
public:
ElfReader();
@@ -59,15 +68,28 @@
bool is_mapped_by_caller() const { return mapped_by_caller_; }
ElfW(Addr) entry_point() const { return header_.e_entry + load_bias_; }
bool should_pad_segments() const { return should_pad_segments_; }
+ bool should_use_16kib_app_compat() const { return should_use_16kib_app_compat_; }
+ ElfW(Addr) compat_relro_start() const { return compat_relro_start_; }
+ ElfW(Addr) compat_relro_size() const { return compat_relro_size_; }
private:
[[nodiscard]] bool ReadElfHeader();
[[nodiscard]] bool VerifyElfHeader();
[[nodiscard]] bool ReadProgramHeaders();
+ [[nodiscard]] bool CheckProgramHeaderAlignment();
[[nodiscard]] bool ReadSectionHeaders();
[[nodiscard]] bool ReadDynamicSection();
[[nodiscard]] bool ReadPadSegmentNote();
[[nodiscard]] bool ReserveAddressSpace(address_space_params* address_space);
+ [[nodiscard]] bool MapSegment(size_t seg_idx, size_t len);
+ [[nodiscard]] bool CompatMapSegment(size_t seg_idx, size_t len);
+ void ZeroFillSegment(const ElfW(Phdr)* phdr);
+ void DropPaddingPages(const ElfW(Phdr)* phdr, uint64_t seg_file_end);
+ [[nodiscard]] bool MapBssSection(const ElfW(Phdr)* phdr, ElfW(Addr) seg_page_end,
+ ElfW(Addr) seg_file_end);
+ [[nodiscard]] bool IsEligibleFor16KiBAppCompat(ElfW(Addr)* vaddr);
+ [[nodiscard]] bool HasAtMostOneRelroSegment(const ElfW(Phdr)** relro_phdr);
+ [[nodiscard]] bool Setup16KiBAppCompat();
[[nodiscard]] bool LoadSegments();
[[nodiscard]] bool FindPhdr();
[[nodiscard]] bool FindGnuPropertySection();
@@ -109,6 +131,10 @@
// Load bias.
ElfW(Addr) load_bias_;
+ // Maximum and minimum alignment requirements across all phdrs.
+ size_t max_align_;
+ size_t min_align_;
+
// Loaded phdr.
const ElfW(Phdr)* loaded_phdr_;
@@ -118,6 +144,13 @@
// Pad gaps between segments when memory mapping?
bool should_pad_segments_ = false;
+ // Use app compat mode when loading 4KiB max-page-size ELFs on 16KiB page-size devices?
+ bool should_use_16kib_app_compat_ = false;
+
+ // RELRO region for 16KiB compat loading
+ ElfW(Addr) compat_relro_start_ = 0;
+ ElfW(Addr) compat_relro_size_ = 0;
+
// Only used by AArch64 at the moment.
GnuPropertySection note_gnu_property_ __unused;
};
@@ -125,17 +158,20 @@
size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr)* min_vaddr = nullptr, ElfW(Addr)* max_vaddr = nullptr);
-size_t phdr_table_get_maximum_alignment(const ElfW(Phdr)* phdr_table, size_t phdr_count);
-
int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat,
const GnuPropertySection* prop = nullptr);
int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, bool should_pad_segments);
+ ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat);
int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, bool should_pad_segments);
+ ElfW(Addr) load_bias, bool should_pad_segments,
+ bool should_use_16kib_app_compat);
+
+int phdr_table_protect_gnu_relro_16kib_compat(ElfW(Addr) start, ElfW(Addr) size);
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, int fd, size_t* file_offset);
@@ -156,3 +192,13 @@
ElfW(Addr) load_bias);
bool page_size_migration_supported();
+
+int remap_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias);
+
+void protect_memtag_globals_ro_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias);
+
+void name_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, const char* soname,
+ std::list<std::string>* vma_names);
diff --git a/linker/linker_phdr_16kib_compat.cpp b/linker/linker_phdr_16kib_compat.cpp
new file mode 100644
index 0000000..d3783cf
--- /dev/null
+++ b/linker/linker_phdr_16kib_compat.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2012 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 "linker_phdr.h"
+
+#include <linux/prctl.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+#include "linker_debug.h"
+#include "linker_dlwarning.h"
+#include "linker_globals.h"
+
+#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
+
+#include <string>
+
+static bool g_enable_16kb_app_compat;
+
+static inline bool segment_contains_prefix(const ElfW(Phdr)* segment, const ElfW(Phdr)* prefix) {
+ return segment && prefix && segment->p_vaddr == prefix->p_vaddr;
+}
+
+void set_16kb_appcompat_mode(bool enable_app_compat) {
+ g_enable_16kb_app_compat = enable_app_compat;
+}
+
+bool get_16kb_appcompat_mode() {
+ return g_enable_16kb_app_compat;
+}
+
+/*
+ * Returns true if the ELF contains at most 1 RELRO segment; and populates @relro_phdr
+ * with the relro phdr or nullptr if none.
+ *
+ * Returns false if more than 1 RELRO segments are found.
+ */
+bool ElfReader::HasAtMostOneRelroSegment(const ElfW(Phdr)** relro_phdr) {
+ const ElfW(Phdr)* relro = nullptr;
+ for (size_t i = 0; i < phdr_num_; ++i) {
+ const ElfW(Phdr)* phdr = &phdr_table_[i];
+
+ if (phdr->p_type != PT_GNU_RELRO) {
+ continue;
+ }
+
+ if (relro == nullptr) {
+ relro = phdr;
+ } else {
+ return false;
+ }
+ }
+
+ *relro_phdr = relro;
+
+ return true;
+}
+
+/*
+ * In 16KiB compatibility mode ELFs with the following segment layout
+ * can be loaded successfully:
+ *
+ * ┌────────────┬─────────────────────────┬────────────┐
+ * │ │ │ │
+ * │ (RO|RX)* │ (RW - RELRO prefix)? │ (RW)* │
+ * │ │ │ │
+ * └────────────┴─────────────────────────┴────────────┘
+ *
+ * In other words, compatible layouts have:
+ * - zero or more RO or RX segments;
+ * - followed by zero or one RELRO prefix;
+ * - followed by zero or more RW segments (this can include the RW
+ * suffix from the segment containing the RELRO prefix, if any)
+ *
+ * In 16KiB compat mode, after relocation, the ELF is layout in virtual
+ * memory is as shown below:
+ * ┌──────────────────────────────────────┬────────────┐
+ * │ │ │
+ * │ (RX)? │ (RW)? │
+ * │ │ │
+ * └──────────────────────────────────────┴────────────┘
+ *
+ * In compat mode:
+ * - the RO and RX segments along with the RELRO prefix are protected
+ * as RX;
+ * - and the RW segments along with RW suffix from the relro segment,
+ * if any; are RW protected.
+ *
+ * This allows for the single RX|RW permission boundary to be aligned with
+ * a 16KiB page boundary; since a single page cannot share multiple
+ * permissions.
+ *
+ * IsEligibleFor16KiBAppCompat() identifies compatible ELFs and populates @vaddr
+ * with the boundary between RX|RW portions.
+ *
+ * Returns true if the ELF can be loaded in compat mode, else false.
+ */
+bool ElfReader::IsEligibleFor16KiBAppCompat(ElfW(Addr)* vaddr) {
+ const ElfW(Phdr)* relro_phdr = nullptr;
+ if (!HasAtMostOneRelroSegment(&relro_phdr)) {
+ DL_WARN("\"%s\": Compat loading failed: Multiple RELRO segments found", name_.c_str());
+ return false;
+ }
+
+ const ElfW(Phdr)* last_rw = nullptr;
+ const ElfW(Phdr)* first_rw = nullptr;
+
+ for (size_t i = 0; i < phdr_num_; ++i) {
+ const ElfW(Phdr)* curr = &phdr_table_[i];
+ const ElfW(Phdr)* prev = (i > 0) ? &phdr_table_[i - 1] : nullptr;
+
+ if (curr->p_type != PT_LOAD) {
+ continue;
+ }
+
+ int prot = PFLAGS_TO_PROT(curr->p_flags);
+
+ if ((prot & PROT_WRITE) && (prot & PROT_READ)) {
+ if (!first_rw) {
+ first_rw = curr;
+ }
+
+ if (last_rw && last_rw != prev) {
+ DL_WARN("\"%s\": Compat loading failed: ELF contains multiple non-adjacent RW segments",
+ name_.c_str());
+ return false;
+ }
+
+ last_rw = curr;
+ }
+ }
+
+ if (!relro_phdr) {
+ *vaddr = __builtin_align_down(first_rw->p_vaddr, kCompatPageSize);
+ return true;
+ }
+
+ // The RELRO segment is present, it must be the prefix of the first RW segment.
+ if (!segment_contains_prefix(first_rw, relro_phdr)) {
+ DL_WARN("\"%s\": Compat loading failed: RELRO is not in the first RW segment",
+ name_.c_str());
+ return false;
+ }
+
+ uint64_t end;
+ if (__builtin_add_overflow(relro_phdr->p_vaddr, relro_phdr->p_memsz, &end)) {
+ DL_WARN("\"%s\": Compat loading failed: relro vaddr + memsz overflowed", name_.c_str());
+ return false;
+ }
+
+ *vaddr = __builtin_align_up(end, kCompatPageSize);
+ return true;
+}
+
+/*
+ * Returns the offset/shift needed to align @vaddr to a page boundary.
+ */
+static inline ElfW(Addr) perm_boundary_offset(const ElfW(Addr) addr) {
+ ElfW(Addr) offset = page_offset(addr);
+
+ return offset ? page_size() - offset : 0;
+}
+
+bool ElfReader::Setup16KiBAppCompat() {
+ if (!should_use_16kib_app_compat_) {
+ return true;
+ }
+
+ ElfW(Addr) rx_rw_boundary; // Permission bounadry for compat mode
+ if (!IsEligibleFor16KiBAppCompat(&rx_rw_boundary)) {
+ return false;
+ }
+
+ // Adjust the load_bias to position the RX|RW boundary on a page boundary
+ load_bias_ += perm_boundary_offset(rx_rw_boundary);
+
+ // RW region (.data, .bss ...)
+ ElfW(Addr) rw_start = load_bias_ + rx_rw_boundary;
+ ElfW(Addr) rw_size = load_size_ - (rw_start - reinterpret_cast<ElfW(Addr)>(load_start_));
+
+ CHECK(rw_start % getpagesize() == 0);
+ CHECK(rw_size % getpagesize() == 0);
+
+ // Compat RELRO (RX) region (.text, .data.relro, ...)
+ compat_relro_start_ = reinterpret_cast<ElfW(Addr)>(load_start_);
+ compat_relro_size_ = load_size_ - rw_size;
+
+ // Label the ELF VMA, since compat mode uses anonymous mappings.
+ std::string compat_name = name_ + " (compat loaded)";
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, load_start_, load_size_, compat_name.c_str());
+
+ return true;
+}
+
+bool ElfReader::CompatMapSegment(size_t seg_idx, size_t len) {
+ const ElfW(Phdr)* phdr = &phdr_table_[seg_idx];
+
+ // NOTE: The compat(legacy) page size (4096) must be used when aligning
+ // the 4KiB segments for loading (reading). The larger 16KiB page size
+ // will lead to overwriting adjacent segments since the ELF's segment(s)
+ // are not 16KiB aligned.
+
+ void* start = reinterpret_cast<void*>(__builtin_align_down(phdr->p_vaddr + load_bias_, kCompatPageSize));
+
+ // The ELF could be being loaded directly from a zipped APK,
+ // the zip offset must be added to find the segment offset.
+ const ElfW(Addr) offset = file_offset_ + __builtin_align_down(phdr->p_offset, kCompatPageSize);
+
+ CHECK(should_use_16kib_app_compat_);
+
+ // Since the 4KiB max-page-size ELF is not properly aligned, loading it by
+ // directly mmapping the ELF file is not feasible.
+ // Instead, read the ELF contents into the anonymous RW mapping.
+ if (TEMP_FAILURE_RETRY(pread64(fd_, start, len, offset)) == -1) {
+ DL_ERR("Compat loading: \"%s\" failed to read LOAD segment %zu: %m", name_.c_str(), seg_idx);
+ return false;
+ }
+
+ return true;
+}
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 5f993ba..bbf8359 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -44,6 +44,8 @@
#include "linker_soinfo.h"
#include "private/bionic_globals.h"
+#include <platform/bionic/mte.h>
+
static bool is_tls_reloc(ElfW(Word) type) {
switch (type) {
case R_GENERIC_TLS_DTPMOD:
@@ -147,12 +149,13 @@
}
void print_linker_stats() {
- PRINT("RELO STATS: %s: %d abs, %d rel, %d symbol (%d cached)",
- g_argv[0],
- linker_stats.count[kRelocAbsolute],
- linker_stats.count[kRelocRelative],
- linker_stats.count[kRelocSymbol],
- linker_stats.count[kRelocSymbolCached]);
+ LD_DEBUG(statistics,
+ "RELO STATS: %s: %d abs, %d rel, %d symbol (%d cached)",
+ g_argv[0],
+ linker_stats.count[kRelocAbsolute],
+ linker_stats.count[kRelocRelative],
+ linker_stats.count[kRelocSymbol],
+ linker_stats.count[kRelocSymbolCached]);
}
static bool process_relocation_general(Relocator& relocator, const rel_t& reloc);
@@ -162,7 +165,8 @@
static bool process_relocation_impl(Relocator& relocator, const rel_t& reloc) {
constexpr bool IsGeneral = Mode == RelocMode::General;
- void* const rel_target = reinterpret_cast<void*>(reloc.r_offset + relocator.si->load_bias);
+ void* const rel_target = reinterpret_cast<void*>(
+ relocator.si->apply_memtag_if_mte_globals(reloc.r_offset + relocator.si->load_bias));
const uint32_t r_type = ELFW(R_TYPE)(reloc.r_info);
const uint32_t r_sym = ELFW(R_SYM)(reloc.r_info);
@@ -187,10 +191,9 @@
auto protect_segments = [&]() {
// Make .text executable.
if (phdr_table_protect_segments(relocator.si->phdr, relocator.si->phnum,
- relocator.si->load_bias,
- relocator.si->should_pad_segments()) < 0) {
- DL_ERR("can't protect segments for \"%s\": %s",
- relocator.si->get_realpath(), strerror(errno));
+ relocator.si->load_bias, relocator.si->should_pad_segments(),
+ relocator.si->should_use_16kib_app_compat()) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %m", relocator.si->get_realpath());
return false;
}
return true;
@@ -198,30 +201,19 @@
auto unprotect_segments = [&]() {
// Make .text writable.
if (phdr_table_unprotect_segments(relocator.si->phdr, relocator.si->phnum,
- relocator.si->load_bias,
- relocator.si->should_pad_segments()) < 0) {
- DL_ERR("can't unprotect loadable segments for \"%s\": %s",
- relocator.si->get_realpath(), strerror(errno));
+ relocator.si->load_bias, relocator.si->should_pad_segments(),
+ relocator.si->should_use_16kib_app_compat()) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %m",
+ relocator.si->get_realpath());
return false;
}
return true;
};
#endif
- auto trace_reloc = [](const char* fmt, ...) __printflike(2, 3) {
- if (IsGeneral &&
- g_ld_debug_verbosity > LINKER_VERBOSITY_TRACE &&
- DO_TRACE_RELO) {
- va_list ap;
- va_start(ap, fmt);
- linker_log_va_list(LINKER_VERBOSITY_TRACE, fmt, ap);
- va_end(ap);
- }
- };
-
// Skip symbol lookup for R_GENERIC_NONE relocations.
if (__predict_false(r_type == R_GENERIC_NONE)) {
- trace_reloc("RELO NONE");
+ LD_DEBUG(reloc && IsGeneral, "RELO NONE");
return true;
}
@@ -314,8 +306,8 @@
if (r_type == R_GENERIC_JUMP_SLOT) {
count_relocation_if<IsGeneral>(kRelocAbsolute);
const ElfW(Addr) result = sym_addr + get_addend_norel();
- trace_reloc("RELO JMP_SLOT %16p <- %16p %s",
- rel_target, reinterpret_cast<void*>(result), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO JMP_SLOT %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
}
@@ -327,9 +319,10 @@
// common in non-platform binaries.
if (r_type == R_GENERIC_ABSOLUTE) {
count_relocation_if<IsGeneral>(kRelocAbsolute);
+ if (found_in) sym_addr = found_in->apply_memtag_if_mte_globals(sym_addr);
const ElfW(Addr) result = sym_addr + get_addend_rel();
- trace_reloc("RELO ABSOLUTE %16p <- %16p %s",
- rel_target, reinterpret_cast<void*>(result), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO ABSOLUTE %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
} else if (r_type == R_GENERIC_GLOB_DAT) {
@@ -337,18 +330,30 @@
// document (IHI0044F) specifies that R_ARM_GLOB_DAT has an addend, but Bionic isn't adding
// it.
count_relocation_if<IsGeneral>(kRelocAbsolute);
+ if (found_in) sym_addr = found_in->apply_memtag_if_mte_globals(sym_addr);
const ElfW(Addr) result = sym_addr + get_addend_norel();
- trace_reloc("RELO GLOB_DAT %16p <- %16p %s",
- rel_target, reinterpret_cast<void*>(result), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO GLOB_DAT %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
} else if (r_type == R_GENERIC_RELATIVE) {
// In practice, r_sym is always zero, but if it weren't, the linker would still look up the
// referenced symbol (and abort if the symbol isn't found), even though it isn't used.
count_relocation_if<IsGeneral>(kRelocRelative);
- const ElfW(Addr) result = relocator.si->load_bias + get_addend_rel();
- trace_reloc("RELO RELATIVE %16p <- %16p",
- rel_target, reinterpret_cast<void*>(result));
+ ElfW(Addr) result = relocator.si->load_bias + get_addend_rel();
+ // MTE globals reuses the place bits for additional tag-derivation metadata for
+ // R_AARCH64_RELATIVE relocations, which makes it incompatible with
+ // `-Wl,--apply-dynamic-relocs`. This is enforced by lld, however there's nothing stopping
+ // Android binaries (particularly prebuilts) from building with this linker flag if they're
+ // not built with MTE globals. Thus, don't use the new relocation semantics if this DSO
+ // doesn't have MTE globals.
+ if (relocator.si->should_tag_memtag_globals()) {
+ int64_t* place = static_cast<int64_t*>(rel_target);
+ int64_t offset = *place;
+ result = relocator.si->apply_memtag_if_mte_globals(result + offset) - offset;
+ }
+ LD_DEBUG(reloc && IsGeneral, "RELO RELATIVE %16p <- %16p",
+ rel_target, reinterpret_cast<void*>(result));
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
}
@@ -369,8 +374,8 @@
if (!relocator.si->is_linker()) {
count_relocation_if<IsGeneral>(kRelocRelative);
const ElfW(Addr) ifunc_addr = relocator.si->load_bias + get_addend_rel();
- trace_reloc("RELO IRELATIVE %16p <- %16p",
- rel_target, reinterpret_cast<void*>(ifunc_addr));
+ LD_DEBUG(reloc && IsGeneral, "RELO IRELATIVE %16p <- %16p",
+ rel_target, reinterpret_cast<void*>(ifunc_addr));
if (handle_text_relocs && !protect_segments()) return false;
const ElfW(Addr) result = call_ifunc_resolver(ifunc_addr);
if (handle_text_relocs && !unprotect_segments()) return false;
@@ -407,8 +412,8 @@
}
}
tpoff += sym_addr + get_addend_rel();
- trace_reloc("RELO TLS_TPREL %16p <- %16p %s",
- rel_target, reinterpret_cast<void*>(tpoff), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLS_TPREL %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(tpoff), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = tpoff;
}
break;
@@ -423,8 +428,8 @@
module_id = found_in->get_tls()->module_id;
CHECK(module_id != kTlsUninitializedModuleId);
}
- trace_reloc("RELO TLS_DTPMOD %16p <- %zu %s",
- rel_target, module_id, sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLS_DTPMOD %16p <- %zu %s",
+ rel_target, module_id, sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = module_id;
}
break;
@@ -432,8 +437,8 @@
count_relocation_if<IsGeneral>(kRelocRelative);
{
const ElfW(Addr) result = sym_addr + get_addend_rel() - TLS_DTV_OFFSET;
- trace_reloc("RELO TLS_DTPREL %16p <- %16p %s",
- rel_target, reinterpret_cast<void*>(result), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLS_DTPREL %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
}
break;
@@ -450,8 +455,8 @@
// Unresolved weak relocation.
desc->func = tlsdesc_resolver_unresolved_weak;
desc->arg = addend;
- trace_reloc("RELO TLSDESC %16p <- unresolved weak, addend 0x%zx %s",
- rel_target, static_cast<size_t>(addend), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLSDESC %16p <- unresolved weak, addend 0x%zx %s",
+ rel_target, static_cast<size_t>(addend), sym_name);
} else {
CHECK(found_in->get_tls() != nullptr); // We rejected a missing TLS segment above.
size_t module_id = found_in->get_tls()->module_id;
@@ -459,10 +464,10 @@
if (mod.static_offset != SIZE_MAX) {
desc->func = tlsdesc_resolver_static;
desc->arg = mod.static_offset - relocator.tls_tp_base + sym_addr + addend;
- trace_reloc("RELO TLSDESC %16p <- static (0x%zx - 0x%zx + 0x%zx + 0x%zx) %s",
- rel_target, mod.static_offset, relocator.tls_tp_base,
- static_cast<size_t>(sym_addr), static_cast<size_t>(addend),
- sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLSDESC %16p <- static (0x%zx - 0x%zx + 0x%zx + 0x%zx) %s",
+ rel_target, mod.static_offset, relocator.tls_tp_base,
+ static_cast<size_t>(sym_addr), static_cast<size_t>(addend),
+ sym_name);
} else {
relocator.tlsdesc_args->push_back({
.generation = mod.first_generation,
@@ -475,9 +480,9 @@
desc, relocator.tlsdesc_args->size() - 1
});
const TlsDynamicResolverArg& desc_arg = relocator.tlsdesc_args->back();
- trace_reloc("RELO TLSDESC %16p <- dynamic (gen %zu, mod %zu, off %zu) %s",
- rel_target, desc_arg.generation, desc_arg.index.module_id,
- desc_arg.index.offset, sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO TLSDESC %16p <- dynamic (gen %zu, mod %zu, off %zu) %s",
+ rel_target, desc_arg.generation, desc_arg.index.module_id,
+ desc_arg.index.offset, sym_name);
}
}
}
@@ -489,8 +494,8 @@
count_relocation_if<IsGeneral>(kRelocAbsolute);
{
const Elf32_Addr result = sym_addr + reloc.r_addend;
- trace_reloc("RELO R_X86_64_32 %16p <- 0x%08x %s",
- rel_target, result, sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO R_X86_64_32 %16p <- 0x%08x %s",
+ rel_target, result, sym_name);
*static_cast<Elf32_Addr*>(rel_target) = result;
}
break;
@@ -500,9 +505,9 @@
const ElfW(Addr) target = sym_addr + reloc.r_addend;
const ElfW(Addr) base = reinterpret_cast<ElfW(Addr)>(rel_target);
const Elf32_Addr result = target - base;
- trace_reloc("RELO R_X86_64_PC32 %16p <- 0x%08x (%16p - %16p) %s",
- rel_target, result, reinterpret_cast<void*>(target),
- reinterpret_cast<void*>(base), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO R_X86_64_PC32 %16p <- 0x%08x (%16p - %16p) %s",
+ rel_target, result, reinterpret_cast<void*>(target),
+ reinterpret_cast<void*>(base), sym_name);
*static_cast<Elf32_Addr*>(rel_target) = result;
}
break;
@@ -513,9 +518,9 @@
const ElfW(Addr) target = sym_addr + get_addend_rel();
const ElfW(Addr) base = reinterpret_cast<ElfW(Addr)>(rel_target);
const ElfW(Addr) result = target - base;
- trace_reloc("RELO R_386_PC32 %16p <- 0x%08x (%16p - %16p) %s",
- rel_target, result, reinterpret_cast<void*>(target),
- reinterpret_cast<void*>(base), sym_name);
+ LD_DEBUG(reloc && IsGeneral, "RELO R_386_PC32 %16p <- 0x%08x (%16p - %16p) %s",
+ rel_target, result, reinterpret_cast<void*>(target),
+ reinterpret_cast<void*>(base), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
}
break;
@@ -560,15 +565,11 @@
}
static bool needs_slow_relocate_loop(const Relocator& relocator __unused) {
-#if STATS
- // TODO: This could become a run-time flag.
- return true;
-#endif
#if !defined(__LP64__)
if (relocator.si->has_text_relocations) return true;
#endif
- if (g_ld_debug_verbosity > LINKER_VERBOSITY_TRACE) {
- // If linker TRACE() is enabled, then each relocation is logged.
+ // Both LD_DEBUG relocation logging and statistics need the slow path.
+ if (g_linker_debug_config.any || g_linker_debug_config.statistics) {
return true;
}
return false;
@@ -612,10 +613,10 @@
// The linker already applied its RELR relocations in an earlier pass, so
// skip the RELR relocations for the linker.
if (relr_ != nullptr && !is_linker()) {
- DEBUG("[ relocating %s relr ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s relr ]", get_realpath());
const ElfW(Relr)* begin = relr_;
const ElfW(Relr)* end = relr_ + relr_count_;
- if (!relocate_relr(begin, end, load_bias)) {
+ if (!relocate_relr(begin, end, load_bias, should_tag_memtag_globals())) {
return false;
}
}
@@ -627,7 +628,7 @@
android_relocs_[1] == 'P' &&
android_relocs_[2] == 'S' &&
android_relocs_[3] == '2') {
- DEBUG("[ relocating %s android rel/rela ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s android rel/rela ]", get_realpath());
const uint8_t* packed_relocs = android_relocs_ + 4;
const size_t packed_relocs_size = android_relocs_size_ - 4;
@@ -643,27 +644,27 @@
#if defined(USE_RELA)
if (rela_ != nullptr) {
- DEBUG("[ relocating %s rela ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s rela ]", get_realpath());
if (!plain_relocate<RelocMode::Typical>(relocator, rela_, rela_count_)) {
return false;
}
}
if (plt_rela_ != nullptr) {
- DEBUG("[ relocating %s plt rela ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s plt rela ]", get_realpath());
if (!plain_relocate<RelocMode::JumpTable>(relocator, plt_rela_, plt_rela_count_)) {
return false;
}
}
#else
if (rel_ != nullptr) {
- DEBUG("[ relocating %s rel ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s rel ]", get_realpath());
if (!plain_relocate<RelocMode::Typical>(relocator, rel_, rel_count_)) {
return false;
}
}
if (plt_rel_ != nullptr) {
- DEBUG("[ relocating %s plt rel ]", get_realpath());
+ LD_DEBUG(reloc, "[ relocating %s plt rel ]", get_realpath());
if (!plain_relocate<RelocMode::JumpTable>(relocator, plt_rel_, plt_rel_count_)) {
return false;
}
diff --git a/linker/linker_sleb128.h b/linker/linker_sleb128.h
index 6bb3199..f48fda8 100644
--- a/linker/linker_sleb128.h
+++ b/linker/linker_sleb128.h
@@ -69,3 +69,32 @@
const uint8_t* current_;
const uint8_t* const end_;
};
+
+class uleb128_decoder {
+ public:
+ uleb128_decoder(const uint8_t* buffer, size_t count) : current_(buffer), end_(buffer + count) {}
+
+ uint64_t pop_front() {
+ uint64_t value = 0;
+
+ size_t shift = 0;
+ uint8_t byte;
+
+ do {
+ if (current_ >= end_) {
+ async_safe_fatal("uleb128_decoder ran out of bounds");
+ }
+ byte = *current_++;
+ value |= (static_cast<size_t>(byte & 127) << shift);
+ shift += 7;
+ } while (byte & 128);
+
+ return value;
+ }
+
+ bool has_bytes() { return current_ < end_; }
+
+ private:
+ const uint8_t* current_;
+ const uint8_t* const end_;
+};
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index d915503..176c133 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -44,21 +44,18 @@
#include "linker_logger.h"
#include "linker_relocate.h"
#include "linker_utils.h"
-
-// Enable the slow lookup path if symbol lookups should be logged.
-static bool is_lookup_tracing_enabled() {
- return g_ld_debug_verbosity > LINKER_VERBOSITY_TRACE && DO_TRACE_LOOKUP;
-}
+#include "platform/bionic/mte.h"
+#include "private/bionic_globals.h"
SymbolLookupList::SymbolLookupList(soinfo* si)
: sole_lib_(si->get_lookup_lib()), begin_(&sole_lib_), end_(&sole_lib_ + 1) {
CHECK(si != nullptr);
- slow_path_count_ += is_lookup_tracing_enabled();
+ slow_path_count_ += !!g_linker_debug_config.lookup;
slow_path_count_ += sole_lib_.needs_sysv_lookup();
}
SymbolLookupList::SymbolLookupList(const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
- slow_path_count_ += is_lookup_tracing_enabled();
+ slow_path_count_ += !!g_linker_debug_config.lookup;
libs_.reserve(1 + global_group.size() + local_group.size());
// Reserve a space in front for DT_SYMBOLIC lookup.
@@ -144,8 +141,8 @@
}
if (IsGeneral) {
- TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
- name, lib->si_->get_realpath(), reinterpret_cast<void*>(lib->si_->base));
+ LD_DEBUG(lookup, "SEARCH %s in %s@%p (gnu)",
+ name, lib->si_->get_realpath(), reinterpret_cast<void*>(lib->si_->base));
}
const uint32_t word_num = (hash / kBloomMaskBits) & lib->gnu_maskwords_;
@@ -159,11 +156,6 @@
break;
}
}
-
- if (IsGeneral) {
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- name, lib->si_->get_realpath(), reinterpret_cast<void*>(lib->si_->base));
- }
}
// Search the library's hash table chain.
@@ -186,21 +178,11 @@
memcmp(lib->strtab_ + sym->st_name, name, name_len + 1) == 0 &&
is_symbol_global_and_defined(lib->si_, sym)) {
*si_found_in = lib->si_;
- if (IsGeneral) {
- TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
- name, lib->si_->get_realpath(), reinterpret_cast<void*>(sym->st_value),
- static_cast<size_t>(sym->st_size));
- }
return sym;
}
}
++sym_idx;
} while ((chain_value & 1) == 0);
-
- if (IsGeneral) {
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- name, lib->si_->get_realpath(), reinterpret_cast<void*>(lib->si_->base));
- }
}
}
@@ -324,6 +306,12 @@
return is_gnu_hash() ? gnu_lookup(symbol_name, vi) : elf_lookup(symbol_name, vi);
}
+ElfW(Addr) soinfo::apply_memtag_if_mte_globals(ElfW(Addr) sym_addr) const {
+ if (!should_tag_memtag_globals()) return sym_addr;
+ if (sym_addr == 0) return sym_addr; // Handle undefined weak symbols.
+ return reinterpret_cast<ElfW(Addr)>(get_tagged_address(reinterpret_cast<void*>(sym_addr)));
+}
+
const ElfW(Sym)* soinfo::gnu_lookup(SymbolName& symbol_name, const version_info* vi) const {
const uint32_t hash = symbol_name.gnu_hash();
@@ -333,14 +321,11 @@
const uint32_t h1 = hash % kBloomMaskBits;
const uint32_t h2 = (hash >> gnu_shift2_) % kBloomMaskBits;
- TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
- symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
+ LD_DEBUG(lookup, "SEARCH %s in %s@%p (gnu)",
+ symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
// test against bloom filter
if ((1 & (bloom_word >> h1) & (bloom_word >> h2)) == 0) {
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
-
return nullptr;
}
@@ -348,9 +333,6 @@
uint32_t n = gnu_bucket_[hash % gnu_nbucket_];
if (n == 0) {
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
-
return nullptr;
}
@@ -363,25 +345,19 @@
check_symbol_version(versym, n, verneed) &&
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
- TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
- symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
- static_cast<size_t>(s->st_size));
return symtab_ + n;
}
} while ((gnu_chain_[n++] & 1) == 0);
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
- symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
-
return nullptr;
}
const ElfW(Sym)* soinfo::elf_lookup(SymbolName& symbol_name, const version_info* vi) const {
uint32_t hash = symbol_name.elf_hash();
- TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
- symbol_name.get_name(), get_realpath(),
- reinterpret_cast<void*>(base), hash, hash % nbucket_);
+ LD_DEBUG(lookup, "SEARCH %s in %s@%p h=%x(elf) %zd",
+ symbol_name.get_name(), get_realpath(),
+ reinterpret_cast<void*>(base), hash, hash % nbucket_);
const ElfW(Versym) verneed = find_verdef_version_index(this, vi);
const ElfW(Versym)* versym = get_versym_table();
@@ -392,18 +368,10 @@
if (check_symbol_version(versym, n, verneed) &&
strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
is_symbol_global_and_defined(this, s)) {
- TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
- symbol_name.get_name(), get_realpath(),
- reinterpret_cast<void*>(s->st_value),
- static_cast<size_t>(s->st_size));
return symtab_ + n;
}
}
- TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
- symbol_name.get_name(), get_realpath(),
- reinterpret_cast<void*>(base), hash, hash % nbucket_);
-
return nullptr;
}
@@ -464,9 +432,9 @@
return;
}
- TRACE("[ Calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ LD_DEBUG(calls, "[ Calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
function(g_argc, g_argv, g_envp);
- TRACE("[ Done calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ LD_DEBUG(calls, "[ Done calling c-tor %s @ %p for '%s' ]", function_name, function, realpath);
}
static void call_function(const char* function_name __unused,
@@ -476,9 +444,9 @@
return;
}
- TRACE("[ Calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ LD_DEBUG(calls, "[ Calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
function();
- TRACE("[ Done calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
+ LD_DEBUG(calls, "[ Done calling d-tor %s @ %p for '%s' ]", function_name, function, realpath);
}
template <typename F>
@@ -488,18 +456,18 @@
return;
}
- TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, realpath);
+ LD_DEBUG(calls, "[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, realpath);
int begin = reverse ? (count - 1) : 0;
int end = reverse ? -1 : count;
int step = reverse ? -1 : 1;
for (int i = begin; i != end; i += step) {
- TRACE("[ %s[%d] == %p ]", array_name, i, functions[i]);
+ LD_DEBUG(calls, "[ %s[%d] == %p ]", array_name, i, functions[i]);
call_function("function", functions[i], realpath);
}
- TRACE("[ Done calling %s for '%s' ]", array_name, realpath);
+ LD_DEBUG(calls, "[ Done calling %s for '%s' ]", array_name, realpath);
}
void soinfo::call_pre_init_constructors() {
@@ -527,7 +495,7 @@
if (!is_main_executable() && preinit_array_ != nullptr) {
// The GNU dynamic linker silently ignores these, but we warn the developer.
- PRINT("\"%s\": ignoring DT_PREINIT_ARRAY in shared library!", get_realpath());
+ DL_WARN("\"%s\": ignoring DT_PREINIT_ARRAY in shared library!", get_realpath());
}
get_children().for_each([] (soinfo* si) {
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 9a13af2..4d02676 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -30,6 +30,7 @@
#include <link.h>
+#include <list>
#include <memory>
#include <string>
#include <vector>
@@ -66,6 +67,7 @@
// soinfo is executed and this flag is
// unset.
#define FLAG_PRELINKED 0x00000400 // prelink_image has successfully processed this soinfo
+#define FLAG_GLOBALS_TAGGED 0x00000800 // globals have been tagged by MTE.
#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
#define SOINFO_VERSION 6
@@ -252,11 +254,14 @@
void call_constructors();
void call_destructors();
void call_pre_init_constructors();
- bool prelink_image();
+ bool prelink_image(bool deterministic_memtag_globals = false);
bool link_image(const SymbolLookupList& lookup_list, soinfo* local_group_root,
const android_dlextinfo* extinfo, size_t* relro_fd_offset);
bool protect_relro();
+ void tag_globals(bool deterministic_memtag_globals);
+ ElfW(Addr) apply_memtag_if_mte_globals(ElfW(Addr) sym_addr) const;
+
void add_child(soinfo* child);
void remove_all_links();
@@ -293,6 +298,9 @@
#if defined(__work_around_b_24465209__)
return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
#else
+ // If you make this return non-true in the case where
+ // __work_around_b_24465209__ is not defined, you will have to change
+ // memtag_dynamic_entries() and vma_names().
return true;
#endif
}
@@ -354,20 +362,66 @@
size_t get_gap_size() const;
const memtag_dynamic_entries_t* memtag_dynamic_entries() const {
- CHECK(has_min_version(7));
+#ifdef __aarch64__
+#ifdef __work_around_b_24465209__
+#error "Assuming aarch64 does not use versioned soinfo."
+#endif
return &memtag_dynamic_entries_;
+#endif
+ return nullptr;
}
- void* memtag_globals() const { return memtag_dynamic_entries()->memtag_globals; }
- size_t memtag_globalssz() const { return memtag_dynamic_entries()->memtag_globalssz; }
- bool has_memtag_mode() const { return memtag_dynamic_entries()->has_memtag_mode; }
- unsigned memtag_mode() const { return memtag_dynamic_entries()->memtag_mode; }
- bool memtag_heap() const { return memtag_dynamic_entries()->memtag_heap; }
- bool memtag_stack() const { return memtag_dynamic_entries()->memtag_stack; }
+ void* memtag_globals() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->memtag_globals : nullptr;
+ }
+ size_t memtag_globalssz() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->memtag_globalssz : 0U;
+ }
+ bool has_memtag_mode() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->has_memtag_mode : false;
+ }
+ unsigned memtag_mode() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->memtag_mode : 0U;
+ }
+ bool memtag_heap() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->memtag_heap : false;
+ }
+ bool memtag_stack() const {
+ const memtag_dynamic_entries_t* entries = memtag_dynamic_entries();
+ return entries ? entries->memtag_stack : false;
+ }
void set_should_pad_segments(bool should_pad_segments) {
should_pad_segments_ = should_pad_segments;
}
bool should_pad_segments() const { return should_pad_segments_; }
+ bool should_tag_memtag_globals() const {
+ return !is_linker() && memtag_globals() && memtag_globalssz() > 0 && __libc_mte_enabled();
+ }
+ std::list<std::string>* vma_names() {
+#ifdef __aarch64__
+#ifdef __work_around_b_24465209__
+#error "Assuming aarch64 does not use versioned soinfo."
+#endif
+ return &vma_names_;
+#endif
+ return nullptr;
+};
+
+ void set_should_use_16kib_app_compat(bool should_use_16kib_app_compat) {
+ should_use_16kib_app_compat_ = should_use_16kib_app_compat;
+ }
+ bool should_use_16kib_app_compat() const { return should_use_16kib_app_compat_; }
+
+ void set_compat_relro_start(ElfW(Addr) start) { compat_relro_start_ = start; }
+ ElfW(Addr) compat_relro_start() const { return compat_relro_start_; }
+
+ void set_compat_relro_size(ElfW(Addr) size) { compat_relro_size_ = size; }
+ ElfW(Addr) compat_relro_size() const { return compat_relro_start_; }
private:
bool is_image_linked() const;
@@ -450,11 +504,19 @@
ElfW(Addr) gap_start_;
size_t gap_size_;
- // version >= 7
+ // __aarch64__ only, which does not use versioning.
memtag_dynamic_entries_t memtag_dynamic_entries_;
+ std::list<std::string> vma_names_;
// Pad gaps between segments when memory mapping?
bool should_pad_segments_ = false;
+
+ // Use app compat mode when loading 4KiB max-page-size ELFs on 16KiB page-size devices?
+ bool should_use_16kib_app_compat_ = false;
+
+ // RELRO region for 16KiB compat loading
+ ElfW(Addr) compat_relro_start_ = 0;
+ ElfW(Addr) compat_relro_size_ = 0;
};
// This function is used by dlvsym() to calculate hash of sym_ver
diff --git a/linker/linker_test_globals.cpp b/linker/linker_test_globals.cpp
index 4b41eed..27ec6f7 100644
--- a/linker/linker_test_globals.cpp
+++ b/linker/linker_test_globals.cpp
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-// To enable logging
-int g_ld_debug_verbosity = 0;
-
// Stub some symbols to avoid linking issues
void DL_WARN_documented_change(int api_level [[maybe_unused]],
const char* doc_link [[maybe_unused]],
diff --git a/linker/linker_translate_path.cpp b/linker/linker_translate_path.cpp
index 4f3fdfb..b41669e 100644
--- a/linker/linker_translate_path.cpp
+++ b/linker/linker_translate_path.cpp
@@ -42,13 +42,13 @@
// Workaround for dlopen(/system/lib(64)/<soname>) when .so is in /apex. http://b/121248172
/**
* Translate /system path to /apex path if needed
- * The workaround should work only when targetSdkVersion < Q.
+ * The workaround should work only when targetSdkVersion < 29.
*
* param out_name_to_apex pointing to /apex path
* return true if translation is needed
*/
bool translateSystemPathToApexPath(const char* name, std::string* out_name_to_apex) {
- static constexpr const char* kPathTranslationQ[][2] = {
+ static constexpr const char* kPathTranslation[][2] = {
APEX_LIB("com.android.i18n", "libicui18n.so"),
APEX_LIB("com.android.i18n", "libicuuc.so")
};
@@ -59,10 +59,10 @@
auto comparator = [name](auto p) { return strcmp(name, p[0]) == 0; };
- if (get_application_target_sdk_version() < __ANDROID_API_Q__) {
+ if (get_application_target_sdk_version() < 29) {
if (auto it =
- std::find_if(std::begin(kPathTranslationQ), std::end(kPathTranslationQ), comparator);
- it != std::end(kPathTranslationQ)) {
+ std::find_if(std::begin(kPathTranslation), std::end(kPathTranslation), comparator);
+ it != std::end(kPathTranslation)) {
*out_name_to_apex = (*it)[1];
return true;
}
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index cd03eed..f72716e 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -75,7 +75,7 @@
bool normalize_path(const char* path, std::string* normalized_path) {
// Input should be an absolute path
if (path[0] != '/') {
- PRINT("normalize_path - invalid input: \"%s\", the input path should be absolute", path);
+ DL_WARN("normalize_path - invalid input: \"%s\", the input path should be absolute", path);
return false;
}
@@ -144,7 +144,7 @@
}
const char* const path = normalized_path.c_str();
- TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
+ LD_DEBUG(any, "Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
// Treat an '!/' separator inside a path as the separator between the name
// of the zip file on disk and the subdirectory to search within it.
@@ -157,7 +157,7 @@
char buf[512];
if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
- PRINT("Warning: ignoring very long library path: %s", path);
+ DL_WARN("ignoring very long library path: %s", path);
return false;
}
@@ -207,7 +207,7 @@
if (realpath(original_path, resolved_path) != nullptr) {
struct stat s;
if (stat(resolved_path, &s) == -1) {
- DL_WARN("Warning: cannot stat file \"%s\": %s (ignoring)", resolved_path, strerror(errno));
+ DL_WARN("Warning: cannot stat file \"%s\": %m (ignoring)", resolved_path);
return "";
}
if (!S_ISDIR(s.st_mode)) {
@@ -226,8 +226,7 @@
std::string entry_path;
if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
- DL_WARN("Warning: unable to resolve \"%s\": %s (ignoring)",
- zip_path.c_str(), strerror(errno));
+ DL_WARN("Warning: unable to resolve \"%s\": %m (ignoring)", zip_path.c_str());
return "";
}
diff --git a/tests/Android.bp b/tests/Android.bp
index d2a3110..f227bbc 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -94,6 +94,13 @@
// Prebuilt shared libraries for use in tests.
// -----------------------------------------------------------------------------
+filegroup {
+ name: "bionic_prebuilt_test_elf_files_arm64",
+ srcs: [
+ "prebuilt-elf-files/arm64/*.so",
+ ],
+}
+
cc_prebuilt_test_library_shared {
name: "libtest_invalid-rw_load_segment",
strip: {
@@ -389,6 +396,9 @@
"bug_26110743_test.cpp",
"byteswap_test.cpp",
"complex_test.cpp",
+ // Disabled while investigating
+ // b/378304366, b/375525252
+ // "cpu_target_features_test.cpp",
"ctype_test.cpp",
"dirent_test.cpp",
"elf_test.cpp",
@@ -427,6 +437,7 @@
"malloc_test.cpp",
"math_test.cpp",
"membarrier_test.cpp",
+ "memtag_globals_test.cpp",
"memtag_stack_test.cpp",
"mntent_test.cpp",
"mte_test.cpp",
@@ -566,12 +577,6 @@
},
generated_headers: ["generated_android_ids"],
-
- // Bug: http://b/218788252 IR verifier too strict for ifunc resolver that
- // accept parameters.
- lto: {
- never: true,
- },
}
cc_test_library {
@@ -719,11 +724,6 @@
],
srcs: ["clang_fortify_tests.cpp"],
tidy: false,
- target: {
- host: {
- cflags: ["-D__clang__"],
- },
- },
}
cc_test_library {
@@ -756,6 +756,40 @@
},
}
+cc_defaults {
+ name: "bionic_fortify_c_tests_defaults",
+ defaults: [
+ "bionic_clang_fortify_tests_w_flags",
+ "bionic_tests_defaults",
+ ],
+ cflags: [
+ "-U_FORTIFY_SOURCE",
+ // -fbuiltin is required here to counteract -fno-builtin from
+ // `bionic_tests_defaults`. With `-fno-builtin`, Clang won't
+ // const-evaluate calls to `strlen`, which is tested for here.
+ "-fbuiltin",
+ ],
+ srcs: [
+ "clang_fortify_c_only_tests.c",
+ ],
+ tidy: false,
+ shared: {
+ enabled: false,
+ },
+}
+
+cc_test_library {
+ name: "libfortify1-c-tests-clang",
+ defaults: ["bionic_fortify_c_tests_defaults"],
+ cflags: ["-D_FORTIFY_SOURCE=1"],
+}
+
+cc_test_library {
+ name: "libfortify2-c-tests-clang",
+ defaults: ["bionic_fortify_c_tests_defaults"],
+ cflags: ["-D_FORTIFY_SOURCE=2"],
+}
+
// -----------------------------------------------------------------------------
// Library of all tests (excluding the dynamic linker tests).
// -----------------------------------------------------------------------------
@@ -767,8 +801,10 @@
"libBionicStandardTests",
"libBionicElfTlsTests",
"libBionicFramePointerTests",
+ "libfortify1-c-tests-clang",
"libfortify1-tests-clang",
"libfortify1-new-tests-clang",
+ "libfortify2-c-tests-clang",
"libfortify2-tests-clang",
"libfortify2-new-tests-clang",
],
@@ -789,6 +825,7 @@
"dlfcn_test.cpp",
"execinfo_test.cpp",
"link_test.cpp",
+ "page_size_16kib_compat_test.cpp",
"pthread_dlfcn_test.cpp",
],
static_libs: [
@@ -797,6 +834,7 @@
],
include_dirs: [
"bionic/libc",
+ "bionic/tests/libs",
],
shared: {
enabled: false,
@@ -863,6 +901,11 @@
"ld_preload_test_helper",
"ld_preload_test_helper_lib1",
"ld_preload_test_helper_lib2",
+ "memtag_globals_binary",
+ "memtag_globals_binary_static",
+ "memtag_globals_dso",
+ "mte_globals_relr_regression_test_b_314038442",
+ "mte_globals_relr_regression_test_b_314038442_mte",
"ns_hidden_child_helper",
"preinit_getauxval_test_helper",
"preinit_syscall_test_helper",
@@ -944,6 +987,7 @@
"libtest_dt_runpath_d",
"libtest_dt_runpath_x",
"libtest_dt_runpath_y",
+ "libtest_elf_max_page_size_4kib",
"libtest_elftls_dynamic",
"libtest_elftls_dynamic_filler_1",
"libtest_elftls_dynamic_filler_2",
@@ -1094,8 +1138,8 @@
],
}
-cc_test {
- name: "hwasan_test",
+cc_defaults {
+ name: "hwasan_test_defaults",
enabled: false,
// This does not use bionic_tests_defaults because it is not supported on
// host.
@@ -1110,9 +1154,6 @@
srcs: [
"hwasan_test.cpp",
],
- shared_libs: [
- "libbase",
- ],
data_libs: [
"libtest_simple_hwasan",
"libtest_simple_hwasan_nohwasan",
@@ -1122,6 +1163,24 @@
}
cc_test {
+ name: "hwasan_test",
+ defaults: ["hwasan_test_defaults"],
+ shared_libs: [
+ "libbase",
+ ],
+}
+
+cc_test {
+ name: "hwasan_test_static",
+ defaults: ["hwasan_test_defaults"],
+ static_libs: [
+ "libbase",
+ ],
+ static_executable: true,
+ cflags: ["-DHWASAN_TEST_STATIC"],
+}
+
+cc_test {
name: "memtag_stack_dlopen_test",
enabled: false,
// This does not use bionic_tests_defaults because it is not supported on
@@ -1155,6 +1214,35 @@
}
cc_test {
+ name: "memtag_stack_abi_test",
+ enabled: false,
+ // This does not use bionic_tests_defaults because it is not supported on
+ // host.
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+ // We don't use `sanitize:` so we generate the appropriate ELF note, but
+ // still support non-MTE devices.
+ // TODO(fmayer): also add a test that enables stack MTE for MTE devices,
+ // which would test for more bugs.
+ ldflags: ["-fsanitize=memtag-stack"],
+ // Turn off all other sanitizers from SANITIZE_TARGET.
+ sanitize: {
+ never: true,
+ },
+ shared_libs: [
+ "libbase",
+ ],
+ srcs: [
+ "memtag_stack_abi_test.cpp",
+ ],
+ header_libs: ["bionic_libc_platform_headers"],
+ test_suites: ["device-tests"],
+}
+
+cc_test {
name: "bionic-stress-tests",
defaults: [
"bionic_tests_defaults",
@@ -1173,6 +1261,7 @@
shared_libs: [
"libbase",
+ "liblog",
],
target: {
@@ -1242,6 +1331,11 @@
"heap_tagging_static_disabled_helper",
"heap_tagging_static_sync_helper",
"heap_tagging_sync_helper",
+ "memtag_globals_binary",
+ "memtag_globals_binary_static",
+ "memtag_globals_dso",
+ "mte_globals_relr_regression_test_b_314038442",
+ "mte_globals_relr_regression_test_b_314038442_mte",
"stack_tagging_helper",
"stack_tagging_static_helper",
],
diff --git a/tools/versioner/src/Preprocessor.h b/tests/DoNotOptimize.h
similarity index 63%
rename from tools/versioner/src/Preprocessor.h
rename to tests/DoNotOptimize.h
index 2a17534..711d339 100644
--- a/tools/versioner/src/Preprocessor.h
+++ b/tests/DoNotOptimize.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,12 @@
#pragma once
-#include <string>
-
-class HeaderDatabase;
-
-bool preprocessHeaders(const std::string& preprocessor_output_path, const std::string& source_dir,
- HeaderDatabase* database);
+// From <benchmark/benchmark.h>.
+template <class Tp>
+static inline void DoNotOptimize(Tp const& value) {
+ asm volatile("" : : "r,m"(value) : "memory");
+}
+template <class Tp>
+static inline void DoNotOptimize(Tp& value) {
+ asm volatile("" : "+r,m"(value) : : "memory");
+}
diff --git a/tests/android_unsafe_frame_pointer_chase_test.cpp b/tests/android_unsafe_frame_pointer_chase_test.cpp
index 7fa50e1..409cfab 100644
--- a/tests/android_unsafe_frame_pointer_chase_test.cpp
+++ b/tests/android_unsafe_frame_pointer_chase_test.cpp
@@ -124,6 +124,7 @@
sigaction(SIGRTMIN, &s, nullptr);
raise(SIGRTMIN);
+ sigaltstack(nullptr, nullptr);
return nullptr;
}
@@ -155,4 +156,25 @@
munmap(stacks, kStackSize * 2);
}
+static void* SigaltstackOnCallerStack(void*) {
+ char altstack[kStackSize];
+ SignalBacktraceThread(altstack);
+ EXPECT_TRUE(g_handler_called);
+ EXPECT_EQ(nullptr, g_handler_tester_result);
+ g_handler_called = false;
+ return nullptr;
+}
+
+TEST(android_unsafe_frame_pointer_chase, sigaltstack_on_main_thread) {
+ SigaltstackOnCallerStack(nullptr);
+}
+
+TEST(android_unsafe_frame_pointer_chase, sigaltstack_on_pthread) {
+ pthread_t t;
+ ASSERT_EQ(0, pthread_create(&t, nullptr, SigaltstackOnCallerStack, nullptr));
+ void* retval;
+ ASSERT_EQ(0, pthread_join(t, &retval));
+ EXPECT_EQ(nullptr, retval);
+}
+
#endif // __BIONIC__
diff --git a/libc/bionic/strnlen.cpp b/tests/clang_fortify_c_only_tests.c
similarity index 79%
copy from libc/bionic/strnlen.cpp
copy to tests/clang_fortify_c_only_tests.c
index 7101b21..3bec848 100644
--- a/libc/bionic/strnlen.cpp
+++ b/tests/clang_fortify_c_only_tests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,11 @@
#include <string.h>
-size_t strnlen(const char* s, size_t n) {
- const char* p = static_cast<const char*>(memchr(s, 0, n));
- return p ? (p - s) : n;
-}
+// This is a test specifically of bionic's FORTIFY machinery. Other stdlibs need not apply.
+#ifdef __BIONIC__
+
+// Ensure that strlen can be evaluated at compile-time. Clang doesn't support
+// this in C++, but does in C.
+_Static_assert(strlen("foo") == 3, "");
+
+#endif // __BIONIC__
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index f4ef4ac..da7926d 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-#ifndef __clang__
-#error "Non-clang isn't supported"
-#endif
-
//
// Clang compile-time and run-time tests for Bionic's FORTIFY.
//
@@ -93,6 +89,10 @@
#include <unistd.h>
#include <wchar.h>
+#include <array>
+
+#include "DoNotOptimize.h"
+
#ifndef COMPILATION_TESTS
#include <android-base/silent_death_test.h>
#include <gtest/gtest.h>
@@ -137,6 +137,24 @@
const static int kBogusFD = -1;
+FORTIFY_TEST(strlen) {
+ auto run_strlen_with_contents = [&](std::array<char, 3> contents) {
+ // A lot of cruft is necessary to make this test DTRT. LLVM and Clang love to fold/optimize
+ // strlen calls, and that's the opposite of what we want to happen.
+
+ // Loop to convince LLVM that `contents` can never be known (since `xor volatile_value` can flip
+ // any bit in each elem of `contents`).
+ volatile char always_zero = 0;
+ for (char& c : contents) {
+ c ^= always_zero;
+ }
+ DoNotOptimize(strlen(&contents.front()));
+ };
+
+ EXPECT_NO_DEATH(run_strlen_with_contents({'f', 'o', '\0'}));
+ EXPECT_FORTIFY_DEATH(run_strlen_with_contents({'f', 'o', 'o'}));
+}
+
FORTIFY_TEST(string) {
char small_buffer[8] = {};
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 8fdb2b2..ed0109a 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -20,6 +20,9 @@
#if !defined(__INTRODUCED_IN)
#define __INTRODUCED_IN(x)
#endif
+#if !defined(__BIONIC_AVAILABILITY_GUARD)
+#define __BIONIC_AVAILABILITY_GUARD(x) 1
+#endif
// libc++ actively gets in the way of including <complex.h> from C++, so we
// have to be naughty.
diff --git a/libm/fenv-access.h b/tests/cpu_target_features_test.cpp
similarity index 60%
copy from libm/fenv-access.h
copy to tests/cpu_target_features_test.cpp
index 7acb34d..d773772 100644
--- a/libm/fenv-access.h
+++ b/tests/cpu_target_features_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,31 @@
* SUCH DAMAGE.
*/
-#pragma once
+#include <gtest/gtest.h>
+#include <stdlib.h>
+#include "utils.h"
+
+TEST(cpu_target_features, has_expected_x86_compiler_values) {
#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
+ ExecTestHelper eth;
+ char* const argv[] = {nullptr};
+ const auto invocation = [&] { execvp("cpu-target-features", argv); };
+ eth.Run(invocation, 0, "(^|\n)__AES__=1($|\n)");
+ eth.Run(invocation, 0, "(^|\n)__CRC32__=1($|\n)");
+#else
+ GTEST_SKIP() << "Not targeting an x86 architecture.";
#endif
+}
+
+TEST(cpu_target_features, has_expected_aarch64_compiler_values) {
+#if defined(__aarch64__)
+ ExecTestHelper eth;
+ char* const argv[] = {nullptr};
+ const auto invocation = [&] { execvp("cpu-target-features", argv); };
+ eth.Run(invocation, 0, "(^|\n)__ARM_FEATURE_AES=1($|\n)");
+ eth.Run(invocation, 0, "(^|\n)__ARM_FEATURE_CRC32=1($|\n)");
+#else
+ GTEST_SKIP() << "Not targeting an aarch64 architecture.";
+#endif
+}
diff --git a/tests/dlext_private.h b/tests/dlext_private_tests.h
similarity index 100%
rename from tests/dlext_private.h
rename to tests/dlext_private_tests.h
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 570da2a..b8826c1 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <link.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -40,11 +41,13 @@
#include <procinfo/process_map.h>
#include <ziparchive/zip_archive.h>
+#include "bionic/mte.h"
+#include "bionic/page.h"
#include "core_shared_libs.h"
+#include "dlext_private_tests.h"
+#include "dlfcn_symlink_support.h"
#include "gtest_globals.h"
#include "utils.h"
-#include "dlext_private.h"
-#include "dlfcn_symlink_support.h"
#define ASSERT_DL_NOTNULL(ptr) \
ASSERT_TRUE((ptr) != nullptr) << "dlerror: " << dlerror()
@@ -1958,6 +1961,14 @@
dlclose(ns_a_handle3);
}
+static inline int MapPflagsToProtFlags(uint32_t flags) {
+ int prot_flags = 0;
+ if (PF_X & flags) prot_flags |= PROT_EXEC;
+ if (PF_W & flags) prot_flags |= PROT_WRITE;
+ if (PF_R & flags) prot_flags |= PROT_READ;
+ return prot_flags;
+}
+
TEST(dlext, ns_anonymous) {
static const char* root_lib = "libnstest_root.so";
std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
@@ -1999,30 +2010,45 @@
typedef const char* (*fn_t)();
fn_t ns_get_dlopened_string_private = reinterpret_cast<fn_t>(ns_get_dlopened_string_addr);
- std::vector<map_record> maps;
- Maps::parse_maps(&maps);
-
+ Dl_info private_library_info;
+ ASSERT_NE(dladdr(reinterpret_cast<void*>(ns_get_dlopened_string_addr), &private_library_info), 0)
+ << dlerror();
+ std::vector<map_record> maps_to_copy;
+ bool has_executable_segment = false;
uintptr_t addr_start = 0;
uintptr_t addr_end = 0;
- bool has_executable_segment = false;
- std::vector<map_record> maps_to_copy;
+ std::tuple dl_iterate_arg = {&private_library_info, &maps_to_copy, &has_executable_segment,
+ &addr_start, &addr_end};
+ ASSERT_EQ(
+ 1, dl_iterate_phdr(
+ [](dl_phdr_info* info, size_t /*size*/, void* data) -> int {
+ auto [private_library_info, maps_to_copy, has_executable_segment, addr_start,
+ addr_end] = *reinterpret_cast<decltype(dl_iterate_arg)*>(data);
+ if (info->dlpi_addr != reinterpret_cast<ElfW(Addr)>(private_library_info->dli_fbase))
+ return 0;
- for (const auto& rec : maps) {
- if (rec.pathname == private_library_absolute_path) {
- if (addr_start == 0) {
- addr_start = rec.addr_start;
- }
- addr_end = rec.addr_end;
- has_executable_segment = has_executable_segment || (rec.perms & PROT_EXEC) != 0;
-
- maps_to_copy.push_back(rec);
- }
- }
+ for (size_t i = 0; i < info->dlpi_phnum; ++i) {
+ const ElfW(Phdr)* phdr = info->dlpi_phdr + i;
+ if (phdr->p_type != PT_LOAD) continue;
+ *has_executable_segment |= phdr->p_flags & PF_X;
+ uintptr_t mapping_start = page_start(info->dlpi_addr + phdr->p_vaddr);
+ uintptr_t mapping_end = page_end(info->dlpi_addr + phdr->p_vaddr + phdr->p_memsz);
+ if (*addr_start == 0 || mapping_start < *addr_start) *addr_start = mapping_start;
+ if (*addr_end == 0 || mapping_end > *addr_end) *addr_end = mapping_end;
+ maps_to_copy->push_back({
+ .addr_start = mapping_start,
+ .addr_end = mapping_end,
+ .perms = MapPflagsToProtFlags(phdr->p_flags),
+ });
+ }
+ return 1;
+ },
+ &dl_iterate_arg));
// Some validity checks.
+ ASSERT_NE(maps_to_copy.size(), 0u);
ASSERT_TRUE(addr_start > 0);
ASSERT_TRUE(addr_end > 0);
- ASSERT_TRUE(maps_to_copy.size() > 0);
ASSERT_TRUE(ns_get_dlopened_string_addr > addr_start);
ASSERT_TRUE(ns_get_dlopened_string_addr < addr_end);
@@ -2052,19 +2078,26 @@
ASSERT_EQ(ret, 0) << "Failed to stat library";
size_t file_size = file_stat.st_size;
- for (const auto& rec : maps_to_copy) {
- uintptr_t offset = rec.addr_start - addr_start;
- size_t size = rec.addr_end - rec.addr_start;
- void* addr = reinterpret_cast<void*>(reserved_addr + offset);
- void* map = mmap(addr, size, PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
- ASSERT_TRUE(map != MAP_FAILED);
- // Attempting the below memcpy from a portion of the map that is off the end of
- // the backing file will cause the kernel to throw a SIGBUS
- size_t _size = ::android::procinfo::MappedFileSize(rec.addr_start, rec.addr_end,
- rec.offset, file_size);
- memcpy(map, reinterpret_cast<void*>(rec.addr_start), _size);
- mprotect(map, size, rec.perms);
+ {
+ // Disable MTE while copying the PROT_MTE-protected global variables from
+ // the existing mappings. We don't really care about turning on PROT_MTE for
+ // the new copy of the mappings, as this isn't the behaviour under test and
+ // tags will be ignored. This only applies for MTE-enabled devices.
+ ScopedDisableMTE disable_mte_for_copying_global_variables;
+ for (const auto& rec : maps_to_copy) {
+ uintptr_t offset = rec.addr_start - addr_start;
+ size_t size = rec.addr_end - rec.addr_start;
+ void* addr = reinterpret_cast<void*>(reserved_addr + offset);
+ void* map =
+ mmap(addr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
+ ASSERT_TRUE(map != MAP_FAILED);
+ // Attempting the below memcpy from a portion of the map that is off the end of
+ // the backing file will cause the kernel to throw a SIGBUS
+ size_t _size =
+ ::android::procinfo::MappedFileSize(rec.addr_start, rec.addr_end, rec.offset, file_size);
+ memcpy(map, reinterpret_cast<void*>(rec.addr_start), _size);
+ mprotect(map, size, rec.perms);
+ }
}
// call the function copy
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index 9cf9d98..bbf339f 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include "DoNotOptimize.h"
#include "utils.h"
#include <fenv.h>
diff --git a/tests/float_test.cpp b/tests/float_test.cpp
index 3ef4593..a2b7ecb 100644
--- a/tests/float_test.cpp
+++ b/tests/float_test.cpp
@@ -122,3 +122,7 @@
#error LDBL_HAS_SUBNORM
#endif
}
+
+TEST(float_h, FLT_EVAL_METHOD_exact) {
+ ASSERT_EQ(0, FLT_EVAL_METHOD);
+}
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index cb96f9f..7b64fbf 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -58,8 +58,7 @@
}
TEST_F(DEATHTEST, stpncpy2_fortified2) {
- foo myfoo;
- memset(&myfoo, 0, sizeof(myfoo));
+ foo myfoo = {};
myfoo.one[0] = 'A'; // not null terminated string
ASSERT_FORTIFY(stpncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
}
@@ -71,8 +70,7 @@
}
TEST_F(DEATHTEST, strncpy2_fortified2) {
- foo myfoo;
- memset(&myfoo, 0, sizeof(myfoo));
+ foo myfoo = {};
myfoo.one[0] = 'A'; // not null terminated string
ASSERT_FORTIFY(strncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
}
@@ -572,8 +570,7 @@
TEST_F(DEATHTEST, FD_ISSET_fortified) {
#if defined(__BIONIC__) // glibc catches this at compile-time.
- fd_set set;
- memset(&set, 0, sizeof(set));
+ fd_set set = {};
ASSERT_FORTIFY(FD_ISSET(-1, &set));
#endif
}
diff --git a/tests/headers/posix/signal_h.c b/tests/headers/posix/signal_h.c
index c2e544e..82751f4 100644
--- a/tests/headers/posix/signal_h.c
+++ b/tests/headers/posix/signal_h.c
@@ -63,6 +63,10 @@
MACRO(SIGEV_SIGNAL);
MACRO(SIGEV_THREAD);
+#if !defined(__GLIBC__) // Our glibc is too old.
+ MACRO(SIG2STR_MAX);
+#endif
+
TYPE(union sigval);
STRUCT_MEMBER(union sigval, int, sival_int);
STRUCT_MEMBER(union sigval, void*, sival_ptr);
@@ -205,6 +209,9 @@
FUNCTION(pthread_kill, int (*f)(pthread_t, int));
FUNCTION(pthread_sigmask, int (*f)(int, const sigset_t*, sigset_t*));
FUNCTION(raise, int (*f)(int));
+#if !defined(__GLIBC__) // Our glibc is too old.
+ FUNCTION(sig2str, int (*f)(int, char*));
+#endif
FUNCTION(sigaction, int (*f)(int, const struct sigaction*, struct sigaction*));
FUNCTION(sigaddset, int (*f)(sigset_t*, int));
FUNCTION(sigaltstack, int (*f)(const stack_t*, stack_t*));
@@ -226,4 +233,7 @@
FUNCTION(sigtimedwait, int (*f)(const sigset_t*, siginfo_t*, const struct timespec*));
FUNCTION(sigwait, int (*f)(const sigset_t*, int*));
FUNCTION(sigwaitinfo, int (*f)(const sigset_t*, siginfo_t*));
+#if !defined(__GLIBC__) // Our glibc is too old.
+ FUNCTION(str2sig, int (*f)(const char*, int*));
+#endif
}
diff --git a/tests/headers/posix/stdatomic_h.c b/tests/headers/posix/stdatomic_h.c
new file mode 100644
index 0000000..eecb89a
--- /dev/null
+++ b/tests/headers/posix/stdatomic_h.c
@@ -0,0 +1,172 @@
+/*
+ * 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 <stdatomic.h>
+
+#include "header_checks.h"
+
+static void stdatomic_h() {
+ TYPE(atomic_flag);
+ TYPE(atomic_bool);
+ TYPE(atomic_char);
+ TYPE(atomic_schar);
+ TYPE(atomic_uchar);
+ TYPE(atomic_short);
+ TYPE(atomic_ushort);
+ TYPE(atomic_int);
+ TYPE(atomic_uint);
+ TYPE(atomic_long);
+ TYPE(atomic_ulong);
+ TYPE(atomic_llong);
+ TYPE(atomic_ullong);
+#if !defined(__GLIBC__)
+ TYPE(atomic_char16_t);
+ TYPE(atomic_char32_t);
+#endif
+ TYPE(atomic_wchar_t);
+ TYPE(atomic_int_least8_t);
+ TYPE(atomic_uint_least8_t);
+ TYPE(atomic_int_least16_t);
+ TYPE(atomic_uint_least16_t);
+ TYPE(atomic_int_least32_t);
+ TYPE(atomic_uint_least32_t);
+ TYPE(atomic_int_least64_t);
+ TYPE(atomic_uint_least64_t);
+ TYPE(atomic_int_fast8_t);
+ TYPE(atomic_uint_fast8_t);
+ TYPE(atomic_int_fast16_t);
+ TYPE(atomic_uint_fast16_t);
+ TYPE(atomic_int_fast32_t);
+ TYPE(atomic_uint_fast32_t);
+ TYPE(atomic_int_fast64_t);
+ TYPE(atomic_uint_fast64_t);
+ TYPE(atomic_intptr_t);
+ TYPE(atomic_uintptr_t);
+ TYPE(atomic_size_t);
+ TYPE(atomic_ptrdiff_t);
+ TYPE(atomic_intmax_t);
+ TYPE(atomic_uintmax_t);
+
+ memory_order m1 = memory_order_relaxed;
+ memory_order m2 = memory_order_consume;
+ memory_order m3 = memory_order_acquire;
+ memory_order m4 = memory_order_release;
+ memory_order m5 = memory_order_acq_rel;
+ memory_order m6 = memory_order_seq_cst;
+
+ MACRO(ATOMIC_BOOL_LOCK_FREE);
+ MACRO(ATOMIC_CHAR_LOCK_FREE);
+ MACRO(ATOMIC_CHAR16_T_LOCK_FREE);
+ MACRO(ATOMIC_CHAR32_T_LOCK_FREE);
+ MACRO(ATOMIC_WCHAR_T_LOCK_FREE);
+ MACRO(ATOMIC_SHORT_LOCK_FREE);
+ MACRO(ATOMIC_INT_LOCK_FREE);
+ MACRO(ATOMIC_LONG_LOCK_FREE);
+ MACRO(ATOMIC_LLONG_LOCK_FREE);
+ MACRO(ATOMIC_POINTER_LOCK_FREE);
+
+ atomic_flag f = ATOMIC_FLAG_INIT;
+ atomic_int i = ATOMIC_VAR_INIT(123);
+
+ i = kill_dependency(i);
+
+#if !defined(atomic_compare_exchange_strong)
+#error atomic_compare_exchange_strong
+#endif
+#if !defined(atomic_compare_exchange_strong_explicit)
+#error atomic_compare_exchange_strong_explicit
+#endif
+#if !defined(atomic_compare_exchange_weak)
+#error atomic_compare_exchange_weak
+#endif
+#if !defined(atomic_compare_exchange_weak_explicit)
+#error atomic_compare_exchange_weak_explicit
+#endif
+#if !defined(atomic_exchange)
+#error atomic_exchange
+#endif
+#if !defined(atomic_exchange_explicit)
+#error atomic_exchange_explicit
+#endif
+#if !defined(atomic_fetch_add)
+#error atomic_fetch_add
+#endif
+#if !defined(atomic_fetch_add_explicit)
+#error atomic_fetch_add_explicit
+#endif
+#if !defined(atomic_fetch_and)
+#error atomic_fetch_and
+#endif
+#if !defined(atomic_fetch_and_explicit)
+#error atomic_fetch_and_explicit
+#endif
+#if !defined(atomic_fetch_or)
+#error atomic_fetch_or
+#endif
+#if !defined(atomic_fetch_or_explicit)
+#error atomic_fetch_or_explicit
+#endif
+#if !defined(atomic_fetch_sub)
+#error atomic_fetch_sub
+#endif
+#if !defined(atomic_fetch_sub_explicit)
+#error atomic_fetch_sub_explicit
+#endif
+#if !defined(atomic_fetch_xor)
+#error atomic_fetch_xor
+#endif
+#if !defined(atomic_fetch_xor_explicit)
+#error atomic_fetch_xor_explicit
+#endif
+#if !defined(atomic_init)
+#error atomic_init
+#endif
+#if !defined(atomic_is_lock_free)
+#error atomic_is_lock_free
+#endif
+#if !defined(atomic_load)
+#error atomic_load
+#endif
+#if !defined(atomic_load_explicit)
+#error atomic_load_explicit
+#endif
+#if !defined(atomic_store)
+#error atomic_store
+#endif
+#if !defined(atomic_store_explicit)
+#error atomic_store_explicit
+#endif
+
+ FUNCTION(atomic_flag_clear, void (*f)(volatile atomic_flag*));
+ FUNCTION(atomic_flag_clear_explicit, void (*f)(volatile atomic_flag*, memory_order));
+ FUNCTION(atomic_flag_test_and_set, bool (*f)(volatile atomic_flag*));
+ FUNCTION(atomic_flag_test_and_set_explicit, bool (*f)(volatile atomic_flag*, memory_order));
+
+ FUNCTION(atomic_signal_fence, void (*f)(memory_order));
+ FUNCTION(atomic_thread_fence, void (*f)(memory_order));
+}
diff --git a/tests/headers/posix/stdbool_h.c b/tests/headers/posix/stdbool_h.c
index f891a73..830c33c 100644
--- a/tests/headers/posix/stdbool_h.c
+++ b/tests/headers/posix/stdbool_h.c
@@ -31,10 +31,8 @@
#include "header_checks.h"
static void stdbool_h() {
-#if !defined(bool)
-#error bool
-#endif
- MACRO_VALUE(true, 1);
- MACRO_VALUE(false, 0);
+ TYPE(bool);
+ bool t = true;
+ bool f = false;
MACRO_VALUE(__bool_true_false_are_defined, 1);
}
diff --git a/tests/headers/posix/stdlib_h.c b/tests/headers/posix/stdlib_h.c
index 52580cf..95769b4 100644
--- a/tests/headers/posix/stdlib_h.c
+++ b/tests/headers/posix/stdlib_h.c
@@ -112,6 +112,9 @@
FUNCTION(ptsname, char* (*f)(int));
FUNCTION(putenv, int (*f)(char*));
FUNCTION(qsort, void (*f)(void*, size_t, size_t, int (*)(const void*, const void*)));
+#if !defined(__GLIBC__) // Our glibc is too old.
+ FUNCTION(qsort_r, void (*f)(void*, size_t, size_t, int (*)(const void*, const void*, void*), void*));
+#endif
FUNCTION(rand, int (*f)(void));
FUNCTION(rand_r, int (*f)(unsigned*));
FUNCTION(random, long (*f)(void));
diff --git a/tests/headers/posix/unistd_h.c b/tests/headers/posix/unistd_h.c
index 0b2cee5..f66609d 100644
--- a/tests/headers/posix/unistd_h.c
+++ b/tests/headers/posix/unistd_h.c
@@ -331,6 +331,9 @@
FUNCTION(fdatasync, int (*f)(int));
FUNCTION(fexecve, int (*f)(int, char* const[], char* const[]));
FUNCTION(fork, pid_t (*f)(void));
+#if !defined(__GLIBC__) // Our glibc is too old.
+ FUNCTION(_Fork, pid_t (*f)(void));
+#endif
FUNCTION(fpathconf, long (*f)(int, int));
FUNCTION(fsync, int (*f)(int));
FUNCTION(ftruncate, int (*f)(int, off_t));
diff --git a/tests/hwasan_test.cpp b/tests/hwasan_test.cpp
index e32534e..ddf84cb 100644
--- a/tests/hwasan_test.cpp
+++ b/tests/hwasan_test.cpp
@@ -36,7 +36,18 @@
using HwasanDeathTest = SilentDeathTest;
-TEST_F(HwasanDeathTest, UseAfterFree) {
+
+#ifdef HWASAN_TEST_STATIC
+#define MAYBE_DlopenAbsolutePath DISABLED_DlopenAbsolutePath
+// TODO(fmayer): figure out why uaf is misclassified as out of bounds for
+// static executables.
+#define MAYBE_UseAfterFree DISABLED_UseAfterFree
+#else
+#define MAYBE_DlopenAbsolutePath DlopenAbsolutePath
+#define MAYBE_UseAfterFree UseAfterFree
+#endif
+
+TEST_F(HwasanDeathTest, MAYBE_UseAfterFree) {
EXPECT_DEATH(
{
void* m = malloc(1);
@@ -59,7 +70,7 @@
}
// Check whether dlopen of /foo/bar.so checks /foo/hwasan/bar.so first.
-TEST(HwasanTest, DlopenAbsolutePath) {
+TEST(HwasanTest, MAYBE_DlopenAbsolutePath) {
std::string path = android::base::GetExecutableDirectory() + "/libtest_simple_hwasan.so";
ASSERT_EQ(0, access(path.c_str(), F_OK)); // Verify test setup.
std::string hwasan_path =
diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp
index da64770..01779f7 100644
--- a/tests/ifaddrs_test.cpp
+++ b/tests/ifaddrs_test.cpp
@@ -116,9 +116,7 @@
static void CheckAddressIsInSet(const std::string& if_name, bool unicast,
const std::set<in_addr_t>& addrs) {
- ifreq ifr;
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_addr.sa_family = AF_INET;
+ ifreq ifr = {.ifr_addr.sa_family = AF_INET};
if_name.copy(ifr.ifr_name, IFNAMSIZ - 1);
int fd = socket(AF_INET, SOCK_DGRAM, 0);
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index fc7fd40..5b86e78 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -48,6 +48,16 @@
}
// -----------------------------------------------------------------------------
+// Test library ELFs for linker page size related tests
+// -----------------------------------------------------------------------------
+cc_test_library {
+ name: "libtest_elf_max_page_size_4kib",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["elf_max_page_size.c"],
+ ldflags: ["-z max-page-size=0x1000"],
+}
+
+// -----------------------------------------------------------------------------
// Libraries and helper binaries for ELF TLS
// -----------------------------------------------------------------------------
cc_test_library {
@@ -1852,7 +1862,7 @@
" cp $(in) $(genDir)/zipdir/libdir/ &&" +
" touch $(genDir)/zipdir/empty_file.txt &&" +
" $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
- " $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
+ " $(location bionic_tests_zipalign) 16384 $(out).unaligned $(out)",
}
@@ -1891,5 +1901,91 @@
" cp $(location :libtest_dt_runpath_y) $(genDir)/zipdir/libdir/dt_runpath_y/$$PRIVATE_LIB_OR_LIB64 &&" +
" touch $(genDir)/zipdir/empty_file.txt &&" +
" $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
- " $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
+ " $(location bionic_tests_zipalign) 16384 $(out).unaligned $(out)",
+}
+
+cc_defaults {
+ name: "memtag_globals_defaults",
+ defaults: [
+ "bionic_testlib_defaults",
+ "bionic_targets_only"
+ ],
+ cflags: [
+ "-Wno-array-bounds",
+ "-Wno-unused-variable",
+ ],
+ header_libs: ["bionic_libc_platform_headers"],
+ sanitize: {
+ hwaddress: false,
+ memtag_heap: true,
+ memtag_globals: true,
+ diag: {
+ memtag_heap: true,
+ }
+ },
+}
+
+cc_test_library {
+ name: "memtag_globals_dso",
+ defaults: [ "memtag_globals_defaults" ],
+ srcs: ["memtag_globals_dso.cpp"],
+}
+
+cc_test {
+ name: "memtag_globals_binary",
+ defaults: [ "memtag_globals_defaults" ],
+ srcs: ["memtag_globals_binary.cpp"],
+ shared_libs: [ "memtag_globals_dso" ],
+ // This binary is used in the bionic-unit-tests as a data dependency, and is
+ // in the same folder as memtag_globals_dso. But, the default cc_test rules
+ // make this binary (when just explicitly built and shoved in
+ // /data/nativetest64/) end up in a subfolder called
+ // 'memtag_globals_binary'. When this happens, the explicit build fails to
+ // find the DSO because the default rpath is just ${ORIGIN}, and because we
+ // want this to be usable both from bionic-unit-tests and explicit builds,
+ // let's just not put it in a subdirectory.
+ no_named_install_directory: true,
+}
+
+cc_test {
+ name: "memtag_globals_binary_static",
+ defaults: [ "memtag_globals_defaults" ],
+ srcs: ["memtag_globals_binary.cpp"],
+ static_libs: [ "memtag_globals_dso" ],
+ no_named_install_directory: true,
+ static_executable: true,
+}
+
+// This is a regression test for b/314038442, where binaries built *without* MTE
+// globals would have out-of-bounds RELR relocations, which where then `ldg`'d,
+// which resulted in linker crashes.
+cc_test {
+ name: "mte_globals_relr_regression_test_b_314038442",
+ defaults: [
+ "bionic_testlib_defaults",
+ "bionic_targets_only"
+ ],
+ cflags: [ "-Wno-array-bounds" ],
+ ldflags: [ "-Wl,--pack-dyn-relocs=relr" ],
+ srcs: ["mte_globals_relr_regression_test_b_314038442.cpp"],
+ no_named_install_directory: true,
+ sanitize: {
+ memtag_globals: false,
+ },
+}
+
+// Same test as above, but also for MTE globals, just for the sake of it.
+cc_test {
+ name: "mte_globals_relr_regression_test_b_314038442_mte",
+ defaults: [
+ "bionic_testlib_defaults",
+ "bionic_targets_only"
+ ],
+ cflags: [ "-Wno-array-bounds" ],
+ ldflags: [ "-Wl,--pack-dyn-relocs=relr" ],
+ srcs: ["mte_globals_relr_regression_test_b_314038442.cpp"],
+ no_named_install_directory: true,
+ sanitize: {
+ memtag_globals: true,
+ },
}
diff --git a/libc/bionic/strnlen.cpp b/tests/libs/elf_max_page_size.c
similarity index 74%
copy from libc/bionic/strnlen.cpp
copy to tests/libs/elf_max_page_size.c
index 7101b21..24c7e89 100644
--- a/libc/bionic/strnlen.cpp
+++ b/tests/libs/elf_max_page_size.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,25 @@
* SUCH DAMAGE.
*/
-#include <string.h>
+#include "elf_max_page_size.h"
-size_t strnlen(const char* s, size_t n) {
- const char* p = static_cast<const char*>(memchr(s, 0, n));
- return p ? (p - s) : n;
+const int ro0 = RO0;
+const int ro1 = RO1;
+int rw0 = RW0;
+
+/* Force some padding alignment */
+int rw1 __attribute__((aligned(0x10000))) = RW1;
+
+int bss0, bss1;
+
+int* const prw0 = &rw0;
+
+int loader_test_func(void) {
+ rw0 += RW0_INCREMENT;
+ rw1 += RW1_INCREMENT;
+
+ bss0 += BSS0_INCREMENT;
+ bss1 += BSS1_INCREMENT;
+
+ return ro0 + ro1 + rw0 + rw1 + bss0 + bss1 + *prw0;
}
diff --git a/libm/fenv-access.h b/tests/libs/elf_max_page_size.h
similarity index 72%
copy from libm/fenv-access.h
copy to tests/libs/elf_max_page_size.h
index 7acb34d..846a8b6 100644
--- a/libm/fenv-access.h
+++ b/tests/libs/elf_max_page_size.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,20 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define RO0 23
+#define RO1 234
+#define RW0 2345
+#define RW1 23456
+#define BSS0 0
+#define BSS1 0
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
-#endif
+#define RW0_INCREMENT 12
+#define RW1_INCREMENT 123
+#define BSS0_INCREMENT 1234
+#define BSS1_INCREMENT 12345
+
+#define TEST_RESULT_BASE (RO0 + RO1 + RW0 + RW1 + BSS0 + BSS1 + RW0)
+#define TEST_RESULT_INCREMENT \
+ (RW0_INCREMENT + RW1_INCREMENT + BSS0_INCREMENT + BSS1_INCREMENT + RW0_INCREMENT)
+
+typedef int (*loader_test_func_t)(void);
diff --git a/libm/fenv-access.h b/tests/libs/memtag_globals.h
similarity index 67%
copy from libm/fenv-access.h
copy to tests/libs/memtag_globals.h
index 7acb34d..a03abae 100644
--- a/libm/fenv-access.h
+++ b/tests/libs/memtag_globals.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,18 @@
* SUCH DAMAGE.
*/
-#pragma once
+#include <utility>
+#include <vector>
-#if defined(__x86_64__) || defined(__i386__)
-#pragma STDC FENV_ACCESS ON
-#endif
+void check_tagged(const void* a);
+void check_untagged(const void* a);
+void check_matching_tags(const void* a, const void* b);
+void check_eq(const void* a, const void* b);
+
+void dso_check_assertions(bool enforce_tagged);
+void dso_print_variables();
+
+void print_variable_address(const char* name, const void* ptr);
+void print_variables(const char* header,
+ const std::vector<std::pair<const char*, const void*>>& tagged_variables,
+ const std::vector<std::pair<const char*, const void*>>& untagged_variables);
diff --git a/tests/libs/memtag_globals_binary.cpp b/tests/libs/memtag_globals_binary.cpp
new file mode 100644
index 0000000..9248728
--- /dev/null
+++ b/tests/libs/memtag_globals_binary.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+
+#include "memtag_globals.h"
+
+// Adapted from the LLD test suite: lld/test/ELF/Inputs/aarch64-memtag-globals.s
+
+/// Global variables defined here, of various semantics.
+char global[30] = {};
+__attribute__((no_sanitize("memtag"))) int global_untagged = 0;
+const int const_global = 0;
+static const int hidden_const_global = 0;
+static char hidden_global[12] = {};
+__attribute__((visibility("hidden"))) int hidden_attr_global = 0;
+__attribute__((visibility("hidden"))) const int hidden_attr_const_global = 0;
+
+/// Should be untagged.
+__thread int tls_global;
+__thread static int hidden_tls_global;
+
+/// Tagged, from the other file.
+extern int global_extern;
+/// Untagged, from the other file.
+extern __attribute__((no_sanitize("memtag"))) int global_extern_untagged;
+/// Tagged here, but untagged in the definition found in the sister objfile
+/// (explicitly).
+extern int global_extern_untagged_definition_but_tagged_import;
+
+/// ABS64 relocations. Also, forces symtab entries for local and external
+/// globals.
+char* pointer_to_global = &global[0];
+char* pointer_inside_global = &global[17];
+char* pointer_to_global_end = &global[30];
+char* pointer_past_global_end = &global[48];
+int* pointer_to_global_untagged = &global_untagged;
+const int* pointer_to_const_global = &const_global;
+/// RELATIVE relocations.
+const int* pointer_to_hidden_const_global = &hidden_const_global;
+char* pointer_to_hidden_global = &hidden_global[0];
+int* pointer_to_hidden_attr_global = &hidden_attr_global;
+const int* pointer_to_hidden_attr_const_global = &hidden_attr_const_global;
+/// RELATIVE relocations with special AArch64 MemtagABI semantics, with the
+/// offset ('12' or '16') encoded in the place.
+char* pointer_to_hidden_global_end = &hidden_global[12];
+char* pointer_past_hidden_global_end = &hidden_global[16];
+/// ABS64 relocations.
+int* pointer_to_global_extern = &global_extern;
+int* pointer_to_global_extern_untagged = &global_extern_untagged;
+int* pointer_to_global_extern_untagged_definition_but_tagged_import =
+ &global_extern_untagged_definition_but_tagged_import;
+
+// Force materialization of these globals into the symtab.
+int* get_address_to_tls_global() {
+ return &tls_global;
+}
+int* get_address_to_hidden_tls_global() {
+ return &hidden_tls_global;
+}
+
+static const std::vector<std::pair<const char*, const void*>>& get_expected_tagged_vars() {
+ static std::vector<std::pair<const char*, const void*>> expected_tagged_vars = {
+ {"global", &global},
+ {"pointer_inside_global", pointer_inside_global},
+ {"pointer_to_global_end", pointer_to_global_end},
+ {"pointer_past_global_end", pointer_past_global_end},
+ {"hidden_global", &hidden_global},
+ {"hidden_attr_global", &hidden_attr_global},
+ {"global_extern", &global_extern},
+ };
+ return expected_tagged_vars;
+}
+
+static const std::vector<std::pair<const char*, const void*>>& get_expected_untagged_vars() {
+ static std::vector<std::pair<const char*, const void*>> expected_untagged_vars = {
+ {"global_extern_untagged", &global_extern_untagged},
+ {"global_extern_untagged_definition_but_tagged_import",
+ &global_extern_untagged_definition_but_tagged_import},
+ {"global_untagged", &global_untagged},
+ {"const_global", &const_global},
+ {"hidden_const_global", &hidden_const_global},
+ {"hidden_attr_const_global", &hidden_attr_const_global},
+ {"tls_global", &tls_global},
+ {"hidden_tls_global", &hidden_tls_global},
+ };
+ return expected_untagged_vars;
+}
+
+void exe_print_variables() {
+ print_variables(" Variables accessible from the binary:\n", get_expected_tagged_vars(),
+ get_expected_untagged_vars());
+}
+
+// Dump the addresses of the global variables to stderr
+void dso_print();
+void dso_print_others();
+
+void exe_check_assertions(bool check_pointers_are_tagged) {
+ // Check that non-const variables are writeable.
+ *pointer_to_global = 0;
+ *pointer_inside_global = 0;
+ *(pointer_to_global_end - 1) = 0;
+ *pointer_to_global_untagged = 0;
+ *pointer_to_hidden_global = 0;
+ *pointer_to_hidden_attr_global = 0;
+ *(pointer_to_hidden_global_end - 1) = 0;
+ *pointer_to_global_extern = 0;
+ *pointer_to_global_extern_untagged = 0;
+ *pointer_to_global_extern_untagged_definition_but_tagged_import = 0;
+
+ if (check_pointers_are_tagged) {
+ for (const auto& [_, pointer] : get_expected_tagged_vars()) {
+ check_tagged(pointer);
+ }
+ }
+
+ for (const auto& [_, pointer] : get_expected_untagged_vars()) {
+ check_untagged(pointer);
+ }
+
+ check_matching_tags(pointer_to_global, pointer_inside_global);
+ check_matching_tags(pointer_to_global, pointer_to_global_end);
+ check_matching_tags(pointer_to_global, pointer_past_global_end);
+ check_eq(pointer_inside_global, pointer_to_global + 17);
+ check_eq(pointer_to_global_end, pointer_to_global + 30);
+ check_eq(pointer_past_global_end, pointer_to_global + 48);
+
+ check_matching_tags(pointer_to_hidden_global, pointer_to_hidden_global_end);
+ check_matching_tags(pointer_to_hidden_global, pointer_past_hidden_global_end);
+ check_eq(pointer_to_hidden_global_end, pointer_to_hidden_global + 12);
+ check_eq(pointer_past_hidden_global_end, pointer_to_hidden_global + 16);
+}
+
+void crash() {
+ *pointer_past_global_end = 0;
+}
+
+int main(int argc, char** argv) {
+ bool check_pointers_are_tagged = false;
+ // For an MTE-capable device, provide argv[1] == '1' to enable the assertions
+ // that pointers should be tagged.
+ if (argc >= 2 && argv[1][0] == '1') {
+ check_pointers_are_tagged = true;
+ }
+
+ char* heap_ptr = static_cast<char*>(malloc(1));
+ print_variable_address("heap address", heap_ptr);
+ *heap_ptr = 0;
+ if (check_pointers_are_tagged) check_tagged(heap_ptr);
+ free(heap_ptr);
+
+ exe_print_variables();
+ dso_print_variables();
+
+ exe_check_assertions(check_pointers_are_tagged);
+ dso_check_assertions(check_pointers_are_tagged);
+
+ printf("Assertions were passed. Now doing a global-buffer-overflow.\n");
+ fflush(stdout);
+ crash();
+ printf("global-buffer-overflow went uncaught.\n");
+ return 0;
+}
diff --git a/tests/libs/memtag_globals_dso.cpp b/tests/libs/memtag_globals_dso.cpp
new file mode 100644
index 0000000..9ed264e
--- /dev/null
+++ b/tests/libs/memtag_globals_dso.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+
+#include "memtag_globals.h"
+
+// Adapted from the LLD test suite: lld/test/ELF/Inputs/aarch64-memtag-globals.s
+
+int global_extern;
+static int global_extern_hidden;
+__attribute__((no_sanitize("memtag"))) int global_extern_untagged;
+__attribute__((no_sanitize("memtag"))) int global_extern_untagged_definition_but_tagged_import;
+
+void assertion_failure() {
+ exit(1);
+}
+
+void check_tagged(const void* a) {
+ uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
+#if defined(__aarch64__)
+ if ((a_uptr >> 56) == 0) {
+ fprintf(stderr, "**********************************\n");
+ fprintf(stderr, "Failed assertion:\n");
+ fprintf(stderr, " tag(0x%zx) != 0\n", a_uptr);
+ fprintf(stderr, "**********************************\n");
+
+ assertion_failure();
+ }
+#endif // defined(__aarch64__)
+}
+
+void check_untagged(const void* a) {
+ uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
+#if defined(__aarch64__)
+ if ((a_uptr >> 56) != 0) {
+ fprintf(stderr, "**********************************\n");
+ fprintf(stderr, "Failed assertion:\n");
+ fprintf(stderr, " tag(0x%zx) == 0\n", a_uptr);
+ fprintf(stderr, "**********************************\n");
+
+ assertion_failure();
+ }
+#endif // defined(__aarch64__)
+}
+
+void check_matching_tags(const void* a, const void* b) {
+ uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
+ uintptr_t b_uptr = reinterpret_cast<uintptr_t>(b);
+#if defined(__aarch64__)
+ if (a_uptr >> 56 != b_uptr >> 56) {
+ fprintf(stderr, "**********************************\n");
+ fprintf(stderr, "Failed assertion:\n");
+ fprintf(stderr, " tag(0x%zx) != tag(0x%zx)\n", a_uptr, b_uptr);
+ fprintf(stderr, "**********************************\n");
+
+ assertion_failure();
+ }
+#endif // defined(__aarch64__)
+}
+
+void check_eq(const void* a, const void* b) {
+ if (a != b) {
+ fprintf(stderr, "**********************************\n");
+ fprintf(stderr, "Failed assertion:\n");
+ fprintf(stderr, " %p != %p\n", a, b);
+ fprintf(stderr, "**********************************\n");
+
+ assertion_failure();
+ }
+}
+
+#define LONGEST_VARIABLE_NAME "51"
+void print_variable_address(const char* name, const void* ptr) {
+ printf("%" LONGEST_VARIABLE_NAME "s: %16p\n", name, ptr);
+}
+
+static const std::vector<std::pair<const char*, const void*>>& get_expected_tagged_vars() {
+ static std::vector<std::pair<const char*, const void*>> expected_tagged_vars = {
+ {"global_extern", &global_extern},
+ {"global_extern_hidden", &global_extern_hidden},
+ };
+ return expected_tagged_vars;
+}
+
+static const std::vector<std::pair<const char*, const void*>>& get_expected_untagged_vars() {
+ static std::vector<std::pair<const char*, const void*>> expected_untagged_vars = {
+ {"global_extern_untagged", &global_extern_untagged},
+ {"global_extern_untagged_definition_but_tagged_import",
+ &global_extern_untagged_definition_but_tagged_import},
+ };
+ return expected_untagged_vars;
+}
+
+void dso_print_variables() {
+ print_variables(" Variables declared in the DSO:\n", get_expected_tagged_vars(),
+ get_expected_untagged_vars());
+}
+
+void print_variables(const char* header,
+ const std::vector<std::pair<const char*, const void*>>& tagged_variables,
+ const std::vector<std::pair<const char*, const void*>>& untagged_variables) {
+ printf("==========================================================\n");
+ printf("%s", header);
+ printf("==========================================================\n");
+ printf(" Variables expected to be tagged:\n");
+ printf("----------------------------------------------------------\n");
+ for (const auto& [name, pointer] : tagged_variables) {
+ print_variable_address(name, pointer);
+ }
+
+ printf("\n----------------------------------------------------------\n");
+ printf(" Variables expected to be untagged:\n");
+ printf("----------------------------------------------------------\n");
+ for (const auto& [name, pointer] : untagged_variables) {
+ print_variable_address(name, pointer);
+ }
+ printf("\n");
+}
+
+void dso_check_assertions(bool check_pointers_are_tagged) {
+ // Check that non-const variables are writeable.
+ global_extern = 0;
+ global_extern_hidden = 0;
+ global_extern_untagged = 0;
+ global_extern_untagged_definition_but_tagged_import = 0;
+
+ if (check_pointers_are_tagged) {
+ for (const auto& [_, pointer] : get_expected_tagged_vars()) {
+ check_tagged(pointer);
+ }
+ }
+
+ for (const auto& [_, pointer] : get_expected_untagged_vars()) {
+ check_untagged(pointer);
+ }
+}
diff --git a/libc/arch-arm/static_function_dispatch.S b/tests/libs/mte_globals_relr_regression_test_b_314038442.cpp
similarity index 63%
rename from libc/arch-arm/static_function_dispatch.S
rename to tests/libs/mte_globals_relr_regression_test_b_314038442.cpp
index a8235c2..20bbba9 100644
--- a/libc/arch-arm/static_function_dispatch.S
+++ b/tests/libs/mte_globals_relr_regression_test_b_314038442.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,21 +26,30 @@
* SUCH DAMAGE.
*/
-#include <private/bionic_asm.h>
+#include <stdint.h>
+#include <stdio.h>
-#define FUNCTION_DELEGATE(name, impl) \
-ENTRY(name); \
- b impl; \
-END(name)
+static volatile char array[0x10000];
+volatile char* volatile oob_ptr = &array[0x111111111];
-FUNCTION_DELEGATE(memmove, memmove_generic)
-FUNCTION_DELEGATE(memcpy, memmove_generic)
-FUNCTION_DELEGATE(memset, memset_generic)
-FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic)
-FUNCTION_DELEGATE(strcpy, strcpy_generic)
-FUNCTION_DELEGATE(__strcpy_chk, __strcpy_chk_generic)
-FUNCTION_DELEGATE(stpcpy, stpcpy_generic)
-FUNCTION_DELEGATE(strcat, strcat_generic)
-FUNCTION_DELEGATE(__strcat_chk, __strcat_chk_generic)
-FUNCTION_DELEGATE(strcmp, strcmp_generic)
-FUNCTION_DELEGATE(strlen, strlen_generic)
+unsigned char get_tag(__attribute__((unused)) volatile void* ptr) {
+#if defined(__aarch64__)
+ return static_cast<unsigned char>(reinterpret_cast<uintptr_t>(ptr) >> 56) & 0xf;
+#else // !defined(__aarch64__)
+ return 0;
+#endif // defined(__aarch64__)
+}
+
+int main() {
+ printf("Program loaded successfully. %p %p. ", array, oob_ptr);
+ if (get_tag(array) != get_tag(oob_ptr)) {
+ printf("Tags are mismatched!\n");
+ return 1;
+ }
+ if (get_tag(array) == 0) {
+ printf("Tags are zero!\n");
+ } else {
+ printf("Tags are non-zero\n");
+ }
+ return 0;
+}
diff --git a/tests/libs/ns_hidden_child_helper.cpp b/tests/libs/ns_hidden_child_helper.cpp
index c2140f1..77608e2 100644
--- a/tests/libs/ns_hidden_child_helper.cpp
+++ b/tests/libs/ns_hidden_child_helper.cpp
@@ -33,7 +33,7 @@
#include <string>
#include "../core_shared_libs.h"
-#include "../dlext_private.h"
+#include "../dlext_private_tests.h"
extern "C" void global_function();
extern "C" void internal_function();
diff --git a/tests/libs/segment_gap_outer.cpp b/tests/libs/segment_gap_outer.cpp
index 3ba90d0..0328a99 100644
--- a/tests/libs/segment_gap_outer.cpp
+++ b/tests/libs/segment_gap_outer.cpp
@@ -1,6 +1,7 @@
#include <android/dlext.h>
#include <dlfcn.h>
#include <stdlib.h>
+#include <unistd.h>
extern "C" void __attribute__((section(".custom_text"))) text_before_start_of_gap() {}
char __attribute__((section(".custom_bss"))) end_of_gap[0x1000];
@@ -10,8 +11,9 @@
info.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
char* start_of_gap =
- reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(text_before_start_of_gap) & ~0xfffull) +
- 0x1000;
+ reinterpret_cast<char*>(
+ (reinterpret_cast<uintptr_t>(text_before_start_of_gap) &
+ ~(sysconf(_SC_PAGESIZE) - 1)) + sysconf(_SC_PAGESIZE));
info.reserved_addr = start_of_gap;
info.reserved_size = end_of_gap - start_of_gap;
diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds
index 527f29e..758b6bc 100644
--- a/tests/libs/segment_gap_outer.lds
+++ b/tests/libs/segment_gap_outer.lds
@@ -3,17 +3,17 @@
# appropriate alignment between them.
. = SIZEOF_HEADERS;
.rodata : {*(.rodata .rodata.*)}
- . = ALIGN(0x1000);
+ . = ALIGN(CONSTANT (MAXPAGESIZE));
.text : {*(.text .text.*)}
- . = ALIGN(0x1000);
+ . = ALIGN(CONSTANT (MAXPAGESIZE));
.dynamic : {*(.dynamic)}
- . = ALIGN(0x1000);
+ . = ALIGN(CONSTANT (MAXPAGESIZE));
.data : {*(.data .data.*)}
.bss : {*(.bss .bss.*)}
# Now create the gap. We need a text segment first to prevent the linker from
# merging .bss with .custom_bss.
- . = ALIGN(0x1000);
+ . = ALIGN(CONSTANT (MAXPAGESIZE));
.custom_text : {
*(.custom_text);
}
diff --git a/tests/libs/testbinary_is_stack_mte.cpp b/tests/libs/testbinary_is_stack_mte.cpp
index 0cdc466..3b6c79c 100644
--- a/tests/libs/testbinary_is_stack_mte.cpp
+++ b/tests/libs/testbinary_is_stack_mte.cpp
@@ -35,7 +35,7 @@
#if defined(__BIONIC__) && defined(__aarch64__)
-extern "C" int main(int, char**) {
+int main(int, char**) {
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;
@@ -45,7 +45,7 @@
#else
-extern "C" int main(int, char**) {
+int main(int, char**) {
printf("RAN\n");
return 1;
}
diff --git a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
index 35af8f4..93b6670 100644
--- a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
+++ b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
@@ -84,7 +84,7 @@
// Useless, but should defeat TCO.
return new_low + fault_new_stack_page(low, f);
}
-extern "C" int main(int argc, char** argv) {
+int main(int argc, char** argv) {
if (argc < 2) {
return 1;
}
@@ -150,7 +150,7 @@
}
#else
-extern "C" int main(int, char**) {
+int main(int, char**) {
return 1;
}
#endif
diff --git a/tests/malloc_stress_test.cpp b/tests/malloc_stress_test.cpp
index b5b06ab..00f5919 100644
--- a/tests/malloc_stress_test.cpp
+++ b/tests/malloc_stress_test.cpp
@@ -27,10 +27,58 @@
#include <thread>
#include <vector>
-#include <android-base/strings.h>
#if defined(__BIONIC__)
#include <meminfo/procmeminfo.h>
#include <procinfo/process_map.h>
+
+#include <log/log.h>
+#include <log/log_read.h>
+#endif
+
+#if defined(__BIONIC__)
+static void PrintLogStats(uint64_t& last_time) {
+ logger_list* logger =
+ android_logger_list_open(android_name_to_log_id("main"), ANDROID_LOG_NONBLOCK, 0, getpid());
+ if (logger == nullptr) {
+ printf("Failed to open log for main\n");
+ return;
+ }
+
+ uint64_t last_message_time = last_time;
+ while (true) {
+ log_msg entry;
+ ssize_t retval = android_logger_list_read(logger, &entry);
+ if (retval == 0) {
+ break;
+ }
+ if (retval < 0) {
+ if (retval == -EINTR) {
+ continue;
+ }
+ // EAGAIN means there is nothing left to read when ANDROID_LOG_NONBLOCK is set.
+ if (retval != -EAGAIN) {
+ printf("Failed to read log entry: %s\n", strerrordesc_np(retval));
+ }
+ break;
+ }
+ if (entry.msg() == nullptr) {
+ continue;
+ }
+ // Only print allocator tagged log entries.
+ std::string_view tag(entry.msg() + 1);
+ if (tag != "scudo" && tag != "jemalloc") {
+ continue;
+ }
+ if (entry.nsec() > last_time) {
+ printf(" %s\n", &tag.back() + 2);
+ // Only update the last time outside this loop just in case two or more
+ // messages have the same timestamp.
+ last_message_time = entry.nsec();
+ }
+ }
+ android_logger_list_close(logger);
+ last_time = last_message_time;
+}
#endif
TEST(malloc_stress, multiple_threads_forever) {
@@ -45,6 +93,8 @@
#endif
uint64_t mallinfo_min = UINT64_MAX;
uint64_t mallinfo_max = 0;
+
+ uint64_t last_message_time = 0;
for (size_t i = 0; ; i++) {
printf("Pass %zu\n", i);
@@ -74,8 +124,8 @@
uint64_t rss_bytes = 0;
uint64_t vss_bytes = 0;
for (auto& vma : maps) {
- if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
- android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
+ if (vma.name == "[anon:libc_malloc]" || vma.name.starts_with("[anon:scudo:") ||
+ vma.name.starts_with("[anon:GWP-ASan")) {
android::meminfo::Vma update_vma(vma);
ASSERT_TRUE(proc_mem.FillInVmaStats(update_vma));
rss_bytes += update_vma.usage.rss;
@@ -112,5 +162,15 @@
printf("Allocated memory %zu %0.2fMB\n", mallinfo_bytes, mallinfo_bytes / (1024.0 * 1024.0));
printf(" Min %" PRIu64 " %0.2fMB\n", mallinfo_min, mallinfo_min / (1024.0 * 1024.0));
printf(" Max %" PRIu64 " %0.2fMB\n", mallinfo_max, mallinfo_max / (1024.0 * 1024.0));
+
+#if defined(__BIONIC__)
+ if (((i + 1) % 100) == 0) {
+ // Send native allocator stats to the log
+ mallopt(M_LOG_STATS, 0);
+
+ printf("Log stats:\n");
+ PrintLogStats(last_message_time);
+ }
+#endif
}
}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index a5916d3..8bd8bc6 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -47,12 +47,13 @@
#include <android-base/file.h>
#include <android-base/test_utils.h>
+#include "DoNotOptimize.h"
#include "utils.h"
#if defined(__BIONIC__)
#include "SignalUtils.h"
-#include "dlext_private.h"
+#include "dlext_private_tests.h"
#include "platform/bionic/malloc.h"
#include "platform/bionic/mte.h"
@@ -465,6 +466,7 @@
// Do not verify output for debug malloc.
ASSERT_TRUE(version == "debug-malloc-1") << "Unknown version: " << version;
}
+ printf("Allocator version: %s\n", version.c_str());
#endif
}
@@ -1627,6 +1629,7 @@
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
#endif
+ SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
if (IsLowRamDevice()) {
GTEST_SKIP() << "Skipped on low memory devices.";
@@ -1657,6 +1660,7 @@
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
#endif
+ SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
if (IsLowRamDevice()) {
GTEST_SKIP() << "Skipped on low memory devices.";
@@ -1687,6 +1691,7 @@
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
#endif
+ SKIP_WITH_HWASAN << "Only test system allocator, not hwasan allocator.";
if (IsLowRamDevice()) {
GTEST_SKIP() << "Skipped on low memory devices.";
diff --git a/tests/memtag_globals_test.cpp b/tests/memtag_globals_test.cpp
new file mode 100644
index 0000000..ff93e7b
--- /dev/null
+++ b/tests/memtag_globals_test.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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(__BIONIC__)
+#include "gtest_globals.h"
+#include "utils.h"
+#endif // defined(__BIONIC__)
+
+#include <android-base/test_utils.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string>
+#include <tuple>
+
+#include "platform/bionic/mte.h"
+
+class MemtagGlobalsTest : public testing::TestWithParam<bool> {};
+
+TEST_P(MemtagGlobalsTest, test) {
+ SKIP_WITH_HWASAN << "MTE globals tests are incompatible with HWASan";
+#if defined(__BIONIC__) && defined(__aarch64__)
+ std::string binary = GetTestLibRoot() + "/memtag_globals_binary";
+ bool is_static = MemtagGlobalsTest::GetParam();
+ if (is_static) {
+ binary += "_static";
+ }
+
+ chmod(binary.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({binary.c_str(), nullptr});
+ eth.Run(
+ [&]() {
+ execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
+ GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
+ },
+ // We catch the global-buffer-overflow and crash only when MTE globals is
+ // supported. Note that MTE globals is unsupported for fully static
+ // executables, but we should still make sure the binary passes its
+ // assertions, just that global variables won't be tagged.
+ (mte_supported() && !is_static) ? -SIGSEGV : 0, "Assertions were passed");
+#else
+ GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
+
+INSTANTIATE_TEST_SUITE_P(MemtagGlobalsTest, MemtagGlobalsTest, testing::Bool(),
+ [](const ::testing::TestParamInfo<MemtagGlobalsTest::ParamType>& info) {
+ if (info.param) return "MemtagGlobalsTest_static";
+ return "MemtagGlobalsTest";
+ });
+
+TEST(MemtagGlobalsTest, RelrRegressionTestForb314038442) {
+ SKIP_WITH_HWASAN << "MTE globals tests are incompatible with HWASan";
+#if defined(__BIONIC__) && defined(__aarch64__)
+ std::string binary = GetTestLibRoot() + "/mte_globals_relr_regression_test_b_314038442";
+ chmod(binary.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({binary.c_str(), nullptr});
+ eth.Run(
+ [&]() {
+ execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
+ GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
+ },
+ /* exit code */ 0, "Program loaded successfully.*Tags are zero!");
+#else
+ GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
+
+TEST(MemtagGlobalsTest, RelrRegressionTestForb314038442WithMteGlobals) {
+ if (!mte_supported()) GTEST_SKIP() << "Must have MTE support.";
+#if defined(__BIONIC__) && defined(__aarch64__)
+ std::string binary = GetTestLibRoot() + "/mte_globals_relr_regression_test_b_314038442_mte";
+ chmod(binary.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({binary.c_str(), nullptr});
+ eth.Run(
+ [&]() {
+ execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
+ GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
+ },
+ /* exit code */ 0, "Program loaded successfully.*Tags are non-zero");
+#else
+ GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
diff --git a/tests/memtag_stack_abi_test.cpp b/tests/memtag_stack_abi_test.cpp
new file mode 100644
index 0000000..4725c8d
--- /dev/null
+++ b/tests/memtag_stack_abi_test.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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 <filesystem>
+#include <fstream>
+#include <iterator>
+#include <string>
+#include <thread>
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+static size_t NumberBuffers() {
+ size_t bufs = 0;
+ std::ifstream file("/proc/self/maps");
+ CHECK(file.is_open());
+ std::string line;
+ while (std::getline(file, line)) {
+ if (line.find("stack_mte_ring") != std::string::npos) {
+ ++bufs;
+ }
+ }
+ return bufs;
+}
+
+static size_t NumberThreads() {
+ std::filesystem::directory_iterator di("/proc/self/task");
+ return std::distance(begin(di), end(di));
+}
+
+TEST(MemtagStackAbiTest, MainThread) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+ ASSERT_EQ(NumberBuffers(), 1U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+#else
+ GTEST_SKIP() << "requires bionic arm64";
+#endif
+}
+
+TEST(MemtagStackAbiTest, JoinableThread) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+ ASSERT_EQ(NumberBuffers(), 1U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+ std::thread th([] {
+ ASSERT_EQ(NumberBuffers(), 2U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+ });
+ th.join();
+ ASSERT_EQ(NumberBuffers(), 1U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+#else
+ GTEST_SKIP() << "requires bionic arm64";
+#endif
+}
+
+TEST(MemtagStackAbiTest, DetachedThread) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+ ASSERT_EQ(NumberBuffers(), 1U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+ std::thread th([] {
+ ASSERT_EQ(NumberBuffers(), 2U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+ });
+ th.detach();
+ // Leave the thread some time to exit.
+ for (int i = 0; NumberBuffers() != 1 && i < 3; ++i) {
+ sleep(1);
+ }
+ ASSERT_EQ(NumberBuffers(), 1U);
+ ASSERT_EQ(NumberBuffers(), NumberThreads());
+#else
+ GTEST_SKIP() << "requires bionic arm64";
+#endif
+}
diff --git a/tests/mntent_test.cpp b/tests/mntent_test.cpp
index 4b8fc9a..fd69ae1 100644
--- a/tests/mntent_test.cpp
+++ b/tests/mntent_test.cpp
@@ -59,9 +59,7 @@
// indices 1 1
// of keys: 0 5 9 1 4
char mnt_opts[]{"aa=b,a=b,b,bb,c=d"};
- struct mntent ent;
- memset(&ent, 0, sizeof(ent));
- ent.mnt_opts = mnt_opts;
+ struct mntent ent = {.mnt_opts = mnt_opts};
EXPECT_EQ(mnt_opts, hasmntopt(&ent, "aa"));
EXPECT_EQ(mnt_opts + 5, hasmntopt(&ent, "a"));
@@ -71,3 +69,9 @@
EXPECT_EQ(nullptr, hasmntopt(&ent, "d"));
EXPECT_EQ(nullptr, hasmntopt(&ent, "e"));
}
+
+TEST(mntent, hasmntopt_no_suffix_match) {
+ char mnt_opts[]{"noatime"};
+ struct mntent ent = {.mnt_opts = mnt_opts};
+ EXPECT_EQ(nullptr, hasmntopt(&ent, "atime"));
+}
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index 1cb569c..f6e8a32 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -79,11 +79,7 @@
}
TEST(netdb, getaddrinfo_hints) {
- addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
+ addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP};
addrinfo* ai = nullptr;
ASSERT_EQ(0, getaddrinfo( "localhost", "9999", &hints, &ai));
@@ -113,8 +109,7 @@
}
TEST(netdb, getnameinfo_salen) {
- sockaddr_storage ss;
- memset(&ss, 0, sizeof(ss));
+ sockaddr_storage ss = {};
sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
char tmp[16];
@@ -142,11 +137,8 @@
}
TEST(netdb, getnameinfo_localhost) {
- sockaddr_in addr;
char host[NI_MAXHOST];
- memset(&addr, 0, sizeof(sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(0x7f000001);
+ sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(0x7f000001)};
ASSERT_EQ(0, getnameinfo(reinterpret_cast<sockaddr*>(&addr), sizeof(addr),
host, sizeof(host), nullptr, 0, 0));
ASSERT_STREQ(host, "localhost");
@@ -160,11 +152,8 @@
}
TEST(netdb, getnameinfo_ip6_localhost) {
- sockaddr_in6 addr;
char host[NI_MAXHOST];
- memset(&addr, 0, sizeof(sockaddr_in6));
- addr.sin6_family = AF_INET6;
- addr.sin6_addr = in6addr_loopback;
+ sockaddr_in6 addr = {.sin6_family = AF_INET6, .sin6_addr = in6addr_loopback};
ASSERT_EQ(0, getnameinfo(reinterpret_cast<sockaddr*>(&addr), sizeof(addr),
host, sizeof(host), nullptr, 0, 0));
VerifyLocalhostName(host);
diff --git a/tests/netinet_ether_test.cpp b/tests/netinet_ether_test.cpp
index d7b81eb..a9de9bf 100644
--- a/tests/netinet_ether_test.cpp
+++ b/tests/netinet_ether_test.cpp
@@ -32,8 +32,7 @@
}
TEST(netinet_ether, ether_aton_r__ether_ntoa_r) {
- ether_addr addr;
- memset(&addr, 0, sizeof(addr));
+ ether_addr addr = {};
ether_addr* a = ether_aton_r("12:34:56:78:9a:Bc", &addr);
ASSERT_EQ(&addr, a);
ASSERT_EQ(0x12, addr.ether_addr_octet[0]);
diff --git a/tests/page_size_16kib_compat_test.cpp b/tests/page_size_16kib_compat_test.cpp
new file mode 100644
index 0000000..cfd52e2
--- /dev/null
+++ b/tests/page_size_16kib_compat_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#if __has_include (<android/dlext_private.h>)
+#define IS_ANDROID_DL
+#endif
+
+#include "page_size_compat_helpers.h"
+
+#include <android-base/properties.h>
+
+#if defined(IS_ANDROID_DL)
+#include <android/dlext_private.h>
+#endif
+
+TEST(PageSize16KiBCompatTest, ElfAlignment4KiB_LoadElf) {
+ if (getpagesize() != 0x4000) {
+ GTEST_SKIP() << "This test is only applicable to 16kB page-size devices";
+ }
+
+ bool app_compat_enabled =
+ android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false);
+ std::string lib = GetTestLibRoot() + "/libtest_elf_max_page_size_4kib.so";
+ void* handle = nullptr;
+
+ OpenTestLibrary(lib, !app_compat_enabled, &handle);
+
+ if (app_compat_enabled) CallTestFunction(handle);
+}
+
+TEST(PageSize16KiBCompatTest, ElfAlignment4KiB_LoadElf_perAppOption) {
+ if (getpagesize() != 0x4000) {
+ GTEST_SKIP() << "This test is only applicable to 16kB page-size devices";
+ }
+
+#if defined(IS_ANDROID_DL)
+ android_set_16kb_appcompat_mode(true);
+#endif
+
+ std::string lib = GetTestLibRoot() + "/libtest_elf_max_page_size_4kib.so";
+ void* handle = nullptr;
+
+ OpenTestLibrary(lib, false /*should_fail*/, &handle);
+ CallTestFunction(handle);
+
+#if defined(IS_ANDROID_DL)
+ android_set_16kb_appcompat_mode(false);
+#endif
+}
diff --git a/tests/page_size_compat_helpers.h b/tests/page_size_compat_helpers.h
new file mode 100644
index 0000000..2f0f1d0
--- /dev/null
+++ b/tests/page_size_compat_helpers.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
+
+#include "elf_max_page_size.h"
+#include "gtest_globals.h"
+
+#include <android-base/stringprintf.h>
+
+#include <string>
+
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+static inline void OpenTestLibrary(std::string lib, bool expect_fail, void** handle) {
+ void* _handle = dlopen(lib.c_str(), RTLD_NODELETE);
+ const char* dlopen_error = dlerror();
+
+ if (expect_fail) {
+ ASSERT_EQ(_handle, nullptr);
+
+ const std::string expected_error = android::base::StringPrintf(
+ "dlopen failed: \"%s\" program alignment (%d) cannot be smaller than system page size (%d)",
+ lib.c_str(), 4096, getpagesize());
+
+ ASSERT_EQ(expected_error, dlopen_error);
+ } else {
+ ASSERT_NE(_handle, nullptr) << "Failed to dlopen shared library \"" << lib
+ << "\": " << dlopen_error;
+ }
+
+ *handle = _handle;
+}
+
+static inline void CallTestFunction(void* handle) {
+ loader_test_func_t loader_test_func = (loader_test_func_t)dlsym(handle, "loader_test_func");
+ const char* dlsym_error = dlerror();
+
+ ASSERT_EQ(dlsym_error, nullptr) << "Failed to locate symbol \"loader_test_func\": "
+ << dlsym_error;
+
+ int res = loader_test_func();
+ ASSERT_EQ(res, TEST_RESULT_BASE + TEST_RESULT_INCREMENT);
+
+ // Call loader_test_func() twice to ensure we can modify writeable data and bss data
+ res = loader_test_func();
+ ASSERT_EQ(res, TEST_RESULT_BASE + (2 * TEST_RESULT_INCREMENT));
+}
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so
index c8b5430..21a8f26 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so
index 20c5765..c902bbe 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so
index 6463c6b..46af37f 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so
index f83bbe4..c60b0d6 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so
index fbf62c5..eb33692 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so
index 6e5a6e3..fb86bca 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so
index 14b80b5..0416db2 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so
index 0aaca72..90892a6 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so
index 4ffc7e8..c186b1d 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so
index 9098310..857f702 100755
--- a/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh b/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh
index 0f3e736..98a2b00 100755
--- a/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh
+++ b/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh
@@ -19,12 +19,18 @@
build() {
arch=$1
target=$2
+
+ if [[ "$arch" == "arm64" || "$arch" == "x86_64" ]]; then
+ alignment="-Wl,-z,max-page-size=16384"
+ fi
+
$NDK21E/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -O2 --target=$target \
-fpic -shared -o $arch/libtest_invalid-local-tls.so -fno-emulated-tls \
- -fuse-ld=gold test.c test2.c
+ $alignment -fuse-ld=gold test.c test2.c
}
build arm armv7a-linux-androideabi29
build arm64 aarch64-linux-android29
build x86 i686-linux-android29
build x86_64 x86_64-linux-android29
+
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so
index af1538d..00fefd4 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so
index 5b689ba..31d2b37 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so
index 113e455..9d2c5f1 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so
index 719fb5a..f231d11 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so
index 9d0741e..97fb5c4 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so
index 87631af..f9c310f 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so
index 27d1138..3d1f5d3 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so
index 3e2c1d1..aeea1d2 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so
index 78fed79..8146676 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so
index 0953633..4ac70f7 100755
--- a/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so
Binary files differ
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 2bf755b..5ce7d4d 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -45,6 +45,7 @@
#include <android-base/test_utils.h>
#include "private/bionic_constants.h"
+#include "private/bionic_time_conversions.h"
#include "SignalUtils.h"
#include "utils.h"
@@ -2437,23 +2438,25 @@
ts.tv_sec = -1;
ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
- // check we wait long enough for the lock.
+ // Check we wait long enough for the lock before timing out...
+
+ // What time is it before we start?
ASSERT_EQ(0, clock_gettime(clock, &ts));
- const int64_t start_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
-
- // add a second to get deadline.
+ const int64_t start_ns = to_ns(ts);
+ // Add a second to get deadline, and wait until we time out.
ts.tv_sec += 1;
-
ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
+ // What time is it now we've timed out?
+ timespec ts2;
+ clock_gettime(clock, &ts2);
+ const int64_t end_ns = to_ns(ts2);
+
// The timedlock must have waited at least 1 second before returning.
- clock_gettime(clock, &ts);
- const int64_t end_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
- ASSERT_GT(end_ns - start_ns, NS_PER_S);
+ ASSERT_GE(end_ns - start_ns, NS_PER_S);
// If the mutex is unlocked, pthread_mutex_timedlock should succeed.
ASSERT_EQ(0, pthread_mutex_unlock(&m));
-
ASSERT_EQ(0, clock_gettime(clock, &ts));
ts.tv_sec += 1;
ASSERT_EQ(0, lock_function(&m, &ts));
@@ -2474,12 +2477,19 @@
#endif // __BIONIC__
}
-TEST(pthread, pthread_mutex_clocklock) {
+TEST(pthread, pthread_mutex_clocklock_MONOTONIC) {
#if defined(__BIONIC__)
pthread_mutex_timedlock_helper(
CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout);
});
+#else // __BIONIC__
+ GTEST_SKIP() << "pthread_mutex_clocklock not available";
+#endif // __BIONIC__
+}
+
+TEST(pthread, pthread_mutex_clocklock_REALTIME) {
+#if defined(__BIONIC__)
pthread_mutex_timedlock_helper(
CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) {
return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout);
@@ -3127,3 +3137,39 @@
GTEST_SKIP() << "bionic-only test";
#endif
}
+
+TEST(pthread, pthread_getaffinity_np_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ errno = 0;
+ ASSERT_EQ(EINVAL, pthread_getaffinity_np(pthread_self(), 0, nullptr));
+ ASSERT_ERRNO(0);
+#pragma clang diagnostic pop
+}
+
+TEST(pthread, pthread_getaffinity) {
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(set), &set));
+ ASSERT_GT(CPU_COUNT(&set), 0);
+}
+
+TEST(pthread, pthread_setaffinity_np_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ errno = 0;
+ ASSERT_EQ(EINVAL, pthread_setaffinity_np(pthread_self(), 0, nullptr));
+ ASSERT_ERRNO(0);
+#pragma clang diagnostic pop
+}
+
+TEST(pthread, pthread_setaffinity) {
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(set), &set));
+ // It's hard to make any more general claim than this,
+ // but it ought to be safe to ask for the same affinity you already have.
+ ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(set), &set));
+}
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 0231de4..448fae9 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -305,8 +305,35 @@
}
TEST(sched, sched_getaffinity_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+ ASSERT_ERRNO(EINVAL);
#pragma clang diagnostic pop
}
+
+TEST(pthread, sched_getaffinity) {
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ ASSERT_EQ(0, sched_getaffinity(getpid(), sizeof(set), &set));
+ ASSERT_GT(CPU_COUNT(&set), 0);
+}
+
+TEST(sched, sched_setaffinity_failure) {
+ // Trivial test of the errno-preserving/returning behavior.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ ASSERT_EQ(-1, sched_setaffinity(getpid(), 0, nullptr));
+ ASSERT_ERRNO(EINVAL);
+#pragma clang diagnostic pop
+}
+
+TEST(pthread, sched_setaffinity) {
+ cpu_set_t set;
+ CPU_ZERO(&set);
+ ASSERT_EQ(0, sched_getaffinity(getpid(), sizeof(set), &set));
+ // It's hard to make any more general claim than this,
+ // but it ought to be safe to ask for the same affinity you already have.
+ ASSERT_EQ(0, sched_setaffinity(getpid(), sizeof(set), &set));
+}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index de126da..f8bfcef 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -804,10 +804,7 @@
ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
- siginfo sent;
- memset(&sent, 0, sizeof(sent));
-
- sent.si_code = SI_TKILL;
+ siginfo sent = {.si_code = SI_TKILL};
ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
<< "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
@@ -982,3 +979,94 @@
ASSERT_EQ(-1, killpg(-1, SIGKILL));
ASSERT_ERRNO(EINVAL);
}
+
+TEST(signal, sig2str) {
+#if defined(__BIONIC__)
+ char str[SIG2STR_MAX];
+
+ // A regular signal.
+ ASSERT_EQ(0, sig2str(SIGHUP, str));
+ ASSERT_STREQ("HUP", str);
+
+ // A real-time signal.
+ ASSERT_EQ(0, sig2str(SIGRTMIN + 4, str));
+ ASSERT_STREQ("RTMIN+4", str);
+ ASSERT_EQ(0, sig2str(SIGRTMAX - 4, str));
+ ASSERT_STREQ("RTMAX-4", str);
+ // Special cases.
+ ASSERT_EQ(0, sig2str(SIGRTMAX, str));
+ ASSERT_STREQ("RTMAX", str);
+ ASSERT_EQ(0, sig2str(SIGRTMIN, str));
+ ASSERT_STREQ("RTMIN", str);
+ // One of the signals the C library keeps to itself.
+ ASSERT_EQ(-1, sig2str(32, str)); // __SIGRTMIN
+
+ // Errors.
+ ASSERT_EQ(-1, sig2str(-1, str)); // Too small.
+ ASSERT_EQ(-1, sig2str(0, str)); // Still too small.
+ ASSERT_EQ(-1, sig2str(1234, str)); // Too large.
+#else
+ GTEST_SKIP() << "our old glibc doesn't have sig2str";
+#endif
+}
+
+TEST(signal, str2sig) {
+#if defined(__BIONIC__)
+ int sig;
+
+ // A regular signal, by number.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("9", &sig));
+ ASSERT_EQ(SIGKILL, sig);
+
+ // A regular signal, by name.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("HUP", &sig));
+ ASSERT_EQ(SIGHUP, sig);
+
+ // A real-time signal, by number.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("64", &sig));
+ ASSERT_EQ(SIGRTMAX, sig);
+
+ // A real-time signal, by name and offset.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMAX-4", &sig));
+ ASSERT_EQ(SIGRTMAX - 4, sig);
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMIN+4", &sig));
+ ASSERT_EQ(SIGRTMIN + 4, sig);
+ // Unspecified by POSIX, but we try to be reasonable.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMAX-0", &sig));
+ ASSERT_EQ(SIGRTMAX, sig);
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMIN+0", &sig));
+ ASSERT_EQ(SIGRTMIN, sig);
+ // One of the signals the C library keeps to itself, numerically.
+ ASSERT_EQ(-1, str2sig("32", &sig)); // __SIGRTMIN
+
+ // Special cases.
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMAX", &sig));
+ ASSERT_EQ(SIGRTMAX, sig);
+ sig = -1;
+ ASSERT_EQ(0, str2sig("RTMIN", &sig));
+ ASSERT_EQ(SIGRTMIN, sig);
+
+ // Errors.
+ ASSERT_EQ(-1, str2sig("SIGHUP", &sig)); // No "SIG" prefix allowed.
+ ASSERT_EQ(-1, str2sig("-1", &sig)); // Too small.
+ ASSERT_EQ(-1, str2sig("0", &sig)); // Still too small.
+ ASSERT_EQ(-1, str2sig("1234", &sig)); // Too large.
+ ASSERT_EQ(-1, str2sig("RTMAX-666", &sig)); // Offset too small.
+ ASSERT_EQ(-1, str2sig("RTMIN+666", &sig)); // Offset too large.
+ ASSERT_EQ(-1, str2sig("RTMAX-+1", &sig)); // Silly.
+ ASSERT_EQ(-1, str2sig("RTMIN+-1", &sig)); // Silly.
+ ASSERT_EQ(-1, str2sig("HUPs", &sig)); // Trailing junk.
+ ASSERT_EQ(-1, str2sig("2b", &sig)); // Trailing junk.
+ ASSERT_EQ(-1, str2sig("RTMIN+2b", &sig)); // Trailing junk.
+#else
+ GTEST_SKIP() << "our old glibc doesn't have str2sig";
+#endif
+}
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 2f891a6..fc6c25c 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -43,8 +43,7 @@
const char* symbol = "<unknown>";
int offset = 0;
- Dl_info info;
- memset(&info, 0, sizeof(info));
+ Dl_info info = {};
if (dladdr(ip, &info) != 0) {
symbol = info.dli_sname;
if (info.dli_saddr != nullptr) {
diff --git a/tests/static_tls_layout_test.cpp b/tests/static_tls_layout_test.cpp
index bf508e8..ada29a5 100644
--- a/tests/static_tls_layout_test.cpp
+++ b/tests/static_tls_layout_test.cpp
@@ -35,6 +35,8 @@
#include <gtest/gtest.h>
+#include <android-base/silent_death_test.h>
+
#include "private/bionic_tls.h"
using namespace std::string_literals;
@@ -138,7 +140,9 @@
return i * sizeof(void*);
}
-TEST(static_tls_layout, arm) {
+using static_tls_layout_DeathTest = SilentDeathTest;
+
+TEST_F(static_tls_layout_DeathTest, arm) {
#if !defined(__arm__) && !defined(__aarch64__)
GTEST_SKIP() << "test only applies to arm32/arm64 targets";
#endif
diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp
index f5c6bb1..8a54080 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -37,10 +37,10 @@
}
TEST(stdatomic, init) {
- atomic_int v = ATOMIC_VAR_INIT(123);
+ atomic_int v = 123;
ASSERT_EQ(123, atomic_load(&v));
- atomic_init(&v, 456);
+ atomic_store_explicit(&v, 456, memory_order_relaxed);
ASSERT_EQ(456, atomic_load(&v));
atomic_flag f = ATOMIC_FLAG_INIT;
@@ -145,35 +145,35 @@
}
TEST(stdatomic, atomic_fetch_add) {
- atomic_int i = ATOMIC_VAR_INIT(123);
+ atomic_int i = 123;
ASSERT_EQ(123, atomic_fetch_add(&i, 1));
ASSERT_EQ(124, atomic_fetch_add_explicit(&i, 1, memory_order_relaxed));
ASSERT_EQ(125, atomic_load(&i));
}
TEST(stdatomic, atomic_fetch_sub) {
- atomic_int i = ATOMIC_VAR_INIT(123);
+ atomic_int i = 123;
ASSERT_EQ(123, atomic_fetch_sub(&i, 1));
ASSERT_EQ(122, atomic_fetch_sub_explicit(&i, 1, memory_order_relaxed));
ASSERT_EQ(121, atomic_load(&i));
}
TEST(stdatomic, atomic_fetch_or) {
- atomic_int i = ATOMIC_VAR_INIT(0x100);
+ atomic_int i = 0x100;
ASSERT_EQ(0x100, atomic_fetch_or(&i, 0x020));
ASSERT_EQ(0x120, atomic_fetch_or_explicit(&i, 0x003, memory_order_relaxed));
ASSERT_EQ(0x123, atomic_load(&i));
}
TEST(stdatomic, atomic_fetch_xor) {
- atomic_int i = ATOMIC_VAR_INIT(0x100);
+ atomic_int i = 0x100;
ASSERT_EQ(0x100, atomic_fetch_xor(&i, 0x120));
ASSERT_EQ(0x020, atomic_fetch_xor_explicit(&i, 0x103, memory_order_relaxed));
ASSERT_EQ(0x123, atomic_load(&i));
}
TEST(stdatomic, atomic_fetch_and) {
- atomic_int i = ATOMIC_VAR_INIT(0x123);
+ atomic_int i = 0x123;
ASSERT_EQ(0x123, atomic_fetch_and(&i, 0x00f));
ASSERT_EQ(0x003, atomic_fetch_and_explicit(&i, 0x2, memory_order_relaxed));
ASSERT_EQ(0x002, atomic_load(&i));
@@ -258,9 +258,9 @@
// Run a memory ordering smoke test.
void* result;
three_atomics a;
- atomic_init(&a.x, 0ul);
- atomic_init(&a.y, 0ul);
- atomic_init(&a.z, 0ul);
+ atomic_store_explicit(&a.x, 0ul, memory_order_relaxed);
+ atomic_store_explicit(&a.y, 0ul, memory_order_relaxed);
+ atomic_store_explicit(&a.z, 0ul, memory_order_relaxed);
pthread_t t1,t2;
ASSERT_EQ(0, pthread_create(&t1, nullptr, reader, &a));
ASSERT_EQ(0, pthread_create(&t2, nullptr, writer, &a));
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 4793150..fac9b9b 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -29,6 +29,7 @@
#include <limits>
#include <string>
+#include <thread>
#include <android-base/file.h>
#include <android-base/macros.h>
@@ -430,6 +431,31 @@
ASSERT_STREQ("charlie", entries[2].name);
}
+TEST(stdlib, qsort_r) {
+ struct s {
+ char name[16];
+ static int comparator(const void* lhs, const void* rhs, void* context) {
+ int* count_p = reinterpret_cast<int*>(context);
+ *count_p += 1;
+ return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
+ }
+ };
+ s entries[3];
+ strcpy(entries[0].name, "charlie");
+ strcpy(entries[1].name, "bravo");
+ strcpy(entries[2].name, "alpha");
+
+ int count;
+ void* context = &count;
+
+ count = 0;
+ qsort_r(entries, 3, sizeof(s), s::comparator, context);
+ ASSERT_STREQ("alpha", entries[0].name);
+ ASSERT_STREQ("bravo", entries[1].name);
+ ASSERT_STREQ("charlie", entries[2].name);
+ ASSERT_EQ(count, 3);
+}
+
static void* TestBug57421_child(void* arg) {
pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
pthread_join(main_thread, nullptr);
@@ -493,7 +519,7 @@
TEST(stdlib, system_NULL) {
// "The system() function shall always return non-zero when command is NULL."
- // http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html
+ // https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/system.html
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_NE(0, system(nullptr));
@@ -650,6 +676,58 @@
AssertChildExited(pid, 99);
}
+static void exit_from_atexit_func4() {
+ std::thread([] { exit(4); }).detach();
+ usleep(1000);
+ fprintf(stderr, "4");
+}
+
+static void exit_from_atexit_func3() {
+ std::thread([] { exit(3); }).detach();
+ fprintf(stderr, "3");
+ usleep(1000);
+ // This should cause us to exit with status 99,
+ // but not before printing "4",
+ // and without re-running the previous atexit handlers.
+ exit(99);
+}
+
+static void exit_from_atexit_func2() {
+ std::thread([] { exit(2); }).detach();
+ fprintf(stderr, "2");
+ usleep(1000);
+ // Register another atexit handler from within an atexit handler.
+ atexit(exit_from_atexit_func3);
+}
+
+static void exit_from_atexit_func1() {
+ // These atexit handlers all spawn another thread that tries to exit,
+ // and sleep to try to lose the race.
+ // The lock in exit() should ensure that only the first thread to call
+ // exit() can ever win (but see exit_from_atexit_func3() for a subtelty).
+ std::thread([] { exit(1); }).detach();
+ usleep(1000);
+ fprintf(stderr, "1");
+}
+
+static void exit_torturer() {
+ atexit(exit_from_atexit_func4);
+ // We deliberately don't register exit_from_atexit_func3() here;
+ // see exit_from_atexit_func2().
+ atexit(exit_from_atexit_func2);
+ atexit(exit_from_atexit_func1);
+ exit(0);
+}
+
+TEST(stdlib, exit_torture) {
+ // Test that the atexit() handlers are run in the defined order (reverse
+ // order of registration), even though one of them is registered by another
+ // when it runs, and that we get the exit code from the last call to exit()
+ // on the first thread to call exit() (rather than one of the other threads
+ // or a deadlock from the second call on the same thread).
+ ASSERT_EXIT(exit_torturer(), testing::ExitedWithCode(99), "1234");
+}
+
TEST(unistd, _Exit) {
pid_t pid = fork();
ASSERT_NE(-1, pid) << strerror(errno);
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 6e1fcfc..502405f 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -740,15 +740,11 @@
// Set the second half of ptr to the expected pattern in ptr2.
memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN);
memcpy(state.ptr + state.MAX_LEN, state.ptr1, copy_len);
- size_t expected_end;
if (copy_len > ptr1_len) {
memset(state.ptr + state.MAX_LEN + ptr1_len, '\0', copy_len - ptr1_len);
- expected_end = ptr1_len;
- } else {
- expected_end = copy_len;
}
- ASSERT_EQ(state.ptr2 + expected_end, stpncpy(state.ptr2, state.ptr1, copy_len));
+ ASSERT_EQ(state.ptr2, strncpy(state.ptr2, state.ptr1, copy_len));
// Verify ptr1 was not modified.
ASSERT_EQ(0, memcmp(state.ptr1, state.ptr, state.MAX_LEN));
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 1f04344..b9fd315 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, 816);
+ CHECK_SIZE(pthread_internal_t, 824);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 8);
CHECK_OFFSET(pthread_internal_t, tid, 16);
@@ -57,6 +57,7 @@
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_OFFSET(pthread_internal_t, should_allocate_stack_mte_ringbuffer, 816);
CHECK_SIZE(bionic_tls, 12200);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 2080);
@@ -74,7 +75,7 @@
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
CHECK_OFFSET(bionic_tls, padding, 12194);
#else
- CHECK_SIZE(pthread_internal_t, 704);
+ CHECK_SIZE(pthread_internal_t, 708);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 4);
CHECK_OFFSET(pthread_internal_t, tid, 8);
@@ -101,6 +102,7 @@
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_OFFSET(pthread_internal_t, should_allocate_stack_mte_ringbuffer, 704);
CHECK_SIZE(bionic_tls, 11080);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 1040);
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index 40c85f2..54a0b64 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -320,3 +320,30 @@
close(fd);
#endif
}
+
+TEST(sys_mseal, mseal) {
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "needs glibc 2.40";
+#else
+ void* map = mmap(nullptr, kPageSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_NE(MAP_FAILED, map);
+
+#if defined(__LP64__)
+ int rc = mseal(map, kPageSize, 0);
+ if (rc == -1) {
+ ASSERT_ERRNO(ENOSYS);
+ GTEST_SKIP() << "needs kernel with mseal(2)";
+ }
+ ASSERT_EQ(-1, mprotect(map, kPageSize, PROT_READ));
+ ASSERT_ERRNO(EPERM);
+#else
+ // No mseal() for ILP32.
+ errno = 0;
+ ASSERT_EQ(-1, mseal(map, kPageSize, 0));
+ ASSERT_ERRNO(ENOSYS);
+ GTEST_SKIP() << "mseal(2) is LP64-only";
+#endif
+
+ // We can't munmap() our test mapping if mseal() actually succeeded :-)
+#endif
+}
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index b2d855d..26e4559 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -45,8 +45,7 @@
ASSERT_NE(id, -1);
// Queue should be empty.
- msqid_ds ds;
- memset(&ds, 0, sizeof(ds));
+ msqid_ds ds = {};
ASSERT_EQ(0, msgctl(id, IPC_STAT, &ds));
ASSERT_EQ(0U, ds.msg_qnum);
ASSERT_EQ(0U, ds.msg_cbytes);
@@ -64,7 +63,7 @@
ASSERT_EQ(sizeof(msg.data), ds.msg_cbytes);
// Read the message.
- memset(&msg, 0, sizeof(msg));
+ msg = {};
ASSERT_EQ(static_cast<ssize_t>(sizeof(msg.data)),
msgrcv(id, &msg, sizeof(msg.data), 0, 0));
ASSERT_EQ(1, msg.type);
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 4a64742..d707c5d 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -20,20 +20,11 @@
#include <sys/procfs.h>
TEST(sys_procfs, types) {
- elf_greg_t reg;
- memset(®, 0, sizeof(reg));
-
- elf_gregset_t regs;
- memset(®s, 0, sizeof(regs));
-
- elf_fpregset_t fp_regs;
- memset(&fp_regs, 0, sizeof(fp_regs));
-
- prgregset_t pr_g_regs;
- memset(&pr_g_regs, 0, sizeof(pr_g_regs));
-
- prfpregset_t pr_fp_regs;
- memset(&pr_fp_regs, 0, sizeof(pr_fp_regs));
+ elf_greg_t reg = {};
+ elf_gregset_t regs = {};
+ elf_fpregset_t fp_regs = {};
+ prgregset_t pr_g_regs = {};
+ prfpregset_t pr_fp_regs = {};
static_assert(sizeof(prgregset_t) == sizeof(elf_gregset_t), "");
static_assert(sizeof(prfpregset_t) == sizeof(elf_fpregset_t), "");
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 93daac3..1f9c2a2 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -41,11 +41,6 @@
using android::base::unique_fd;
-// Host libc does not define this.
-#ifndef TRAP_HWBKPT
-#define TRAP_HWBKPT 4
-#endif
-
class ChildGuard {
public:
explicit ChildGuard(pid_t pid) : pid(pid) {}
@@ -121,8 +116,7 @@
ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, -1, &address)) << strerror(errno);
ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, -2, &control)) << strerror(errno);
#else // aarch64
- user_hwdebug_state dreg_state;
- memset(&dreg_state, 0, sizeof dreg_state);
+ user_hwdebug_state dreg_state = {};
dreg_state.dbg_regs[0].addr = address;
dreg_state.dbg_regs[0].ctrl = control;
@@ -309,8 +303,7 @@
ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, 1, &address)) << strerror(errno);
ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, 2, &control)) << strerror(errno);
#else // aarch64
- user_hwdebug_state dreg_state;
- memset(&dreg_state, 0, sizeof dreg_state);
+ user_hwdebug_state dreg_state = {};
dreg_state.dbg_regs[0].addr = reinterpret_cast<uintptr_t>(address);
dreg_state.dbg_regs[0].ctrl = control;
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index 27943cf..0b7a7ff 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -47,8 +47,7 @@
ASSERT_NE(id, -1);
// Check semaphore info.
- semid_ds ds;
- memset(&ds, 0, sizeof(ds));
+ semid_ds ds = {};
ASSERT_EQ(0, semctl(id, 0, IPC_STAT, &ds));
ASSERT_EQ(1U, ds.sem_nsems);
diff --git a/tests/sys_shm_test.cpp b/tests/sys_shm_test.cpp
index 65f9eba..74d13b5 100644
--- a/tests/sys_shm_test.cpp
+++ b/tests/sys_shm_test.cpp
@@ -44,8 +44,7 @@
ASSERT_NE(id, -1);
// Check segment info.
- shmid_ds ds;
- memset(&ds, 0, sizeof(ds));
+ shmid_ds ds = {};
ASSERT_EQ(0, shmctl(id, IPC_STAT, &ds));
ASSERT_EQ(1234U, ds.shm_segsz);
diff --git a/tests/sys_socket_test.cpp b/tests/sys_socket_test.cpp
index 1cfbfb2..559ee7d 100644
--- a/tests/sys_socket_test.cpp
+++ b/tests/sys_socket_test.cpp
@@ -42,10 +42,7 @@
return reinterpret_cast<void*>(-1);
}
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- addr.sun_path[0] = '\0';
+ struct sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path[0] = '\0'};
strcpy(addr.sun_path + 1, pdata->sock_path);
if (connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) {
@@ -66,10 +63,7 @@
int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
ASSERT_NE(fd, -1) << strerror(errno);
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- addr.sun_path[0] = '\0';
+ struct sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path[0] = '\0'};
strcpy(addr.sun_path + 1, sock_path);
ASSERT_NE(-1, bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))) << strerror(errno);
@@ -141,9 +135,7 @@
int fd_acc = accept(fd, reinterpret_cast<struct sockaddr*>(addr), &len);
ASSERT_NE(fd_acc, -1) << strerror(errno);
- struct mmsghdr msgs[NUM_RECV_MSGS];
- memset(msgs, 0, sizeof(struct mmsghdr)*NUM_RECV_MSGS);
-
+ struct mmsghdr msgs[NUM_RECV_MSGS] = {};
struct iovec io[NUM_RECV_MSGS];
char bufs[NUM_RECV_MSGS][100];
for (size_t i = 0; i < NUM_RECV_MSGS; i++) {
@@ -155,10 +147,7 @@
msgs[i].msg_len = sizeof(struct msghdr);
}
- struct timespec ts;
- memset(&ts, 0, sizeof(ts));
- ts.tv_sec = 5;
- ts.tv_nsec = 0;
+ struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
ASSERT_EQ(NUM_RECV_MSGS,
static_cast<size_t>(recvmmsg(fd_acc, msgs, NUM_RECV_MSGS, 0, &ts)))
<< strerror(errno);
@@ -189,8 +178,7 @@
#define NUM_SEND_MSGS (sizeof(g_SendMsgs)/sizeof(const char*))
static bool SendMMsg(int fd) {
- struct mmsghdr msgs[NUM_SEND_MSGS];
- memset(msgs, 0, sizeof(struct mmsghdr)*NUM_SEND_MSGS);
+ struct mmsghdr msgs[NUM_SEND_MSGS] = {};
struct iovec io[NUM_SEND_MSGS];
for (size_t i = 0; i < NUM_SEND_MSGS; i++) {
io[i].iov_base = reinterpret_cast<void*>(const_cast<char*>(g_SendMsgs[i]));
diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp
index 126f469..50c50df 100644
--- a/tests/sys_stat_test.cpp
+++ b/tests/sys_stat_test.cpp
@@ -151,12 +151,12 @@
ASSERT_ERRNO(EINVAL);
}
-TEST(sys_stat, fchmodat_nonexistant_file) {
+TEST(sys_stat, fchmodat_nonexistent_file) {
ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, 0));
ASSERT_ERRNO(ENOENT);
}
-TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_nonexistant_file) {
+TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_nonexistent_file) {
ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, AT_SYMLINK_NOFOLLOW));
#if defined(__BIONIC__)
ASSERT_ERRNO(ENOENT);
@@ -305,7 +305,7 @@
ASSERT_EQ(0, faccessat(AT_FDCWD, "/dev/null", R_OK|W_OK, 0));
}
-TEST(sys_stat, faccessat_nonexistant) {
+TEST(sys_stat, faccessat_nonexistent) {
ASSERT_EQ(-1, faccessat(AT_FDCWD, "/blah", F_OK, AT_SYMLINK_NOFOLLOW));
#if defined(__BIONIC__)
// Android doesn't support AT_SYMLINK_NOFOLLOW
@@ -314,3 +314,26 @@
ASSERT_ERRNO(ENOENT);
#endif
}
+
+TEST(sys_stat, lchmod) {
+ TemporaryFile tf;
+ struct stat tf_sb;
+ ASSERT_EQ(0, stat(tf.path, &tf_sb));
+
+ char linkname[255];
+ snprintf(linkname, sizeof(linkname), "%s.link", tf.path);
+
+ ASSERT_EQ(0, symlink(tf.path, linkname));
+ int result = lchmod(linkname, 0751);
+ // Whether or not chmod is allowed on a symlink depends on the kernel.
+ if (result == 0) {
+ AssertSymlinkModeEquals(0751, linkname);
+ } else {
+ ASSERT_EQ(-1, result);
+ ASSERT_ERRNO(ENOTSUP);
+ }
+
+ // The target file mode shouldn't be modified.
+ AssertFileModeEquals(tf_sb.st_mode, tf.path);
+ unlink(linkname);
+}
diff --git a/tests/sys_statvfs_test.cpp b/tests/sys_statvfs_test.cpp
index 5dd7b93..25256ff 100644
--- a/tests/sys_statvfs_test.cpp
+++ b/tests/sys_statvfs_test.cpp
@@ -25,7 +25,15 @@
#include <string>
template <typename StatVfsT> void Check(StatVfsT& sb) {
+#if defined(__x86_64__)
+ // On x86_64 based 16kb page size targets, the page size in userspace is simulated to 16kb but
+ // the underlying filesystem block size would remain unchanged, i.e., 4kb.
+ // For more info:
+ // https://source.android.com/docs/core/architecture/16kb-page-size/getting-started-cf-x86-64-pgagnostic
+ EXPECT_EQ(4096, static_cast<int>(sb.f_bsize));
+#else
EXPECT_EQ(getpagesize(), static_cast<int>(sb.f_bsize));
+#endif
EXPECT_EQ(0U, sb.f_bfree);
EXPECT_EQ(0U, sb.f_ffree);
EXPECT_EQ(255U, sb.f_namemax);
diff --git a/tests/sys_sysinfo_test.cpp b/tests/sys_sysinfo_test.cpp
index 69656ad..b8bcf92 100644
--- a/tests/sys_sysinfo_test.cpp
+++ b/tests/sys_sysinfo_test.cpp
@@ -39,8 +39,7 @@
}
TEST(sys_sysinfo, sysinfo) {
- struct sysinfo si;
- memset(&si, 0, sizeof(si));
+ struct sysinfo si = {};
ASSERT_EQ(0, sysinfo(&si));
ASSERT_GT(static_cast<long>(si.uptime), 10); // You're not running CTS within 10s of booting!
diff --git a/tests/sys_time_test.cpp b/tests/sys_time_test.cpp
index ff9271f..b0e52aa 100644
--- a/tests/sys_time_test.cpp
+++ b/tests/sys_time_test.cpp
@@ -23,6 +23,7 @@
#include <android-base/file.h>
+#include "private/bionic_time_conversions.h"
#include "utils.h"
// http://b/11383777
@@ -147,14 +148,6 @@
ASSERT_EQ(0, syscall(__NR_gettimeofday, &tv2, nullptr));
// What's the difference between the two?
- tv2.tv_sec -= tv1.tv_sec;
- tv2.tv_usec -= tv1.tv_usec;
- if (tv2.tv_usec < 0) {
- --tv2.tv_sec;
- tv2.tv_usec += 1000000;
- }
-
// To try to avoid flakiness we'll accept answers within 10,000us (0.01s).
- ASSERT_EQ(0, tv2.tv_sec);
- ASSERT_LT(tv2.tv_usec, 10'000);
+ ASSERT_LT(to_us(tv2) - to_us(tv1), 10'000);
}
diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp
index 44b73c9..627c1ee 100644
--- a/tests/sys_timex_test.cpp
+++ b/tests/sys_timex_test.cpp
@@ -21,15 +21,13 @@
#include <gtest/gtest.h>
TEST(sys_timex, adjtimex_smoke) {
- timex t;
- memset(&t, 0, sizeof(t));
+ timex t = {};
// adjtimex/clock_adjtime return the clock state on success, -1 on failure.
ASSERT_NE(-1, adjtimex(&t));
}
TEST(sys_timex, clock_adjtime_smoke) {
- timex t;
- memset(&t, 0, sizeof(t));
+ timex t = {};
// adjtimex/clock_adjtime return the clock state on success, -1 on failure.
ASSERT_NE(-1, clock_adjtime(CLOCK_REALTIME, &t));
}
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index e783190..90b6da9 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -27,7 +27,15 @@
#include "utils.h"
template <typename StatFsT> void Check(StatFsT& sb) {
+#if defined(__x86_64__)
+ // On x86_64 based 16kb page size targets, the page size in userspace is simulated to 16kb but
+ // the underlying filesystem block size would remain unchanged, i.e., 4kb.
+ // For more info:
+ // https://source.android.com/docs/core/architecture/16kb-page-size/getting-started-cf-x86-64-pgagnostic
+ EXPECT_EQ(4096, static_cast<int>(sb.f_bsize));
+#else
EXPECT_EQ(getpagesize(), static_cast<int>(sb.f_bsize));
+#endif
EXPECT_EQ(0U, sb.f_bfree);
EXPECT_EQ(0U, sb.f_ffree);
EXPECT_EQ(255, static_cast<int>(sb.f_namelen));
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index f11f509..5b5e009 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -33,10 +33,9 @@
#if defined(__BIONIC__)
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <stdlib.h>
-#include <sys/_system_properties.h>
#include <sys/mount.h>
+#include <sys/system_properties.h>
#include <system_properties/system_properties.h>
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index baafbf6..cf4de06 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -126,8 +126,7 @@
// tzcode used to have a bug where it didn't reinitialize some internal state.
// Choose a time where DST is set.
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
t.tm_year = 1980 - 1900;
t.tm_mon = 6;
t.tm_mday = 2;
@@ -136,7 +135,7 @@
tzset();
ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
- memset(&t, 0, sizeof(tm));
+ t = {};
t.tm_year = 1980 - 1900;
t.tm_mon = 6;
t.tm_mday = 2;
@@ -173,8 +172,7 @@
TEST(time, mktime_EOVERFLOW) {
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
// LP32 year range is 1901-2038, so this year is guaranteed not to overflow.
t.tm_year = 2016 - 1900;
@@ -212,8 +210,7 @@
TEST(time, mktime_invalid_tm_TZ_combination) {
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
t.tm_year = 2022 - 1900;
t.tm_mon = 11;
t.tm_mday = 31;
@@ -248,8 +245,7 @@
TEST(time, strftime) {
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
t.tm_year = 200;
t.tm_mon = 2;
t.tm_mday = 10;
@@ -270,8 +266,7 @@
TEST(time, strftime_second_before_epoch) {
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
t.tm_year = 1969 - 1900;
t.tm_mon = 11;
t.tm_mday = 31;
@@ -287,9 +282,7 @@
TEST(time, strftime_Z_null_tm_zone) {
// Netflix on Nexus Player wouldn't start (http://b/25170306).
- struct tm t;
- memset(&t, 0, sizeof(tm));
-
+ struct tm t = {};
char buf[64];
setenv("TZ", "America/Los_Angeles", 1);
@@ -409,8 +402,7 @@
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
+ struct tm t = {};
t.tm_year = 200;
t.tm_mon = 2;
t.tm_mday = 10;
@@ -427,15 +419,14 @@
TEST(time, strptime) {
setenv("TZ", "UTC", 1);
- struct tm t;
+ struct tm t = {};
char buf[64];
- memset(&t, 0, sizeof(t));
strptime("11:14", "%R", &t);
strftime(buf, sizeof(buf), "%H:%M", &t);
EXPECT_STREQ("11:14", buf);
- memset(&t, 0, sizeof(t));
+ t = {};
strptime("09:41:53", "%T", &t);
strftime(buf, sizeof(buf), "%H:%M:%S", &t);
EXPECT_STREQ("09:41:53", buf);
@@ -445,15 +436,14 @@
#if !defined(ANDROID_HOST_MUSL)
setenv("TZ", "UTC", 1);
- struct tm t;
+ struct tm t = {};
char buf[64];
- memset(&t, 0, sizeof(t));
strptime_l("11:14", "%R", &t, LC_GLOBAL_LOCALE);
strftime_l(buf, sizeof(buf), "%H:%M", &t, LC_GLOBAL_LOCALE);
EXPECT_STREQ("11:14", buf);
- memset(&t, 0, sizeof(t));
+ t = {};
strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
EXPECT_STREQ("09:41:53", buf);
@@ -637,8 +627,7 @@
}
TEST(time, timer_create) {
- sigevent se;
- memset(&se, 0, sizeof(se));
+ sigevent se = {};
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = NoOpNotifyFunction;
timer_t timer_id;
@@ -666,8 +655,7 @@
}
TEST(time, timer_create_SIGEV_SIGNAL) {
- sigevent se;
- memset(&se, 0, sizeof(se));
+ sigevent se = {};
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGUSR1;
@@ -705,10 +693,7 @@
public:
explicit Counter(void (*fn)(sigval)) : value(0), timer_valid(false) {
- memset(&se, 0, sizeof(se));
- se.sigev_notify = SIGEV_THREAD;
- se.sigev_notify_function = fn;
- se.sigev_value.sival_ptr = this;
+ se = {.sigev_notify = SIGEV_THREAD, .sigev_notify_function = fn, .sigev_value.sival_ptr = this};
Create();
}
void DeleteTimer() {
@@ -909,9 +894,7 @@
TEST(time, timer_delete_from_timer_thread) {
TimerDeleteData tdd;
- sigevent se;
-
- memset(&se, 0, sizeof(se));
+ sigevent se = {};
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = TimerDeleteCallback;
se.sigev_value.sival_ptr = &tdd;
@@ -1252,11 +1235,9 @@
strftime(buf, sizeof(buf), "<%s>", &tm0);
EXPECT_STREQ("<378691200>", buf);
- struct tm tm;
-
setenv("TZ", "America/Los_Angeles", 1);
tzset();
- memset(&tm, 0xff, sizeof(tm));
+ struct tm tm = {};
char* p = strptime("378720000x", "%s", &tm);
ASSERT_EQ('x', *p);
EXPECT_EQ(0, tm.tm_sec);
@@ -1271,7 +1252,7 @@
setenv("TZ", "UTC", 1);
tzset();
- memset(&tm, 0xff, sizeof(tm));
+ tm = {};
p = strptime("378691200x", "%s", &tm);
ASSERT_EQ('x', *p);
EXPECT_EQ(0, tm.tm_sec);
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index fd3b332..b554ee5 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -73,9 +73,8 @@
uselocale(LC_GLOBAL_LOCALE);
char out[MB_LEN_MAX];
- mbstate_t ps;
+ mbstate_t ps = {};
- memset(&ps, 0, sizeof(ps));
EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xc2", 1, &ps));
errno = 0;
EXPECT_EQ(static_cast<size_t>(-1), c32rtomb(out, 0x00a2, &ps));
@@ -86,12 +85,12 @@
// If the first argument to c32rtomb is nullptr or the second is L'\0' the shift
// state should be reset.
- memset(&ps, 0, sizeof(ps));
+ ps = {};
EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xc2", 1, &ps));
EXPECT_EQ(1U, c32rtomb(nullptr, 0x00a2, &ps));
EXPECT_TRUE(mbsinit(&ps));
- memset(&ps, 0, sizeof(ps));
+ ps = {};
EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xf0\xa4", 1, &ps));
EXPECT_EQ(1U, c32rtomb(out, L'\0', &ps));
EXPECT_TRUE(mbsinit(&ps));
@@ -299,8 +298,7 @@
ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
uselocale(LC_GLOBAL_LOCALE);
- mbstate_t ps;
- memset(&ps, 0, sizeof(ps));
+ mbstate_t ps = {};
test_mbrtoc16_incomplete(&ps);
test_mbrtoc16_incomplete(nullptr);
@@ -475,8 +473,7 @@
ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
uselocale(LC_GLOBAL_LOCALE);
- mbstate_t ps;
- memset(&ps, 0, sizeof(ps));
+ mbstate_t ps = {};
test_mbrtoc32_incomplete(&ps);
test_mbrtoc32_incomplete(nullptr);
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 78b55c1..3143c23 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include "DoNotOptimize.h"
#include "SignalUtils.h"
#include "utils.h"
@@ -1392,9 +1393,7 @@
}
TEST(UNISTD_TEST, setdomainname) {
- __user_cap_header_struct header;
- memset(&header, 0, sizeof(header));
- header.version = _LINUX_CAPABILITY_VERSION_3;
+ __user_cap_header_struct header = {.version = _LINUX_CAPABILITY_VERSION_3};
__user_cap_data_struct old_caps[_LINUX_CAPABILITY_U32S_3];
ASSERT_EQ(0, capget(&header, &old_caps[0]));
diff --git a/tests/utils.h b/tests/utils.h
index 3c83b73..4740e59 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -295,16 +295,6 @@
size_t start_count_ = CountOpenFds();
};
-// From <benchmark/benchmark.h>.
-template <class Tp>
-static inline void DoNotOptimize(Tp const& value) {
- asm volatile("" : : "r,m"(value) : "memory");
-}
-template <class Tp>
-static inline void DoNotOptimize(Tp& value) {
- asm volatile("" : "+r,m"(value) : : "memory");
-}
-
static inline bool running_with_mte() {
#ifdef __aarch64__
int level = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 387d23b..ba2a4d8 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -130,22 +130,21 @@
uselocale(LC_GLOBAL_LOCALE);
char out[MB_LEN_MAX];
- mbstate_t ps;
+ mbstate_t ps = {};
// Any non-initial state is invalid when calling wcrtomb.
- memset(&ps, 0, sizeof(ps));
EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(out, 0x00a2, &ps));
EXPECT_ERRNO(EILSEQ);
// If the first argument to wcrtomb is NULL or the second is L'\0' the shift
// state should be reset.
- memset(&ps, 0, sizeof(ps));
+ ps = {};
EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
EXPECT_EQ(1U, wcrtomb(nullptr, 0x00a2, &ps));
EXPECT_TRUE(mbsinit(&ps));
- memset(&ps, 0, sizeof(ps));
+ ps = {};
EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xf0\xa4", 1, &ps));
EXPECT_EQ(1U, wcrtomb(out, L'\0', &ps));
EXPECT_TRUE(mbsinit(&ps));
@@ -253,9 +252,8 @@
EXPECT_STREQ("hix", bytes);
// Any non-initial state is invalid when calling wcsrtombs.
- mbstate_t ps;
+ mbstate_t ps = {};
src = chars;
- memset(&ps, 0, sizeof(ps));
ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(nullptr, &src, 0, &ps));
EXPECT_ERRNO(EILSEQ);
@@ -449,8 +447,7 @@
}
TEST(wchar, mbrtowc_incomplete) {
- mbstate_t ps;
- memset(&ps, 0, sizeof(ps));
+ mbstate_t ps = {};
test_mbrtowc_incomplete(&ps);
test_mbrtowc_incomplete(nullptr);
@@ -508,8 +505,7 @@
ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
uselocale(LC_GLOBAL_LOCALE);
- mbstate_t ps;
- memset(&ps, 0, sizeof(ps));
+ mbstate_t ps = {};
test_mbsrtowcs(&ps);
test_mbsrtowcs(nullptr);
@@ -556,7 +552,7 @@
} else {
// If the subject sequence begins with a <hyphen-minus>, the value resulting
// from the conversion shall be negated.
- // http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html
+ // https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/strtoul.html
ASSERT_EQ(std::numeric_limits<T>::max(), fn(min_str, nullptr, 0)) << min_str;
}
ASSERT_EQ(std::numeric_limits<T>::max(), fn(max_str, nullptr, 0)) << max_str;
@@ -659,12 +655,7 @@
TEST(wchar, wcsftime__wcsftime_l) {
setenv("TZ", "UTC", 1);
- struct tm t;
- memset(&t, 0, sizeof(tm));
- t.tm_year = 200;
- t.tm_mon = 2;
- t.tm_mday = 10;
-
+ struct tm t = {.tm_year = 200, .tm_mon = 2, .tm_mday = 10};
wchar_t buf[64];
EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));
diff --git a/tests/wctype_test.cpp b/tests/wctype_test.cpp
index 38d26ca..f4b7a8f 100644
--- a/tests/wctype_test.cpp
+++ b/tests/wctype_test.cpp
@@ -226,34 +226,64 @@
EXPECT_EQ(0, iswctype_l(WEOF, wctype_l("alnum", l.l), l.l));
}
-TEST(wctype, towctrans) {
+TEST(wctype, wctrans) {
EXPECT_TRUE(wctrans("tolower") != nullptr);
EXPECT_TRUE(wctrans("toupper") != nullptr);
+ errno = 0;
EXPECT_TRUE(wctrans("monkeys") == nullptr);
-}
-
-TEST(wctype, towctrans_l) {
- UtfLocale l;
- EXPECT_TRUE(wctrans_l("tolower", l.l) != nullptr);
- EXPECT_TRUE(wctrans_l("toupper", l.l) != nullptr);
-
- EXPECT_TRUE(wctrans_l("monkeys", l.l) == nullptr);
-}
-
-TEST(wctype, wctrans) {
- EXPECT_EQ(wint_t('a'), towctrans(L'A', wctrans("tolower")));
- EXPECT_EQ(WEOF, towctrans(WEOF, wctrans("tolower")));
-
- EXPECT_EQ(wint_t('A'), towctrans(L'a', wctrans("toupper")));
- EXPECT_EQ(WEOF, towctrans(WEOF, wctrans("toupper")));
+ #if defined(__BIONIC__)
+ // Android/FreeBSD/iOS set errno, but musl/glibc don't.
+ EXPECT_ERRNO(EINVAL);
+ #endif
}
TEST(wctype, wctrans_l) {
UtfLocale l;
- EXPECT_EQ(wint_t('a'), towctrans_l(L'A', wctrans_l("tolower", l.l), l.l));
- EXPECT_EQ(WEOF, towctrans_l(WEOF, wctrans_l("tolower", l.l), l.l));
+ EXPECT_TRUE(wctrans_l("tolower", l.l) != nullptr);
+ EXPECT_TRUE(wctrans_l("toupper", l.l) != nullptr);
- EXPECT_EQ(wint_t('A'), towctrans_l(L'a', wctrans_l("toupper", l.l), l.l));
- EXPECT_EQ(WEOF, towctrans_l(WEOF, wctrans_l("toupper", l.l), l.l));
+ errno = 0;
+ EXPECT_TRUE(wctrans_l("monkeys", l.l) == nullptr);
+ #if defined(__BIONIC__)
+ // Android/FreeBSD/iOS set errno, but musl/glibc don't.
+ EXPECT_ERRNO(EINVAL);
+ #endif
+}
+
+TEST(wctype, towctrans) {
+ wctrans_t lower = wctrans("tolower");
+ EXPECT_EQ(wint_t('a'), towctrans(L'A', lower));
+ EXPECT_EQ(WEOF, towctrans(WEOF, lower));
+
+ wctrans_t upper = wctrans("toupper");
+ EXPECT_EQ(wint_t('A'), towctrans(L'a', upper));
+ EXPECT_EQ(WEOF, towctrans(WEOF, upper));
+
+ wctrans_t invalid = wctrans("monkeys");
+ errno = 0;
+ EXPECT_EQ(wint_t('a'), towctrans(L'a', invalid));
+ #if defined(__BIONIC__)
+ // Android/FreeBSD/iOS set errno, but musl/glibc don't.
+ EXPECT_ERRNO(EINVAL);
+ #endif
+}
+
+TEST(wctype, towctrans_l) {
+ UtfLocale l;
+ wctrans_t lower = wctrans_l("tolower", l.l);
+ EXPECT_EQ(wint_t('a'), towctrans_l(L'A', lower, l.l));
+ EXPECT_EQ(WEOF, towctrans_l(WEOF, lower, l.l));
+
+ wctrans_t upper = wctrans_l("toupper", l.l);
+ EXPECT_EQ(wint_t('A'), towctrans_l(L'a', upper, l.l));
+ EXPECT_EQ(WEOF, towctrans_l(WEOF, upper, l.l));
+
+ wctrans_t invalid = wctrans_l("monkeys", l.l);
+ errno = 0;
+ EXPECT_EQ(wint_t('a'), towctrans_l(L'a', invalid, l.l));
+ #if defined(__BIONIC__)
+ // Android/FreeBSD/iOS set errno, but musl/glibc don't.
+ EXPECT_ERRNO(EINVAL);
+ #endif
}
diff --git a/tools/NOTICE b/tools/NOTICE
index a4ec954..e69de29 100644
--- a/tools/NOTICE
+++ b/tools/NOTICE
@@ -1,32 +0,0 @@
-Copyright (C) 2016 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2018 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
diff --git a/tools/versioner/Android.bp b/tools/versioner/Android.bp
deleted file mode 100644
index cc4dbfa..0000000
--- a/tools/versioner/Android.bp
+++ /dev/null
@@ -1,7 +0,0 @@
-package {
- default_applicable_licenses: ["bionic_tools_license"],
-}
-
-subdirs = [
- "src",
-]
diff --git a/tools/versioner/README.md b/tools/versioner/README.md
deleted file mode 100644
index edb32be..0000000
--- a/tools/versioner/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-## versioner
-Use clang to verify the correctness of bionic's availability attributes against the NDK platform definitions.
-
-#### Build
-Build with `LLVM_BUILD_HOST_TOOLS=true mma -j48`
-
-#### Use
-`versioner -p platforms current dependencies`
diff --git a/tools/versioner/current b/tools/versioner/current
deleted file mode 120000
index 234dfe7..0000000
--- a/tools/versioner/current
+++ /dev/null
@@ -1 +0,0 @@
-../../libc/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies b/tools/versioner/dependencies
deleted file mode 120000
index 4ec3391..0000000
--- a/tools/versioner/dependencies
+++ /dev/null
@@ -1 +0,0 @@
-../../libc/versioner-dependencies
\ No newline at end of file
diff --git a/tools/versioner/platforms/crtbegin.map.txt b/tools/versioner/platforms/crtbegin.map.txt
deleted file mode 100644
index b844c1e..0000000
--- a/tools/versioner/platforms/crtbegin.map.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file lists the libc functions are included in `crtbegin.o` and not
-# exported by `libc.so`.
-
-CRTBEGIN {
- global:
- atexit; # arm64 x86 x86_64
-};
diff --git a/tools/versioner/platforms/libc.map.txt b/tools/versioner/platforms/libc.map.txt
deleted file mode 120000
index 8527b2e..0000000
--- a/tools/versioner/platforms/libc.map.txt
+++ /dev/null
@@ -1 +0,0 @@
-../../../libc/libc.map.txt
\ No newline at end of file
diff --git a/tools/versioner/run_tests.py b/tools/versioner/run_tests.py
deleted file mode 100755
index 396f895..0000000
--- a/tools/versioner/run_tests.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import subprocess
-import sys
-
-red = '\033[91m'
-green = '\033[92m'
-bold = '\033[1m'
-reset = '\033[0m'
-prefix_pass = bold + "[" + green + "PASS" + reset + bold + "]" + reset
-prefix_fail = bold + "[" + red + "FAIL" + reset + bold + "]" + reset
-
-
-def indent(text, spaces=4):
- text = text.decode("utf-8")
- prefix = " "
- return "\n".join([prefix + line for line in text.split("\n")])
-
-
-def run_test(test_name, path):
- os.chdir(path)
- process = subprocess.Popen(
- ["/bin/sh", "run.sh"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- (output, _) = process.communicate()
-
- if os.path.exists("expected_fail"):
- with open("expected_fail", "rb") as f:
- expected_output = f.read()
- if process.returncode == 0:
- print("{} {}: unexpected success:".format(prefix_fail, test_name))
- print("")
- print(" Expected:")
- print(indent(expected_output))
- print(" Actual:")
- print(indent(output))
- return False
- elif not output.endswith(expected_output):
- print("{} {}: expected output mismatch".format(
- prefix_fail, test_name))
- print("")
- print(" Expected:")
- print(indent(expected_output))
- print(" Actual:")
- print(indent(output))
- return False
- elif process.returncode != 0:
- print("{} {}: unexpected failure:".format(prefix_fail, test_name))
- print("")
- print(indent(output))
- return False
-
- print("{} {}".format(prefix_pass, test_name))
- return True
-
-
-def usage():
- print("Usage: run_tests.py [-f]")
- print(" -f\t\tdon't run slow tests")
- sys.exit(0)
-
-
-root_dir = os.path.dirname(os.path.realpath(__file__))
-test_dir = os.path.join(root_dir, "tests")
-tests = os.listdir(test_dir)
-run_slow = True
-
-if len(sys.argv) > 2:
- usage()
-elif len(sys.argv) == 2:
- if sys.argv[1] != "-f":
- usage()
- run_slow = False
-
-success = True
-for test in sorted(tests):
- if test.startswith("slow") and not run_slow:
- continue
- path = os.path.join(test_dir, test)
- if not os.path.isdir(path):
- continue
- if not run_test(test, path):
- success = False
-
-sys.exit(0 if success else 1)
diff --git a/tools/versioner/src/Android.bp b/tools/versioner/src/Android.bp
deleted file mode 100644
index 6551e77..0000000
--- a/tools/versioner/src/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-package {
- default_applicable_licenses: ["bionic_tools_license"],
-}
-
-cc_binary_host {
- name: "versioner",
-
- defaults: ["llvm-build-host-tools-defaults"],
-
- srcs: [
- "versioner.cpp",
- "Arch.cpp",
- "CompilationType.cpp",
- "DeclarationDatabase.cpp",
- "Driver.cpp",
- "Preprocessor.cpp",
- "SymbolDatabase.cpp",
- "SymbolFileParser.cpp",
- "Utils.cpp",
- "VFS.cpp",
- ],
-
- shared_libs: [
- "libclang-cpp_host",
- "libbase",
- ],
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wno-unused-parameter",
- "-fno-omit-frame-pointer",
- ],
-
- target: {
- host: {
- cppflags: [
- "-fno-rtti",
- ],
- },
- windows: {
- enabled: false,
- },
- },
-}
diff --git a/tools/versioner/src/Arch.cpp b/tools/versioner/src/Arch.cpp
deleted file mode 100644
index d4d0208..0000000
--- a/tools/versioner/src/Arch.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Arch.h"
-
-#include <err.h>
-
-#include <string>
-
-std::string to_string(const Arch& arch) {
- switch (arch) {
- case Arch::arm:
- return "arm";
-
- case Arch::arm64:
- return "arm64";
-
- case Arch::riscv64:
- return "riscv64";
-
- case Arch::x86:
- return "x86";
-
- case Arch::x86_64:
- return "x86_64";
- }
-
- errx(1, "unknown arch '%zu'", size_t(arch));
-}
-
-static const std::unordered_map<std::string, Arch> arch_name_map{
- {"arm", Arch::arm},
- {"arm64", Arch::arm64},
- {"riscv64", Arch::riscv64},
- {"x86", Arch::x86},
- {"x86_64", Arch::x86_64},
-};
-
-std::optional<Arch> arch_from_string(const std::string& name) {
- auto it = arch_name_map.find(name);
- if (it == arch_name_map.end()) {
- return std::nullopt;
- }
- return std::make_optional(it->second);
-}
diff --git a/tools/versioner/src/Arch.h b/tools/versioner/src/Arch.h
deleted file mode 100644
index fd98abc..0000000
--- a/tools/versioner/src/Arch.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdlib.h>
-
-#include <array>
-#include <initializer_list>
-#include <optional>
-#include <set>
-#include <string>
-#include <unordered_map>
-
-enum class Arch : size_t {
- arm = 0,
- arm64,
- riscv64,
- x86,
- x86_64,
-};
-
-std::string to_string(const Arch& arch);
-std::optional<Arch> arch_from_string(const std::string& name);
-
-template <typename T>
-class ArchMapIterator;
-
-template <typename T>
-class ArchMap {
- public:
- ArchMap() {
- }
-
- ArchMap(std::initializer_list<std::pair<Arch, T>> initializer) {
- for (auto& pair : initializer) {
- this->operator[](pair.first) = pair.second;
- }
- }
-
- T& operator[](Arch arch) {
- return data_[size_t(arch)];
- }
-
- const T& operator[](Arch arch) const {
- return data_[size_t(arch)];
- }
-
- bool operator==(const ArchMap& other) const {
- for (size_t i = 0; i < data_.size(); ++i) {
- if (data_[i] != other.data_[i]) {
- return false;
- }
- }
- return true;
- }
-
- ArchMapIterator<T> begin() const {
- return ArchMapIterator<T>(*this, Arch::arm);
- }
-
- ArchMapIterator<T> end() const {
- return ArchMapIterator<T>(*this, Arch(size_t(Arch::x86_64) + 1));
- }
-
- private:
- std::array<T, size_t(Arch::x86_64) + 1> data_ = {};
-};
-
-template <typename T>
-class ArchMapIterator {
- const ArchMap<T>& map_;
- Arch arch_ = Arch::arm;
-
- public:
- ArchMapIterator() = delete;
-
- ArchMapIterator(const ArchMap<T>& map, Arch arch) : map_(map), arch_(arch) {
- }
-
- bool operator==(const ArchMapIterator<T>& rhs) const {
- return map_ == rhs.map_ && arch_ == rhs.arch_;
- }
-
- bool operator!=(const ArchMapIterator<T>& rhs) const {
- return !(*this == rhs);
- }
-
- ArchMapIterator& operator++() {
- arch_ = Arch(size_t(arch_) + 1);
- return *this;
- }
-
- ArchMapIterator operator++(int) {
- ArchMapIterator result = *this;
- ++*this;
- return result;
- }
-
- std::pair<const Arch&, const T&> operator*() const {
- return std::tie(arch_, map_[arch_]);
- }
-
- std::pair<const Arch&, const T&> operator->() const {
- return std::tie(arch_, map_[arch_]);
- }
-};
-
-static const std::set<Arch> supported_archs = {
- Arch::arm,
- Arch::arm64,
- Arch::riscv64,
- Arch::x86,
- Arch::x86_64,
-};
-
-static ArchMap<std::string> arch_targets = {
- { Arch::arm, "arm-linux-androideabi" },
- { Arch::arm64, "aarch64-linux-android" },
- { Arch::riscv64, "riscv64-linux-android" },
- { Arch::x86, "i686-linux-android" },
- { Arch::x86_64, "x86_64-linux-android" },
-};
-
-static const std::set<int> default_levels = {
- 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34,
-};
-
-static const ArchMap<int> arch_min_api = {
- { Arch::arm, 9 },
- { Arch::arm64, 21 },
- { Arch::riscv64, 10000 },
- { Arch::x86, 9 },
- { Arch::x86_64, 21 },
-};
-
-static const std::unordered_map<std::string, int> api_codename_map{
- {"G", 9},
- {"I", 14},
- {"J", 16},
- {"J-MR1", 17},
- {"J-MR2", 18},
- {"K", 19},
- {"L", 21},
- {"L-MR1", 22},
- {"M", 23},
- {"N", 24},
- {"N-MR1", 25},
- {"O", 26},
- {"O-MR1", 27},
- {"P", 28},
- {"Q", 29},
- {"R", 30},
- {"S", 31},
- {"T", 33},
- {"U", 34},
-};
diff --git a/tools/versioner/src/CompilationType.cpp b/tools/versioner/src/CompilationType.cpp
deleted file mode 100644
index 7e7bb5d..0000000
--- a/tools/versioner/src/CompilationType.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "CompilationType.h"
-
-#include <sstream>
-#include <string>
-
-std::string to_string(const CompilationType& type) {
- std::stringstream ss;
- ss << to_string(type.arch) << "-" << type.api_level << " [" << (type.cpp ? "c++" : "c")
- << ", fob = " << type.file_offset_bits << "]";
- return ss.str();
-}
diff --git a/tools/versioner/src/CompilationType.h b/tools/versioner/src/CompilationType.h
deleted file mode 100644
index 2f4cf5c..0000000
--- a/tools/versioner/src/CompilationType.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include <functional>
-#include <utility>
-
-#include "Arch.h"
-
-struct CompilationType {
- Arch arch;
- bool cpp;
- int api_level;
- int file_offset_bits;
-
- private:
- auto tie() const {
- return std::tie(arch, cpp, api_level, file_offset_bits);
- }
-
- public:
- bool operator<(const CompilationType& other) const {
- return tie() < other.tie();
- }
-
- bool operator==(const CompilationType& other) const {
- return tie() == other.tie();
- }
-};
-
-namespace std {
-template <>
-struct hash<CompilationType> {
- size_t operator()(CompilationType type) const {
- struct {
- int32_t arch : 3;
- int32_t cpp : 1;
- int32_t api_level : 6;
- int32_t file_offset_bits : 1;
- int32_t padding : 21;
- } packed;
- packed.arch = static_cast<int32_t>(type.arch);
- packed.cpp = type.cpp;
- packed.api_level = type.api_level;
- packed.file_offset_bits = (type.file_offset_bits == 64);
- packed.padding = 0;
- int32_t value;
- memcpy(&value, &packed, sizeof(value));
- return std::hash<int32_t>()(value);
- }
-};
-}
-
-std::string to_string(const CompilationType& type);
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
deleted file mode 100644
index 9794286..0000000
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "DeclarationDatabase.h"
-
-#include <err.h>
-
-#include <iostream>
-#include <map>
-#include <mutex>
-#include <set>
-#include <sstream>
-#include <string>
-#include <utility>
-
-#include <clang/AST/AST.h>
-#include <clang/AST/Attr.h>
-#include <clang/AST/Mangle.h>
-#include <clang/AST/RecursiveASTVisitor.h>
-#include <clang/Frontend/ASTUnit.h>
-#include <llvm/Support/raw_ostream.h>
-
-using namespace clang;
-
-static bool shouldMangle(MangleContext* mangler, NamedDecl* decl) {
- // Passing a decl with static linkage to the mangler gives incorrect results.
- // Check some things ourselves before handing it off to the mangler.
- if (auto FD = dyn_cast<FunctionDecl>(decl)) {
- if (FD->isExternC()) {
- return false;
- }
-
- if (FD->isInExternCContext()) {
- return false;
- }
- }
-
- return mangler->shouldMangleDeclName(decl);
-}
-
-class Visitor : public RecursiveASTVisitor<Visitor> {
- HeaderDatabase& database;
- CompilationType type;
- SourceManager& src_manager;
- std::unique_ptr<MangleContext> mangler;
-
- public:
- Visitor(HeaderDatabase& database, CompilationType type, ASTContext& ctx)
- : database(database), type(type), src_manager(ctx.getSourceManager()) {
- mangler.reset(ItaniumMangleContext::create(ctx, ctx.getDiagnostics()));
- }
-
- std::string getDeclName(NamedDecl* decl) {
- if (auto var_decl = dyn_cast<VarDecl>(decl)) {
- if (!var_decl->isFileVarDecl()) {
- return "<local var>";
- }
- }
-
- // <math.h> maps fool onto foo on 32-bit, since long double is the same as double.
- if (auto asm_attr = decl->getAttr<AsmLabelAttr>()) {
- return asm_attr->getLabel().str();
- }
-
- // The decl might not have a name (e.g. bitfields).
- if (auto identifier = decl->getIdentifier()) {
- if (shouldMangle(mangler.get(), decl)) {
- std::string mangled;
- llvm::raw_string_ostream ss(mangled);
- mangler->mangleName(decl, ss);
- return mangled;
- }
-
- return identifier->getName().str();
- }
-
- return "<unnamed>";
- }
-
- bool VisitDeclaratorDecl(DeclaratorDecl* decl, SourceRange range) {
- // Skip declarations inside of functions (function arguments, variable declarations inside of
- // inline functions, etc).
- if (decl->getParentFunctionOrMethod()) {
- return true;
- }
-
- auto named_decl = dyn_cast<NamedDecl>(decl);
- if (!named_decl) {
- return true;
- }
-
- std::string declaration_name = getDeclName(named_decl);
- bool is_extern = named_decl->getFormalLinkage() == Linkage::External;
- bool is_definition = false;
- bool no_guard = false;
- bool fortify_inline = false;
-
- if (auto function_decl = dyn_cast<FunctionDecl>(decl)) {
- is_definition = function_decl->isThisDeclarationADefinition();
- } else if (auto var_decl = dyn_cast<VarDecl>(decl)) {
- if (!var_decl->isFileVarDecl()) {
- return true;
- }
-
- switch (var_decl->isThisDeclarationADefinition()) {
- case VarDecl::DeclarationOnly:
- is_definition = false;
- break;
-
- case VarDecl::Definition:
- is_definition = true;
- break;
-
- case VarDecl::TentativeDefinition:
- // Forbid tentative definitions in headers.
- fprintf(stderr, "ERROR: declaration '%s' is a tentative definition\n",
- declaration_name.c_str());
- decl->dump();
- abort();
- }
- } else {
- // We only care about function and variable declarations.
- return true;
- }
-
- if (decl->hasAttr<UnavailableAttr>()) {
- // Skip declarations that exist only for compile-time diagnostics.
- return true;
- }
-
- DeclarationAvailability availability;
-
- // Find and parse __ANDROID_AVAILABILITY_DUMP__ annotations.
- for (const AnnotateAttr* attr : decl->specific_attrs<AnnotateAttr>()) {
- llvm::StringRef annotation = attr->getAnnotation();
- if (annotation == "versioner_no_guard") {
- no_guard = true;
- } else if (annotation == "versioner_fortify_inline") {
- fortify_inline = true;
- } else {
- llvm::SmallVector<llvm::StringRef, 2> fragments;
- annotation.split(fragments, "=");
- if (fragments.size() != 2) {
- continue;
- }
-
- auto& global_availability = availability.global_availability;
- auto& arch_availability = availability.arch_availability;
- std::map<std::string, std::vector<int*>> prefix_map = {
- { "introduced_in", { &global_availability.introduced } },
- { "deprecated_in", { &global_availability.deprecated } },
- { "obsoleted_in", { &global_availability.obsoleted } },
- { "introduced_in_arm", { &arch_availability[Arch::arm].introduced } },
- { "introduced_in_x86", { &arch_availability[Arch::x86].introduced } },
- { "introduced_in_32",
- { &arch_availability[Arch::arm].introduced,
- &arch_availability[Arch::x86].introduced } },
- { "introduced_in_64",
- { &arch_availability[Arch::arm64].introduced,
- &arch_availability[Arch::riscv64].introduced,
- &arch_availability[Arch::x86_64].introduced } },
- };
-
- if (auto it = prefix_map.find(fragments[0].str()); it != prefix_map.end()) {
- int value;
- if (fragments[1].getAsInteger(10, value)) {
- errx(1, "invalid __ANDROID_AVAILABILITY_DUMP__ annotation: '%s'",
- annotation.str().c_str());
- }
-
- for (int* ptr : it->second) {
- *ptr = value;
- }
- }
- }
- }
-
- auto symbol_it = database.symbols.find(declaration_name);
- if (symbol_it == database.symbols.end()) {
- Symbol symbol = {.name = declaration_name };
- bool unused;
- std::tie(symbol_it, unused) = database.symbols.insert({declaration_name, symbol});
- }
-
- auto expansion_range = src_manager.getExpansionRange(range);
- auto filename = src_manager.getFilename(expansion_range.getBegin());
- if (filename != src_manager.getFilename(expansion_range.getEnd())) {
- errx(1, "expansion range filenames don't match");
- }
-
- Location location = {
- .filename = filename.str(),
- .start = {
- .line = src_manager.getExpansionLineNumber(expansion_range.getBegin()),
- .column = src_manager.getExpansionColumnNumber(expansion_range.getBegin()),
- },
- .end = {
- .line = src_manager.getExpansionLineNumber(expansion_range.getEnd()),
- .column = src_manager.getExpansionColumnNumber(expansion_range.getEnd()),
- }
- };
-
- // Find or insert an entry for the declaration.
- if (auto declaration_it = symbol_it->second.declarations.find(location);
- declaration_it != symbol_it->second.declarations.end()) {
- if (declaration_it->second.is_extern != is_extern ||
- declaration_it->second.is_definition != is_definition ||
- declaration_it->second.no_guard != no_guard ||
- declaration_it->second.fortify_inline != fortify_inline) {
- errx(1, "varying declaration of '%s' at %s:%u:%u", declaration_name.c_str(),
- location.filename.c_str(), location.start.line, location.start.column);
- }
- declaration_it->second.availability.insert(std::make_pair(type, availability));
- } else {
- Declaration declaration;
- declaration.name = declaration_name;
- declaration.location = location;
- declaration.is_extern = is_extern;
- declaration.is_definition = is_definition;
- declaration.no_guard = no_guard;
- declaration.fortify_inline = fortify_inline;
- declaration.availability.insert(std::make_pair(type, availability));
- symbol_it->second.declarations.insert(std::make_pair(location, declaration));
- }
-
- return true;
- }
-
- bool VisitDeclaratorDecl(DeclaratorDecl* decl) {
- return VisitDeclaratorDecl(decl, decl->getSourceRange());
- }
-
- bool TraverseLinkageSpecDecl(LinkageSpecDecl* decl) {
- // Make sure that we correctly calculate the SourceRange of a declaration that has a non-braced
- // extern "C"/"C++".
- if (!decl->hasBraces()) {
- DeclaratorDecl* child = nullptr;
- for (auto child_decl : decl->decls()) {
- if (child != nullptr) {
- errx(1, "LinkageSpecDecl has multiple children");
- }
-
- if (DeclaratorDecl* declarator_decl = dyn_cast<DeclaratorDecl>(child_decl)) {
- child = declarator_decl;
- } else {
- errx(1, "child of LinkageSpecDecl is not a DeclaratorDecl");
- }
- }
-
- return VisitDeclaratorDecl(child, decl->getSourceRange());
- }
-
- for (auto child : decl->decls()) {
- if (!TraverseDecl(child)) {
- return false;
- }
- }
- return true;
- }
-};
-
-bool DeclarationAvailability::merge(const DeclarationAvailability& other) {
-#define check_avail(expr) error |= (!this->expr.empty() && this->expr != other.expr);
- bool error = false;
-
- if (!other.global_availability.empty()) {
- check_avail(global_availability);
- this->global_availability = other.global_availability;
- }
-
- for (Arch arch : supported_archs) {
- if (!other.arch_availability[arch].empty()) {
- check_avail(arch_availability[arch]);
- this->arch_availability[arch] = other.arch_availability[arch];
- }
- }
-#undef check_avail
-
- return !error;
-}
-
-bool Declaration::calculateAvailability(DeclarationAvailability* output) const {
- DeclarationAvailability avail;
- for (const auto& it : this->availability) {
- if (!avail.merge(it.second)) {
- return false;
- }
- }
- *output = avail;
- return true;
-}
-
-bool Symbol::calculateAvailability(DeclarationAvailability* output) const {
- DeclarationAvailability avail;
- for (const auto& it : this->declarations) {
- // Don't merge availability for inline functions (because they shouldn't have any).
- if (it.second.is_definition) {
- continue;
- }
-
- DeclarationAvailability decl_availability;
- if (!it.second.calculateAvailability(&decl_availability)) {
- return false;
- abort();
- }
-
- if (!avail.merge(decl_availability)) {
- return false;
- }
- }
- *output = avail;
- return true;
-}
-
-bool Symbol::hasDeclaration(const CompilationType& type) const {
- for (const auto& decl_it : this->declarations) {
- for (const auto& compilation_it : decl_it.second.availability) {
- if (compilation_it.first == type) {
- return true;
- }
- }
- }
- return false;
-}
-
-void HeaderDatabase::parseAST(CompilationType type, ASTContext& ctx) {
- std::unique_lock<std::mutex> lock(this->mutex);
- Visitor visitor(*this, type, ctx);
- visitor.TraverseDecl(ctx.getTranslationUnitDecl());
-}
-
-std::string to_string(const AvailabilityValues& av) {
- std::stringstream ss;
-
- if (av.introduced != 0) {
- ss << "introduced = " << av.introduced << ", ";
- }
-
- if (av.deprecated != 0) {
- ss << "deprecated = " << av.deprecated << ", ";
- }
-
- if (av.obsoleted != 0) {
- ss << "obsoleted = " << av.obsoleted << ", ";
- }
-
- std::string result = ss.str();
- if (!result.empty()) {
- result = result.substr(0, result.length() - 2);
- }
- return result;
-}
-
-std::string to_string(const DeclarationType& type) {
- switch (type) {
- case DeclarationType::function:
- return "function";
- case DeclarationType::variable:
- return "variable";
- case DeclarationType::inconsistent:
- return "inconsistent";
- }
- abort();
-}
-
-std::string to_string(const DeclarationAvailability& decl_av) {
- std::stringstream ss;
- if (!decl_av.global_availability.empty()) {
- ss << to_string(decl_av.global_availability) << ", ";
- }
-
- for (const auto& it : decl_av.arch_availability) {
- if (!it.second.empty()) {
- ss << to_string(it.first) << ": " << to_string(it.second) << ", ";
- }
- }
-
- std::string result = ss.str();
- if (result.size() == 0) {
- return "no availability";
- }
-
- return result.substr(0, result.length() - 2);
-}
-
-std::string to_string(const Location& loc) {
- std::stringstream ss;
- ss << loc.filename << ":" << loc.start.line << ":" << loc.start.column;
- return ss.str();
-}
diff --git a/tools/versioner/src/DeclarationDatabase.h b/tools/versioner/src/DeclarationDatabase.h
deleted file mode 100644
index 9a45227..0000000
--- a/tools/versioner/src/DeclarationDatabase.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdio.h>
-
-#include <map>
-#include <mutex>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <llvm/ADT/StringRef.h>
-
-#include "Arch.h"
-#include "CompilationType.h"
-#include "Utils.h"
-
-namespace clang {
-class ASTContext;
-class Decl;
-}
-
-enum class DeclarationType {
- function,
- variable,
- inconsistent,
-};
-
-struct AvailabilityValues {
- int introduced = 0;
- int deprecated = 0;
- int obsoleted = 0;
-
- bool empty() const {
- return !(introduced || deprecated || obsoleted);
- }
-
- bool operator==(const AvailabilityValues& rhs) const {
- return std::tie(introduced, deprecated, obsoleted) ==
- std::tie(rhs.introduced, rhs.deprecated, rhs.obsoleted);
- }
-
- bool operator!=(const AvailabilityValues& rhs) const {
- return !(*this == rhs);
- }
-};
-
-std::string to_string(const AvailabilityValues& av);
-
-struct DeclarationAvailability {
- AvailabilityValues global_availability;
- ArchMap<AvailabilityValues> arch_availability;
-
- bool empty() const {
- if (!global_availability.empty()) {
- return false;
- }
-
- for (const auto& it : arch_availability) {
- if (!it.second.empty()) {
- return false;
- }
- }
-
- return true;
- }
-
- bool operator==(const DeclarationAvailability& rhs) const {
- return std::tie(global_availability, arch_availability) ==
- std::tie(rhs.global_availability, rhs.arch_availability);
- }
-
- bool operator!=(const DeclarationAvailability& rhs) const {
- return !(*this == rhs);
- }
-
- // Returns false if the availability declarations conflict.
- bool merge(const DeclarationAvailability& other);
-};
-
-std::string to_string(const DeclarationAvailability& decl_av);
-
-struct FileLocation {
- unsigned line;
- unsigned column;
-
- bool operator<(const FileLocation& rhs) const {
- return std::tie(line, column) < std::tie(rhs.line, rhs.column);
- }
-
- bool operator==(const FileLocation& rhs) const {
- return std::tie(line, column) == std::tie(rhs.line, rhs.column);
- }
-};
-
-struct Location {
- std::string filename;
- FileLocation start;
- FileLocation end;
-
- bool operator<(const Location& rhs) const {
- return std::tie(filename, start, end) < std::tie(rhs.filename, rhs.start, rhs.end);
- }
-};
-
-std::string to_string(const Location& loc);
-
-struct Declaration {
- std::string name;
- Location location;
-
- bool is_extern;
- bool is_definition;
- bool no_guard;
- bool fortify_inline;
- std::map<CompilationType, DeclarationAvailability> availability;
-
- bool calculateAvailability(DeclarationAvailability* output) const;
- bool operator<(const Declaration& rhs) const {
- return location < rhs.location;
- }
-
- void dump(const std::string& base_path = "", FILE* out = stdout, unsigned indent = 0) const {
- std::string indent_str(indent, ' ');
- fprintf(out, "%s", indent_str.c_str());
-
- fprintf(out, "%s ", is_extern ? "extern" : "static");
- fprintf(out, "%s ", is_definition ? "definition" : "declaration");
- if (no_guard) {
- fprintf(out, "no_guard ");
- }
- if (fortify_inline) {
- fprintf(out, "fortify_inline ");
- }
- fprintf(out, "@ %s:%u:%u", StripPrefix(location.filename, base_path).str().c_str(),
- location.start.line, location.start.column);
-
- if (!availability.empty()) {
- DeclarationAvailability avail;
-
- fprintf(out, "\n%s ", indent_str.c_str());
- if (!calculateAvailability(&avail)) {
- fprintf(out, "invalid availability\n");
- } else {
- fprintf(out, "%s\n", to_string(avail).c_str());
- }
- }
- }
-};
-
-struct Symbol {
- std::string name;
- std::map<Location, Declaration> declarations;
-
- bool calculateAvailability(DeclarationAvailability* output) const;
- bool hasDeclaration(const CompilationType& type) const;
-
- bool operator<(const Symbol& rhs) const {
- return name < rhs.name;
- }
-
- bool operator==(const Symbol& rhs) const {
- return name == rhs.name;
- }
-
- void dump(const std::string& base_path = "", FILE* out = stdout) const {
- DeclarationAvailability availability;
- bool valid_availability = calculateAvailability(&availability);
- fprintf(out, " %s: ", name.c_str());
-
- if (valid_availability) {
- fprintf(out, "%s\n", to_string(availability).c_str());
- } else {
- fprintf(out, "invalid\n");
- }
-
- for (auto& it : declarations) {
- it.second.dump(base_path, out, 4);
- }
- }
-};
-
-class HeaderDatabase {
- std::mutex mutex;
-
- public:
- std::map<std::string, Symbol> symbols;
-
- void parseAST(CompilationType type, clang::ASTContext& ast);
-
- void dump(const std::string& base_path = "", FILE* out = stdout) const {
- fprintf(out, "HeaderDatabase contains %zu symbols:\n", symbols.size());
- for (const auto& pair : symbols) {
- pair.second.dump(base_path, out);
- }
- }
-};
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
deleted file mode 100644
index 79672ac..0000000
--- a/tools/versioner/src/Driver.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Driver.h"
-
-#include <err.h>
-#include <string.h>
-
-#include <chrono>
-#include <mutex>
-#include <string>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <clang/AST/ASTConsumer.h>
-#include <clang/Basic/Diagnostic.h>
-#include <clang/Basic/TargetInfo.h>
-#include <clang/Driver/Compilation.h>
-#include <clang/Driver/Driver.h>
-#include <clang/Frontend/CompilerInstance.h>
-#include <clang/Frontend/CompilerInvocation.h>
-#include <clang/Frontend/FrontendAction.h>
-#include <clang/Frontend/FrontendActions.h>
-#include <clang/Frontend/TextDiagnosticPrinter.h>
-#include <clang/Frontend/Utils.h>
-#include <clang/FrontendTool/Utils.h>
-#include <llvm/ADT/IntrusiveRefCntPtr.h>
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Option/Option.h>
-#include <llvm/TargetParser/Host.h>
-#include <llvm/Support/VirtualFileSystem.h>
-
-#include "Arch.h"
-#include "DeclarationDatabase.h"
-#include "versioner.h"
-
-using namespace std::chrono_literals;
-using namespace std::string_literals;
-
-using namespace clang;
-
-class VersionerASTConsumer : public clang::ASTConsumer {
- public:
- HeaderDatabase* header_database;
- CompilationType type;
-
- VersionerASTConsumer(HeaderDatabase* header_database, CompilationType type)
- : header_database(header_database), type(type) {
- }
-
- void HandleTranslationUnit(ASTContext& ctx) override {
- header_database->parseAST(type, ctx);
- }
-};
-
-class VersionerASTAction : public clang::ASTFrontendAction {
- public:
- HeaderDatabase* header_database;
- CompilationType type;
-
- VersionerASTAction(HeaderDatabase* header_database, CompilationType type)
- : header_database(header_database), type(type) {
- }
-
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance&, llvm::StringRef) override {
- return std::make_unique<VersionerASTConsumer>(header_database, type);
- }
-};
-
-static IntrusiveRefCntPtr<DiagnosticsEngine> constructDiags() {
- IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions());
- auto diag_printer = std::make_unique<TextDiagnosticPrinter>(llvm::errs(), diag_opts.get());
- IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
- IntrusiveRefCntPtr<DiagnosticsEngine> diags(
- new DiagnosticsEngine(diag_ids.get(), diag_opts.get(), diag_printer.release()));
- return diags;
-}
-
-// clang's driver is slow compared to the work it performs to compile our headers.
-// Run it once to generate flags for each target, and memoize the results.
-static std::unordered_map<CompilationType, std::vector<std::string>> cc1_flags;
-static const char* filename_placeholder = "__VERSIONER_PLACEHOLDER__";
-static void generateTargetCC1Flags(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
- CompilationType type,
- const std::vector<std::string>& include_dirs) {
- std::vector<std::string> cmd = { "versioner" };
- if (type.cpp) {
- cmd.push_back("-std=gnu++11");
- cmd.push_back("-x");
- cmd.push_back("c++");
- } else {
- cmd.push_back("-std=gnu11");
- cmd.push_back("-x");
- cmd.push_back("c");
- }
-
- cmd.push_back("-fsyntax-only");
-
- cmd.push_back("-Wall");
- cmd.push_back("-Wextra");
- cmd.push_back("-Weverything");
- cmd.push_back("-Werror");
- cmd.push_back("-Wundef");
- cmd.push_back("-Wno-unused-macros");
- cmd.push_back("-Wno-unused-function");
- cmd.push_back("-Wno-unused-variable");
- cmd.push_back("-Wno-unknown-attributes");
- cmd.push_back("-Wno-pragma-once-outside-header");
-
- cmd.push_back("-target");
- cmd.push_back(arch_targets[type.arch]);
-
- cmd.push_back("-DANDROID");
- cmd.push_back("-D__BIONIC_VERSIONER=1");
- cmd.push_back("-D__ANDROID_API__="s + std::to_string(type.api_level));
- cmd.push_back("-D_FORTIFY_SOURCE=2");
- cmd.push_back("-D_GNU_SOURCE");
- cmd.push_back("-D_FILE_OFFSET_BITS="s + std::to_string(type.file_offset_bits));
-
- cmd.push_back("-nostdinc");
-
- if (add_include) {
- cmd.push_back("-include");
- cmd.push_back("android/versioning.h");
- }
-
- for (const auto& dir : include_dirs) {
- cmd.push_back("-isystem");
- cmd.push_back(dir);
- }
-
- cmd.push_back("-include");
- cmd.push_back(filename_placeholder);
- cmd.push_back("-");
-
- auto diags = constructDiags();
- driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, "versioner", vfs);
- driver.setCheckInputsExist(false);
-
- llvm::SmallVector<const char*, 32> driver_args;
- for (const std::string& str : cmd) {
- driver_args.push_back(str.c_str());
- }
-
- std::unique_ptr<driver::Compilation> Compilation(driver.BuildCompilation(driver_args));
- const driver::JobList& jobs = Compilation->getJobs();
- if (jobs.size() != 1) {
- errx(1, "driver returned %zu jobs for %s", jobs.size(), to_string(type).c_str());
- }
-
- const driver::Command& driver_cmd = llvm::cast<driver::Command>(*jobs.begin());
- const llvm::opt::ArgStringList& cc_args = driver_cmd.getArguments();
-
- if (cc_args.size() == 0) {
- errx(1, "driver returned empty command for %s", to_string(type).c_str());
- }
-
- std::vector<std::string> result(cc_args.begin(), cc_args.end());
-
- {
- static std::mutex cc1_init_mutex;
- std::unique_lock<std::mutex> lock(cc1_init_mutex);
- if (cc1_flags.count(type) > 0) {
- errx(1, "attemped to generate cc1 flags for existing CompilationType %s",
- to_string(type).c_str());
- }
-
- cc1_flags.emplace(std::make_pair(type, std::move(result)));
- }
-}
-
-static std::vector<const char*> getCC1Command(CompilationType type, const std::string& filename) {
- const auto& target_flag_it = cc1_flags.find(type);
- if (target_flag_it == cc1_flags.end()) {
- errx(1, "failed to find target flags for CompilationType %s", to_string(type).c_str());
- }
-
- std::vector<const char*> result;
- for (const std::string& flag : target_flag_it->second) {
- if (flag == "-disable-free") {
- continue;
- } else if (flag == filename_placeholder) {
- result.push_back(filename.c_str());
- } else {
- result.push_back(flag.c_str());
- }
- }
- return result;
-}
-
-void initializeTargetCC1FlagCache(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
- const std::set<CompilationType>& types,
- const std::unordered_map<Arch, CompilationRequirements>& reqs) {
- if (!cc1_flags.empty()) {
- errx(1, "reinitializing target CC1 flag cache?");
- }
-
- auto start = std::chrono::high_resolution_clock::now();
- std::vector<std::thread> threads;
- for (const CompilationType type : types) {
- threads.emplace_back([type, &vfs, &reqs]() {
- const auto& arch_req_it = reqs.find(type.arch);
- if (arch_req_it == reqs.end()) {
- errx(1, "CompilationRequirement map missing entry for CompilationType %s",
- to_string(type).c_str());
- }
-
- generateTargetCC1Flags(vfs, type, arch_req_it->second.dependencies);
- });
- }
- for (auto& thread : threads) {
- thread.join();
- }
- auto end = std::chrono::high_resolution_clock::now();
-
- if (verbose) {
- auto diff = (end - start) / 1.0ms;
- printf("Generated compiler flags for %zu targets in %0.2Lfms\n", types.size(), diff);
- }
-
- if (cc1_flags.empty()) {
- errx(1, "failed to initialize target CC1 flag cache");
- }
-}
-
-void compileHeader(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
- HeaderDatabase* header_database, CompilationType type,
- const std::string& filename) {
- auto diags = constructDiags();
- std::vector<const char*> cc1_flags = getCC1Command(type, filename);
- auto invocation = std::make_unique<CompilerInvocation>();
- if (!CompilerInvocation::CreateFromArgs(*invocation.get(), cc1_flags, *diags)) {
- errx(1, "failed to create CompilerInvocation");
- }
-
- clang::CompilerInstance Compiler;
-
- Compiler.setInvocation(std::move(invocation));
- Compiler.setDiagnostics(diags.get());
- Compiler.createFileManager(vfs);
-
- VersionerASTAction versioner_action(header_database, type);
- if (!Compiler.ExecuteAction(versioner_action)) {
- errx(1, "compilation generated warnings or errors");
- }
-
- if (diags->getNumWarnings() || diags->hasErrorOccurred()) {
- errx(1, "compilation generated warnings or errors");
- }
-}
diff --git a/tools/versioner/src/Driver.h b/tools/versioner/src/Driver.h
deleted file mode 100644
index 99e57ae..0000000
--- a/tools/versioner/src/Driver.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <set>
-#include <string>
-#include <unordered_map>
-
-#include <llvm/ADT/IntrusiveRefCntPtr.h>
-
-#include "Arch.h"
-#include "DeclarationDatabase.h"
-#include "VFS.h"
-
-struct CompilationRequirements {
- std::vector<std::string> headers;
- std::vector<std::string> dependencies;
-};
-
-void initializeTargetCC1FlagCache(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
- const std::set<CompilationType>& types,
- const std::unordered_map<Arch, CompilationRequirements>& reqs);
-
-void compileHeader(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
- HeaderDatabase* header_database, CompilationType type,
- const std::string& filename);
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
deleted file mode 100644
index 74d5ba0..0000000
--- a/tools/versioner/src/Preprocessor.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Preprocessor.h"
-
-#include <err.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <libgen.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <deque>
-#include <fstream>
-#include <string>
-#include <unordered_map>
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/Twine.h>
-#include <llvm/Support/FileSystem.h>
-#include <llvm/Support/Path.h>
-
-#include "Arch.h"
-#include "DeclarationDatabase.h"
-#include "versioner.h"
-
-using namespace std::string_literals;
-
-static DeclarationAvailability calculateRequiredGuard(const Declaration& declaration) {
- // To avoid redundant macro guards, the availability calculated by this function is the set
- // difference of 'targets marked-available' from 'targets the declaration is visible in'.
- // For example, a declaration that is visible always and introduced in 9 would return introduced
- // in 9, but the same declaration, except only visible in 9+ would return an empty
- // DeclarationAvailability.
-
- // This currently only handles __INTRODUCED_IN.
- // TODO: Do the same for __REMOVED_IN.
- int global_min_api_visible = 0;
- ArchMap<int> arch_visibility;
-
- for (const auto& it : declaration.availability) {
- const CompilationType& type = it.first;
-
- if (global_min_api_visible == 0 || global_min_api_visible > type.api_level) {
- global_min_api_visible = type.api_level;
- }
-
- if (arch_visibility[type.arch] == 0 || arch_visibility[type.arch] > type.api_level) {
- arch_visibility[type.arch] = type.api_level;
- }
- }
-
- DeclarationAvailability decl_av;
- if (!declaration.calculateAvailability(&decl_av)) {
- fprintf(stderr, "versioner: failed to calculate availability while preprocessing:\n");
- declaration.dump("", stderr, 2);
- exit(1);
- }
-
- D("Calculating required guard for %s:\n", declaration.name.c_str());
- D(" Declaration availability: %s\n", to_string(decl_av).c_str());
-
- if (verbose) {
- std::string arch_visibility_str;
- for (Arch arch : supported_archs) {
- if (arch_visibility[arch] != 0) {
- arch_visibility_str += to_string(arch);
- arch_visibility_str += ": ";
- arch_visibility_str += std::to_string(arch_visibility[arch]);
- arch_visibility_str += ", ";
- }
- }
- if (!arch_visibility_str.empty()) {
- arch_visibility_str.resize(arch_visibility_str.size() - 2);
- }
- D(" Declaration visibility: global = %d, arch = %s\n", global_min_api_visible,
- arch_visibility_str.c_str());
- }
-
- DeclarationAvailability result = decl_av;
- if (result.global_availability.introduced <= global_min_api_visible) {
- result.global_availability.introduced = 0;
- }
-
- for (Arch arch : supported_archs) {
- if (result.arch_availability[arch].introduced <= arch_visibility[arch] ||
- result.arch_availability[arch].introduced <= arch_min_api[arch]) {
- result.arch_availability[arch].introduced = 0;
- }
- }
-
- D(" Calculated result: %s\n", to_string(result).c_str());
- D("\n");
-
- return result;
-}
-
-static std::deque<std::string> readFileLines(const std::string& path) {
- std::ifstream is(path.c_str());
- std::deque<std::string> result;
- std::string line;
-
- while (std::getline(is, line)) {
- result.push_back(std::move(line));
- }
-
- return result;
-}
-
-static void writeFileLines(const std::string& path, const std::deque<std::string>& lines) {
- if (!mkdirs(dirname(path))) {
- err(1, "failed to create directory '%s'", dirname(path).c_str());
- }
-
- std::ofstream os(path.c_str(), std::ios_base::out | std::ios_base::trunc);
-
- for (const std::string& line : lines) {
- os << line << "\n";
- }
-}
-
-using GuardMap = std::map<Location, DeclarationAvailability>;
-
-static std::string generateGuardCondition(const DeclarationAvailability& avail) {
- // Logically orred expressions that constitute the macro guard.
- std::vector<std::string> expressions;
- static const std::vector<std::pair<std::string, std::set<Arch>>> arch_sets = {
- {"!defined(__LP64__)", {Arch::arm, Arch::x86}},
- {"defined(__LP64__)", {Arch::arm64, Arch::riscv64, Arch::x86_64}},
- };
- std::map<Arch, std::string> individual_archs = {
- { Arch::arm, "defined(__arm__)" },
- { Arch::arm64, "defined(__aarch64__)" },
- { Arch::riscv64, "defined(__riscv)" },
- { Arch::x86, "defined(__i386__)" },
- { Arch::x86_64, "defined(__x86_64__)" },
- };
-
- auto generate_guard = [](const std::string& arch_expr, int min_version) {
- if (min_version == 0) {
- return arch_expr;
- }
- return arch_expr + " && __ANDROID_API__ >= " + std::to_string(min_version);
- };
-
- D("Generating guard for availability: %s\n", to_string(avail).c_str());
- if (!avail.global_availability.empty()) {
- for (Arch arch : supported_archs) {
- if (!avail.arch_availability[arch].empty()) {
- errx(1, "attempted to generate guard with global and per-arch values: %s",
- to_string(avail).c_str());
- }
- }
-
- if (avail.global_availability.introduced == 0) {
- // We currently get here for the "__sF" symbol because it's marked __REMOVED_IN(23). This
- // symbol is the only use of __REMOVED_IN, and it's already guarded manually, so there's no
- // need to do anything.
- fprintf(stderr, "warning: attempted to generate guard with empty availability: %s\n",
- to_string(avail).c_str());
- return "";
- }
-
- if (avail.global_availability.introduced <= 9) {
- return "";
- }
-
- return "__ANDROID_API__ >= "s + std::to_string(avail.global_availability.introduced);
- }
-
- for (const auto& it : arch_sets) {
- const std::string& arch_expr = it.first;
- const std::set<Arch>& archs = it.second;
-
- D(" Checking arch set '%s'\n", arch_expr.c_str());
-
- int version = 0;
-
- // Find the architectures that need to check __ANDROID_API__ and verify that they check against
- // the same API level.
- for (Arch arch : archs) {
- const int arch_version = avail.arch_availability[arch].introduced;
- if (arch_version == 0) {
- continue;
- } else if (version == 0) {
- version = arch_version;
- } else if (version != arch_version) {
- D(" Skipping arch set, availability for %s doesn't match %s\n",
- to_string(*it.second.begin()).c_str(), to_string(arch).c_str());
- goto skip;
- }
- }
-
- // Verify that a non-zero version is acceptable to reuse for other archs with a higher minimum
- // API, like riscv64. (e.g. It's OK to reuse an (__ANDROID_API__ >= 24) check if the arch's
- // minimum API is 35.)
- if (version != 0) {
- for (Arch arch : archs) {
- const int arch_version = avail.arch_availability[arch].introduced;
- if (arch_version == 0 && version > arch_min_api[arch]) {
- D(" Skipping arch set, availability for %s doesn't match %s\n",
- to_string(*it.second.begin()).c_str(), to_string(arch).c_str());
- goto skip;
- }
- }
- }
-
- expressions.emplace_back(generate_guard(arch_expr, version));
-
- D(" Generated expression '%s'\n", expressions.rbegin()->c_str());
-
- for (Arch arch : archs) {
- individual_archs.erase(arch);
- }
-
- skip:
- continue;
- }
-
- for (const auto& it : individual_archs) {
- const std::string& arch_expr = it.second;
- int introduced = avail.arch_availability[it.first].introduced;
- expressions.emplace_back(generate_guard(arch_expr, introduced));
- }
-
- if (expressions.size() == 0) {
- errx(1, "generated empty guard for availability %s", to_string(avail).c_str());
- } else if (expressions.size() == 1) {
- return expressions[0];
- }
-
- return "("s + Join(expressions, ") || (") + ")";
-}
-
-// Assumes that nothing weird is happening (e.g. having the semicolon be in a macro).
-static FileLocation findNextSemicolon(const std::deque<std::string>& lines, FileLocation start) {
- unsigned current_line = start.line;
- unsigned current_column = start.column;
- while (current_line <= lines.size()) {
- size_t result = lines[current_line - 1].find_first_of(';', current_column - 1);
-
- if (result != std::string::npos) {
- FileLocation loc = {
- .line = current_line,
- .column = unsigned(result) + 1,
- };
-
- return loc;
- }
-
- ++current_line;
- current_column = 0;
- }
-
- errx(1, "failed to find semicolon starting from %u:%u", start.line, start.column);
-}
-
-// Merge adjacent blocks with identical guards.
-static void mergeGuards(std::deque<std::string>& file_lines, GuardMap& guard_map) {
- if (guard_map.size() < 2) {
- return;
- }
-
- auto current = guard_map.begin();
- auto next = current;
- ++next;
-
- while (next != guard_map.end()) {
- if (current->second != next->second) {
- ++current;
- ++next;
- continue;
- }
-
- // Scan from the end of current to the beginning of next.
- bool in_block_comment = false;
- bool valid = true;
-
- FileLocation current_location = current->first.end;
- FileLocation end_location = next->first.start;
-
- auto nextLine = [¤t_location]() {
- ++current_location.line;
- current_location.column = 1;
- };
-
- auto nextCol = [&file_lines, ¤t_location, &nextLine]() {
- if (current_location.column == file_lines[current_location.line - 1].length()) {
- nextLine();
- } else {
- ++current_location.column;
- }
- };
-
- // The end location will point to the semicolon, which we don't want to read, so skip it.
- nextCol();
-
- while (current_location < end_location) {
- const std::string& line = file_lines[current_location.line - 1];
- size_t line_index = current_location.column - 1;
-
- if (in_block_comment) {
- size_t pos = line.find("*/", line_index);
- if (pos == std::string::npos) {
- D("Didn't find block comment terminator, skipping line\n");
- nextLine();
- continue;
- } else {
- D("Found block comment terminator\n");
- in_block_comment = false;
- current_location.column = pos + 2;
- nextCol();
- continue;
- }
- } else {
- size_t pos = line.find_first_not_of(" \t", line_index);
- if (pos == std::string::npos) {
- nextLine();
- continue;
- }
-
- current_location.column = pos + 1;
- if (line[pos] != '/') {
- valid = false;
- break;
- }
-
- nextCol();
- if (line.length() <= pos + 1) {
- // Trailing slash at the end of a line?
- D("Trailing slash at end of line\n");
- valid = false;
- break;
- }
-
- if (line[pos + 1] == '/') {
- // C++ style comment
- nextLine();
- } else if (line[pos + 1] == '*') {
- // Block comment
- nextCol();
- in_block_comment = true;
- D("In a block comment\n");
- } else {
- // Garbage?
- D("Unexpected output after /: %s\n", line.substr(pos).c_str());
- valid = false;
- break;
- }
- }
- }
-
- if (!valid) {
- D("Not merging blocks %s and %s\n", to_string(current->first).c_str(),
- to_string(next->first).c_str());
- ++current;
- ++next;
- continue;
- }
-
- D("Merging blocks %s and %s\n", to_string(current->first).c_str(),
- to_string(next->first).c_str());
-
- Location merged = current->first;
- merged.end = next->first.end;
-
- DeclarationAvailability avail = current->second;
-
- guard_map.erase(current);
- guard_map.erase(next);
- bool unused;
- std::tie(current, unused) = guard_map.insert(std::make_pair(merged, avail));
- next = current;
- ++next;
- }
-}
-
-static void rewriteFile(const std::string& output_path, std::deque<std::string>& file_lines,
- const GuardMap& guard_map) {
- for (auto it = guard_map.rbegin(); it != guard_map.rend(); ++it) {
- const Location& loc = it->first;
- const DeclarationAvailability& avail = it->second;
-
- std::string condition = generateGuardCondition(avail);
- if (condition.empty()) {
- continue;
- }
-
- std::string prologue = "\n#if "s + condition + "\n";
- std::string epilogue = "\n#endif /* " + condition + " */\n";
-
- file_lines[loc.end.line - 1].insert(loc.end.column, epilogue);
- file_lines[loc.start.line - 1].insert(loc.start.column - 1, prologue);
- }
-
- if (verbose) {
- printf("Preprocessing %s...\n", output_path.c_str());
- }
- writeFileLines(output_path, file_lines);
-}
-
-bool preprocessHeaders(const std::string& dst_dir, const std::string& src_dir,
- HeaderDatabase* database) {
- std::unordered_map<std::string, GuardMap> guards;
- std::unordered_map<std::string, std::deque<std::string>> file_lines;
-
- for (const auto& symbol_it : database->symbols) {
- const Symbol& symbol = symbol_it.second;
-
- for (const auto& decl_it : symbol.declarations) {
- const Location& location = decl_it.first;
- const Declaration& decl = decl_it.second;
-
- if (decl.no_guard) {
- // No guard required.
- continue;
- }
-
- DeclarationAvailability macro_guard = calculateRequiredGuard(decl);
- if (!macro_guard.empty()) {
- guards[location.filename][location] = macro_guard;
- }
- }
- }
-
- // Copy over the original headers before preprocessing.
- char* fts_paths[2] = { const_cast<char*>(src_dir.c_str()), nullptr };
- std::unique_ptr<FTS, decltype(&fts_close)> fts(fts_open(fts_paths, FTS_LOGICAL, nullptr),
- fts_close);
- if (!fts) {
- err(1, "failed to open directory %s", src_dir.c_str());
- }
-
- while (FTSENT* ent = fts_read(fts.get())) {
- llvm::StringRef path = ent->fts_path;
- if (!path.starts_with(src_dir)) {
- err(1, "path '%s' doesn't start with source dir '%s'", ent->fts_path, src_dir.c_str());
- }
-
- if (ent->fts_info != FTS_F) {
- continue;
- }
-
- std::string rel_path = path.substr(src_dir.length() + 1).str();
- std::string dst_path = dst_dir + "/" + rel_path;
- llvm::StringRef parent_path = llvm::sys::path::parent_path(dst_path);
- if (llvm::sys::fs::create_directories(parent_path)) {
- errx(1, "failed to ensure existence of directory '%s'", parent_path.str().c_str());
- }
- if (llvm::sys::fs::copy_file(path, dst_path)) {
- errx(1, "failed to copy '%s/%s' to '%s'", src_dir.c_str(), path.str().c_str(),
- dst_path.c_str());
- }
- }
-
- for (const auto& file_it : guards) {
- file_lines[file_it.first] = readFileLines(file_it.first);
- }
-
- for (auto& file_it : guards) {
- llvm::StringRef file_path = file_it.first;
- GuardMap& orig_guard_map = file_it.second;
-
- // The end positions given to us are the end of the declaration, which is some point before the
- // semicolon. Fix up the end positions by scanning for the next semicolon.
- GuardMap guard_map;
- for (const auto& it : orig_guard_map) {
- Location loc = it.first;
- loc.end = findNextSemicolon(file_lines[file_path.str()], loc.end);
- guard_map[loc] = it.second;
- }
-
- // TODO: Make sure that the Locations don't overlap.
- // TODO: Merge adjacent non-identical guards.
- mergeGuards(file_lines[file_path.str()], guard_map);
-
- if (!file_path.starts_with(src_dir)) {
- errx(1, "input file %s is not in %s\n", file_path.str().c_str(), src_dir.c_str());
- }
-
- // rel_path has a leading slash.
- llvm::StringRef rel_path = file_path.substr(src_dir.size(), file_path.size() - src_dir.size());
- std::string output_path = (llvm::Twine(dst_dir) + rel_path).str();
-
- rewriteFile(output_path, file_lines[file_path.str()], guard_map);
- }
-
- return true;
-}
diff --git a/tools/versioner/src/SymbolDatabase.cpp b/tools/versioner/src/SymbolDatabase.cpp
deleted file mode 100644
index c483c0f..0000000
--- a/tools/versioner/src/SymbolDatabase.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SymbolDatabase.h"
-
-#include "SymbolFileParser.h"
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <fstream>
-#include <streambuf>
-#include <string>
-#include <unordered_set>
-
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Object/Binary.h>
-#include <llvm/Object/ELFObjectFile.h>
-
-#include "versioner.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-std::unordered_set<std::string> getSymbols(const std::string& filename) {
- std::unordered_set<std::string> result;
- auto binaryOrError = createBinary(filename);
- if (!binaryOrError) {
- errx(1, "failed to open library at %s: %s\n", filename.c_str(),
- llvm::toString(binaryOrError.takeError()).c_str());
- }
-
- ELFObjectFileBase* elf = dyn_cast_or_null<ELFObjectFileBase>(binaryOrError.get().getBinary());
- if (!elf) {
- errx(1, "failed to parse %s as ELF", filename.c_str());
- }
-
- for (const ELFSymbolRef symbol : elf->getDynamicSymbolIterators()) {
- Expected<StringRef> symbolNameOrError = symbol.getName();
-
- if (!symbolNameOrError) {
- errx(1, "failed to get symbol name for symbol in %s: %s", filename.c_str(),
- llvm::toString(symbolNameOrError.takeError()).c_str());
- }
-
- result.insert(symbolNameOrError.get().str());
- }
-
- return result;
-}
-
-static std::map<std::string, NdkSymbolType> parsePlatform(const CompilationType& type,
- const std::string& platform_dir) {
- static const std::pair<const char*, bool> wanted_files[] = {
- {"crtbegin.map.txt", false},
- {"libc.map.txt", true},
- };
-
- std::map<std::string, NdkSymbolType> result;
-
- for (auto&& [filename, required] : wanted_files) {
- std::string path = platform_dir + "/" + filename;
-
- std::optional<SymbolMap> symbols = parseSymbolFile(path, type);
- if (!symbols) {
- if (required) {
- errx(1, "error: failed to load: %s", path.c_str());
- }
- continue;
- }
-
- for (auto&& [symbol_name, symbol_type] : *symbols) {
- if (symbol_name.empty()) {
- continue;
- }
-
- if (result.count(symbol_name) != 0) {
- if (strict) {
- printf("duplicated symbol '%s' in '%s'\n", symbol_name.c_str(), path.c_str());
- }
- }
-
- result[symbol_name] = symbol_type;
- }
- }
-
- return result;
-}
-
-std::optional<NdkSymbolDatabase> parsePlatforms(const std::set<CompilationType>& types,
- const std::string& platform_dir) {
- NdkSymbolDatabase result;
- for (const CompilationType& type : types) {
- std::map<std::string, NdkSymbolType> symbols = parsePlatform(type, platform_dir);
- for (const auto& it : symbols) {
- result[it.first][type] = it.second;
- }
- }
- return std::make_optional(std::move(result));
-}
diff --git a/tools/versioner/src/SymbolDatabase.h b/tools/versioner/src/SymbolDatabase.h
deleted file mode 100644
index dbbba4f..0000000
--- a/tools/versioner/src/SymbolDatabase.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <map>
-#include <optional>
-#include <set>
-#include <string>
-#include <unordered_set>
-
-#include "DeclarationDatabase.h"
-
-using LibrarySymbolDatabase = std::unordered_set<std::string>;
-std::unordered_set<std::string> getSymbols(const std::string& filename);
-
-enum class NdkSymbolType {
- function,
- variable,
-};
-
-using NdkSymbolDatabase = std::map<std::string, std::map<CompilationType, NdkSymbolType>>;
-std::optional<NdkSymbolDatabase> parsePlatforms(const std::set<CompilationType>& types,
- const std::string& platform_dir);
diff --git a/tools/versioner/src/SymbolFileParser.cpp b/tools/versioner/src/SymbolFileParser.cpp
deleted file mode 100644
index 1b4adae..0000000
--- a/tools/versioner/src/SymbolFileParser.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SymbolFileParser.h"
-
-#include "Arch.h"
-#include "CompilationType.h"
-
-#include <android-base/strings.h>
-
-#include <fstream>
-#include <ios>
-#include <optional>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <err.h>
-
-namespace {
-
-using TagList = std::vector<std::string>;
-
-struct SymbolEnt {
- std::string name;
- TagList tags;
-};
-
-using SymbolList = std::vector<SymbolEnt>;
-
-struct Version {
- std::string name;
- std::string base;
- SymbolList symbols;
- TagList tags;
-};
-
-class SymbolFileParser {
- public:
- SymbolFileParser(const std::string& path, const CompilationType& type)
- : file_path(path),
- compilation_type(type),
- api_level_arch_prefix("api-level-" + to_string(type.arch) + "="),
- intro_arch_perfix("introduced-" + to_string(type.arch) + "="),
- file(path, std::ios_base::in),
- curr_line_num(0) {
- }
-
- // Parse the version script and build a symbol map.
- std::optional<SymbolMap> parse() {
- if (!file) {
- return std::nullopt;
- }
-
- SymbolMap symbol_map;
- while (hasNextLine()) {
- auto&& version = parseVersion();
- if (!version) {
- return std::nullopt;
- }
-
- if (isInArch(version->tags) && isInApi(version->tags)) {
- for (auto&& [name, tags] : version->symbols) {
- if (isInArch(tags) && isInApi(tags)) {
- symbol_map[name] = getSymbolType(tags);
- }
- }
- }
- }
- return std::make_optional(std::move(symbol_map));
- }
-
- private:
- // Read a non-empty line from the input and split at the first '#' character.
- bool hasNextLine() {
- std::string line;
- while (std::getline(file, line)) {
- ++curr_line_num;
-
- size_t hash_pos = line.find('#');
- curr_line = android::base::Trim(line.substr(0, hash_pos));
- if (!curr_line.empty()) {
- if (hash_pos != std::string::npos) {
- curr_tags = parseTags(line.substr(hash_pos + 1));
- } else {
- curr_tags.clear();
- }
- return true;
- }
- }
- return false;
- }
-
- // Tokenize the tags after the '#' character.
- static std::vector<std::string> parseTags(const std::string& tags_line) {
- std::vector<std::string> tags = android::base::Split(tags_line, " \t");
- tags.erase(std::remove(tags.begin(), tags.end(), ""), tags.end());
- return tags;
- }
-
- // Parse a version scope.
- std::optional<Version> parseVersion() {
- size_t start_line_num = curr_line_num;
-
- std::string::size_type lparen_pos = curr_line.find('{');
- if (lparen_pos == std::string::npos) {
- errx(1, "%s:%zu: error: expected '{' cannot be found in this line",
- file_path.c_str(), curr_line_num);
- }
-
- // Record the version name and version tags (before hasNextLine()).
- std::string name = android::base::Trim(curr_line.substr(0, lparen_pos));
- TagList tags = std::move(curr_tags);
-
- // Read symbol lines.
- SymbolList symbols;
- bool global_scope = true;
- bool cpp_scope = false;
- while (hasNextLine()) {
- size_t rparen_pos = curr_line.find('}');
- if (rparen_pos != std::string::npos) {
- size_t semicolon_pos = curr_line.find(';', rparen_pos + 1);
- if (semicolon_pos == std::string::npos) {
- errx(1, "%s:%zu: error: the line that ends a scope must end with ';'",
- file_path.c_str(), curr_line_num);
- }
-
- if (cpp_scope) {
- cpp_scope = false;
- continue;
- }
-
- std::string base = android::base::Trim(
- curr_line.substr(rparen_pos + 1, semicolon_pos - 1));
-
- return std::make_optional(Version{std::move(name), std::move(base),
- std::move(symbols), std::move(tags)});
- }
-
- if (android::base::StartsWith(curr_line, R"(extern "C++" {)")) {
- cpp_scope = true;
- continue;
- }
-
- if (cpp_scope) {
- continue;
- }
-
- size_t colon_pos = curr_line.find(':');
- if (colon_pos != std::string::npos) {
- std::string visibility =
- android::base::Trim(curr_line.substr(0, colon_pos));
-
- if (visibility == "global") {
- global_scope = true;
- } else if (visibility == "local") {
- global_scope = false;
- } else {
- errx(1, "%s:%zu: error: unknown version visibility: %s",
- file_path.c_str(), curr_line_num, visibility.c_str());
- }
- continue;
- }
-
- if (global_scope) {
- size_t semicolon_pos = curr_line.find(';');
- if (semicolon_pos == std::string::npos) {
- errx(1, "%s:%zu: error: symbol name line must end with ';'",
- file_path.c_str(), curr_line_num);
- }
-
- std::string symbol_name =
- android::base::Trim(curr_line.substr(0, semicolon_pos));
-
- size_t asterisk_pos = symbol_name.find('*');
- if (asterisk_pos != std::string::npos) {
- errx(1, "%s:%zu: error: global symbol name must not have wildcards",
- file_path.c_str(), curr_line_num);
- }
-
- symbols.push_back(SymbolEnt{std::move(symbol_name),
- std::move(curr_tags)});
- }
- }
-
- errx(1, "%s:%zu: error: scope started from %zu must be closed before EOF",
- file_path.c_str(), curr_line_num, start_line_num);
- }
-
- static NdkSymbolType getSymbolType(const TagList& tags) {
- for (auto&& tag : tags) {
- if (tag == "var") {
- return NdkSymbolType::variable;
- }
- }
- return NdkSymbolType::function;
- }
-
- // isInArch() returns true if there is a matching arch-specific tag or there
- // are no arch-specific tags.
- bool isInArch(const TagList& tags) const {
- bool has_arch_tags = false;
- for (auto&& tag : tags) {
- std::optional<Arch> arch = arch_from_string(tag);
- if (!arch) {
- continue;
- }
- if (*arch == compilation_type.arch) {
- return true;
- }
- has_arch_tags = true;
- }
- return !has_arch_tags;
- }
-
- // isInApi() returns true if the specified API level is equal to the
- // api-level tag, or the specified API level is greater than or equal to the
- // introduced tag, or there are no api-level or introduced tags.
- bool isInApi(const TagList& tags) const {
- bool api_level_arch = false;
- bool intro_arch = false;
- std::string api_level;
- std::string intro;
-
- for (const std::string& tag : tags) {
- // Check api-level tags.
- if (android::base::StartsWith(tag, "api-level=") && !api_level_arch) {
- api_level = tag;
- continue;
- }
- if (android::base::StartsWith(tag, api_level_arch_prefix)) {
- api_level = tag;
- api_level_arch = true;
- continue;
- }
-
- // Check introduced tags.
- if (android::base::StartsWith(tag, "introduced=") && !intro_arch) {
- intro = tag;
- continue;
- }
- if (android::base::StartsWith(tag, intro_arch_perfix)) {
- intro = tag;
- intro_arch = true;
- continue;
- }
- }
-
- if (intro.empty() && api_level.empty()) {
- return true;
- }
-
- if (!api_level.empty()) {
- // If an api-level tag is specified, it must be an exact match (mainly
- // for versioner unit tests).
- return compilation_type.api_level == parseApiLevelValue(api_level);
- }
-
- return compilation_type.api_level >= parseApiLevelValue(intro);
- }
-
- // Parse the integer API level from api-level or introduced tags.
- int parseApiLevelValue(const std::string& tag) const {
- std::string api_level = tag.substr(tag.find('=') + 1);
- auto it = api_codename_map.find(api_level);
- if (it != api_codename_map.end()) {
- return it->second;
- }
- if (api_level.find_first_not_of("0123456789") != std::string::npos) {
- errx(1, "%s:%zu: error: unknown API level codename specified: \"%s\"",
- file_path.c_str(), curr_line_num, tag.c_str());
- }
- return std::stoi(api_level);
- }
-
- private:
- const std::string& file_path;
- const CompilationType& compilation_type;
- const std::string api_level_arch_prefix;
- const std::string intro_arch_perfix;
-
- std::ifstream file;
- std::string curr_line;
- std::vector<std::string> curr_tags;
- size_t curr_line_num;
-};
-
-} // anonymous namespace
-
-
-std::optional<SymbolMap> parseSymbolFile(const std::string& file_path,
- const CompilationType& type) {
- SymbolFileParser parser(file_path, type);
- return parser.parse();
-}
diff --git a/tools/versioner/src/SymbolFileParser.h b/tools/versioner/src/SymbolFileParser.h
deleted file mode 100644
index 5cdbf2f..0000000
--- a/tools/versioner/src/SymbolFileParser.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <map>
-#include <string>
-#include <optional>
-
-#include "DeclarationDatabase.h"
-#include "SymbolDatabase.h"
-
-using SymbolMap = std::map<std::string, NdkSymbolType>;
-
-std::optional<SymbolMap> parseSymbolFile(const std::string &file,
- const CompilationType& type);
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
deleted file mode 100644
index d2bb1a8..0000000
--- a/tools/versioner/src/Utils.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Utils.h"
-
-#include <err.h>
-#include <fts.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <android-base/strings.h>
-
-#include "DeclarationDatabase.h"
-
-std::string getWorkingDir() {
- char buf[PATH_MAX];
- if (!getcwd(buf, sizeof(buf))) {
- err(1, "getcwd failed");
- }
- return buf;
-}
-
-std::vector<std::string> collectHeaders(const std::string& directory,
- const std::unordered_set<std::string>& ignored_directories) {
- std::vector<std::string> headers;
-
- char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
- std::unique_ptr<FTS, decltype(&fts_close)> fts(
- fts_open(dir_argv, FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close);
-
- if (!fts) {
- err(1, "failed to open directory '%s'", directory.c_str());
- }
-
- FTSENT* skipping = nullptr;
- while (FTSENT* ent = fts_read(fts.get())) {
- if (ent->fts_info & FTS_DP) {
- if (ent == skipping) {
- skipping = nullptr;
- }
- continue;
- }
-
- if (skipping != nullptr) {
- continue;
- }
-
- if (ent->fts_info & FTS_D) {
- if (ignored_directories.count(ent->fts_path) != 0) {
- // fts_read guarantees that `ent` is valid and okay to hold on to until
- // after it's returned with FTS_DP set.
- skipping = ent;
- }
- continue;
- }
-
- std::string path = ent->fts_path;
- if (!android::base::EndsWith(path, ".h")) {
- continue;
- }
-
- headers.push_back(std::move(path));
- }
-
- return headers;
-}
-
-llvm::StringRef StripPrefix(llvm::StringRef string, llvm::StringRef prefix) {
- if (string.starts_with(prefix)) {
- return string.drop_front(prefix.size());
- }
- return string;
-}
diff --git a/tools/versioner/src/Utils.h b/tools/versioner/src/Utils.h
deleted file mode 100644
index 9b45dcd..0000000
--- a/tools/versioner/src/Utils.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <errno.h>
-#include <libgen.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include <llvm/ADT/StringRef.h>
-
-std::string getWorkingDir();
-std::vector<std::string> collectHeaders(const std::string& directory,
- const std::unordered_set<std::string>& ignored_directories);
-
-static inline std::string dirname(const std::string& path) {
- std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
- return dirname(path_copy.get());
-}
-
-static inline bool is_directory(const std::string& path) {
- struct stat st;
- if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
- return true;
- }
- return false;
-}
-
-static inline bool mkdirs(const std::string& path) {
- if (is_directory(path)) {
- return true;
- }
-
- std::string parent = dirname(path);
- if (parent == path) {
- return false;
- }
-
- if (!mkdirs(parent)) {
- return false;
- }
-
- if (mkdir(path.c_str(), 0700) != 0) {
- if (errno != EEXIST) {
- return false;
- }
- return is_directory(path);
- }
-
- return true;
-}
-
-static inline std::string to_string(const char* c) {
- return c;
-}
-
-static inline const std::string& to_string(const std::string& str) {
- return str;
-}
-
-template <typename Collection>
-static inline std::string Join(Collection c, const std::string& delimiter = ", ") {
- std::string result;
- for (const auto& item : c) {
- using namespace std;
- result.append(to_string(item));
- result.append(delimiter);
- }
- if (!result.empty()) {
- result.resize(result.length() - delimiter.length());
- }
- return result;
-}
-
-llvm::StringRef StripPrefix(llvm::StringRef string, llvm::StringRef prefix);
diff --git a/tools/versioner/src/VFS.cpp b/tools/versioner/src/VFS.cpp
deleted file mode 100644
index d797f82..0000000
--- a/tools/versioner/src/VFS.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <err.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-
-#include <android-base/unique_fd.h>
-#include <llvm/ADT/IntrusiveRefCntPtr.h>
-#include <llvm/Support/MemoryBuffer.h>
-#include <llvm/Support/VirtualFileSystem.h>
-
-#include "Utils.h"
-
-using android::base::unique_fd;
-using namespace llvm::vfs;
-
-static void addDirectoryToVFS(InMemoryFileSystem* vfs, const std::string& path) {
- char* paths[] = { const_cast<char*>(path.c_str()), nullptr };
- std::unique_ptr<FTS, decltype(&fts_close)> fts(
- fts_open(paths, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, nullptr), fts_close);
-
- if (!fts) {
- err(1, "failed to open directory %s", path.c_str());
- }
-
- while (FTSENT* ent = fts_read(fts.get())) {
- if ((ent->fts_info & FTS_F) == 0) {
- continue;
- }
-
- const char* file_path = ent->fts_accpath;
- unique_fd fd(open(file_path, O_RDONLY | O_CLOEXEC));
- if (fd == -1) {
- err(1, "failed to open header '%s'", file_path);
- }
-
- auto buffer_opt = llvm::MemoryBuffer::getOpenFile(fd, file_path, -1, false, false);
- if (!buffer_opt) {
- errx(1, "failed to map header '%s'", file_path);
- }
-
- if (!vfs->addFile(file_path, ent->fts_statp->st_mtime, std::move(buffer_opt.get()))) {
- errx(1, "failed to add file '%s'", file_path);
- }
- }
-}
-
-llvm::IntrusiveRefCntPtr<FileSystem> createCommonVFS(const std::string& header_dir,
- const std::string& dependency_dir,
- bool add_versioning_header) {
- auto vfs = std::make_unique<InMemoryFileSystem>();
- addDirectoryToVFS(vfs.get(), header_dir);
- if (!dependency_dir.empty()) {
- addDirectoryToVFS(vfs.get(), dependency_dir);
- }
-
- if (add_versioning_header) {
- const char* top = getenv("ANDROID_BUILD_TOP");
- if (!top) {
- errx(1, "-i passed, but ANDROID_BUILD_TOP is unset");
- }
-
- std::string header_path = std::string(top) + "/bionic/libc/include/android/versioning.h";
- auto buffer_opt = llvm::MemoryBuffer::getFile(header_path);
- if (!buffer_opt) {
- err(1, "failed to open %s", header_path.c_str());
- }
- vfs->addFile("android/versioning.h", 0, std::move(buffer_opt.get()));
- }
-
- return llvm::IntrusiveRefCntPtr<FileSystem>(vfs.release());
-}
diff --git a/tools/versioner/src/VFS.h b/tools/versioner/src/VFS.h
deleted file mode 100644
index e4aac75..0000000
--- a/tools/versioner/src/VFS.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-#include <string>
-
-#include <llvm/ADT/IntrusiveRefCntPtr.h>
-#include <llvm/Support/VirtualFileSystem.h>
-
-llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> createCommonVFS(const std::string& header_dir,
- const std::string& dependency_dir,
- bool add_versioning_header);
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
deleted file mode 100644
index 37c8bac..0000000
--- a/tools/versioner/src/versioner.cpp
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-#include <err.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#if defined(__linux__)
-#include <sched.h>
-#endif
-
-#include <atomic>
-#include <chrono>
-#include <functional>
-#include <iostream>
-#include <map>
-#include <memory>
-#include <set>
-#include <sstream>
-#include <string>
-#include <string_view>
-#include <thread>
-#include <unordered_map>
-#include <vector>
-
-#include <llvm/ADT/StringRef.h>
-
-#include <android-base/file.h>
-#include <android-base/macros.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include "Arch.h"
-#include "DeclarationDatabase.h"
-#include "Driver.h"
-#include "Preprocessor.h"
-#include "SymbolDatabase.h"
-#include "Utils.h"
-#include "VFS.h"
-
-#include "versioner.h"
-
-using namespace std::chrono_literals;
-using namespace std::string_literals;
-
-bool strict;
-bool verbose;
-bool add_include;
-
-static int getCpuCount();
-static int max_thread_count = getCpuCount();
-
-static int getCpuCount() {
-#if defined(__linux__)
- cpu_set_t cpu_set;
- int rc = sched_getaffinity(getpid(), sizeof(cpu_set), &cpu_set);
- if (rc != 0) {
- err(1, "sched_getaffinity failed");
- }
- return CPU_COUNT(&cpu_set);
-#else
- return 1;
-#endif
-}
-
-namespace {
-struct HeaderLocationInformation {
- std::string header_path;
- std::string dependency_dir;
- // Absolute paths to ignore all children -- including subdirectories -- of.
- std::unordered_set<std::string> ignored_directories;
-};
-}
-
-static bool is_dir(const std::string& path) {
- struct stat st;
- return stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
-}
-
-static CompilationRequirements collectRequirements(const Arch& arch,
- const HeaderLocationInformation& location) {
- std::vector<std::string> headers =
- collectHeaders(location.header_path, location.ignored_directories);
- std::vector<std::string> dependencies;
-
- if (is_dir(location.header_path)) {
- dependencies.emplace_back(location.header_path);
- }
-
- if (!location.dependency_dir.empty()) {
- auto collect_children = [&dependencies](const std::string& dir_path) {
- DIR* dir = opendir(dir_path.c_str());
- if (!dir) {
- err(1, "failed to open dependency directory '%s'", dir_path.c_str());
- }
-
- struct dirent* dent;
- while ((dent = readdir(dir))) {
- if (dent->d_name[0] == '.') {
- continue;
- }
-
- // TODO: Resolve symlinks.
- std::string dependency = dir_path + "/" + dent->d_name;
-
- struct stat st;
- if (stat(dependency.c_str(), &st) != 0) {
- err(1, "failed to stat dependency '%s'", dependency.c_str());
- }
-
- if (!S_ISDIR(st.st_mode)) {
- errx(1, "'%s' is not a directory", dependency.c_str());
- }
-
- dependencies.push_back(dependency);
- }
-
- closedir(dir);
- };
-
- collect_children(location.dependency_dir + "/common");
- collect_children(location.dependency_dir + "/" + to_string(arch));
- }
-
- auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
- for (const auto& it : ignored_headers) {
- if (!it.second.contains(arch)) {
- continue;
- }
-
- if (header.ends_with("/" + it.first)) {
- return true;
- }
- }
- return false;
- });
-
- headers.erase(new_end, headers.end());
-
- CompilationRequirements result = { .headers = headers, .dependencies = dependencies };
- return result;
-}
-
-static std::set<CompilationType> generateCompilationTypes(const std::set<Arch> selected_architectures,
- const std::set<int>& selected_levels) {
- std::set<CompilationType> result;
- for (const auto& arch : selected_architectures) {
- int min_api = arch_min_api[arch];
- for (int api_level : selected_levels) {
- if (api_level < min_api) {
- continue;
- }
-
- for (int file_offset_bits : { 32, 64 }) {
- for (bool cpp : { true, false }) {
- CompilationType type = {
- .arch = arch, .cpp = cpp, .api_level = api_level, .file_offset_bits = file_offset_bits
- };
- result.insert(type);
- }
- }
- }
- }
- return result;
-}
-
-static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types,
- const HeaderLocationInformation& location) {
- if (types.empty()) {
- errx(1, "compileHeaders received no CompilationTypes");
- }
-
- auto vfs = createCommonVFS(location.header_path, location.dependency_dir, add_include);
-
- size_t thread_count = max_thread_count;
- std::vector<std::thread> threads;
-
- std::map<CompilationType, HeaderDatabase> header_databases;
- std::unordered_map<Arch, CompilationRequirements> requirements;
-
- auto result = std::make_unique<HeaderDatabase>();
- for (const auto& type : types) {
- if (requirements.count(type.arch) == 0) {
- requirements[type.arch] = collectRequirements(type.arch, location);
- }
- }
-
- initializeTargetCC1FlagCache(vfs, types, requirements);
-
- std::vector<std::pair<CompilationType, const std::string&>> jobs;
- std::atomic<size_t> job_index(0);
- for (CompilationType type : types) {
- CompilationRequirements& req = requirements[type.arch];
- for (const std::string& header : req.headers) {
- jobs.emplace_back(type, header);
- }
- }
-
- // Dup an empty file to stdin, so that we can use `clang -include a.h -` instead of `clang a.h`,
- // since some warnings don't get generated in files that are compiled directly.
- FILE* empty_file = tmpfile();
- if (!empty_file) {
- err(1, "failed to create temporary file");
- }
-
- int empty_file_fd = fileno(empty_file);
- if (empty_file_fd == -1) {
- errx(1, "fileno failed on tmpfile");
- }
-
- dup2(empty_file_fd, STDIN_FILENO);
- fclose(empty_file);
-
- thread_count = std::min(thread_count, jobs.size());
-
- if (thread_count == 1) {
- for (const auto& job : jobs) {
- compileHeader(vfs, result.get(), job.first, job.second);
- }
- } else {
- // Spawn threads.
- for (size_t i = 0; i < thread_count; ++i) {
- threads.emplace_back([&jobs, &job_index, &result, vfs]() {
- while (true) {
- size_t idx = job_index++;
- if (idx >= jobs.size()) {
- return;
- }
-
- const auto& job = jobs[idx];
- compileHeader(vfs, result.get(), job.first, job.second);
- }
- });
- }
-
- // Reap them.
- for (auto& thread : threads) {
- thread.join();
- }
- threads.clear();
- }
-
- return result;
-}
-
-static std::set<CompilationType> getCompilationTypes(const Declaration* decl) {
- std::set<CompilationType> result;
- for (const auto& it : decl->availability) {
- result.insert(it.first);
- }
- return result;
-}
-
-template<typename T>
-static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
- std::vector<T> intersection;
- std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection));
- return intersection;
-}
-
-// Perform a validity check on a symbol's declarations, enforcing the following invariants:
-// 1. At most one inline definition of the function exists (overloaded inline functions for
-// _FORTIFY_SOURCE do not count because they are usually introduced to intercept the original
-// functions or usually have enable_if attributes).
-// 2. All of the availability declarations for a symbol are compatible.
-// If a function is declared as an inline before a certain version, the inline definition
-// should have no version tag.
-// 3. Each availability type must only be present globally or on a per-arch basis.
-// (e.g. __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(22) __DEPRECATED_IN(23) is fine,
-// but not __INTRODUCED_IN(9) __INTRODUCED_IN_32(10))
-static bool checkSymbol(const Symbol& symbol) {
- std::string cwd = getWorkingDir() + "/";
-
- std::unordered_map<const Declaration*, std::set<CompilationType>> inline_definitions;
- for (const auto& decl_it : symbol.declarations) {
- const Declaration* decl = &decl_it.second;
- if (decl->is_definition && !decl->fortify_inline) {
- std::set<CompilationType> compilation_types = getCompilationTypes(decl);
- for (const auto& inline_def_it : inline_definitions) {
- auto intersection = Intersection(compilation_types, inline_def_it.second);
- if (!intersection.empty()) {
- fprintf(stderr, "versioner: conflicting inline definitions for symbol %s:\n",
- symbol.name.c_str());
- fprintf(stderr, " declarations visible in: %s\n", Join(intersection, ", ").c_str());
- decl->dump(cwd, stderr, 4);
- inline_def_it.first->dump(cwd, stderr, 4);
- return false;
- }
- }
-
- inline_definitions[decl] = std::move(compilation_types);
- }
-
- DeclarationAvailability availability;
- if (!decl->calculateAvailability(&availability)) {
- fprintf(stderr, "versioner: failed to calculate availability for declaration:\n");
- decl->dump(cwd, stderr, 2);
- return false;
- }
-
- if (decl->is_definition && !availability.empty()) {
- fprintf(stderr, "versioner: inline definition has non-empty versioning information:\n");
- decl->dump(cwd, stderr, 2);
- return false;
- }
- }
-
- DeclarationAvailability availability;
- if (!symbol.calculateAvailability(&availability)) {
- fprintf(stderr, "versioner: inconsistent availability for symbol '%s'\n", symbol.name.c_str());
- symbol.dump(cwd);
- return false;
- }
-
- // TODO: Check invariant #3.
- return true;
-}
-
-static bool validityCheck(const HeaderDatabase* database) {
- bool error = false;
- std::string cwd = getWorkingDir() + "/";
-
- for (const auto& symbol_it : database->symbols) {
- if (!checkSymbol(symbol_it.second)) {
- error = true;
- }
- }
- return !error;
-}
-
-// Check that our symbol availability declarations match the actual NDK
-// platform symbol availability.
-static bool checkVersions(const std::set<CompilationType>& types,
- const HeaderDatabase* header_database,
- const NdkSymbolDatabase& symbol_database) {
- std::string cwd = getWorkingDir() + "/";
- bool failed = false;
-
- std::map<Arch, std::set<CompilationType>> arch_types;
- for (const CompilationType& type : types) {
- arch_types[type.arch].insert(type);
- }
-
- std::set<std::string> completely_unavailable;
- std::map<std::string, std::set<CompilationType>> missing_availability;
- std::map<std::string, std::set<CompilationType>> extra_availability;
-
- for (const auto& symbol_it : header_database->symbols) {
- const auto& symbol_name = symbol_it.first;
- DeclarationAvailability symbol_availability;
-
- if (!symbol_it.second.calculateAvailability(&symbol_availability)) {
- errx(1, "failed to calculate symbol availability");
- }
-
- const auto platform_availability_it = symbol_database.find(symbol_name);
- if (platform_availability_it == symbol_database.end()) {
- completely_unavailable.insert(symbol_name);
- continue;
- }
-
- const auto& platform_availability = platform_availability_it->second;
-
- for (const CompilationType& type : types) {
- bool should_be_available = true;
- const auto& global_availability = symbol_availability.global_availability;
- const auto& arch_availability = symbol_availability.arch_availability[type.arch];
- if (global_availability.introduced != 0 && global_availability.introduced > type.api_level) {
- should_be_available = false;
- }
-
- if (arch_availability.introduced != 0 && arch_availability.introduced > type.api_level) {
- should_be_available = false;
- }
-
- if (global_availability.obsoleted != 0 && global_availability.obsoleted <= type.api_level) {
- should_be_available = false;
- }
-
- if (arch_availability.obsoleted != 0 && arch_availability.obsoleted <= type.api_level) {
- should_be_available = false;
- }
-
- // The function declaration might be (validly) missing for the given CompilationType.
- if (!symbol_it.second.hasDeclaration(type)) {
- should_be_available = false;
- }
-
- bool is_available = platform_availability.count(type);
-
- if (should_be_available != is_available) {
- if (is_available) {
- extra_availability[symbol_name].insert(type);
- } else {
- missing_availability[symbol_name].insert(type);
- }
- }
- }
- }
-
- for (const auto& it : symbol_database) {
- const std::string& symbol_name = it.first;
-
- bool symbol_error = false;
- if (auto missing_it = missing_availability.find(symbol_name);
- missing_it != missing_availability.end()) {
- printf("%s: declaration marked available but symbol missing in [%s]\n", symbol_name.c_str(),
- Join(missing_it->second, ", ").c_str());
- symbol_error = true;
- failed = true;
- }
-
- if (strict) {
- if (auto extra_it = extra_availability.find(symbol_name);
- extra_it != extra_availability.end()) {
- printf("%s: declaration marked unavailable but symbol available in [%s]\n",
- symbol_name.c_str(), Join(extra_it->second, ", ").c_str());
- symbol_error = true;
- failed = true;
- }
- }
-
- if (symbol_error) {
- if (auto symbol_it = header_database->symbols.find(symbol_name);
- symbol_it != header_database->symbols.end()) {
- symbol_it->second.dump(cwd);
- } else {
- errx(1, "failed to find symbol in header database");
- }
- }
- }
-
- // TODO: Verify that function/variable declarations are actually function/variable symbols.
- return !failed;
-}
-
-static void usage(bool help = false) {
- fprintf(stderr, "Usage: versioner [OPTION]... [HEADER_PATH] [DEPS_PATH]\n");
- if (!help) {
- printf("Try 'versioner -h' for more information.\n");
- exit(1);
- } else {
- fprintf(stderr, "Version headers at HEADER_PATH, with DEPS_PATH/ARCH/* on the include path\n");
- fprintf(stderr, "Autodetects paths if HEADER_PATH and DEPS_PATH are not specified\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Target specification (defaults to all):\n");
- fprintf(stderr, " -a API_LEVEL\tbuild with specified API level (can be repeated)\n");
- fprintf(stderr, " \t\tdefaults to %s\n", Join(default_levels).c_str());
- fprintf(stderr, " -r ARCH\tbuild with specified architecture (can be repeated)\n");
- fprintf(stderr, " \t\tvalid architectures are %s\n", Join(supported_archs).c_str());
- fprintf(stderr, "\n");
- fprintf(stderr, "Validation:\n");
- fprintf(stderr, " -p PATH\tcompare against NDK platform at PATH\n");
- fprintf(stderr, " -s\t\tenable strict warnings\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Preprocessing:\n");
- fprintf(stderr, " -o PATH\tpreprocess header files and emit them at PATH\n");
- fprintf(stderr, " -f\t\tpreprocess header files even if validation fails\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Miscellaneous:\n");
- fprintf(stderr, " -F\t\tdo not ignore FORTIFY headers by default\n");
- fprintf(stderr, " -d\t\tdump function availability\n");
- fprintf(stderr, " -j THREADS\tmaximum number of threads to use\n");
- fprintf(stderr, " -v\t\tenable verbose logging\n");
- fprintf(stderr, " -h\t\tdisplay this message\n");
- exit(0);
- }
-}
-
-// versioner uses a prebuilt version of clang, which is not up-to-date wrt/
-// container annotations. So disable container overflow checking. b/37775238
-extern "C" const char* __asan_default_options() {
- return "detect_container_overflow=0";
-}
-
-int main(int argc, char** argv) {
- std::string cwd = getWorkingDir() + "/";
- std::string platform_dir;
- std::set<Arch> selected_architectures;
- std::set<int> selected_levels;
- std::string preprocessor_output_path;
- bool force = false;
- bool dump = false;
- bool ignore_fortify_headers = true;
-
- int c;
- while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
- switch (c) {
- case 'a': {
- char* end;
- int api_level = strtol(optarg, &end, 10);
- if (end == optarg || strlen(end) > 0) {
- usage();
- }
-
- selected_levels.insert(api_level);
- break;
- }
-
- case 'r': {
- std::optional<Arch> arch = arch_from_string(optarg);
- if (!arch) {
- errx(1, "unknown architecture '%s'", optarg);
- }
- selected_architectures.insert(*arch);
- break;
- }
-
- case 'p': {
- if (!platform_dir.empty()) {
- usage();
- }
-
- platform_dir = optarg;
-
- if (platform_dir.empty()) {
- usage();
- }
-
- struct stat st;
- if (stat(platform_dir.c_str(), &st) != 0) {
- err(1, "failed to stat platform directory '%s'", platform_dir.c_str());
- }
- if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) {
- errx(1, "'%s' is not a file or directory", optarg);
- }
- break;
- }
-
- case 's':
- strict = true;
- break;
-
- case 'o':
- if (!preprocessor_output_path.empty()) {
- usage();
- }
- preprocessor_output_path = optarg;
- if (preprocessor_output_path.empty()) {
- usage();
- }
- break;
-
- case 'f':
- force = true;
- break;
-
- case 'd':
- dump = true;
- break;
-
- case 'j':
- if (!android::base::ParseInt<int>(optarg, &max_thread_count, 1)) {
- usage();
- }
- break;
-
- case 'v':
- verbose = true;
- break;
-
- case 'h':
- usage(true);
- break;
-
- case 'i':
- // Secret option for tests to -include <android/versioning.h>.
- add_include = true;
- break;
-
- case 'F':
- ignore_fortify_headers = false;
- break;
-
- default:
- usage();
- break;
- }
- }
-
- if (argc - optind > 2 || optind > argc) {
- usage();
- }
-
- HeaderLocationInformation location;
-
- const char* top = getenv("ANDROID_BUILD_TOP");
- if (!top && (optind == argc || add_include)) {
- fprintf(stderr, "versioner: failed to autodetect bionic paths. Is ANDROID_BUILD_TOP set?\n");
- usage();
- }
-
- if (optind == argc) {
- // Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
- std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
- location.header_path = versioner_dir + "/current";
- location.dependency_dir = versioner_dir + "/dependencies";
- if (platform_dir.empty()) {
- platform_dir = versioner_dir + "/platforms";
- }
- } else {
- if (!android::base::Realpath(argv[optind], &location.header_path)) {
- err(1, "failed to get realpath for path '%s'", argv[optind]);
- }
-
- if (argc - optind == 2) {
- location.dependency_dir = argv[optind + 1];
- }
- }
-
- // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
- // This makes the files there impossible to build on their own.
- if (ignore_fortify_headers) {
- std::string fortify_path = location.header_path;
- if (!android::base::EndsWith(location.header_path, "/")) {
- fortify_path += '/';
- }
- fortify_path += "bits/fortify";
- location.ignored_directories.insert(std::move(fortify_path));
- }
-
- if (selected_levels.empty()) {
- selected_levels = default_levels;
- }
-
- if (selected_architectures.empty()) {
- selected_architectures = supported_archs;
- }
-
-
- struct stat st;
- if (const char *path = location.header_path.c_str(); stat(path, &st) != 0) {
- err(1, "failed to stat '%s'", path);
- }
-
- std::set<CompilationType> compilation_types;
- std::optional<NdkSymbolDatabase> symbol_database;
-
- compilation_types = generateCompilationTypes(selected_architectures, selected_levels);
-
- // Do this before compiling so that we can early exit if the platforms don't match what we
- // expect.
- if (!platform_dir.empty()) {
- symbol_database = parsePlatforms(compilation_types, platform_dir);
- }
-
- auto start = std::chrono::high_resolution_clock::now();
- std::unique_ptr<HeaderDatabase> declaration_database =
- compileHeaders(compilation_types, location);
- auto end = std::chrono::high_resolution_clock::now();
-
- if (verbose) {
- auto diff = (end - start) / 1.0ms;
- printf("Compiled headers for %zu targets in %0.2LFms\n", compilation_types.size(), diff);
- }
-
- bool failed = false;
- if (dump) {
- declaration_database->dump(location.header_path + "/");
- } else {
- if (!validityCheck(declaration_database.get())) {
- printf("versioner: validity check failed\n");
- failed = true;
- }
-
- if (symbol_database) {
- if (!checkVersions(compilation_types, declaration_database.get(), *symbol_database)) {
- printf("versioner: version check failed\n");
- failed = true;
- }
- }
- }
-
- if (!preprocessor_output_path.empty() && (force || !failed)) {
- failed = !preprocessHeaders(preprocessor_output_path, location.header_path,
- declaration_database.get());
- }
- return failed;
-}
diff --git a/tools/versioner/src/versioner.h b/tools/versioner/src/versioner.h
deleted file mode 100644
index 225e14b..0000000
--- a/tools/versioner/src/versioner.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <map>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-
-extern bool strict;
-extern bool verbose;
-extern bool add_include;
-
-#define D(...) \
- do { \
- if (verbose) { \
- printf(__VA_ARGS__); \
- } \
- } while (0)
-
-static const std::unordered_map<std::string, std::set<Arch>> ignored_headers = {
- // Internal header.
- // TODO: we should probably just admit we're never getting rid of this.
- { "sys/_system_properties.h", supported_archs },
-
- // time64.h #errors when included on LP64 archs.
- { "time64.h", { Arch::arm64, Arch::riscv64, Arch::x86_64 } },
-};
diff --git a/tools/versioner/tests/.gitignore b/tools/versioner/tests/.gitignore
deleted file mode 100644
index 89f9ac0..0000000
--- a/tools/versioner/tests/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-out/
diff --git a/tools/versioner/tests/arch_specific/headers/foo.h b/tools/versioner/tests/arch_specific/headers/foo.h
deleted file mode 100644
index 4830a68..0000000
--- a/tools/versioner/tests/arch_specific/headers/foo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo();
-
-#if defined(__i386__)
-int bar();
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/arch_specific/platforms/libc.map.txt b/tools/versioner/tests/arch_specific/platforms/libc.map.txt
deleted file mode 100644
index 5aa11ed..0000000
--- a/tools/versioner/tests/arch_specific/platforms/libc.map.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-LIBC {
- global:
- foo; # arm x86
- bar; # x86
-};
diff --git a/tools/versioner/tests/arch_specific/run.sh b/tools/versioner/tests/arch_specific/run.sh
deleted file mode 100644
index f0d95ae..0000000
--- a/tools/versioner/tests/arch_specific/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -r x86 -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/compilation_error/expected_fail b/tools/versioner/tests/compilation_error/expected_fail
deleted file mode 100644
index f18b625..0000000
--- a/tools/versioner/tests/compilation_error/expected_fail
+++ /dev/null
@@ -1 +0,0 @@
-versioner: compilation generated warnings or errors
diff --git a/tools/versioner/tests/compilation_error/headers/foo.h b/tools/versioner/tests/compilation_error/headers/foo.h
deleted file mode 100644
index 51c087a..0000000
--- a/tools/versioner/tests/compilation_error/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#error foo
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/compilation_error/platforms/libc.map.txt b/tools/versioner/tests/compilation_error/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/compilation_error/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/compilation_error/run.sh b/tools/versioner/tests/compilation_error/run.sh
deleted file mode 100644
index 7e8d489..0000000
--- a/tools/versioner/tests/compilation_error/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i -j1
diff --git a/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h b/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h
deleted file mode 100644
index b2d357a..0000000
--- a/tools/versioner/tests/dependencies/dependencies/arm/archdep/archdep.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef int arm_t;
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h b/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h
deleted file mode 100644
index baa5857..0000000
--- a/tools/versioner/tests/dependencies/dependencies/common/foo/foodep.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef int foo_t;
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h b/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h
deleted file mode 100644
index b73f7cc..0000000
--- a/tools/versioner/tests/dependencies/dependencies/x86/archdep/archdep.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef int x86_t;
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/dependencies/headers/foo.h b/tools/versioner/tests/dependencies/headers/foo.h
deleted file mode 100644
index 875de1b..0000000
--- a/tools/versioner/tests/dependencies/headers/foo.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#include <archdep.h>
-#include <foodep.h>
-
-#if defined(__i386__)
-x86_t foo(foo_t);
-#elif defined(__arm__)
-arm_t foo(foo_t);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/dependencies/platforms/libc.map.txt b/tools/versioner/tests/dependencies/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/dependencies/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/dependencies/run.sh b/tools/versioner/tests/dependencies/run.sh
deleted file mode 100644
index 0c17907..0000000
--- a/tools/versioner/tests/dependencies/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers dependencies -p platforms -r arm -r x86 -a 9
\ No newline at end of file
diff --git a/tools/versioner/tests/extern_cpp/headers/string.h b/tools/versioner/tests/extern_cpp/headers/string.h
deleted file mode 100644
index 5ac43ac..0000000
--- a/tools/versioner/tests/extern_cpp/headers/string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#define __RENAME(x) __asm__(#x)
-
-#if defined(__cplusplus)
-extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-#else
-char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-#endif
-
-char* foo() __INTRODUCED_IN(8);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/extern_cpp/platforms/libc.map.txt b/tools/versioner/tests/extern_cpp/platforms/libc.map.txt
deleted file mode 100644
index 297d1fb..0000000
--- a/tools/versioner/tests/extern_cpp/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- __gnu_basename; # introduced=23
-};
diff --git a/tools/versioner/tests/extern_cpp/run.sh b/tools/versioner/tests/extern_cpp/run.sh
deleted file mode 100644
index e320c95..0000000
--- a/tools/versioner/tests/extern_cpp/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 21 -a 23 -i
diff --git a/tools/versioner/tests/extern_cpp_mismatch/headers/string.h b/tools/versioner/tests/extern_cpp_mismatch/headers/string.h
deleted file mode 100644
index 66133d8..0000000
--- a/tools/versioner/tests/extern_cpp_mismatch/headers/string.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#define __RENAME(x) __asm__(#x)
-
-#if defined(__cplusplus)
-extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-#else
-char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/extern_cpp_mismatch/platforms/libc.map.txt b/tools/versioner/tests/extern_cpp_mismatch/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/extern_cpp_mismatch/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/extern_cpp_mismatch/run.sh b/tools/versioner/tests/extern_cpp_mismatch/run.sh
deleted file mode 100644
index a34fda8..0000000
--- a/tools/versioner/tests/extern_cpp_mismatch/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/fortify_inline/headers/fcntl.h b/tools/versioner/tests/fortify_inline/headers/fcntl.h
deleted file mode 100644
index dc81ef8..0000000
--- a/tools/versioner/tests/fortify_inline/headers/fcntl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern int open_real(const char* name, int flags, ...) __asm__("open");
-
-#define O_CREAT 00000100
-
-typedef unsigned int mode_t;
-
-static inline __attribute__((always_inline))
-int open(const char* name, int flags)
- __attribute__((annotate("versioner_fortify_inline")))
- __attribute__((overloadable))
- __attribute__((enable_if(!(flags & O_CREAT), ""))) {
- return open_real(name, flags);
-}
-
-static inline __attribute__((always_inline))
-int open(const char* name, int flags, mode_t mode)
- __attribute__((annotate("versioner_fortify_inline")))
- __attribute__((overloadable))
- __attribute__((enable_if(flags & O_CREAT, ""))) {
- return open_real(name, flags, mode);
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/fortify_inline/platforms/libc.map.txt b/tools/versioner/tests/fortify_inline/platforms/libc.map.txt
deleted file mode 100644
index 2f09034..0000000
--- a/tools/versioner/tests/fortify_inline/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- open;
-};
diff --git a/tools/versioner/tests/fortify_inline/run.sh b/tools/versioner/tests/fortify_inline/run.sh
deleted file mode 100644
index 9bfbe6d..0000000
--- a/tools/versioner/tests/fortify_inline/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/inline/headers/foo.h b/tools/versioner/tests/inline/headers/foo.h
deleted file mode 100644
index a337f9c..0000000
--- a/tools/versioner/tests/inline/headers/foo.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ < 12
-static int foo() {
- return 0;
-}
-#else
-int foo() __INTRODUCED_IN(12);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/inline/platforms/libc.map.txt b/tools/versioner/tests/inline/platforms/libc.map.txt
deleted file mode 100644
index 4dced92..0000000
--- a/tools/versioner/tests/inline/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo; # introduced=12
-};
diff --git a/tools/versioner/tests/inline/run.sh b/tools/versioner/tests/inline/run.sh
deleted file mode 100644
index 9bfbe6d..0000000
--- a/tools/versioner/tests/inline/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/missing_api/expected_fail b/tools/versioner/tests/missing_api/expected_fail
deleted file mode 100644
index 9f097f7..0000000
--- a/tools/versioner/tests/missing_api/expected_fail
+++ /dev/null
@@ -1,4 +0,0 @@
- foo: introduced = 9
- extern declaration @ headers/foo.h:5:1
- introduced = 9
-versioner: version check failed
diff --git a/tools/versioner/tests/missing_api/headers/foo.h b/tools/versioner/tests/missing_api/headers/foo.h
deleted file mode 100644
index c201dbb..0000000
--- a/tools/versioner/tests/missing_api/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __INTRODUCED_IN(9);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/missing_api/platforms/libc.map.txt b/tools/versioner/tests/missing_api/platforms/libc.map.txt
deleted file mode 100644
index 3701a9d..0000000
--- a/tools/versioner/tests/missing_api/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo; # api-level=9
-};
diff --git a/tools/versioner/tests/missing_api/run.sh b/tools/versioner/tests/missing_api/run.sh
deleted file mode 100644
index 9bfbe6d..0000000
--- a/tools/versioner/tests/missing_api/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/missing_arch/expected_fail b/tools/versioner/tests/missing_arch/expected_fail
deleted file mode 100644
index 7b33e19..0000000
--- a/tools/versioner/tests/missing_arch/expected_fail
+++ /dev/null
@@ -1,4 +0,0 @@
- foo: no availability
- extern declaration @ headers/foo.h:5:1
- no availability
-versioner: version check failed
diff --git a/tools/versioner/tests/missing_arch/headers/foo.h b/tools/versioner/tests/missing_arch/headers/foo.h
deleted file mode 100644
index 5ba4794..0000000
--- a/tools/versioner/tests/missing_arch/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo();
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/missing_arch/platforms/libc.map.txt b/tools/versioner/tests/missing_arch/platforms/libc.map.txt
deleted file mode 100644
index f56190e..0000000
--- a/tools/versioner/tests/missing_arch/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo; # arm
-};
diff --git a/tools/versioner/tests/missing_arch/run.sh b/tools/versioner/tests/missing_arch/run.sh
deleted file mode 100644
index f0d95ae..0000000
--- a/tools/versioner/tests/missing_arch/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -r x86 -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/multiple_decl/headers/bar.h b/tools/versioner/tests/multiple_decl/headers/bar.h
deleted file mode 100644
index b16617b..0000000
--- a/tools/versioner/tests/multiple_decl/headers/bar.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __REMOVED_IN(12);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_decl/headers/foo.h b/tools/versioner/tests/multiple_decl/headers/foo.h
deleted file mode 100644
index b16617b..0000000
--- a/tools/versioner/tests/multiple_decl/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __REMOVED_IN(12);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_decl/platforms/libc.map.txt b/tools/versioner/tests/multiple_decl/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/multiple_decl/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/multiple_decl/run.sh b/tools/versioner/tests/multiple_decl/run.sh
deleted file mode 100644
index a34fda8..0000000
--- a/tools/versioner/tests/multiple_decl/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/multiple_decl_mismatch/expected_fail b/tools/versioner/tests/multiple_decl_mismatch/expected_fail
deleted file mode 100644
index 30e7233..0000000
--- a/tools/versioner/tests/multiple_decl_mismatch/expected_fail
+++ /dev/null
@@ -1,8 +0,0 @@
-versioner: inconsistent availability for symbol 'foo'
-versioner: failed to calculate symbol availability
- foo: invalid
- extern declaration @ headers/bar.h:5:1
- obsoleted = 12
- extern declaration @ headers/foo.h:5:1
- obsoleted = 9
-versioner: validity check failed
diff --git a/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h b/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h
deleted file mode 100644
index b16617b..0000000
--- a/tools/versioner/tests/multiple_decl_mismatch/headers/bar.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __REMOVED_IN(12);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h b/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h
deleted file mode 100644
index 8e8f98c..0000000
--- a/tools/versioner/tests/multiple_decl_mismatch/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __REMOVED_IN(9);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_decl_mismatch/platforms/libc.map.txt b/tools/versioner/tests/multiple_decl_mismatch/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/multiple_decl_mismatch/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/multiple_decl_mismatch/run.sh b/tools/versioner/tests/multiple_decl_mismatch/run.sh
deleted file mode 100644
index a34fda8..0000000
--- a/tools/versioner/tests/multiple_decl_mismatch/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/multiple_definition/expected_fail b/tools/versioner/tests/multiple_definition/expected_fail
deleted file mode 100644
index 5abb833..0000000
--- a/tools/versioner/tests/multiple_definition/expected_fail
+++ /dev/null
@@ -1,7 +0,0 @@
-versioner: conflicting inline definitions for symbol foo:
- declarations visible in: arm-9 [c, fob = 32], arm-9 [c, fob = 64], arm-12 [c, fob = 32], arm-12 [c, fob = 64], arm-9 [c++, fob = 32], arm-9 [c++, fob = 64], arm-12 [c++, fob = 32], arm-12 [c++, fob = 64]
- static definition @ headers/foo.h:5:1
- no availability
- static definition @ headers/bar.h:5:1
- no availability
-versioner: validity check failed
diff --git a/tools/versioner/tests/multiple_definition/headers/bar.h b/tools/versioner/tests/multiple_definition/headers/bar.h
deleted file mode 100644
index 29592c6..0000000
--- a/tools/versioner/tests/multiple_definition/headers/bar.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-static int foo() {
- return 0;
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_definition/headers/foo.h b/tools/versioner/tests/multiple_definition/headers/foo.h
deleted file mode 100644
index 29592c6..0000000
--- a/tools/versioner/tests/multiple_definition/headers/foo.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-static int foo() {
- return 0;
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_definition/platforms/libc.map.txt b/tools/versioner/tests/multiple_definition/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/multiple_definition/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/multiple_definition/run.sh b/tools/versioner/tests/multiple_definition/run.sh
deleted file mode 100644
index e4abbe7..0000000
--- a/tools/versioner/tests/multiple_definition/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/bar.h b/tools/versioner/tests/multiple_definition_ok/headers/bar.h
deleted file mode 100644
index 6eced51..0000000
--- a/tools/versioner/tests/multiple_definition_ok/headers/bar.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ == 12
-static int foo() {
- return 0;
-}
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/foo.h b/tools/versioner/tests/multiple_definition_ok/headers/foo.h
deleted file mode 100644
index 773d274..0000000
--- a/tools/versioner/tests/multiple_definition_ok/headers/foo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ == 9
-static int foo() {
- return 0;
-}
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/platforms/libc.map.txt b/tools/versioner/tests/multiple_definition_ok/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/multiple_definition_ok/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/multiple_definition_ok/run.sh b/tools/versioner/tests/multiple_definition_ok/run.sh
deleted file mode 100644
index e4abbe7..0000000
--- a/tools/versioner/tests/multiple_definition_ok/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
diff --git a/tools/versioner/tests/obsoleted/headers/foo.h b/tools/versioner/tests/obsoleted/headers/foo.h
deleted file mode 100644
index e9630e5..0000000
--- a/tools/versioner/tests/obsoleted/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __INTRODUCED_IN(9) __REMOVED_IN(11);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/obsoleted/platforms/libc.map.txt b/tools/versioner/tests/obsoleted/platforms/libc.map.txt
deleted file mode 100644
index 3701a9d..0000000
--- a/tools/versioner/tests/obsoleted/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo; # api-level=9
-};
diff --git a/tools/versioner/tests/obsoleted/run.sh b/tools/versioner/tests/obsoleted/run.sh
deleted file mode 100644
index 9bfbe6d..0000000
--- a/tools/versioner/tests/obsoleted/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/preprocessor/expected/foo.h b/tools/versioner/tests/preprocessor/expected/foo.h
deleted file mode 100644
index 4f74927..0000000
--- a/tools/versioner/tests/preprocessor/expected/foo.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int always_available();
-
-int also_always_available() __INTRODUCED_IN(9);
-
-
-#if __ANDROID_API__ >= 13
-int needs_guard() __INTRODUCED_IN(13);
-#endif /* __ANDROID_API__ >= 13 */
-
-
-#if __ANDROID_API__ >= 12
-
-#if __ANDROID_API__ >= 13
-int needs_guard_2() __INTRODUCED_IN(13);
-#endif /* __ANDROID_API__ >= 13 */
-
-#endif
-
-#if __ANDROID_API__ >= 13
-int already_guarded() __INTRODUCED_IN(13);
-#endif
-
-#if __ANDROID_API__ > 13
-int already_guarded_2() __INTRODUCED_IN(13);
-#endif
-
-#if defined(__arm__)
-
-#if __ANDROID_API__ >= 14
-int specific_arch() __INTRODUCED_IN(14);
-#endif /* __ANDROID_API__ >= 14 */
-
-
-#if __ANDROID_API__ >= 14
-int specific_arch_already_guarded() __INTRODUCED_IN(14);
-#endif
-
-#if __ANDROID_API__ > 14
-int specific_arch_already_guarded_2() __INTRODUCED_IN(14);
-#endif
-#endif
-
-#if defined(__arm__) || defined(__i386__)
-
-#if __ANDROID_API__ >= 14
-int multiple_archs() __INTRODUCED_IN(14);
-#endif /* __ANDROID_API__ >= 14 */
-
-#endif
-
-// __INTRODUCED_IN_64(21) should be ignored.
-
-#if (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__))
-int multiple_introduced_1() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__)) */
-
-
-// This needs different guards for 32 vs 64.
-
-#if (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__) && __ANDROID_API__ >= 26)
-int multiple_introduced_2() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(26);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 24) || (defined(__LP64__) && __ANDROID_API__ >= 26) */
-
-
-// This produces both an LP64 and a not-LP64 check, but it doesn't need to check for all 64-bit
-// targets separately.
-
-#if (!defined(__LP64__) && __ANDROID_API__ >= 23) || (defined(__LP64__) && __ANDROID_API__ >= 23)
-int multiple_introduced_3() __INTRODUCED_IN_32(23) __INTRODUCED_IN_64(23);
-#endif /* (!defined(__LP64__) && __ANDROID_API__ >= 23) || (defined(__LP64__) && __ANDROID_API__ >= 23) */
-
-
-
-#if (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28)
-int added_to_lp64_late() __INTRODUCED_IN_64(28);
-#endif /* (!defined(__LP64__)) || (defined(__LP64__) && __ANDROID_API__ >= 28) */
-
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor/headers/foo.h b/tools/versioner/tests/preprocessor/headers/foo.h
deleted file mode 100644
index b01d8a9..0000000
--- a/tools/versioner/tests/preprocessor/headers/foo.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int always_available();
-
-int also_always_available() __INTRODUCED_IN(9);
-
-int needs_guard() __INTRODUCED_IN(13);
-
-#if __ANDROID_API__ >= 12
-int needs_guard_2() __INTRODUCED_IN(13);
-#endif
-
-#if __ANDROID_API__ >= 13
-int already_guarded() __INTRODUCED_IN(13);
-#endif
-
-#if __ANDROID_API__ > 13
-int already_guarded_2() __INTRODUCED_IN(13);
-#endif
-
-#if defined(__arm__)
-int specific_arch() __INTRODUCED_IN(14);
-
-#if __ANDROID_API__ >= 14
-int specific_arch_already_guarded() __INTRODUCED_IN(14);
-#endif
-
-#if __ANDROID_API__ > 14
-int specific_arch_already_guarded_2() __INTRODUCED_IN(14);
-#endif
-#endif
-
-#if defined(__arm__) || defined(__i386__)
-int multiple_archs() __INTRODUCED_IN(14);
-#endif
-
-// __INTRODUCED_IN_64(21) should be ignored.
-int multiple_introduced_1() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
-
-// This needs different guards for 32 vs 64.
-int multiple_introduced_2() __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(26);
-
-// This produces both an LP64 and a not-LP64 check, but it doesn't need to check for all 64-bit
-// targets separately.
-int multiple_introduced_3() __INTRODUCED_IN_32(23) __INTRODUCED_IN_64(23);
-
-int added_to_lp64_late() __INTRODUCED_IN_64(28);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor/run.sh b/tools/versioner/tests/preprocessor/run.sh
deleted file mode 100644
index b039656..0000000
--- a/tools/versioner/tests/preprocessor/run.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-set -e
-
-function run_test {
- SRC=$1
- DST=$2
- rm -rf $2
- versioner -a 9 -a 12 -a 13 -a 14 -a 15 -a 21 -a 23 $1 -i -o $2
- diff -q -w -B $2 expected
-}
-
-run_test headers out
-run_test headers/ out
-run_test headers out/
-run_test headers/ out/
-
-run_test `pwd`/headers out
-run_test `pwd`/headers/ out
-run_test `pwd`/headers out/
-run_test `pwd`/headers/ out/
-
-run_test headers `pwd`/out
-run_test headers/ `pwd`/out
-run_test headers `pwd`/out/
-run_test headers/ `pwd`/out/
-
-run_test `pwd`/headers `pwd`/out
-run_test `pwd`/headers/ `pwd`/out
-run_test `pwd`/headers `pwd`/out/
-run_test `pwd`/headers/ `pwd`/out/
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h b/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h
deleted file mode 100644
index 9b2d122..0000000
--- a/tools/versioner/tests/preprocessor_extern_cpp/expected/foo.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#define __RENAME(x) asm(#x)
-
-#if defined(__cplusplus)
-
-#if __ANDROID_API__ >= 24
-extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __INTRODUCED_IN(24);
-#endif /* __ANDROID_API__ >= 24 */
-
-#endif
-
-#if defined(__cplusplus)
-extern "C" int foo();
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-#if __ANDROID_API__ >= 24
-char* strchrnul(char*, int) __INTRODUCED_IN(24);
-#endif /* __ANDROID_API__ >= 24 */
-
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h b/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h
deleted file mode 100644
index de26d21..0000000
--- a/tools/versioner/tests/preprocessor_extern_cpp/headers/foo.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#define __RENAME(x) asm(#x)
-
-#if defined(__cplusplus)
-extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __INTRODUCED_IN(24);
-#endif
-
-#if defined(__cplusplus)
-extern "C" int foo();
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-char* strchrnul(char*, int) __INTRODUCED_IN(24);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_extern_cpp/run.sh b/tools/versioner/tests/preprocessor_extern_cpp/run.sh
deleted file mode 100644
index 50d9b5c..0000000
--- a/tools/versioner/tests/preprocessor_extern_cpp/run.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-set -e
-
-function run_test {
- SRC=$1
- DST=$2
- rm -rf $2
- versioner -a 9 -a 12 -a 13 -a 14 -a 15 $1 -i -o $2
- diff -q -w -B $2 expected
-}
-
-run_test headers out
-run_test headers/ out
-run_test headers out/
-run_test headers/ out/
-
-run_test `pwd`/headers out
-run_test `pwd`/headers/ out
-run_test `pwd`/headers out/
-run_test `pwd`/headers/ out/
-
-run_test headers `pwd`/out
-run_test headers/ `pwd`/out
-run_test headers `pwd`/out/
-run_test headers/ `pwd`/out/
-
-run_test `pwd`/headers `pwd`/out
-run_test `pwd`/headers/ `pwd`/out
-run_test `pwd`/headers `pwd`/out/
-run_test `pwd`/headers/ `pwd`/out/
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
deleted file mode 100644
index dcfaaee..0000000
--- a/tools/versioner/tests/preprocessor_file_offset_bits/expected/foo.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef int off_t;
-typedef int ssize_t;
-typedef unsigned size_t;
-
-#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
-#if _FILE_OFFSET_BITS == 64
-#define __USE_FILE_OFFSET64 1
-#endif
-#endif
-
-#define __RENAME(x) __asm__(#x)
-
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21
-int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
-#else
-int truncate(const char* __path, off_t __length);
-#endif
-
-#if defined(__USE_FILE_OFFSET64)
-
-#if __ANDROID_API__ >= 12
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64)
- __INTRODUCED_IN(12);
-#endif /* __ANDROID_API__ >= 12 */
-
-#else
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
-#endif
-
-#if defined(__USE_FILE_OFFSET64)
-off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
-#else
-off_t lseek(int __fd, off_t __offset, int __whence);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h b/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
deleted file mode 100644
index 5ffffa8..0000000
--- a/tools/versioner/tests/preprocessor_file_offset_bits/headers/foo.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef int off_t;
-typedef int ssize_t;
-typedef unsigned size_t;
-
-#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
-#if _FILE_OFFSET_BITS == 64
-#define __USE_FILE_OFFSET64 1
-#endif
-#endif
-
-#define __RENAME(x) __asm__(#x)
-
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= 21
-int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
-#else
-int truncate(const char* __path, off_t __length);
-#endif
-
-#if defined(__USE_FILE_OFFSET64)
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64)
- __INTRODUCED_IN(12);
-#else
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
-#endif
-
-#if defined(__USE_FILE_OFFSET64)
-off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
-#else
-off_t lseek(int __fd, off_t __offset, int __whence);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_file_offset_bits/run.sh b/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
deleted file mode 100644
index d974cba..0000000
--- a/tools/versioner/tests/preprocessor_file_offset_bits/run.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-set -e
-
-rm -rf out
-versioner headers -a 9 -a 12 -a 13 -i -o out
-diff -q -w -B out expected
diff --git a/tools/versioner/tests/preprocessor_idempotence/expected/foo.h b/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
deleted file mode 100644
index bc442e5..0000000
--- a/tools/versioner/tests/preprocessor_idempotence/expected/foo.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ >= 10
-int foo() __INTRODUCED_IN(10);
-#endif
-
-#if __ANDROID_API__ >= 21
-int bar(int) __INTRODUCED_IN(21);
-#endif
-
-#if __ANDROID_API__ >= 10
-int multiple_1() __INTRODUCED_IN(10);
-int multiple_2() __INTRODUCED_IN(10);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_idempotence/headers/foo.h b/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
deleted file mode 100644
index bc442e5..0000000
--- a/tools/versioner/tests/preprocessor_idempotence/headers/foo.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ >= 10
-int foo() __INTRODUCED_IN(10);
-#endif
-
-#if __ANDROID_API__ >= 21
-int bar(int) __INTRODUCED_IN(21);
-#endif
-
-#if __ANDROID_API__ >= 10
-int multiple_1() __INTRODUCED_IN(10);
-int multiple_2() __INTRODUCED_IN(10);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_idempotence/run.sh b/tools/versioner/tests/preprocessor_idempotence/run.sh
deleted file mode 100644
index 1b0aae2..0000000
--- a/tools/versioner/tests/preprocessor_idempotence/run.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-rm -rf out
-set -e
-versioner headers -i -o out
-diff -q -w -B out expected
diff --git a/tools/versioner/tests/preprocessor_merging/expected/foo.h b/tools/versioner/tests/preprocessor_merging/expected/foo.h
deleted file mode 100644
index ecd7f71..0000000
--- a/tools/versioner/tests/preprocessor_merging/expected/foo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-#if __ANDROID_API__ >= 10
-int block_merging_1() __INTRODUCED_IN(10); // foo
-int block_merging_2() __INTRODUCED_IN(10); /* bar */
-int block_merging_3() __INTRODUCED_IN(10); /* baz
-//*/
-int block_merging_4() __INTRODUCED_IN(10);
-#endif /* __ANDROID_API__ >= 10 */
-
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_merging/headers/foo.h b/tools/versioner/tests/preprocessor_merging/headers/foo.h
deleted file mode 100644
index 7aaa471..0000000
--- a/tools/versioner/tests/preprocessor_merging/headers/foo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int block_merging_1() __INTRODUCED_IN(10); // foo
-int block_merging_2() __INTRODUCED_IN(10); /* bar */
-int block_merging_3() __INTRODUCED_IN(10); /* baz
-//*/
-int block_merging_4() __INTRODUCED_IN(10);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_merging/run.sh b/tools/versioner/tests/preprocessor_merging/run.sh
deleted file mode 100644
index 1929757..0000000
--- a/tools/versioner/tests/preprocessor_merging/run.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-rm -rf out
-set -e
-versioner headers -a 9 -a 10 -a 11 -i -o out
-diff -q -w -B out expected
diff --git a/tools/versioner/tests/preprocessor_no_guard/expected/foo.h b/tools/versioner/tests/preprocessor_no_guard/expected/foo.h
deleted file mode 100644
index 3ef0c30..0000000
--- a/tools/versioner/tests/preprocessor_no_guard/expected/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __VERSIONER_NO_GUARD __INTRODUCED_IN(14);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_no_guard/headers/foo.h b/tools/versioner/tests/preprocessor_no_guard/headers/foo.h
deleted file mode 100644
index 3ef0c30..0000000
--- a/tools/versioner/tests/preprocessor_no_guard/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __VERSIONER_NO_GUARD __INTRODUCED_IN(14);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/preprocessor_no_guard/run.sh b/tools/versioner/tests/preprocessor_no_guard/run.sh
deleted file mode 100644
index 1b0aae2..0000000
--- a/tools/versioner/tests/preprocessor_no_guard/run.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-rm -rf out
-set -e
-versioner headers -i -o out
-diff -q -w -B out expected
diff --git a/tools/versioner/tests/slow_preprocessor_idempotence/run.sh b/tools/versioner/tests/slow_preprocessor_idempotence/run.sh
deleted file mode 100644
index 6426156..0000000
--- a/tools/versioner/tests/slow_preprocessor_idempotence/run.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-rm -rf out
-set -e
-mkdir out
-versioner -o out/initial
-versioner out/initial ../../dependencies -o out/second
-diff -qrwB out/initial out/second
diff --git a/tools/versioner/tests/smoke/headers/foo.h b/tools/versioner/tests/smoke/headers/foo.h
deleted file mode 100644
index c201dbb..0000000
--- a/tools/versioner/tests/smoke/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __INTRODUCED_IN(9);
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/smoke/platforms/libc.map.txt b/tools/versioner/tests/smoke/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/smoke/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/smoke/run.sh b/tools/versioner/tests/smoke/run.sh
deleted file mode 100644
index a34fda8..0000000
--- a/tools/versioner/tests/smoke/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/unnamed_bitfield/headers/foo.h b/tools/versioner/tests/unnamed_bitfield/headers/foo.h
deleted file mode 100644
index 58686c3..0000000
--- a/tools/versioner/tests/unnamed_bitfield/headers/foo.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// <sys/timex.h> was causing a segfault when compiled in C++ mode because
-// versioner was trying to mangle the name of an unnamed bitfield.
-struct foo {
- int : 32;
- int : 32;
- int : 32;
- int : 32;
-};
diff --git a/tools/versioner/tests/unnamed_bitfield/platforms/libc.map.txt b/tools/versioner/tests/unnamed_bitfield/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/unnamed_bitfield/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/unnamed_bitfield/run.sh b/tools/versioner/tests/unnamed_bitfield/run.sh
deleted file mode 100644
index a34fda8..0000000
--- a/tools/versioner/tests/unnamed_bitfield/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/version_mismatch/expected_fail b/tools/versioner/tests/version_mismatch/expected_fail
deleted file mode 100644
index 95d284b..0000000
--- a/tools/versioner/tests/version_mismatch/expected_fail
+++ /dev/null
@@ -1,8 +0,0 @@
-versioner: inconsistent availability for symbol 'foo'
-versioner: failed to calculate symbol availability
- foo: invalid
- extern declaration @ headers/foo.h:6:1
- introduced = 9
- extern declaration @ headers/foo.h:8:1
- introduced = 10
-versioner: validity check failed
diff --git a/tools/versioner/tests/version_mismatch/headers/foo.h b/tools/versioner/tests/version_mismatch/headers/foo.h
deleted file mode 100644
index ea35f36..0000000
--- a/tools/versioner/tests/version_mismatch/headers/foo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if __ANDROID_API__ <= 9
-int foo() __INTRODUCED_IN(9);
-#else
-int foo() __INTRODUCED_IN(10);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/version_mismatch/platforms/libc.map.txt b/tools/versioner/tests/version_mismatch/platforms/libc.map.txt
deleted file mode 100644
index 6cc4a2e..0000000
--- a/tools/versioner/tests/version_mismatch/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo;
-};
diff --git a/tools/versioner/tests/version_mismatch/run.sh b/tools/versioner/tests/version_mismatch/run.sh
deleted file mode 100644
index 9bfbe6d..0000000
--- a/tools/versioner/tests/version_mismatch/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner headers -p platforms -r arm -a 9 -a 12 -i
\ No newline at end of file