Merge "cpp: Explicitly retain array definitions" into main
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/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/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/status.md b/docs/status.md
index 0810499..94784de 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,
@@ -57,6 +61,8 @@
New libc functions in API level 36:
* `qsort_r`, `sig2str`/`str2sig` (POSIX Issue 8 additions).
+ * GNU/BSD extension `lchmod`.
+ * 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`,
diff --git a/libc/Android.bp b/libc/Android.bp
index 42ffd37..eeea728 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -571,7 +571,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",
@@ -625,10 +624,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,
@@ -687,9 +688,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",
@@ -699,8 +702,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",
],
@@ -711,11 +712,7 @@
],
local_include_dirs: [
- "private",
"upstream-openbsd/android/include/",
- "upstream-openbsd/lib/libc/gdtoa/",
- "upstream-openbsd/lib/libc/include/",
- "upstream-openbsd/lib/libc/stdio/",
],
}
@@ -916,6 +913,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",
@@ -1032,7 +1030,6 @@
"bionic/thread_private.cpp",
"bionic/threads.cpp",
"bionic/time.cpp",
- "bionic/time_l.cpp",
"bionic/tmpfile.cpp",
"bionic/umount.cpp",
"bionic/unlink.cpp",
@@ -1184,22 +1181,9 @@
"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",
@@ -1213,18 +1197,14 @@
"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",
@@ -1416,43 +1396,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"],
@@ -1470,6 +1420,30 @@
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",
+ ],
}
// ========================================================
@@ -1666,7 +1640,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
@@ -1696,8 +1669,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"],
},
}
@@ -1808,7 +1780,7 @@
}
cc_library_headers {
- name: "libc_llndk_headers",
+ name: "libc_uapi_headers",
visibility: [
"//external/musl",
],
@@ -1903,13 +1875,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"],
},
},
}
@@ -2229,17 +2201,29 @@
visibility: [
"//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 {
@@ -2259,6 +2243,7 @@
"kernel/uapi/xen/**/*.h",
],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2275,6 +2260,7 @@
to: "scsi",
srcs: ["kernel/android/scsi/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2283,6 +2269,7 @@
to: "arm-linux-androideabi",
srcs: ["kernel/uapi/asm-arm/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2291,6 +2278,7 @@
to: "aarch64-linux-android",
srcs: ["kernel/uapi/asm-arm64/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2299,6 +2287,7 @@
to: "riscv64-linux-android",
srcs: ["kernel/uapi/asm-riscv/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2307,6 +2296,7 @@
to: "i686-linux-android",
srcs: ["kernel/uapi/asm-x86/**/*.h"],
license: "NOTICE",
+ skip_verification: true,
}
ndk_headers {
@@ -2315,23 +2305,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 {
@@ -2981,13 +2961,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/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 182de17..8c5572e 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -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
@@ -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-arm/static_function_dispatch.S b/libc/arch-arm/static_function_dispatch.S
deleted file mode 100644
index a8235c2..0000000
--- a/libc/arch-arm/static_function_dispatch.S
+++ /dev/null
@@ -1,46 +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); \
- b impl; \
-END(name)
-
-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)
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-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
index bb2ba51..ce6c028 100644
--- a/libc/arch-riscv64/dynamic_function_dispatch.cpp
+++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp
@@ -27,12 +27,11 @@
*/
#include <fcntl.h>
+#include <private/bionic_ifuncs.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) {
@@ -53,94 +52,94 @@
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);
+ if (have_fast_v()) RETURN_FUNC(memchr_func_t, memchr_v);
+ RETURN_FUNC(memchr_func_t, memchr_gc);
}
+MEMCHR_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(memcmp_func_t, memcmp_v);
+ RETURN_FUNC(memcmp_func_t, memcmp_gc);
}
+MEMCMP_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(memcpy_func_t, memcpy_v);
+ RETURN_FUNC(memcpy_func_t, memcpy_gc);
}
+MEMCPY_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(memmove_func_t, memmove_v);
+ RETURN_FUNC(memmove_func_t, memmove_gc);
}
+MEMMOVE_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(memset_func_t, memset_v);
+ RETURN_FUNC(memset_func_t, memset_gc);
}
+MEMSET_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(stpcpy_func_t, stpcpy_v);
+ RETURN_FUNC(stpcpy_func_t, stpcpy_gc);
}
+STPCPY_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strcat_func_t, strcat_v);
+ RETURN_FUNC(strcat_func_t, strcat_gc);
}
+STRCAT_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strchr_func_t, strchr_v);
+ RETURN_FUNC(strchr_func_t, strchr_gc);
}
+STRCHR_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strcmp_func_t, strcmp_v);
+ RETURN_FUNC(strcmp_func_t, strcmp_gc);
}
+STRCMP_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strcpy_func_t, strcpy_v);
+ RETURN_FUNC(strcpy_func_t, strcpy_gc);
}
+STRCPY_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strlen_func_t, strlen_v);
+ RETURN_FUNC(strlen_func_t, strlen_gc);
}
+STRLEN_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strncat_func_t, strncat_v);
+ RETURN_FUNC(strncat_func_t, strncat_gc);
}
+STRNCAT_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strncmp_func_t, strncmp_v);
+ RETURN_FUNC(strncmp_func_t, strncmp_gc);
}
+STRNCMP_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strncpy_func_t, strncpy_v);
+ RETURN_FUNC(strncpy_func_t, strncpy_gc);
}
+STRNCPY_SHIM()
-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);
+ if (have_fast_v()) RETURN_FUNC(strnlen_func_t, strnlen_v);
+ RETURN_FUNC(strnlen_func_t, strnlen_gc);
}
+STRNLEN_SHIM()
} // 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-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index 38d8a0a..98d7ec2 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -26,129 +26,26 @@
* 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);
}
+MEMCMP_SHIM()
-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);
+typedef int wmemcmp_func_t(const wchar_t*, const wchar_t*, size_t);
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);
+ __builtin_cpu_init();
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(wmemcmp_func_t, wmemcmp_sse4);
+ RETURN_FUNC(wmemcmp_func_t, wmemcmp_atom);
}
-
-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);
-}
+DEFINE_STATIC_SHIM(int wmemcmp(const wchar_t* lhs, const wchar_t* rhs, size_t n) {
+ FORWARD(wmemcmp)(lhs, rhs, n);
+})
} // 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/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/sse2-memmove-slm.S b/libc/arch-x86/string/sse2-memmove-slm.S
index 7f42374..2ed4e7b 100644
--- a/libc/arch-x86/string/sse2-memmove-slm.S
+++ b/libc/arch-x86/string/sse2-memmove-slm.S
@@ -31,7 +31,7 @@
#define FOR_SILVERMONT
#ifndef MEMMOVE
-# define MEMMOVE memmove_generic
+# define MEMMOVE memmove
#endif
#ifndef L
@@ -551,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-memset-atom.S b/libc/arch-x86/string/sse2-memset-atom.S
deleted file mode 100644
index e43ead0..0000000
--- a/libc/arch-x86/string/sse2-memset-atom.S
+++ /dev/null
@@ -1,841 +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
-
-#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
-
-#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) \
- /* 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)
- 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)
-# define RESTORE_EBX_STATE CFI_PUSH(%ebx)
- PUSH(%ebx)
- SETUP_PIC_REG(bx)
- add $_GLOBAL_OFFSET_TABLE_, %ebx
- cmp __x86_data_cache_size@GOTOFF(%ebx), %ecx
- POP(%ebx)
-
- 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 e4c8fa1..ec2ee52 100644
--- a/libc/arch-x86/string/sse2-memset-slm.S
+++ b/libc/arch-x86/string/sse2-memset-slm.S
@@ -79,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
@@ -88,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
@@ -755,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-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/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
old mode 100755
new mode 100644
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 83e1985..0000000
--- a/libc/arch-x86/string/ssse3-memcpy-atom.S
+++ /dev/null
@@ -1,3124 +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
-
-#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
index 055b489..daaf254 100644
--- a/libc/arch-x86/string/ssse3-strlcat-atom.S
+++ b/libc/arch-x86/string/ssse3-strlcat-atom.S
@@ -82,7 +82,7 @@
#define LEN SRC+4
.text
-ENTRY (strlcat_ssse3)
+ENTRY (strlcat)
mov DST(%esp), %edx
PUSH (%ebx)
mov LEN(%esp), %ebx
diff --git a/libc/arch-x86/string/ssse3-strlcpy-atom.S b/libc/arch-x86/string/ssse3-strlcpy-atom.S
index 1671da6..cdb17cc 100644
--- a/libc/arch-x86/string/ssse3-strlcpy-atom.S
+++ b/libc/arch-x86/string/ssse3-strlcpy-atom.S
@@ -29,8 +29,8 @@
*/
#define USE_AS_STRNCPY
-#define STRCPY strlcpy_ssse3
-#define STRLEN strlcpy_ssse3
+#define STRCPY strlcpy
+#define STRLEN strlcpy
#define USE_AS_STRLCPY
#include "ssse3-strcpy-atom.S"
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
index a307983..8a389a3 100644
--- a/libc/arch-x86/string/ssse3-wcscat-atom.S
+++ b/libc/arch-x86/string/ssse3-wcscat-atom.S
@@ -85,7 +85,7 @@
#define USE_AS_WCSCAT
.text
-ENTRY (wcscat_ssse3)
+ENTRY (wcscat)
PUSH (%edi)
mov STR1(%esp), %edi
mov %edi, %edx
@@ -111,4 +111,4 @@
#define RETURN POP(%edi); ret; CFI_PUSH(%edi)
#include "ssse3-wcscpy-atom.S"
-END (wcscat_ssse3)
+END (wcscat)
diff --git a/libc/arch-x86/string/ssse3-wcscpy-atom.S b/libc/arch-x86/string/ssse3-wcscpy-atom.S
index 80aa15f..27cb61e 100644
--- a/libc/arch-x86/string/ssse3-wcscpy-atom.S
+++ b/libc/arch-x86/string/ssse3-wcscpy-atom.S
@@ -88,7 +88,7 @@
# define LEN STR2+4
.text
-ENTRY (wcscpy_ssse3)
+ENTRY (wcscpy)
mov STR1(%esp), %edx
mov STR2(%esp), %ecx
@@ -648,5 +648,5 @@
ret
#ifndef USE_AS_WCSCAT
-END (wcscpy_ssse3)
+END (wcscpy)
#endif
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/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/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/time_l.cpp b/libc/bionic/lchmod.cpp
similarity index 84%
rename from libc/bionic/time_l.cpp
rename to libc/bionic/lchmod.cpp
index e5fa9a5..928a724 100644
--- a/libc/bionic/time_l.cpp
+++ b/libc/bionic/lchmod.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 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 <time.h>
-//#include <xlocale.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
-char* strptime_l(const char* buf, const char* fmt, struct tm* tm, locale_t) {
- return strptime(buf, fmt, tm);
+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_static.cpp b/libc/bionic/libc_init_static.cpp
index ac97376..7c46113 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>
@@ -293,6 +294,28 @@
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;
@@ -366,7 +389,10 @@
async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
}
}
-
+ struct sigaction action = {};
+ action.sa_flags = SA_SIGINFO | SA_RESTART;
+ action.sa_sigaction = __enable_mte_signal_handler;
+ sigaction(BIONIC_ENABLE_MTE, &action, nullptr);
return;
}
}
@@ -395,12 +421,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();
@@ -447,17 +472,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__};
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/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..65749a4 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) {
@@ -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_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index 9b37225..0a452e9 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;
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..a636d08 100644
--- a/libc/bionic/stdlib_l.cpp
+++ b/libc/bionic/stdlib_l.cpp
@@ -37,23 +37,6 @@
return strtof(s, end_ptr);
}
-long strtol_l(const char* s, char** end_ptr, int base, locale_t) {
- return strtol(s, end_ptr, base);
-}
-
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/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/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/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 b37f17b..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);
@@ -153,10 +162,7 @@
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);
@@ -164,7 +170,4 @@
errno = EINVAL;
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/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/dlext.h b/libc/include/android/dlext.h
index b42e5b2..842ceea 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -30,7 +30,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 +174,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/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index f0985fe..a5a07ef 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -46,10 +46,6 @@
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
#endif
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 6bab291..4411aa1 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -16,42 +16,30 @@
#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, msg) __attribute__((__annotate__("deprecated_in=" #api_level)))
-#define __REMOVED_IN(api_level, msg) __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)
#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)
#endif
#define __INTRODUCED_IN(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
@@ -72,13 +60,8 @@
#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__)
+// Vendor and product modules do not follow SDK versioning. Ignore NDK guards for these modules.
+#if defined(__ANDROID_VNDK__)
#undef __BIONIC_AVAILABILITY
#define __BIONIC_AVAILABILITY(api_level, ...)
-#endif // defined(__ANDROID_VENDOR__)
+#endif // defined(__ANDROID_VNDK__)
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/socket.h b/libc/include/bits/fortify/socket.h
index 02f94cc..1c3605b 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -30,8 +30,7 @@
#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);
+ssize_t __sendto_chk(int, const void* _Nonnull, size_t, size_t, int, const struct sockaddr* _Nullable, socklen_t) __INTRODUCED_IN(26);
ssize_t __recvfrom_chk(int, void* _Nullable, size_t, size_t, int, struct sockaddr* _Nullable, socklen_t* _Nullable);
#if defined(__BIONIC_FORTIFY)
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 7df0b05..041967b 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -38,7 +38,7 @@
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 +220,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/getentropy.h b/libc/include/bits/getentropy.h
index a5a14f7..98d8879 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,6 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+__nodiscard int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __INTRODUCED_IN(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 7b171e8..879b110 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -1371,6 +1371,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..195b34a 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.
*
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..bfc02a8 100644
--- a/libc/include/bits/seek_constants.h
+++ b/libc/include/bits/seek_constants.h
@@ -46,7 +46,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 +54,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/strcasecmp.h b/libc/include/bits/strcasecmp.h
index 23acbe5..be910ad 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,
@@ -54,7 +54,7 @@
int strcasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(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
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 459866e..05b785a 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -116,13 +116,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..13a4254 100644
--- a/libc/include/bits/wctype.h
+++ b/libc/include/bits/wctype.h
@@ -58,8 +58,8 @@
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);
+wint_t towctrans(wint_t __wc, wctrans_t _Nonnull __transform) __INTRODUCED_IN(26);
+wctrans_t _Nullable wctrans(const char* _Nonnull __name) __INTRODUCED_IN(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/dirent.h b/libc/include/dirent.h
index 4f5d0fb..5333d78 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -90,7 +90,7 @@
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 +98,7 @@
DIR* _Nullable opendir(const char* _Nonnull __path);
/**
- * [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * [fopendir(3)](https://man7.org/linux/man-pages/man3/opendir.3.html)
* opens a directory stream for the directory at `__dir_fd`.
*
* Returns null and sets `errno` on failure.
@@ -106,7 +106,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 +116,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 +129,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,13 +137,13 @@
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().
*
@@ -152,7 +152,7 @@
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().
*
@@ -163,7 +163,7 @@
long telldir(DIR* _Nonnull __dir) __INTRODUCED_IN(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 +171,19 @@
int dirfd(DIR* _Nonnull __dir);
/**
- * [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * [alphasort](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](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 +195,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 +209,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
@@ -224,7 +224,7 @@
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
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index d65a409..071d50a 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -48,7 +48,7 @@
} 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.
*
* Returns a pointer to an opaque handle for use with other <dlfcn.h> functions
@@ -58,7 +58,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 +84,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 +97,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 +108,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.
@@ -119,7 +119,7 @@
void* _Nullable dlvsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol, const char* _Nullable __version) __INTRODUCED_IN(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
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..d8122d7 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -43,7 +43,7 @@
__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 +53,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 +63,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 +73,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/err.3.html) outputs the program name, and
* the vprintf()-like formatted message.
*
* Calls exit() with `__status`.
@@ -83,7 +83,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 +91,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 +99,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 +107,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/warn.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..cb867cd 100644
--- a/libc/include/error.h
+++ b/libc/include/error.h
@@ -38,7 +38,7 @@
__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.
*
@@ -47,7 +47,7 @@
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 +55,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 +64,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 +73,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.
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 16ce6fa..1e9a285 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
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..1a30eb7 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.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.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/iconv.h b/libc/include/iconv.h
index 27e04bb..9da46b4 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`,
@@ -63,7 +63,7 @@
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 +74,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.
diff --git a/libc/include/ifaddrs.h b/libc/include/ifaddrs.h
index 7c0dcbf..c4d0e10 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,
@@ -83,7 +83,7 @@
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.
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/link.h b/libc/include/link.h
index ee1fc42..216502e 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -99,7 +99,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..2fa4b49 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,29 +55,29 @@
* 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
+ * [reallocarray(3)](https://man7.org/linux/man-pages/man3/realloc.3.html) resizes
* allocated memory on the heap.
*
* Equivalent to `realloc(__ptr, __item_count * __item_size)` but fails if the
@@ -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);
+#else
+#include <errno.h>
+static __inline __nodiscard void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) {
+ 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:
@@ -349,7 +361,7 @@
#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.
@@ -359,7 +371,7 @@
int mallopt(int __option, int __value) __INTRODUCED_IN(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.
*
@@ -370,7 +382,7 @@
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 +393,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 +404,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.
*
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/nl_types.h b/libc/include/nl_types.h
index f4d7f43..6c9935d 100644
--- a/libc/include/nl_types.h
+++ b/libc/include/nl_types.h
@@ -56,7 +56,7 @@
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)`.
*
@@ -65,7 +65,7 @@
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,7 +75,7 @@
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`.
*/
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 6bdc886..0dda3da 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.
*
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 0163c07..d718b40 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -70,9 +70,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
@@ -144,7 +142,7 @@
const struct timespec* _Nullable __timeout) __INTRODUCED_IN_64(28);
int pthread_cond_wait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex);
-int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nonnull (* _Nonnull __start_routine)(void* _Nonnull), void* _Nullable);
+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;
@@ -246,26 +244,20 @@
int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull __rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull __rwlock);
-#if __ANDROID_API__ >= 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
pthread_t pthread_self(void) __attribute_const__;
diff --git a/libc/include/pty.h b/libc/include/pty.h
index be447d6..1cfb772 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.
*
@@ -52,7 +52,7 @@
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,
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 9f043b6..e8f7736 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -45,42 +45,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 +116,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 +124,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 +132,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 +140,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 +148,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 +156,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 +166,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 +175,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 +183,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 +191,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 +219,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 +227,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.
diff --git a/libc/include/search.h b/libc/include/search.h
index fe897d1..85e31ee 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.
@@ -88,7 +88,7 @@
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 +98,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.
@@ -113,7 +113,7 @@
#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.
@@ -123,7 +123,7 @@
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 +131,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.
@@ -144,7 +144,7 @@
#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 +155,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 +168,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 +177,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 +192,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 +203,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/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 a827c2f..893fa9d 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -128,7 +128,7 @@
#define SIG2STR_MAX 32
/**
- * [sig2str(3)](http://man7.org/linux/man-pages/man3/sig2str.3.html)
+ * [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.
@@ -140,7 +140,7 @@
int sig2str(int __signal, char* _Nonnull __buf) __INTRODUCED_IN(36);
/**
- * [str2sig(3)](http://man7.org/linux/man-pages/man3/str2sig.3.html)
+ * [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.
*
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index 3ce402f..f366239 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -46,14 +46,17 @@
#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);
+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);
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 279c658..d24f6af 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,25 +172,25 @@
#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.
*
@@ -201,17 +201,17 @@
#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)
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);
# 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),
@@ -221,10 +221,10 @@
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),
@@ -234,22 +234,22 @@
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);
#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,
+__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
-__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);
+__nodiscard FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
FILE* _Nullable freopen(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp);
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);
+__nodiscard FILE* _Nullable tmpfile(void);
+__nodiscard FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(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);
@@ -260,20 +260,20 @@
#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);
+__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);
+__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);
#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
int asprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, ...) __printflike(2, 3);
@@ -283,16 +283,16 @@
int setlinebuf(FILE* _Nonnull __fp);
int vasprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
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);
+__nodiscard int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(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)
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);
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index 8b106a6..d426a4a 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -39,7 +39,7 @@
__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.
@@ -47,7 +47,7 @@
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.
@@ -55,7 +55,7 @@
int __freadable(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -63,7 +63,7 @@
int __freading(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -71,7 +71,7 @@
int __fwritable(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -79,7 +79,7 @@
int __fwriting(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -87,15 +87,13 @@
int __flbf(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -111,7 +109,7 @@
size_t __freadahead(FILE* _Nonnull __fp) __INTRODUCED_IN(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.
@@ -134,7 +132,7 @@
#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`.
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index b160e6b..076a978 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -68,28 +68,23 @@
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);
-
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.
+ */
+__nodiscard void* _Nullable aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
-double strtod(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-long double strtold(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr);
-
-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,28 +95,28 @@
* 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));
/**
- * [qsort(3)](http://man7.org/linux/man-pages/man3/qsort.3.html) sorts an array
+ * [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)](http://man7.org/linux/man-pages/man3/qsort_r.3.html) sorts an
+ * [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.
*
@@ -180,7 +175,7 @@
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.
*
@@ -192,7 +187,7 @@
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);
+int mblen(const char* _Nullable __s, size_t __n) __INTRODUCED_IN(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);
@@ -210,22 +205,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 a67df4c..7c1c3be 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -57,7 +57,7 @@
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,7 +65,7 @@
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.
*
@@ -108,8 +108,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 +144,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/strerrordesc_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
@@ -133,7 +160,7 @@
#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.
*
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 4b8cc08..d203bd2 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -72,7 +72,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 +83,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 +94,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/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/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..a5e3c14 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,
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..237d2e2 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(2)](https://man7.org/linux/man-pages/man2/syslog.2.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..1a0e7f6 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,7 +126,7 @@
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/mlock.2.html)
* locks pages (preventing swapping), with optional flags.
*
* Available since API level 30.
@@ -136,7 +136,7 @@
int mlock2(const void* _Nonnull __addr, size_t __size, int __flags) __INTRODUCED_IN(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 +144,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 +152,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 +160,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.
*
@@ -176,7 +176,7 @@
#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.
@@ -212,7 +212,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.
@@ -222,4 +222,16 @@
*/
int posix_madvise(void* _Nonnull __addr, size_t __size, int __advice) __INTRODUCED_IN(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.
+ */
+int mseal(void* _Nonnull __addr, size_t __size, unsigned long __flags) __INTRODUCED_IN(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/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/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..6e32705 100644
--- a/libc/include/sys/quota.h
+++ b/libc/include/sys/quota.h
@@ -45,7 +45,7 @@
__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.
*
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index 2ff5349..b4a9993 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,6 @@
*
* 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);
+__nodiscard ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __INTRODUCED_IN(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/select.h b/libc/include/sys/select.h
index 437a234..d5b3495 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -87,7 +87,7 @@
#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.
@@ -98,7 +98,7 @@
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/select.2.html) waits on a
* set of file descriptors.
*
* Use ppoll() instead.
@@ -109,7 +109,7 @@
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.
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/signalfd.h b/libc/include/sys/signalfd.h
index 2be9bdc..5568b7d 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.
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index f916573..2633b69 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -99,7 +99,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 +142,145 @@
#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.
+ */
+int lchmod(const char* _Nonnull __path, mode_t __mode) __INTRODUCED_IN(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);
+
+/**
+ * [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* _Nonnull __path, struct stat* _Nonnull __buf, int __flags);
+
+/** An alias for fstatat(). */
int fstatat64(int __dir_fd, const char* _Nonnull __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.
+ */
+int mkfifoat(int __dir_fd, const char* _Nonnull __path, mode_t __mode) __INTRODUCED_IN(23);
/**
* Used in the tv_nsec field of an argument to utimensat()/futimens()
@@ -205,14 +324,14 @@
#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);
+int statx(int __dir_fd, const char* _Nullable __path, int __flags, unsigned __mask, struct statx* _Nonnull __buf) __INTRODUCED_IN(30);
#endif
__END_DECLS
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index 7bc5e63..2feca81 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -92,7 +92,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 +100,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/sysinfo.h b/libc/include/sys/sysinfo.h
index cae5c49..5956feb 100644
--- a/libc/include/sys/sysinfo.h
+++ b/libc/include/sys/sysinfo.h
@@ -39,14 +39,14 @@
__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.
@@ -56,7 +56,7 @@
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 +66,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 +76,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.
diff --git a/libc/include/sys/timerfd.h b/libc/include/sys/timerfd.h
index de1f55b..bfa9a55 100644
--- a/libc/include/sys/timerfd.h
+++ b/libc/include/sys/timerfd.h
@@ -33,20 +33,23 @@
* @brief Timer file descriptors.
*/
-#include <fcntl.h> /* For O_CLOEXEC and O_NONBLOCK. */
+#include <fcntl.h>
+#include <linux/timerfd.h>
#include <time.h>
#include <sys/cdefs.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 +62,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 +70,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..828eb47 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -40,7 +40,7 @@
__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.
*
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index c8c64ae..d3e6561 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.
*
@@ -72,7 +72,7 @@
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.
*
@@ -98,7 +98,7 @@
ssize_t pwritev64(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset) __INTRODUCED_IN(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.
*
@@ -110,7 +110,7 @@
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.
*
@@ -136,7 +136,7 @@
ssize_t pwritev64v2(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(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,
@@ -147,7 +147,7 @@
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,
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..1a640ba 100644
--- a/libc/include/sys/vfs.h
+++ b/libc/include/sys/vfs.h
@@ -40,6 +40,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/xattr.h b/libc/include/sys/xattr.h
index 745f50c..38c11e2 100644
--- a/libc/include/sys/xattr.h
+++ b/libc/include/sys/xattr.h
@@ -40,7 +40,7 @@
__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 +55,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 +69,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 +84,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 +96,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 +107,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 +119,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 +131,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 +142,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 +154,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 +163,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 +172,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..33979f0 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -212,34 +212,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..e9d6569 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()
@@ -169,7 +169,7 @@
time_t mktime_z(timezone_t _Nonnull __tz, struct tm* _Nonnull __tm) __INTRODUCED_IN(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 +180,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`.
*
@@ -208,7 +208,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 +219,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 +235,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 +245,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 +261,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 +273,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.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 +283,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
@@ -328,7 +328,7 @@
void tzfree(timezone_t _Nullable __tz) __INTRODUCED_IN(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,7 +340,7 @@
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.
@@ -348,7 +348,7 @@
int clock_getcpuclockid(pid_t __pid, clockid_t* _Nonnull __clock) __INTRODUCED_IN(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 +356,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 +364,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 +375,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 +383,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 +391,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 +399,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 +407,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 +415,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.
*
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 626372a..55a36e7 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -55,7 +55,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 +64,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 +73,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..9bc01f0 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -79,7 +79,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,
@@ -103,7 +103,7 @@
pid_t _Fork(void) __INTRODUCED_IN(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 +114,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 +122,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.
@@ -150,7 +150,7 @@
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 +161,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 +172,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 +183,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 +194,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 +205,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 +216,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 +227,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
@@ -257,8 +257,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/chdir.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)
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/wchar.h b/libc/include/wchar.h
index c4e9679..e86f94d 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);
@@ -94,20 +94,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);
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 73b9a12..df50806 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -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,7 @@
struct timeval timeval;
struct itimerval itimerval;
};
+#include <linux/time.h>
"""
self.assertEqual(self.parse(text), expected)
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index ae89a80..9e5ed42 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -92,7 +92,8 @@
'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-riscv/asm/unistd_32.h',
+ 'kernel/uapi/asm-riscv/asm/unistd_64.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']:
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/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 7eaa89a..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
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
index 3f30c88..2e5f9a4 100644
--- a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -54,6 +54,18 @@
#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)
@@ -62,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 12d8f61..51f4977 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -128,6 +128,13 @@
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/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 17b1c5d..cd647b6 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;
@@ -532,6 +533,9 @@
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 {
@@ -644,6 +648,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 {
@@ -667,4 +707,5 @@
#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_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index 5dd666c..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
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index a2ff6f4..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)
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..4902d6c 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -255,12 +255,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 8fccdaf..06c91c5 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -357,9 +357,6 @@
struct drm_color_ctm {
__u64 matrix[9];
};
-struct drm_color_ctm_3x4 {
- __u64 matrix[12];
-};
struct drm_color_lut {
__u16 red;
__u16 green;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 13eda7c..b43d8df 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -745,6 +745,7 @@
#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 {
@@ -799,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..7ec5ed2 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -37,6 +37,7 @@
#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_NR_RINGS MSM_PARAM_PRIORITIES
struct drm_msm_param {
__u32 pipe;
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 d1b6dad..a034b29 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;
@@ -120,6 +122,7 @@
__u16 gt_id;
#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
__u16 type;
__u32 num_bytes;
@@ -155,6 +158,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;
@@ -309,6 +313,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/bpf.h b/libc/kernel/uapi/linux/bpf.h
index c732920..8d64816 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -367,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,
};
@@ -773,8 +774,11 @@
#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;
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/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/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 334c788..e213ba1 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -270,6 +270,56 @@
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,
@@ -311,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;
@@ -749,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))
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index 6757ef5..ac6391a 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -52,6 +52,7 @@
ETHTOOL_MSG_PLCA_GET_STATUS,
ETHTOOL_MSG_MM_GET,
ETHTOOL_MSG_MM_SET,
+ ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
};
@@ -100,6 +101,7 @@
ETHTOOL_MSG_PLCA_NTF,
ETHTOOL_MSG_MM_GET_REPLY,
ETHTOOL_MSG_MM_NTF,
+ ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
};
@@ -316,10 +318,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,
@@ -635,6 +653,11 @@
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,
@@ -643,6 +666,12 @@
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)
};
@@ -699,6 +728,18 @@
__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)
+};
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
#define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
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/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/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 5505963..6b4f2ea 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -176,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)
diff --git a/libc/kernel/uapi/linux/iommufd.h b/libc/kernel/uapi/linux/iommufd.h
index 2570628..6f663b4 100644
--- a/libc/kernel/uapi/linux/iommufd.h
+++ b/libc/kernel/uapi/linux/iommufd.h
@@ -12,19 +12,20 @@
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/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 62c9872..193dd8e 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 16
struct kfd_ioctl_get_version_args {
__u32 major_version;
__u32 minor_version;
@@ -269,6 +269,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;
@@ -465,6 +466,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/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/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/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 45cb504..bd3f02c 100644
--- a/libc/kernel/uapi/linux/nfsd_netlink.h
+++ b/libc/kernel/uapi/linux/nfsd_netlink.h
@@ -58,6 +58,12 @@
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,
@@ -65,6 +71,8 @@
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 98180c2..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
@@ -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..c8f2208 100644
--- a/libc/kernel/uapi/linux/nsfs.h
+++ b/libc/kernel/uapi/linux/nsfs.h
@@ -7,9 +7,15 @@
#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)
#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/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 6b5143c..bdca553 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -419,6 +419,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)
@@ -497,7 +499,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/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/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/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/stat.h b/libc/kernel/uapi/linux/stat.h
index ff98fd2..aae9ed4 100644
--- a/libc/kernel/uapi/linux/stat.h
+++ b/libc/kernel/uapi/linux/stat.h
@@ -69,7 +69,11 @@
__u32 stx_dio_mem_align;
__u32 stx_dio_offset_align;
__u64 stx_subvol;
- __u64 __spare3[11];
+ __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
@@ -88,6 +92,7 @@
#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
@@ -99,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/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/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/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/version.h b/libc/kernel/uapi/linux/version.h
index 7faa30f..0cc45cf 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 395776
+#define LINUX_VERSION_CODE 396032
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
#define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 10
+#define LINUX_VERSION_PATCHLEVEL 11
#define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 3905949..fb69a8a 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -236,6 +236,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', ' ')
@@ -425,6 +427,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')
@@ -444,6 +456,7 @@
#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_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
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index b8e79e8..9509efe 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -260,6 +260,7 @@
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/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 3dceafd..50f8b8a 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,
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 7347175..02bb061 100644
--- a/libc/kernel/uapi/rdma/mana-abi.h
+++ b/libc/kernel/uapi/rdma/mana-abi.h
@@ -33,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..ebafb00 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -201,6 +201,9 @@
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,
+};
#define MLX5_IB_DW_MATCH_PARAM 0xA0
struct mlx5_ib_match_params {
__u32 match_params[MLX5_IB_DW_MATCH_PARAM];
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index 912a3c0..ac027ac 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -199,6 +199,8 @@
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_NUM_OPS
};
enum rdma_nldev_print_type {
@@ -306,6 +308,9 @@
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_MAX
};
enum rdma_nl_counter_mode {
@@ -318,4 +323,11 @@
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,
+};
#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..a3826a5 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
@@ -343,7 +343,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/asound.h b/libc/kernel/uapi/sound/asound.h
index b608ed5..cfe9f66 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,
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/libc.map.txt b/libc/libc.map.txt
index ffd5d1e..0d2e42f 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -591,6 +591,7 @@
killpg;
klogctl;
labs;
+ lchmod; # introduced=36
lchown;
lcong48; # introduced=23
ldexp;
@@ -670,6 +671,7 @@
mprotect;
mrand48;
mremap;
+ mseal; # introduced=36
msync;
munlock;
munlockall;
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_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_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/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..37b9665 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -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/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-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/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..87db4b1 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -123,7 +123,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
}
@@ -170,7 +169,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
}
diff --git a/libm/Android.bp b/libm/Android.bp
index 9fd79f8..ee86959 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -435,7 +435,6 @@
},
apex_available: [
- "//apex_available:platform",
"com.android.runtime",
],
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosf.c b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
index 42ba126..ede552e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
@@ -22,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)
@@ -46,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;
@@ -66,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_asinf.c b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
index a2ee1a1..8d1aca2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asinf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
@@ -18,12 +18,18 @@
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;
@@ -46,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;
}
@@ -54,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/math_private.h b/libm/upstream-freebsd/lib/msun/src/math_private.h
index f3f7985..1595f90 100644
--- a/libm/upstream-freebsd/lib/msun/src/math_private.h
+++ b/libm/upstream-freebsd/lib/msun/src/math_private.h
@@ -405,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_fma.c b/libm/upstream-freebsd/lib/msun/src/s_fma.c
index 6c889a6..23a8449 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fma.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fma.c
@@ -260,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) {
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmal.c b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
index 80c835d..2fca206 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
@@ -241,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) {
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 4365ea5..bcc2500 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -316,7 +316,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 +326,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 +349,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 +387,7 @@
auto length = readlink(proc_self_fd, buf, sizeof(buf));
if (length == -1) {
if (!is_first_stage_init()) {
- PRINT("readlink(\"%s\" [fd=%d]) failed: %m", proc_self_fd, fd);
+ DL_WARN("readlink(\"%s\" [fd=%d]) failed: %m", proc_self_fd, fd);
}
return false;
}
@@ -818,8 +818,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 +923,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 +936,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 +976,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 +988,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 +1009,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 +1042,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) {
@@ -1249,15 +1248,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 +1329,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 +1472,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 */)) {
@@ -1906,8 +1904,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 +2195,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 +2215,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();
}
}
@@ -2589,8 +2587,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;
}
@@ -2842,8 +2840,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 +2851,7 @@
return false;
} else {
if (!relocating_linker) {
- DEBUG("dynamic = %p", dynamic);
+ LD_DEBUG(dynamic, "dynamic section @%p", dynamic);
}
}
@@ -2883,8 +2881,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 +3096,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 +3115,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 +3124,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 +3264,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) {
@@ -3374,7 +3372,7 @@
return false;
}
- DEBUG("[ finished linking %s ]", get_realpath());
+ LD_DEBUG(any, "[ finished linking %s ]", get_realpath());
#if !defined(__LP64__)
if (has_text_relocations) {
@@ -3556,7 +3554,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_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 73ae2ef..35a93fc 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -251,10 +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: %m",
- ld_config_file_path,
- cp.lineno(),
- value.c_str());
+ 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;
}
@@ -265,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 e6211f7..430a151 100644
--- a/linker/linker_debug.cpp
+++ b/linker/linker_debug.cpp
@@ -30,19 +30,76 @@
#include <unistd.h>
-void linker_log_va_list(int prio, const char* fmt, va_list ap) {
+#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;
+ }
+}
+
+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(5 - prio, "linker", fmt, ap2);
+ 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, ...) {
+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 3aab185..e5f17c4 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -28,54 +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.
-
-#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 0e5fb96..6ccd75b 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -73,21 +73,6 @@
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);
-__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);
- write(STDERR_FILENO, "\n", 1);
- 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", argv0, linker_get_error_buffer());
}
@@ -119,7 +104,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;
}
@@ -147,7 +132,6 @@
}
bool g_is_ldd;
-int g_ld_debug_verbosity;
static std::vector<std::string> g_ld_preload_names;
@@ -250,12 +234,6 @@
return result;
}
-#if defined(__LP64__)
-static char kFallbackLinkerPath[] = "/system/bin/linker64";
-#else
-static char kFallbackLinkerPath[] = "/system/bin/linker";
-#endif
-
// 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.
@@ -302,10 +280,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);
@@ -323,13 +299,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);
- INFO("[ Android dynamic linker (" ABI_STRING ") ]");
+ 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.
@@ -338,18 +312,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,
@@ -380,7 +354,12 @@
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);
@@ -497,27 +476,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;
}
@@ -834,7 +808,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_note_gnu_property.cpp b/linker/linker_note_gnu_property.cpp
index be1aebc..082a604 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.
@@ -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_phdr.cpp b/linker/linker_phdr.cpp
index e89acb5..b7db4cd 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -851,6 +851,106 @@
*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) {
+ 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) {
+ 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) {
+ // 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() {
size_t min_palign = phdr_table_get_minimum_alignment(phdr_table_, phdr_num_);
// Only enforce this on 16 KB systems. Apps may rely on undefined behavior
@@ -876,7 +976,6 @@
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_file_end = seg_start + p_filesz;
@@ -917,79 +1016,18 @@
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: %m", name_.c_str(), i);
+ // Pass the file_length, since it may have been extended by _extend_load_segment_vma().
+ if (!MapSegment(i, file_length)) {
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);
- }
}
- // 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: %m", name_.c_str());
- 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;
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index e865a03..1d6bbe3 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -68,6 +68,11 @@
[[nodiscard]] bool ReadDynamicSection();
[[nodiscard]] bool ReadPadSegmentNote();
[[nodiscard]] bool ReserveAddressSpace(address_space_params* address_space);
+ [[nodiscard]] bool MapSegment(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 LoadSegments();
[[nodiscard]] bool FindPhdr();
[[nodiscard]] bool FindGnuPropertySection();
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 8f85871..bcb1efc 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -147,12 +147,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);
@@ -207,20 +208,9 @@
};
#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;
}
@@ -313,8 +303,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,8 +317,8 @@
if (r_type == R_GENERIC_ABSOLUTE) {
count_relocation_if<IsGeneral>(kRelocAbsolute);
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,8 +327,8 @@
// it.
count_relocation_if<IsGeneral>(kRelocAbsolute);
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) {
@@ -346,8 +336,8 @@
// 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));
+ LD_DEBUG(reloc && IsGeneral, "RELO RELATIVE %16p <- %16p",
+ rel_target, reinterpret_cast<void*>(result));
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
}
@@ -368,8 +358,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;
@@ -406,8 +396,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;
@@ -422,8 +412,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;
@@ -431,8 +421,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;
@@ -449,8 +439,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;
@@ -458,10 +448,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,
@@ -474,9 +464,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);
}
}
}
@@ -488,8 +478,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;
@@ -499,9 +489,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;
@@ -512,9 +502,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;
@@ -559,15 +549,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;
@@ -611,7 +597,7 @@
// 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)) {
@@ -626,7 +612,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;
@@ -642,27 +628,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_soinfo.cpp b/linker/linker_soinfo.cpp
index b2170d8..0549d36 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -45,20 +45,15 @@
#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;
-}
-
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 +139,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_;
@@ -318,8 +313,8 @@
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) {
@@ -352,9 +347,9 @@
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();
@@ -429,9 +424,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,
@@ -441,9 +436,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>
@@ -453,18 +448,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() {
@@ -492,7 +487,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_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 9abe542..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;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index cfaeced..0bd4a32 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -389,6 +389,7 @@
"bug_26110743_test.cpp",
"byteswap_test.cpp",
"complex_test.cpp",
+ "cpu_target_features_test.cpp",
"ctype_test.cpp",
"dirent_test.cpp",
"elf_test.cpp",
@@ -566,12 +567,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 {
@@ -751,6 +746,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).
// -----------------------------------------------------------------------------
@@ -762,8 +791,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",
],
@@ -1089,8 +1120,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.
@@ -1105,9 +1136,6 @@
srcs: [
"hwasan_test.cpp",
],
- shared_libs: [
- "libbase",
- ],
data_libs: [
"libtest_simple_hwasan",
"libtest_simple_hwasan_nohwasan",
@@ -1117,6 +1145,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
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/libc/arch-x86/generic/string/wcscat.c b/tests/clang_fortify_c_only_tests.c
similarity index 78%
rename from libc/arch-x86/generic/string/wcscat.c
rename to tests/clang_fortify_c_only_tests.c
index a102551..3bec848 100644
--- a/libc/arch-x86/generic/string/wcscat.c
+++ b/tests/clang_fortify_c_only_tests.c
@@ -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,5 +26,13 @@
* SUCH DAMAGE.
*/
-#define wcscat wcscat_freebsd
-#include <upstream-freebsd/lib/libc/string/wcscat.c>
+#include <string.h>
+
+// 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 f08fd1f..da7926d 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -89,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>
@@ -133,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/cpu_target_features_test.cpp b/tests/cpu_target_features_test.cpp
new file mode 100644
index 0000000..d773772
--- /dev/null
+++ b/tests/cpu_target_features_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#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__)
+ 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/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/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index ddc0fc1..7b7e0e5 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -444,10 +444,9 @@
return result;
};
- // AID_UPROBESTATS (1093) was added in V, but "trunk stable" means
- // that the 2024Q builds don't have branches like the QPR builds used
- // to, and are tested with the _previous_ release's CTS.
- if (android::base::GetIntProperty("ro.build.version.sdk", 0) == __ANDROID_API_U__) {
+ // AID_UPROBESTATS (1093) was added in API level 35, but "trunk stable" means
+ // that the 2024Q* builds are tested with the _previous_ release's CTS.
+ if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 34) {
#if !defined(AID_UPROBESTATS)
#define AID_UPROBESTATS 1093
#endif
@@ -457,10 +456,9 @@
EXPECT_STREQ(getpwuid(AID_UPROBESTATS)->pw_name, "uprobestats");
}
}
- // AID_VIRTUALMACHINE (3013) was added in V, but "trunk stable" means
- // that the 2024Q builds don't have branches like the QPR builds used
- // to, and are tested with the _previous_ release's CTS.
- if (android::base::GetIntProperty("ro.build.version.sdk", 0) == __ANDROID_API_U__) {
+ // AID_VIRTUALMACHINE (3013) was added in API level 35, but "trunk stable" means
+ // that the 2024Q* builds are tested with the _previous_ release's CTS.
+ if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 34) {
#if !defined(AID_VIRTUALMACHINE)
#define AID_VIRTUALMACHINE 3013
#endif
@@ -470,6 +468,18 @@
EXPECT_STREQ(getpwuid(AID_VIRTUALMACHINE)->pw_name, "virtualmachine");
}
}
+ // AID_CROS_EC (1094) was added in API level 36, but "trunk stable" means
+ // that the 2024Q* builds are tested with the _previous_ release's CTS.
+ if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 35) {
+#if !defined(AID_CROS_EC)
+#define AID_CROS_EC 1094
+#endif
+ ids.erase(AID_CROS_EC);
+ expected_ids.erase(AID_CROS_EC);
+ if (getpwuid(AID_CROS_EC)) {
+ EXPECT_STREQ(getpwuid(AID_CROS_EC)->pw_name, "cros_ec");
+ }
+ }
EXPECT_EQ(expected_ids, ids) << return_differences();
}
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/libs/Android.bp b/tests/libs/Android.bp
index fc7fd40..35f0f0c 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -1852,7 +1852,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 +1891,5 @@
" 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)",
}
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/malloc_test.cpp b/tests/malloc_test.cpp
index 813f348..3f1ba79 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -47,6 +47,7 @@
#include <android-base/file.h>
#include <android-base/test_utils.h>
+#include "DoNotOptimize.h"
#include "utils.h"
#if defined(__BIONIC__)
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/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-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/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-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/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..1c51b11 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -37,7 +37,7 @@
}
TEST(stdatomic, init) {
- atomic_int v = ATOMIC_VAR_INIT(123);
+ atomic_int v = 123;
ASSERT_EQ(123, atomic_load(&v));
atomic_init(&v, 456);
@@ -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));
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 3216066..fac9b9b 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -519,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));
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_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 93daac3..499adbb 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) {}
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_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/unistd_test.cpp b/tests/unistd_test.cpp
index 78b55c1..9ad3b6d 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"
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..a811fd8 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -556,7 +556,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;
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