Merge "Revert "Add debug logging for memtag level""
diff --git a/README.md b/README.md
index 8d8e583..5107f42 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,9 @@
#### tests/ --- unit tests
The `tests/` directory contains unit tests. Roughly arranged as one file per
-publicly-exported header file.
+publicly-exported header file. `tests/headers/` contains compile-only tests
+that just check that things are _in_ the headers, whereas the "real" tests
+check actual _behavior_.
#### benchmarks/ --- benchmarks
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index c5a6ac3..8ffd96f 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -107,7 +107,7 @@
## Correct soname/path handling (Available in API level >= 23)
The dynamic linker now understands the difference
-between a library’s soname and its path (public bug
+between a library’s soname and its path (public bug
https://code.google.com/p/android/issues/detail?id=6670). API level 23
is the first release where search by soname is implemented. Earlier
releases would assume that the basename of the library was the soname,
@@ -326,12 +326,12 @@
## Missing SONAME (Enforced for API level >= 23)
-Each ELF shared object (“native library”) must have a SONAME (Shared
-Object Name) attribute. The NDK toolchain adds this attribute by default,
-so its absence indicates either a misconfigured alternative toolchain
-or a misconfiguration in your build system. A missing SONAME may lead
-to runtime issues such as the wrong library being loaded: the filename
-is used instead when this attribute is missing.
+Each ELF shared object (“native library”) must have a SONAME
+(Shared Object Name) attribute. The NDK build systems add this
+attribute by default, so its absence (or an incorrect soname) indicates
+a misconfiguration in your build system. A missing SONAME may lead to
+runtime issues such as the wrong library being loaded: the filename is
+used instead when this attribute is missing.
```
$ readelf --dynamic libWithSoName.so | grep SONAME
@@ -346,7 +346,7 @@
*Resolution*: the current NDK generates the correct SONAME by
default. Ensure you're using the current NDK and that you haven't
configured your build system to generate incorrect SONAME entries (using
-the -soname linker option).
+the `-soname` linker option).
## `__register_atfork` (Available in API level >= 23)
diff --git a/apex/Android.bp b/apex/Android.bp
index 90a14b2..6201ad1 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -41,6 +41,11 @@
"libc_malloc_debug",
"libc_malloc_hooks",
],
+ arch: {
+ arm64: {
+ native_shared_libs: ["libc_hwasan", "libclang_rt.hwasan"],
+ },
+ },
binaries: [
"linkerconfig",
],
diff --git a/benchmarks/malloc_benchmark.cpp b/benchmarks/malloc_benchmark.cpp
index 18ba523..e733cd0 100644
--- a/benchmarks/malloc_benchmark.cpp
+++ b/benchmarks/malloc_benchmark.cpp
@@ -36,11 +36,11 @@
#if defined(__BIONIC__)
-static void BM_mallopt_purge(benchmark::State& state) {
+static void RunMalloptPurge(benchmark::State& state, int purge_value) {
static size_t sizes[] = {8, 16, 32, 64, 128, 1024, 4096, 16384, 65536, 131072, 1048576};
static int pagesize = getpagesize();
mallopt(M_DECAY_TIME, 1);
- mallopt(M_PURGE, 0);
+ mallopt(M_PURGE_ALL, 0);
for (auto _ : state) {
state.PauseTiming();
std::vector<void*> ptrs;
@@ -63,10 +63,19 @@
ptrs.clear();
state.ResumeTiming();
- mallopt(M_PURGE, 0);
+ mallopt(purge_value, 0);
}
mallopt(M_DECAY_TIME, 0);
}
+
+static void BM_mallopt_purge(benchmark::State& state) {
+ RunMalloptPurge(state, M_PURGE);
+}
BIONIC_BENCHMARK(BM_mallopt_purge);
+static void BM_mallopt_purge_all(benchmark::State& state) {
+ RunMalloptPurge(state, M_PURGE_ALL);
+}
+BIONIC_BENCHMARK(BM_mallopt_purge_all);
+
#endif
diff --git a/benchmarks/malloc_map_benchmark.cpp b/benchmarks/malloc_map_benchmark.cpp
index ba4d62c..5757325 100644
--- a/benchmarks/malloc_map_benchmark.cpp
+++ b/benchmarks/malloc_map_benchmark.cpp
@@ -69,7 +69,7 @@
for (auto _ : state) {
#if defined(__BIONIC__)
state.PauseTiming();
- mallopt(M_PURGE, 0);
+ mallopt(M_PURGE_ALL, 0);
uint64_t rss_bytes_before = 0;
Gather(&rss_bytes_before);
state.ResumeTiming();
@@ -80,7 +80,7 @@
}
#if defined(__BIONIC__)
state.PauseTiming();
- mallopt(M_PURGE, 0);
+ mallopt(M_PURGE_ALL, 0);
Gather(&rss_bytes);
// Try and record only the memory used in the map.
rss_bytes -= rss_bytes_before;
diff --git a/benchmarks/malloc_rss_benchmark.cpp b/benchmarks/malloc_rss_benchmark.cpp
index 58f61d9..4b34e72 100644
--- a/benchmarks/malloc_rss_benchmark.cpp
+++ b/benchmarks/malloc_rss_benchmark.cpp
@@ -112,7 +112,7 @@
// Do an explicit purge to ensure we will be more likely to get the actual
// in-use memory.
- mallopt(M_PURGE, 0);
+ mallopt(M_PURGE_ALL, 0);
android::meminfo::ProcMemInfo proc_mem(getpid());
const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
diff --git a/docs/defines.md b/docs/defines.md
index 4775cd2..65a715e 100644
--- a/docs/defines.md
+++ b/docs/defines.md
@@ -54,7 +54,7 @@
work around issues with some of them, use these macros to detect the versinon of
the NDK you're being built with. Usually only `__NDK_MAJOR__` will be necessary.
-## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`
+## `__arm__`, `__aarch64__`, `__i386__`, `__x86_64__`, `__riscv`
If your code is specific to a particular processor architecture, use these
macros to conditionally compile. Note that the ABI usually called `arm64` uses
diff --git a/docs/elf-tls.md b/docs/elf-tls.md
index 4a62793..d408b3f 100644
--- a/docs/elf-tls.md
+++ b/docs/elf-tls.md
@@ -101,9 +101,9 @@
`R_TLS_DTPOFF` is a dynamic relocation to the offset of `tls_var` within its module's `PT_TLS`
segment.
-`__tls_get_addr` looks up `TlsIndex::module`'s entry in the DTV and adds `TlsIndex::offset` to the
-module's TLS block. Before it can do this, it ensures that the module's TLS block is allocated. A
-simple approach is to allocate memory lazily:
+`__tls_get_addr` looks up `TlsIndex::module_id`'s entry in the DTV and adds `TlsIndex::offset` to
+the module's TLS block. Before it can do this, it ensures that the module's TLS block is allocated.
+A simple approach is to allocate memory lazily:
1. If the current thread's DTV generation count is less than the current global TLS generation, then
`__tls_get_addr` may reallocate the DTV or free blocks for unloaded modules.
diff --git a/docs/status.md b/docs/status.md
index 5d2603a..411b140 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -55,15 +55,23 @@
Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
+New libc functions in V (API level 35):
+ * `timespec_getres` (C23 addition).
+
New libc functions in U (API level 34):
* `close_range` and `copy_file_range` (Linux-specific GNU extensions).
* `memset_explicit` in <string.h> (C23 addition).
* `__freadahead` in <stdio_ext.h> (in musl but not glibc).
+ * `posix_spawn_file_actions_addchdir_np` and
+ `posix_spawn_file_actions_addfchdir_np` in <spawn.h> (in musl/glibc
+ and macOS, but not iOS).
New libc behavior in U (API level 34):
* Support for `%b` and `%B` in the printf/wprintf family, `%b` in the
scanf/wscanf family, and `0b` prefixes with base 0 in the strtol/wcstol
family.
+ * Support for `wN` length modifiers in the printf/wprintf family.
+ * tmpfile() now respects $TMPDIR.
New libc functions in T (API level 33):
* `backtrace`, `backtrace_symbols`, `backtrace_symbols_fd` (`<execinfo.h>`).
diff --git a/libc/Android.bp b/libc/Android.bp
index c101f45..ecabb06 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -827,6 +827,7 @@
riscv64: {
srcs: [
"arch-riscv64/string/__memset_chk.S",
+ "arch-riscv64/string/__memcpy_chk.S",
],
},
},
@@ -1204,8 +1205,8 @@
"bionic/termios.cpp",
"bionic/thread_private.cpp",
"bionic/threads.cpp",
+ "bionic/time.cpp",
"bionic/time_l.cpp",
- "bionic/timespec_get.cpp",
"bionic/tmpfile.cpp",
"bionic/umount.cpp",
"bionic/unlink.cpp",
@@ -1317,7 +1318,7 @@
// ========================================================
genrule {
- name: "syscalls-arm.S",
+ name: "syscalls-arm",
out: ["syscalls-arm.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1325,7 +1326,7 @@
}
genrule {
- name: "syscalls-arm64.S",
+ name: "syscalls-arm64",
out: ["syscalls-arm64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1333,7 +1334,7 @@
}
genrule {
- name: "syscalls-riscv64.S",
+ name: "syscalls-riscv64",
out: ["syscalls-riscv64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1341,7 +1342,7 @@
}
genrule {
- name: "syscalls-x86.S",
+ name: "syscalls-x86",
out: ["syscalls-x86.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1349,7 +1350,7 @@
}
genrule {
- name: "syscalls-x86_64.S",
+ name: "syscalls-x86_64",
out: ["syscalls-x86_64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1361,19 +1362,19 @@
srcs: ["bionic/__set_errno.cpp"],
arch: {
arm: {
- srcs: [":syscalls-arm.S"],
+ srcs: [":syscalls-arm"],
},
arm64: {
- srcs: [":syscalls-arm64.S"],
+ srcs: [":syscalls-arm64"],
},
riscv64: {
- srcs: [":syscalls-riscv64.S"],
+ srcs: [":syscalls-riscv64"],
},
x86: {
- srcs: [":syscalls-x86.S"],
+ srcs: [":syscalls-x86"],
},
x86_64: {
- srcs: [":syscalls-x86_64.S"],
+ srcs: [":syscalls-x86_64"],
},
},
name: "libc_syscalls",
@@ -1673,13 +1674,12 @@
// ========================================================
// libc.a + libc.so
// ========================================================
-cc_library {
+cc_defaults {
defaults: [
"libc_defaults",
"libc_native_allocator_defaults",
],
- name: "libc",
- static_ndk_lib: true,
+ name: "libc_library_defaults",
product_variables: {
platform_sdk_version: {
asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1806,20 +1806,7 @@
},
},
- stubs: {
- symbol_file: "libc.map.txt",
- versions: [
- "29",
- "R",
- "current",
- ],
- },
- llndk: {
- symbol_file: "libc.map.txt",
- export_headers_as_system: true,
- export_preprocessed_headers: ["include"],
- export_llndk_headers: ["libc_llndk_headers"],
- },
+
apex_available: [
"//apex_available:platform",
"com.android.runtime",
@@ -1834,9 +1821,58 @@
},
}
+cc_library {
+ name: "libc",
+ defaults: [
+ "libc_library_defaults",
+ ],
+ stubs: {
+ symbol_file: "libc.map.txt",
+ versions: [
+ "29",
+ "R",
+ "current",
+ ],
+ },
+ static_ndk_lib: true,
+ llndk: {
+ symbol_file: "libc.map.txt",
+ export_headers_as_system: true,
+ export_preprocessed_headers: ["include"],
+ export_llndk_headers: ["libc_llndk_headers"],
+ },
+}
+
+cc_library {
+ name: "libc_hwasan",
+ defaults: [
+ "libc_library_defaults",
+ ],
+ sanitize: {
+ hwaddress: true,
+ },
+ enabled: false,
+ target: {
+ android_arm64: {
+ enabled: true,
+ },
+ },
+ stem: "libc",
+ relative_install_path: "hwasan",
+ // We don't really need the stubs, but this needs to stay to trigger the
+ // symlink logic in soong.
+ stubs: {
+ symbol_file: "libc.map.txt",
+ },
+ native_bridge_supported: false,
+ // It is never correct to depend on this directly. This is only
+ // needed for the runtime apex, and in base_system.mk.
+ visibility: ["//bionic/apex"],
+}
+
genrule {
name: "libc.arm.map",
- out: ["libc.arm.map"],
+ out: ["libc.arm.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -1844,7 +1880,7 @@
genrule {
name: "libc.arm64.map",
- out: ["libc.arm64.map"],
+ out: ["libc.arm64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -1852,7 +1888,7 @@
genrule {
name: "libc.riscv64.map",
- out: ["libc.riscv64.map"],
+ out: ["libc.riscv64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -1860,7 +1896,7 @@
genrule {
name: "libc.x86.map",
- out: ["libc.x86.map"],
+ out: ["libc.x86.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -1868,7 +1904,7 @@
genrule {
name: "libc.x86_64.map",
- out: ["libc.x86_64.map"],
+ out: ["libc.x86_64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2073,7 +2109,7 @@
genrule {
name: "libstdc++.arm.map",
- out: ["libstdc++.arm.map"],
+ out: ["libstdc++.arm.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -2081,7 +2117,7 @@
genrule {
name: "libstdc++.arm64.map",
- out: ["libstdc++.arm64.map"],
+ out: ["libstdc++.arm64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -2089,7 +2125,7 @@
genrule {
name: "libstdc++.riscv64.map",
- out: ["libstdc++.riscv64.map"],
+ out: ["libstdc++.riscv64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -2097,7 +2133,7 @@
genrule {
name: "libstdc++.x86.map",
- out: ["libstdc++.x86.map"],
+ out: ["libstdc++.x86.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -2105,7 +2141,7 @@
genrule {
name: "libstdc++.x86_64.map",
- out: ["libstdc++.x86_64.map"],
+ out: ["libstdc++.x86_64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2178,6 +2214,8 @@
srcs: ["arch-common/bionic/crtbrand.S"],
defaults: ["crt_so_defaults"],
+ // crtbrand is an intermediate artifact, not a final CRT object.
+ exclude_from_ndk_sysroot: true,
}
cc_object {
@@ -2307,6 +2345,11 @@
"arch-arm64/string/__memcpy_chk.S",
],
},
+ riscv64: {
+ srcs: [
+ "arch-riscv64/string/__memcpy_chk.S",
+ ],
+ },
},
whole_static_libs: [
"libarm-optimized-routines-mem",
diff --git a/libc/NOTICE b/libc/NOTICE
index 9d55592..4d3a108 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -894,6 +894,34 @@
-------------------------------------------------------------------
+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.
+
+-------------------------------------------------------------------
+
Copyright (c) 1980, 1983, 1988, 1993
The Regents of the University of California. All rights reserved.
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index 8e00b56..d787a56 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -46,8 +46,6 @@
// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
// 1 sigmask signal mask (not used with _setjmp / _longjmp)
// 2 core_base base of core registers (x18-x30, sp)
-// (We only store the low bits of x18 to avoid leaking the
-// shadow call stack address into memory.)
// 16 float_base base of float registers (d8-d15)
// 24 checksum checksum of core registers
// 25 reserved reserved entries (room to grow)
@@ -68,8 +66,6 @@
#define _JB_D8_D9 (_JB_D10_D11 + 2)
#define _JB_CHECKSUM (_JB_D8_D9 + 2)
-#define SCS_MASK (SCS_SIZE - 1)
-
.macro m_mangle_registers reg, sp_reg
eor x3, x3, \reg
eor x19, x19, \reg
@@ -155,6 +151,9 @@
bic x1, x1, #1
// Mask off the high bits of the shadow call stack pointer.
+ // We only store the low bits of x18 to avoid leaking the
+ // shadow call stack address into memory.
+ // See the SCS commentary in pthread_internal.h for more detail.
and x3, x18, #SCS_MASK
// Save core registers.
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 9eb82d8..9b19232 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -28,6 +28,7 @@
#include <platform/bionic/tls_defines.h>
#include <private/bionic_asm.h>
+#include <private/bionic_asm_offsets.h>
#include <asm/signal.h>
#include <linux/sched.h>
@@ -42,10 +43,29 @@
ldr w10, [x9, #20]
str w0, [x9, #20]
- // Clear vfork_child_stack_bottom_.
- str xzr, [x9, #776]
+ mov x0, #SIGCHLD
- mov x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
+ // If either HWASan or stack MTE is enabled, set up the clone() flags to
+ // make vfork() act like fork(). We don't call the atfork handlers, so we
+ // may deadlock if the child allocates, but we have seen badly written
+ // atfork handlers themselves cause deadlocks [1]. ndk_translation already
+ // implements vfork() as fork() without calling handlers, so we have some
+ // evidence that it isn't necessary to call them.
+ //
+ // POSIX.1 defines vfork() to have the same effect as fork() except that
+ // most behavior, including heap allocation, becomes undefined in the child,
+ // so we aren't violating POSIX by doing this.
+ //
+ // [1] https://cs.android.com/android/platform/superproject/+/master:system/extras/simpleperf/app_api/cpp/simpleperf.cpp;drc=788fa4183441f4977ddbd5a055e42a7fe7691d21;l=308
+#if !__has_feature(hwaddress_sanitizer)
+ // if (!__libc_globals->memtag_stack) x0 |= CLONE_VM | CLONE_VFORK;
+ adrp x1, __libc_globals + OFFSETOF_libc_globals_memtag_stack
+ ldrb w1, [x1, :lo12:__libc_globals + OFFSETOF_libc_globals_memtag_stack]
+ cbnz w1, 1f
+ orr x0, x0, #CLONE_VM
+ orr x0, x0, #CLONE_VFORK
+1:
+#endif
mov x1, xzr
mov x2, xzr
mov x3, xzr
@@ -62,25 +82,6 @@
cneg x0, x0, hi
b.hi __set_errno_internal
- // Clean up stack shadow in the parent process.
- // https://github.com/google/sanitizers/issues/925
- paciasp
- .cfi_negate_ra_state
- stp x0, x30, [sp, #-16]!
- .cfi_adjust_cfa_offset 16
- .cfi_rel_offset x0, 0
- .cfi_rel_offset x30, 8
-
- add x0, sp, #16
- bl memtag_handle_vfork
-
- ldp x0, x30, [sp], #16
- .cfi_adjust_cfa_offset -16
- .cfi_restore x0
- .cfi_restore x30
- autiasp
- .cfi_negate_ra_state
-
.L_exit:
ret
END(vfork)
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index eea2978..26f7ec9 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -36,45 +36,47 @@
// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
// 1 sigmask 64-bit signal mask
// 2 ra
-// 3 s0
+// 3 sp
+// 4 gp
+// 5 s0
// ......
-// 14 s11
-// 15 sp
-// 16 fs0
+// 16 s11
+// 17 fs0
// ......
-// 27 fs11
-// 28 checksum
+// 28 fs11
+// 29 checksum
// _JBLEN: defined in bionic/libc/include/setjmp.h
#define _JB_SIGFLAG 0
#define _JB_SIGMASK 1 * 8
#define _JB_RA 2 * 8
-#define _JB_S0 3 * 8
-#define _JB_S1 4 * 8
-#define _JB_S2 5 * 8
-#define _JB_S3 6 * 8
-#define _JB_S4 7 * 8
-#define _JB_S5 8 * 8
-#define _JB_S6 9 * 8
-#define _JB_S7 10 * 8
-#define _JB_S8 11 * 8
-#define _JB_S9 12 * 8
-#define _JB_S10 13 * 8
-#define _JB_S11 14 * 8
-#define _JB_SP 15 * 8
-#define _JB_FS0 16 * 8
-#define _JB_FS1 17 * 8
-#define _JB_FS2 18 * 8
-#define _JB_FS3 19 * 8
-#define _JB_FS4 20 * 8
-#define _JB_FS5 21 * 8
-#define _JB_FS6 22 * 8
-#define _JB_FS7 23 * 8
-#define _JB_FS8 24 * 8
-#define _JB_FS9 25 * 8
-#define _JB_FS10 26 * 8
-#define _JB_FS11 27 * 8
-#define _JB_CHECKSUM 28 * 8
+#define _JB_SP 3 * 8
+#define _JB_GP 4 * 8
+#define _JB_S0 5 * 8
+#define _JB_S1 6 * 8
+#define _JB_S2 7 * 8
+#define _JB_S3 8 * 8
+#define _JB_S4 9 * 8
+#define _JB_S5 10 * 8
+#define _JB_S6 11 * 8
+#define _JB_S7 12 * 8
+#define _JB_S8 13 * 8
+#define _JB_S9 14 * 8
+#define _JB_S10 15 * 8
+#define _JB_S11 16 * 8
+#define _JB_FS0 17 * 8
+#define _JB_FS1 18 * 8
+#define _JB_FS2 19 * 8
+#define _JB_FS3 20 * 8
+#define _JB_FS4 21 * 8
+#define _JB_FS5 22 * 8
+#define _JB_FS6 23 * 8
+#define _JB_FS7 24 * 8
+#define _JB_FS8 25 * 8
+#define _JB_FS9 26 * 8
+#define _JB_FS10 27 * 8
+#define _JB_FS11 28 * 8
+#define _JB_CHECKSUM 29 * 8
.macro m_mangle_registers reg, sp_reg
xor s0, s0, \reg
@@ -89,12 +91,13 @@
xor s9, s9, \reg
xor s10, s10, \reg
xor s11, s11, \reg
+ xor a4, a4, \reg // a4 is the masked gp (x3) for SCS.
xor \sp_reg, \sp_reg, \reg
.endm
.macro m_calculate_checksum dst, src, scratch
li \dst, 0
- .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
+ .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
ld \scratch, (\i * 8)(\src)
xor \dst, \dst, \scratch
.endr
@@ -151,10 +154,19 @@
ld a1, _JB_SIGFLAG(a0)
andi a1, a1, -2
+ // Mask off the high bits of the shadow call stack pointer.
+ // We only store the low bits of gp to avoid leaking the
+ // shadow call stack address into memory.
+ // See the SCS commentary in pthread_internal.h for more detail.
+ li a4, SCS_MASK
+ and a4, a4, gp
+
// Save core registers.
mv a2, sp
m_mangle_registers a1, sp_reg=a2
sd ra, _JB_RA(a0)
+ sd a4, _JB_GP(a0) // a4 is the masked gp (x3) for SCS.
+ sd a2, _JB_SP(a0)
sd s0, _JB_S0(a0)
sd s1, _JB_S1(a0)
sd s2, _JB_S2(a0)
@@ -167,7 +179,6 @@
sd s9, _JB_S9(a0)
sd s10, _JB_S10(a0)
sd s11, _JB_S11(a0)
- sd a2, _JB_SP(a0)
m_unmangle_registers a1, sp_reg=a2
// Save floating point registers.
@@ -229,6 +240,7 @@
// Restore core registers.
andi a2, a2, -2
ld ra, _JB_RA(a0)
+ ld a4, _JB_GP(a0) // Don't clobber the upper bits of gp (x3) used for SCS yet.
ld s0, _JB_S0(a0)
ld s1, _JB_S1(a0)
ld s2, _JB_S2(a0)
@@ -245,6 +257,11 @@
m_unmangle_registers a2, sp_reg=a3
mv sp, a3
+ // Restore the low bits of the shadow call stack pointer.
+ li a5, ~SCS_MASK
+ and gp, gp, a5
+ or gp, gp, a4
+
addi sp, sp, -24
sd ra, 0(sp)
sd a0, 8(sp)
diff --git a/libc/arch-riscv64/string/__memcpy_chk.S b/libc/arch-riscv64/string/__memcpy_chk.S
new file mode 100644
index 0000000..4a2d13d
--- /dev/null
+++ b/libc/arch-riscv64/string/__memcpy_chk.S
@@ -0,0 +1,9 @@
+#include <private/bionic_asm.h>
+
+ENTRY(__memcpy_chk)
+ bleu a2, a3, 1f
+ call __memcpy_chk_fail
+
+1:
+ tail memcpy
+END(__memcpy_chk)
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index d31fe03..420560f 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -254,7 +254,7 @@
bool alternate = false;
size_t bytelen = sizeof(int);
int slen;
- char buffer[32]; /* temporary buffer used to format numbers */
+ char buffer[64]; // temporary buffer used to format numbers/format errno string
char c;
@@ -345,7 +345,6 @@
/* conversion specifier */
const char* str = buffer;
- char strerror_buf[256];
if (c == 's') {
/* string */
str = va_arg(args, const char*);
@@ -360,7 +359,7 @@
buffer[1] = 'x';
format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
} else if (c == 'm') {
- str = strerror_r(errno, strerror_buf, sizeof(strerror_buf));
+ strerror_r(errno, buffer, sizeof(buffer));
} else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
/* integers - first read value from stack */
uint64_t value;
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 40612e7..863aa97 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -186,6 +186,5 @@
__attribute__((no_sanitize("memtag"))) int execve(const char* pathname, char* const* argv,
char* const* envp) {
- __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
return __execve(pathname, argv, envp);
}
diff --git a/libc/bionic/exit.cpp b/libc/bionic/exit.cpp
index 52fd193..04baac2 100644
--- a/libc/bionic/exit.cpp
+++ b/libc/bionic/exit.cpp
@@ -37,7 +37,6 @@
extern "C" __noreturn void __exit_group(int status);
__attribute__((no_sanitize("memtag"))) void _exit(int status) {
- __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
__exit_group(status);
}
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 73cf973..7dee5e3 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -489,9 +489,9 @@
return strcpy(dst, src);
}
-#if !defined(__arm__) && !defined(__aarch64__)
+#if !defined(__arm__) && !defined(__aarch64__) && !defined(__riscv)
// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-// arm32 and arm64 have assembler implementations, and don't need this C fallback.
+// arm32,arm64,riscv have assembler implementations, and don't need this C fallback.
extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
__check_count("memcpy", "count", count);
__check_buffer_access("memcpy", "write into", count, dst_len);
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index 78d21b0..be21e0c 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -212,29 +212,3 @@
__hwasan_handle_longjmp(sp_dst);
#endif // __has_feature(hwaddress_sanitizer)
}
-
-extern "C" __LIBC_HIDDEN__ __attribute__((no_sanitize("memtag"), no_sanitize("hwaddress"))) void
-memtag_handle_vfork(void* sp __unused) {
-#ifdef __aarch64__
- if (__libc_globals->memtag_stack) {
- void* child_sp = __get_thread()->vfork_child_stack_bottom;
- __get_thread()->vfork_child_stack_bottom = nullptr;
- if (child_sp) {
- size_t distance = reinterpret_cast<uintptr_t>(sp) - reinterpret_cast<uintptr_t>(child_sp);
- if (distance > kUntagLimit) {
- async_safe_fatal(
- "memtag_handle_vfork: stack adjustment too large! %p -> %p, distance %zx > %zx\n",
- child_sp, sp, distance, kUntagLimit);
- } else {
- untag_memory(child_sp, sp);
- }
- } else {
- async_safe_fatal("memtag_handle_vfork: child SP unknown\n");
- }
- }
-#endif // __aarch64__
-
-#if __has_feature(hwaddress_sanitizer)
- __hwasan_handle_vfork(sp);
-#endif // __has_feature(hwaddress_sanitizer)
-}
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index ef488ee..ce3f314 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -102,7 +102,7 @@
}
}
return 1;
- } else if (param == M_PURGE) {
+ } else if (param == M_PURGE || param == M_PURGE_ALL) {
// Only clear the current thread cache since there is no easy way to
// clear the caches of other threads.
// This must be done first so that cleared allocations get purged
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 5d5ecac..59b2ddb 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -289,6 +289,7 @@
"LD_DEBUG",
"LD_DEBUG_OUTPUT",
"LD_DYNAMIC_WEAK",
+ "LD_HWASAN",
"LD_LIBRARY_PATH",
"LD_ORIGIN_PATH",
"LD_PRELOAD",
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 417ce76..844f9d8 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -116,14 +116,14 @@
}
static void __init_shadow_call_stack(pthread_internal_t* thread __unused) {
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__riscv)
// Allocate the stack and the guard region.
char* scs_guard_region = reinterpret_cast<char*>(
mmap(nullptr, SCS_GUARD_REGION_SIZE, 0, MAP_PRIVATE | MAP_ANON, -1, 0));
thread->shadow_call_stack_guard_region = scs_guard_region;
// The address is aligned to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
- // in jmp_buf.
+ // in jmp_buf. See the SCS commentary in pthread_internal.h for more detail.
char* scs_aligned_guard_region =
reinterpret_cast<char*>(align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
@@ -133,11 +133,15 @@
size_t scs_offset =
(getpid() == 1) ? 0 : (arc4random_uniform(SCS_GUARD_REGION_SIZE / SCS_SIZE - 1) * SCS_SIZE);
- // Make the stack readable and writable and store its address in register x18. This is
- // deliberately the only place where the address is stored.
- char *scs = scs_aligned_guard_region + scs_offset;
+ // Make the stack read-write, and store its address in the register we're using as the shadow
+ // stack pointer. This is deliberately the only place where the address is stored.
+ char* scs = scs_aligned_guard_region + scs_offset;
mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
+#if defined(__aarch64__)
__asm__ __volatile__("mov x18, %0" ::"r"(scs));
+#elif defined(__riscv)
+ __asm__ __volatile__("mv x3, %0" ::"r"(scs));
+#endif
#endif
}
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index bde95ec..f584b27 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -117,7 +117,7 @@
__rt_sigprocmask(SIG_BLOCK, &set, nullptr, sizeof(sigset64_t));
}
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__riscv)
// Free the shadow call stack and guard pages.
munmap(thread->shadow_call_stack_guard_region, SCS_GUARD_REGION_SIZE);
#endif
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 7222b62..7efbf6d 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -105,9 +105,14 @@
void* alternate_signal_stack;
- // The start address of the shadow call stack's guard region (arm64 only).
+ // The start address of the shadow call stack's guard region (arm64/riscv64).
+ // This region is SCS_GUARD_REGION_SIZE bytes large, but only SCS_SIZE bytes
+ // are actually used.
+ //
// This address is only used to deallocate the shadow call stack on thread
- // exit; the address of the stack itself is stored only in the x18 register.
+ // exit; the address of the stack itself is stored only in the register used
+ // as the shadow stack pointer (x18 on arm64, gp on riscv64).
+ //
// Because the protection offered by SCS relies on the secrecy of the stack
// address, storing the address here weakens the protection, but only
// slightly, because it is relatively easy for an attacker to discover the
@@ -115,13 +120,24 @@
// to other allocations), but not the stack itself, which is <0.1% of the size
// of the guard region.
//
+ // longjmp()/setjmp() don't store all the bits of the shadow stack pointer,
+ // only the bottom bits covered by SCS_MASK. Since longjmp()/setjmp() between
+ // different threads is undefined behavior (and unsupported on Android), we
+ // can retrieve the high bits of the shadow stack pointer from the current
+ // value in the register --- all the jmp_buf needs to store is where exactly
+ // the shadow stack pointer is *within* the thread's shadow stack: the bottom
+ // bits of the register.
+ //
// There are at least two other options for discovering the start address of
// the guard region on thread exit, but they are not as simple as storing in
// TLS.
- // 1) Derive it from the value of the x18 register. This is only possible in
- // processes that do not contain legacy code that might clobber x18,
- // therefore each process must declare early during process startup whether
- // it might load legacy code.
+ //
+ // 1) Derive it from the current value of the shadow stack pointer. This is
+ // only possible in processes that do not contain legacy code that might
+ // clobber x18 on arm64, therefore each process must declare early during
+ // process startup whether it might load legacy code.
+ // TODO: riscv64 has no legacy code, so we can actually go this route
+ // there, but hopefully we'll actually get the Zisslpcfi extension instead.
// 2) Mark the guard region as such using prctl(PR_SET_VMA_ANON_NAME) and
// discover its address by reading /proc/self/maps. One issue with this is
// that reading /proc/self/maps can race with allocations, so we may need
@@ -160,13 +176,6 @@
bionic_tls* bionic_tls;
int errno_value;
-
- // The last observed value of SP in a vfork child process.
- // The part of the stack between this address and the value of SP when the vfork parent process
- // regains control may have stale MTE tags and needs cleanup. This field is only meaningful while
- // the parent is waiting for the vfork child to return control by calling either exec*() or
- // exit().
- void* vfork_child_stack_bottom;
};
struct ThreadMapping {
diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
index f528286..0acef36 100644
--- a/libc/bionic/scandir.cpp
+++ b/libc/bionic/scandir.cpp
@@ -69,11 +69,8 @@
}
void Sort(int (*comparator)(const dirent**, const dirent**)) {
- // If we have entries and a comparator, sort them.
- if (size_ > 0 && comparator != nullptr) {
- qsort(names_, size_, sizeof(dirent*),
- reinterpret_cast<int (*)(const void*, const void*)>(comparator));
- }
+ qsort(names_, size_, sizeof(dirent*),
+ reinterpret_cast<int (*)(const void*, const void*)>(comparator));
}
private:
@@ -120,7 +117,9 @@
names.Add(entry);
}
- names.Sort(comparator);
+ if (comparator != nullptr) {
+ names.Sort(comparator);
+ }
size_t size = names.size();
*name_list = names.release();
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 7e80ef6..5d76f77 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -68,7 +68,9 @@
enum Action {
kOpen,
kClose,
- kDup2
+ kDup2,
+ kChdir,
+ kFchdir,
};
struct __posix_spawn_file_action {
@@ -93,6 +95,10 @@
} else if (what == kClose) {
// Failure to close is ignored.
close(fd);
+ } else if (what == kChdir) {
+ if (chdir(path) == -1) _exit(127);
+ } else if (what == kFchdir) {
+ if (fchdir(fd) == -1) _exit(127);
} else {
// It's a dup2.
if (fd == new_fd) {
@@ -340,7 +346,7 @@
if (action == nullptr) return errno;
action->next = nullptr;
- if (path != nullptr) {
+ if (what == kOpen || what == kChdir) {
action->path = strdup(path);
if (action->path == nullptr) {
free(action);
@@ -380,3 +386,12 @@
if (fd < 0 || new_fd < 0) return EBADF;
return posix_spawn_add_file_action(actions, kDup2, fd, new_fd, nullptr, 0, 0);
}
+
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t* actions, const char* path) {
+ return posix_spawn_add_file_action(actions, kChdir, -1, -1, path, 0, 0);
+}
+
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t* actions, int fd) {
+ if (fd < 0) return EBADF;
+ return posix_spawn_add_file_action(actions, kFchdir, fd, -1, nullptr, 0, 0);
+}
diff --git a/libc/bionic/syslog.cpp b/libc/bionic/syslog.cpp
index 6b17d26..a459c6b 100644
--- a/libc/bionic/syslog.cpp
+++ b/libc/bionic/syslog.cpp
@@ -18,18 +18,22 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
+#include <unistd.h>
#include <async_safe/log.h>
static const char* syslog_log_tag = nullptr;
static int syslog_priority_mask = 0xff;
+static int syslog_options = 0;
void closelog() {
syslog_log_tag = nullptr;
+ syslog_options = 0;
}
-void openlog(const char* log_tag, int /*options*/, int /*facility*/) {
+void openlog(const char* log_tag, int options, int /*facility*/) {
syslog_log_tag = log_tag;
+ syslog_options = options;
}
int setlogmask(int new_mask) {
@@ -73,10 +77,16 @@
android_log_priority = ANDROID_LOG_DEBUG;
}
- // We can't let async_safe_format_log do the formatting because it doesn't support
- // all the printf functionality.
+ // We can't let async_safe_format_log do the formatting because it doesn't
+ // support all the printf functionality.
char log_line[1024];
- vsnprintf(log_line, sizeof(log_line), fmt, args);
+ int n = vsnprintf(log_line, sizeof(log_line), fmt, args);
+ if (n < 0) return;
async_safe_format_log(android_log_priority, log_tag, "%s", log_line);
+ if ((syslog_options & LOG_PERROR) != 0) {
+ bool have_newline =
+ (n > 0 && n < static_cast<int>(sizeof(log_line)) && log_line[n - 1] == '\n');
+ dprintf(STDERR_FILENO, "%s: %s%s", log_tag, log_line, have_newline ? "" : "\n");
+ }
}
diff --git a/libc/bionic/timespec_get.cpp b/libc/bionic/time.cpp
similarity index 89%
rename from libc/bionic/timespec_get.cpp
rename to libc/bionic/time.cpp
index 7fc2182..800395e 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/libc/bionic/time.cpp
@@ -29,5 +29,9 @@
#include <time.h>
int timespec_get(timespec* ts, int base) {
- return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
+ return (clock_gettime(base - 1, ts) != -1) ? base : 0;
+}
+
+int timespec_getres(timespec* ts, int base) {
+ return (clock_getres(base - 1, ts) != -1) ? base : 0;
}
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index 3d04610..4d6a1fb 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -51,6 +51,9 @@
return nullptr;
}
+// O_TMPFILE isn't available until Linux 3.11, so we fall back to this on
+// older kernels. AOSP was on a new enough kernel in the Lollipop timeframe,
+// so this code should be obsolete by 2025.
static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
char* path = nullptr;
if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
@@ -79,25 +82,18 @@
return __fd_to_fp(fd);
}
-static FILE* __tmpfile_dir(const char* tmp_dir) {
- int fd = open(tmp_dir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd == -1) return __tmpfile_dir_legacy(tmp_dir);
- return __fd_to_fp(fd);
+const char* __get_TMPDIR() {
+ // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
+ // Useless for apps, but good enough for the shell.
+ const char* tmpdir = getenv("TMPDIR");
+ return (tmpdir == nullptr) ? "/data/local/tmp" : tmpdir;
}
FILE* tmpfile() {
- // TODO: get this app's temporary directory from the framework ("/data/data/app/cache").
-
- // $EXTERNAL_STORAGE turns out not to be very useful because it doesn't support hard links.
- // This means we can't do the usual trick of calling unlink before handing the file back.
-
- FILE* fp = __tmpfile_dir("/data/local/tmp");
- if (fp == nullptr) {
- // P_tmpdir is "/tmp/", but POSIX explicitly says that tmpdir(3) should try P_tmpdir before
- // giving up. This is potentially useful for bionic on the host anyway.
- fp = __tmpfile_dir(P_tmpdir);
- }
- return fp;
+ const char* tmpdir = __get_TMPDIR();
+ int fd = open(tmpdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd == -1) return __tmpfile_dir_legacy(tmpdir);
+ return __fd_to_fp(fd);
}
__strong_alias(tmpfile64, tmpfile);
@@ -107,7 +103,7 @@
// since we can't easily remove it...
// $TMPDIR overrides any directory passed in.
- char* tmpdir = getenv("TMPDIR");
+ const char* tmpdir = getenv("TMPDIR");
if (tmpdir != nullptr) dir = tmpdir;
// If we still have no directory, we'll give you a default.
@@ -136,12 +132,7 @@
static char buf[L_tmpnam];
if (s == nullptr) s = buf;
- // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
- // Useless for apps, but good enough for the shell.
- const char* dir = getenv("TMPDIR");
- if (dir == nullptr) dir = "/data/local/tmp";
-
// Make up a mktemp(3) template and defer to it for the real work.
- snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", dir);
+ snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", __get_TMPDIR());
return mktemp(s);
}
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 79085d1..6602e5d 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -162,9 +162,15 @@
*/
#define __ANDROID_API_T__ 33
-/** Names the "U" API level (34), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 14 (aka "U" or "UpsideDownCake") API level (34),
+ * for comparison against `__ANDROID_API__`.
+ */
#define __ANDROID_API_U__ 34
+/** Names the "V" API level (35), for comparison against `__ANDROID_API__`. */
+#define __ANDROID_API_V__ 35
+
/* This file is included in <features.h>, and might be used from .S files. */
#if !defined(__ASSEMBLY__)
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index f0b731c..f216aab 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -157,7 +157,7 @@
uint64_t flags;
/** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
- void* reserved_addr;
+ void* _Nullable reserved_addr;
/** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
size_t reserved_size;
@@ -170,7 +170,7 @@
off64_t library_fd_offset;
/** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
- struct android_namespace_t* library_namespace;
+ struct android_namespace_t* _Nullable library_namespace;
} android_dlextinfo;
/**
@@ -180,7 +180,7 @@
*
* Available since API level 21.
*/
-void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
+void* _Nullable android_dlopen_ext(const char* _Nullable __filename, int __flags, const android_dlextinfo* _Nullable __info)
__INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 59ce133..3de0649 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -159,7 +159,7 @@
*
* The return value points to memory with static lifetime, do not attempt to modify it.
*/
-const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
+const char* _Nonnull android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
/*
* Get an owner tag's value, with the type masked off.
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index e9b606a..f0985fe 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -38,15 +38,15 @@
__BEGIN_DECLS
-static __inline double strtod_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
return strtod(__s, __end_ptr);
}
-static __inline float strtof_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
return strtof(__s, __end_ptr);
}
-static __inline long strtol_l(const char* __s, char** __end_ptr, int __base, locale_t __l) {
+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);
}
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index 5d8d8ee..2be01a9 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -46,6 +46,6 @@
*
* Available since API level 21.
*/
-void android_set_abort_message(const char* __msg) __INTRODUCED_IN(21);
+void android_set_abort_message(const char* _Nullable __msg) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/bits/ctype_inlines.h b/libc/include/bits/ctype_inlines.h
index 744eb91..089a642 100644
--- a/libc/include/bits/ctype_inlines.h
+++ b/libc/include/bits/ctype_inlines.h
@@ -61,7 +61,7 @@
__BEGIN_DECLS
/** Internal implementation detail. Do not use. */
-extern const char* _ctype_;
+extern const char* _Nonnull _ctype_;
/** Returns true if `ch` is in `[A-Za-z0-9]`. */
__BIONIC_CTYPE_INLINE int isalnum(int __ch) {
@@ -175,33 +175,33 @@
#if __ANDROID_API__ >= 21
/** Like isalnum but with an ignored `locale_t`. */
-int isalnum_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isalnum_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isalpha but with an ignored `locale_t`. */
-int isalpha_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isalpha_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isblank but with an ignored `locale_t`. */
-int isblank_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isblank_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like iscntrl but with an ignored `locale_t`. */
-int iscntrl_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int iscntrl_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isdigit but with an ignored `locale_t`. */
-int isdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isdigit_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isgraph but with an ignored `locale_t`. */
-int isgraph_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isgraph_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like islower but with an ignored `locale_t`. */
-int islower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int islower_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isprint but with an ignored `locale_t`. */
-int isprint_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isprint_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like ispunct but with an ignored `locale_t`. */
-int ispunct_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int ispunct_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isspace but with an ignored `locale_t`. */
-int isspace_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isspace_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isupper but with an ignored `locale_t`. */
-int isupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isupper_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like isxdigit but with an ignored `locale_t`. */
-int isxdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isxdigit_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like tolower but with an ignored `locale_t`. */
-int tolower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int tolower_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
/** Like toupper but with an ignored `locale_t`. */
-int toupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int toupper_l(int __ch, locale_t _Nonnull __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines in libc++ before 21.
#endif
diff --git a/libc/include/bits/elf_common.h b/libc/include/bits/elf_common.h
index ea833f4..b3c57a2 100644
--- a/libc/include/bits/elf_common.h
+++ b/libc/include/bits/elf_common.h
@@ -418,12 +418,12 @@
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_X86_64_UNWIND 0x70000001 /* unwind information */
-#define SHT_AMD64_UNWIND SHT_X86_64_UNWIND
+#define SHT_AMD64_UNWIND SHT_X86_64_UNWIND
#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */
-#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
pre-emption map. */
-#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
attributes. */
#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */
#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */
@@ -648,6 +648,11 @@
#define DT_AARCH64_BTI_PLT 0x70000001
#define DT_AARCH64_PAC_PLT 0x70000003
#define DT_AARCH64_VARIANT_PCS 0x70000005
+#define DT_AARCH64_MEMTAG_MODE 0x70000009
+#define DT_AARCH64_MEMTAG_HEAP 0x7000000b
+#define DT_AARCH64_MEMTAG_STACK 0x7000000c
+#define DT_AARCH64_MEMTAG_GLOBALS 0x7000000d
+#define DT_AARCH64_MEMTAG_GLOBALSSZ 0x7000000f
#define DT_ARM_SYMTABSZ 0x70000001
#define DT_ARM_PREEMPTMAP 0x70000002
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index d14eb2c..dc5871b 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -35,8 +35,8 @@
__BEGIN_DECLS
// Avoid circular dependencies since this is exposed from <sys/cdefs.h>.
-int __system_property_get(const char* __name, char* __value);
-int atoi(const char* __s) __attribute_pure__;
+int __system_property_get(const char* _Nonnull __name, char* _Nonnull __value);
+int atoi(const char* _Nonnull __s) __attribute_pure__;
__BIONIC_GET_DEVICE_API_LEVEL_INLINE int android_get_device_api_level() {
char value[92] = { 0 };
diff --git a/libc/include/bits/getopt.h b/libc/include/bits/getopt.h
index 0411716..60a89ed 100644
--- a/libc/include/bits/getopt.h
+++ b/libc/include/bits/getopt.h
@@ -38,12 +38,12 @@
* Returns the next option character on success, returns -1 if all options have been parsed, and
* returns `'?'` on error.
*/
-int getopt(int __argc, char* const __argv[], const char* __options);
+int getopt(int __argc, char* const _Nonnull __argv[_Nullable], const char* _Nonnull __options);
/**
* Points to the text of the corresponding value for options that take an argument.
*/
-extern char* optarg;
+extern char* _Nullable optarg;
/**
* The index of the next element to be processed.
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index c144919..79f7da0 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -906,6 +906,9 @@
#if defined(__NR_restart_syscall)
#define SYS_restart_syscall __NR_restart_syscall
#endif
+#if defined(__NR_riscv_flush_icache)
+ #define SYS_riscv_flush_icache __NR_riscv_flush_icache
+#endif
#if defined(__NR_rmdir)
#define SYS_rmdir __NR_rmdir
#endif
diff --git a/libc/include/bits/strcasecmp.h b/libc/include/bits/strcasecmp.h
index 3994b68..23acbe5 100644
--- a/libc/include/bits/strcasecmp.h
+++ b/libc/include/bits/strcasecmp.h
@@ -46,12 +46,12 @@
* Returns an integer less than, equal to, or greater than zero if the first string is less than,
* equal to, or greater than the second string (ignoring case).
*/
-int strcasecmp(const char* __s1, const char* __s2) __attribute_pure__;
+int strcasecmp(const char* _Nonnull __s1, const char* _Nonnull __s2) __attribute_pure__;
/**
* Like strcasecmp() but taking a `locale_t`.
*/
-int strcasecmp_l(const char* __s1, const char* __s2, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
+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
@@ -61,11 +61,11 @@
* first string is less than, equal to, or greater than the first `n` bytes of the second
* string (ignoring case).
*/
-int strncasecmp(const char* __s1, const char* __s2, size_t __n) __attribute_pure__;
+int strncasecmp(const char* _Nonnull __s1, const char* _Nonnull __s2, size_t __n) __attribute_pure__;
/**
* Like strncasecmp() but taking a `locale_t`.
*/
-int strncasecmp_l(const char* __s1, const char* __s2, size_t __n, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
+int strncasecmp_l(const char* _Nonnull __s1, const char* _Nonnull __s2, size_t __n, locale_t _Nonnull __l) __attribute_pure__ __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/bits/swab.h b/libc/include/bits/swab.h
index 63281b6..9591c2e 100644
--- a/libc/include/bits/swab.h
+++ b/libc/include/bits/swab.h
@@ -38,7 +38,7 @@
__BEGIN_DECLS
-__BIONIC_SWAB_INLINE void swab(const void* __void_src, void* __void_dst, ssize_t __byte_count) {
+__BIONIC_SWAB_INLINE void swab(const void* _Nonnull __void_src, void* _Nonnull __void_dst, ssize_t __byte_count) {
const uint8_t* __src = __BIONIC_CAST(static_cast, const uint8_t*, __void_src);
uint8_t* __dst = __BIONIC_CAST(static_cast, uint8_t*, __void_dst);
while (__byte_count > 1) {
diff --git a/libc/include/bits/wait.h b/libc/include/bits/wait.h
index a6a2129..c7f1fb0 100644
--- a/libc/include/bits/wait.h
+++ b/libc/include/bits/wait.h
@@ -53,7 +53,7 @@
#define WIFEXITED(__status) (WTERMSIG(__status) == 0)
/** Returns true if the process was stopped by a signal. */
-#define WIFSTOPPED(__status) (WTERMSIG(__status) == 0x7f)
+#define WIFSTOPPED(__status) (((__status) & 0xff) == 0x7f)
/** Returns true if the process was terminated by a signal. */
#define WIFSIGNALED(__status) (WTERMSIG((__status)+1) >= 2)
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 2328b1a..2751b9e 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -95,7 +95,7 @@
*
* Returns null and sets `errno` on failure.
*/
-DIR* opendir(const char* __path);
+DIR* _Nullable opendir(const char* _Nonnull __path);
/**
* [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
@@ -103,7 +103,7 @@
*
* Returns null and sets `errno` on failure.
*/
-DIR* fdopendir(int __dir_fd);
+DIR* _Nullable fdopendir(int __dir_fd);
/**
* [readdir(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
@@ -113,7 +113,7 @@
* or returns null and leaves `errno` unchanged at the end of the directory,
* or returns null and sets `errno` on failure.
*/
-struct dirent* readdir(DIR* __dir);
+struct dirent* _Nullable readdir(DIR* _Nonnull __dir);
/**
* [readdir64(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
@@ -123,10 +123,10 @@
* or returns null and leaves `errno` unchanged at the end of the directory,
* or returns null and sets `errno` on failure.
*/
-struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
+struct dirent64* _Nullable readdir64(DIR* _Nonnull __dir) __INTRODUCED_IN(21);
-int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
-int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
+int readdir_r(DIR* _Nonnull __dir, struct dirent* _Nonnull __entry, struct dirent* _Nullable * _Nonnull __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
+int readdir64_r(DIR* _Nonnull __dir, struct dirent64* _Nonnull __entry, struct dirent64* _Nullable * _Nonnull __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
/**
* [closedir(3)](http://man7.org/linux/man-pages/man3/closedir.3.html)
@@ -134,13 +134,13 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int closedir(DIR* __dir);
+int closedir(DIR* _Nonnull __dir);
/**
* [rewinddir(3)](http://man7.org/linux/man-pages/man3/rewinddir.3.html)
* rewinds a directory stream to the first entry.
*/
-void rewinddir(DIR* __dir);
+void rewinddir(DIR* _Nonnull __dir);
/**
* [seekdir(3)](http://man7.org/linux/man-pages/man3/seekdir.3.html)
@@ -149,7 +149,7 @@
*
* Available since API level 23.
*/
-void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
+void seekdir(DIR* _Nonnull __dir, long __location) __INTRODUCED_IN(23);
/**
* [telldir(3)](http://man7.org/linux/man-pages/man3/telldir.3.html)
@@ -160,7 +160,7 @@
*
* Available since API level 23.
*/
-long telldir(DIR* __dir) __INTRODUCED_IN(23);
+long telldir(DIR* _Nonnull __dir) __INTRODUCED_IN(23);
/**
* [dirfd(3)](http://man7.org/linux/man-pages/man3/dirfd.3.html)
@@ -168,13 +168,13 @@
*
* Returns a file descriptor on success and returns -1 and sets `errno` on failure.
*/
-int dirfd(DIR* __dir);
+int dirfd(DIR* _Nonnull __dir);
/**
* [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
* comparator for use with scandir() that uses strcoll().
*/
-int alphasort(const struct dirent** __lhs, const struct dirent** __rhs);
+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
@@ -182,31 +182,33 @@
*
* Available since API level 21.
*/
-int alphasort64(const struct dirent64** __lhs, const struct dirent64** __rhs) __INTRODUCED_IN(21);
+int alphasort64(const struct dirent64* _Nonnull * _Nonnull __lhs, const struct dirent64* _Nonnull * _Nonnull __rhs) __INTRODUCED_IN(21);
/**
* [scandir(3)](http://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.
+ * Passing NULL as the comparator skips sorting.
*
* Returns the number of entries returned in the list on success,
* and returns -1 and sets `errno` on failure.
*/
-int scandir(const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**));
+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)
* 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.
+ * Passing NULL as the comparator skips sorting.
*
* Returns the number of entries returned in the list on success,
* and returns -1 and sets `errno` on failure.
*
* Available since API level 21.
*/
-int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+int scandir64(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(21);
#if defined(__USE_GNU)
@@ -216,13 +218,14 @@
* 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.
+ * Passing NULL as the comparator skips sorting.
*
* Returns the number of entries returned in the list on success,
* and returns -1 and sets `errno` on failure.
*
* Available since API level 24.
*/
-int scandirat64(int __dir_fd, const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
+int scandirat64(int __dir_fd, const char* _Nonnull __path, struct dirent64* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent64* _Nonnull), int (* _Nullable __comparator)(const struct dirent64* _Nonnull * _Nonnull, const struct dirent64* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
/**
* [scandirat(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
@@ -230,13 +233,14 @@
* 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.
+ * Passing NULL as the comparator skips sorting.
*
* Returns the number of entries returned in the list on success,
* and returns -1 and sets `errno` on failure.
*
* Available since API level 24.
*/
-int scandirat(int __dir_fd, const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
+int scandirat(int __dir_fd, const char* _Nonnull __path, struct dirent* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent* _Nonnull), int (* _Nullable __comparator)(const struct dirent* _Nonnull * _Nonnull, const struct dirent* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
#endif
diff --git a/libc/include/fts.h b/libc/include/fts.h
index 7e63111..bae2615 100644
--- a/libc/include/fts.h
+++ b/libc/include/fts.h
@@ -39,15 +39,15 @@
#include <sys/types.h>
typedef struct {
- struct _ftsent *fts_cur; /* current node */
- struct _ftsent *fts_child; /* linked list of children */
- struct _ftsent **fts_array; /* sort array */
+ struct _ftsent * _Nullable fts_cur; /* current node */
+ struct _ftsent * _Nullable fts_child; /* linked list of children */
+ struct _ftsent * _Nullable * _Nullable fts_array; /* sort array */
dev_t fts_dev; /* starting device # */
- char *fts_path; /* path for this descent */
+ char * _Nullable fts_path; /* path for this descent */
int fts_rfd; /* fd for root */
size_t fts_pathlen; /* sizeof(path) */
int fts_nitems; /* elements in the sort array */
- int (*fts_compar)(); /* compare function */
+ int (* _Nullable fts_compar)(); /* compare function */
#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */
#define FTS_LOGICAL 0x0002 /* logical walk */
@@ -65,13 +65,13 @@
} FTS;
typedef struct _ftsent {
- struct _ftsent *fts_cycle; /* cycle node */
- struct _ftsent *fts_parent; /* parent directory */
- struct _ftsent *fts_link; /* next file in directory */
+ struct _ftsent * _Nullable fts_cycle; /* cycle node */
+ struct _ftsent * _Nullable fts_parent; /* parent directory */
+ struct _ftsent * _Nullable fts_link; /* next file in directory */
long fts_number; /* local numeric value */
- void *fts_pointer; /* local address value */
- char *fts_accpath; /* access path */
- char *fts_path; /* root path */
+ void * _Nullable fts_pointer; /* local address value */
+ char * _Nullable fts_accpath; /* access path */
+ char * _Nullable fts_path; /* root path */
int fts_errno; /* errno for this node */
int fts_symfd; /* fd for symlink */
size_t fts_pathlen; /* strlen(fts_path) */
@@ -111,7 +111,7 @@
#define FTS_SKIP 4 /* discard node */
unsigned short fts_instr; /* fts_set() instructions */
- struct stat *fts_statp; /* stat(2) information */
+ struct stat * _Nullable fts_statp; /* stat(2) information */
char fts_name[1]; /* file name */
} FTSENT;
@@ -122,11 +122,11 @@
* breakage in 21 that means you can't write code that runs on current devices and pre-21 devices,
* so we break the tie in favor of current and future devices.
*/
-FTSENT* fts_children(FTS* __fts, int __options) __INTRODUCED_IN(21);
-int fts_close(FTS* __fts) __INTRODUCED_IN(21);
-FTS* fts_open(char* const* __path, int __options, int (*__comparator)(const FTSENT** __lhs, const FTSENT** __rhs)) __INTRODUCED_IN(21);
-FTSENT* fts_read(FTS* __fts) __INTRODUCED_IN(21);
-int fts_set(FTS* __fts, FTSENT* __entry, int __options) __INTRODUCED_IN(21);
+FTSENT* _Nullable fts_children(FTS* _Nonnull __fts, int __options) __INTRODUCED_IN(21);
+int fts_close(FTS* _Nonnull __fts) __INTRODUCED_IN(21);
+FTS* _Nullable fts_open(char* _Nonnull const* _Nonnull __path, int __options, int (* _Nullable __comparator)(const FTSENT* _Nonnull * _Nonnull __lhs, const FTSENT* _Nonnull * _Nonnull __rhs)) __INTRODUCED_IN(21);
+FTSENT* _Nullable fts_read(FTS* _Nonnull __fts) __INTRODUCED_IN(21);
+int fts_set(FTS* _Nonnull __fts, FTSENT* _Nonnull __entry, int __options) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/link.h b/libc/include/link.h
index bd430f5..a0a3d60 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -44,41 +44,41 @@
struct dl_phdr_info {
ElfW(Addr) dlpi_addr;
- const char* dlpi_name;
- const ElfW(Phdr)* dlpi_phdr;
+ const char* _Nullable dlpi_name;
+ const ElfW(Phdr)* _Nullable dlpi_phdr;
ElfW(Half) dlpi_phnum;
// These fields were added in Android R.
unsigned long long dlpi_adds;
unsigned long long dlpi_subs;
size_t dlpi_tls_modid;
- void* dlpi_tls_data;
+ void* _Nullable dlpi_tls_data;
};
#if defined(__arm__)
-int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data) __INTRODUCED_IN(21);
+int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void* _Nullable), void* _Nullable __data) __INTRODUCED_IN(21);
#else
-int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data);
+int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void*_Nullable ), void* _Nullable __data);
#endif
#ifdef __arm__
typedef uintptr_t _Unwind_Ptr;
-_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull);
#endif
/* Used by the dynamic linker to communicate with the debugger. */
struct link_map {
ElfW(Addr) l_addr;
- char* l_name;
- ElfW(Dyn)* l_ld;
- struct link_map* l_next;
- struct link_map* l_prev;
+ char* _Nullable l_name;
+ ElfW(Dyn)* _Nullable l_ld;
+ struct link_map* _Nullable l_next;
+ struct link_map* _Nullable l_prev;
};
/* Used by the dynamic linker to communicate with the debugger. */
struct r_debug {
int32_t r_version;
- struct link_map* r_map;
+ struct link_map* _Nullable r_map;
ElfW(Addr) r_brk;
enum {
RT_CONSISTENT,
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 02bda60..91d63b3 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -183,7 +183,15 @@
* Available since API level 28.
*/
#define M_PURGE (-101)
-
+/**
+ * mallopt() option to immediately purge all possible memory back to
+ * the kernel. This call can take longer than a normal purge since it
+ * examines everything. In some cases, it can take more than twice the
+ * time of a M_PURGE call. The value is ignored.
+ *
+ * Available since API level 34.
+ */
+#define M_PURGE_ALL (-104)
/**
* mallopt() option to tune the allocator's choice of memory tags to
@@ -224,8 +232,9 @@
/**
* mallopt() option for per-thread memory initialization tuning.
* The value argument should be one of:
- * 1: Disable automatic heap initialization and, where possible, memory tagging,
- * on this thread.
+ * 1: Disable automatic heap initialization on this thread only.
+ * If memory tagging is enabled, disable as much as possible of the
+ * memory tagging initialization for this thread.
* 0: Normal behavior.
*
* Available since API level 31.
diff --git a/libc/include/net/if.h b/libc/include/net/if.h
index f261f71..79b4195 100644
--- a/libc/include/net/if.h
+++ b/libc/include/net/if.h
@@ -41,13 +41,13 @@
struct if_nameindex {
unsigned if_index;
- char* if_name;
+ char* _Nullable if_name;
};
-char* if_indextoname(unsigned __index, char* __buf);
-unsigned if_nametoindex(const char* __name);
-struct if_nameindex* if_nameindex(void) __INTRODUCED_IN(24);
-void if_freenameindex(struct if_nameindex* __ptr) __INTRODUCED_IN(24);
+char* _Nullable if_indextoname(unsigned __index, char* _Nonnull __buf);
+unsigned if_nametoindex(const char* _Nonnull __name);
+struct if_nameindex* _Nullable if_nameindex(void) __INTRODUCED_IN(24);
+void if_freenameindex(struct if_nameindex* _Nullable __ptr) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 7a1987e..7afdc1a 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -79,31 +79,31 @@
* use in system calls).
*/
struct hostent {
- char *h_name; /* official name of host */
- char **h_aliases; /* alias list */
+ char * _Nullable h_name; /* official name of host */
+ char * _Nullable * _Nullable h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
- char **h_addr_list; /* list of addresses from name server */
+ char * _Nullable * _Nullable h_addr_list; /* list of addresses from name server */
#define h_addr h_addr_list[0] /* address, for backward compatibility */
};
struct netent {
- char *n_name; /* official name of net */
- char **n_aliases; /* alias list */
+ char * _Nullable n_name; /* official name of net */
+ char * _Nullable * _Nullable n_aliases; /* alias list */
int n_addrtype; /* net address type */
uint32_t n_net; /* network # */
};
struct servent {
- char *s_name; /* official service name */
- char **s_aliases; /* alias list */
+ char * _Nullable s_name; /* official service name */
+ char * _Nullable * _Nullable s_aliases; /* alias list */
int s_port; /* port # */
- char *s_proto; /* protocol to use */
+ char * _Nullable s_proto; /* protocol to use */
};
struct protoent {
- char *p_name; /* official protocol name */
- char **p_aliases; /* alias list */
+ char * _Nullable p_name; /* official protocol name */
+ char * _Nullable * _Nullable p_aliases; /* alias list */
int p_proto; /* protocol # */
};
@@ -113,9 +113,9 @@
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
socklen_t ai_addrlen; /* length of ai_addr */
- char *ai_canonname; /* canonical name for hostname */
- struct sockaddr *ai_addr; /* binary address */
- struct addrinfo *ai_next; /* next structure in linked list */
+ char * _Nullable ai_canonname; /* canonical name for hostname */
+ struct sockaddr * _Nullable ai_addr; /* binary address */
+ struct addrinfo * _Nullable ai_next; /* next structure in linked list */
};
/*
@@ -196,47 +196,47 @@
__BEGIN_DECLS
-int getaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result);
-void freeaddrinfo(struct addrinfo* __ptr);
+int getaddrinfo(const char* _Nullable __node, const char* _Nullable __service, const struct addrinfo* _Nullable __hints, struct addrinfo* _Nullable * _Nonnull __result);
+void freeaddrinfo(struct addrinfo* _Nullable __ptr);
/* Android ABI error: POSIX getnameinfo(3) uses socklen_t rather than size_t. */
-int getnameinfo(const struct sockaddr* __sa, socklen_t __sa_length, char* __host, size_t __host_length, char* __service, size_t __service_length, int __flags);
-const char* gai_strerror(int __error);
+int getnameinfo(const struct sockaddr* _Nonnull __sa, socklen_t __sa_length, char* _Nullable __host, size_t __host_length, char* _Nullable __service, size_t __service_length, int __flags);
+const char* _Nonnull gai_strerror(int __error);
/* These functions are obsolete. Use getaddrinfo/getnameinfo instead. */
#define h_errno (*__get_h_errno())
-int* __get_h_errno(void);
-void herror(const char* __s);
-const char* hstrerror(int __error);
-struct hostent* gethostbyaddr(const void* __addr, socklen_t __length, int __type);
-int gethostbyaddr_r(const void* __addr, socklen_t __length, int __type, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
-struct hostent* gethostbyname(const char* __name);
-int gethostbyname_r(const char* __name, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr);
-struct hostent* gethostbyname2(const char* __name, int __af);
-int gethostbyname2_r(const char* __name, int __af, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
+int* _Nonnull __get_h_errno(void);
+void herror(const char* _Nonnull __s);
+const char* _Nonnull hstrerror(int __error);
+struct hostent* _Nullable gethostbyaddr(const void* _Nonnull __addr, socklen_t __length, int __type);
+int gethostbyaddr_r(const void* _Nonnull __addr, socklen_t __length, int __type, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
+struct hostent* _Nullable gethostbyname(const char* _Nonnull __name);
+int gethostbyname_r(const char* _Nonnull __name, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr);
+struct hostent* _Nullable gethostbyname2(const char* _Nonnull __name, int __af);
+int gethostbyname2_r(const char* _Nonnull __name, int __af, struct hostent* _Nonnull __ret, char* _Nonnull __buf, size_t __buf_size, struct hostent* _Nullable * _Nonnull __result, int* _Nonnull __h_errno_ptr) __INTRODUCED_IN(23);
void endhostent(void) __INTRODUCED_IN(28);
-struct hostent* gethostent(void);
+struct hostent* _Nullable gethostent(void);
void sethostent(int __stay_open) __INTRODUCED_IN(28);
/* These functions are obsolete. None of these functions return anything but nullptr. */
void endnetent(void) __INTRODUCED_IN(28);
-struct netent* getnetbyaddr(uint32_t __net, int __type);
-struct netent* getnetbyname(const char* __name);
-struct netent* getnetent(void) __INTRODUCED_IN(28);
+struct netent* _Nullable getnetbyaddr(uint32_t __net, int __type);
+struct netent* _Nullable getnetbyname(const char* _Nonnull __name);
+struct netent* _Nullable getnetent(void) __INTRODUCED_IN(28);
void setnetent(int __stay_open) __INTRODUCED_IN(28);
/* None of these functions return anything but nullptr. */
void endprotoent(void) __INTRODUCED_IN(28);
-struct protoent* getprotobyname(const char* __name);
-struct protoent* getprotobynumber(int __proto);
-struct protoent* getprotoent(void) __INTRODUCED_IN(28);
+struct protoent* _Nullable getprotobyname(const char* _Nonnull __name);
+struct protoent* _Nullable getprotobynumber(int __proto);
+struct protoent* _Nullable getprotoent(void) __INTRODUCED_IN(28);
void setprotoent(int __stay_open) __INTRODUCED_IN(28);
/* These functions return entries from a built-in database. */
void endservent(void);
-struct servent* getservbyname(const char* __name, const char* __proto);
-struct servent* getservbyport(int __port_in_network_order, const char* __proto);
-struct servent* getservent(void);
+struct servent* _Nullable getservbyname(const char* _Nonnull __name, const char* _Nullable __proto);
+struct servent* _Nullable getservbyport(int __port_in_network_order, const char* _Nullable __proto);
+struct servent* _Nullable getservent(void);
void setservent(int __stay_open);
__END_DECLS
diff --git a/libc/include/netinet/ether.h b/libc/include/netinet/ether.h
index 480063d..d570c18 100644
--- a/libc/include/netinet/ether.h
+++ b/libc/include/netinet/ether.h
@@ -44,7 +44,7 @@
*
* Returns a pointer to a static buffer.
*/
-char* ether_ntoa(const struct ether_addr* __addr);
+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
@@ -52,7 +52,7 @@
*
* Returns a pointer to the given buffer.
*/
-char* ether_ntoa_r(const struct ether_addr* __addr, char* __buf);
+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`
@@ -60,7 +60,7 @@
*
* Returns a pointer to a static buffer, or NULL if the given string isn't a valid MAC address.
*/
-struct ether_addr* ether_aton(const char* __ascii);
+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
@@ -68,6 +68,6 @@
*
* Returns a pointer to the given buffer, or NULL if the given string isn't a valid MAC address.
*/
-struct ether_addr* ether_aton_r(const char* __ascii, struct ether_addr* __addr);
+struct ether_addr* _Nullable ether_aton_r(const char* _Nonnull __ascii, struct ether_addr* _Nonnull __addr);
__END_DECLS
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 46e3543..b235e6e 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -54,7 +54,7 @@
typedef uint16_t in_port_t;
-int bindresvport(int __fd, struct sockaddr_in* __sin);
+int bindresvport(int __fd, struct sockaddr_in* _Nullable __sin);
#if __ANDROID_API__ >= 24
extern const struct in6_addr in6addr_any __INTRODUCED_IN(24);
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index fd1ebc3..98695eb 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -94,41 +94,41 @@
#define PTHREAD_SCOPE_SYSTEM 0
#define PTHREAD_SCOPE_PROCESS 1
-int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void));
+int pthread_atfork(void (* _Nullable __prepare)(void), void (* _Nullable __parent)(void), void (* _Nullable __child)(void));
-int pthread_attr_destroy(pthread_attr_t* __attr);
-int pthread_attr_getdetachstate(const pthread_attr_t* __attr, int* __state);
-int pthread_attr_getguardsize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_getinheritsched(const pthread_attr_t* __attr, int* __flag) __INTRODUCED_IN(28);
-int pthread_attr_getschedparam(const pthread_attr_t* __attr, struct sched_param* __param);
-int pthread_attr_getschedpolicy(const pthread_attr_t* __attr, int* __policy);
-int pthread_attr_getscope(const pthread_attr_t* __attr, int* __scope);
-int pthread_attr_getstack(const pthread_attr_t* __attr, void** __addr, size_t* __size);
-int pthread_attr_getstacksize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_init(pthread_attr_t* __attr);
-int pthread_attr_setdetachstate(pthread_attr_t* __attr, int __state);
-int pthread_attr_setguardsize(pthread_attr_t* __attr, size_t __size);
-int pthread_attr_setinheritsched(pthread_attr_t* __attr, int __flag) __INTRODUCED_IN(28);
-int pthread_attr_setschedparam(pthread_attr_t* __attr, const struct sched_param* __param);
-int pthread_attr_setschedpolicy(pthread_attr_t* __attr, int __policy);
-int pthread_attr_setscope(pthread_attr_t* __attr, int __scope);
-int pthread_attr_setstack(pthread_attr_t* __attr, void* __addr, size_t __size);
-int pthread_attr_setstacksize(pthread_attr_t* __addr, size_t __size);
+int pthread_attr_destroy(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __state);
+int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_getinheritsched(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __flag) __INTRODUCED_IN(28);
+int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull __attr, struct sched_param* _Nonnull __param);
+int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __policy);
+int pthread_attr_getscope(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __scope);
+int pthread_attr_getstack(const pthread_attr_t* _Nonnull __attr, void* _Nullable * _Nonnull __addr, size_t* _Nonnull __size);
+int pthread_attr_getstacksize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_init(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull __attr, int __state);
+int pthread_attr_setguardsize(pthread_attr_t* _Nonnull __attr, size_t __size);
+int pthread_attr_setinheritsched(pthread_attr_t* _Nonnull __attr, int __flag) __INTRODUCED_IN(28);
+int pthread_attr_setschedparam(pthread_attr_t* _Nonnull __attr, const struct sched_param* _Nonnull __param);
+int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull __attr, int __policy);
+int pthread_attr_setscope(pthread_attr_t* _Nonnull __attr, int __scope);
+int pthread_attr_setstack(pthread_attr_t* _Nonnull __attr, void* _Nonnull __addr, size_t __size);
+int pthread_attr_setstacksize(pthread_attr_t* _Nonnull __addr, size_t __size);
-int pthread_condattr_destroy(pthread_condattr_t* __attr);
-int pthread_condattr_getclock(const pthread_condattr_t* __attr, clockid_t* __clock) __INTRODUCED_IN(21);
-int pthread_condattr_getpshared(const pthread_condattr_t* __attr, int* __shared);
-int pthread_condattr_init(pthread_condattr_t* __attr);
-int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __INTRODUCED_IN(21);
-int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared);
+int pthread_condattr_destroy(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_getclock(const pthread_condattr_t* _Nonnull __attr, clockid_t* _Nonnull __clock) __INTRODUCED_IN(21);
+int pthread_condattr_getpshared(const pthread_condattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_condattr_init(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_setclock(pthread_condattr_t* _Nonnull __attr, clockid_t __clock) __INTRODUCED_IN(21);
+int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull __attr, int __shared);
-int pthread_cond_broadcast(pthread_cond_t* __cond);
-int pthread_cond_clockwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, clockid_t __clock,
- const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_cond_destroy(pthread_cond_t* __cond);
-int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr);
-int pthread_cond_signal(pthread_cond_t* __cond);
-int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout);
+int pthread_cond_broadcast(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_clockwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_cond_destroy(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_init(pthread_cond_t* _Nonnull __cond, const pthread_condattr_t* _Nullable __attr);
+int pthread_cond_signal(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_timedwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout);
/*
* Condition variables use CLOCK_REALTIME by default for their timeouts, however that is
* typically inappropriate, since that clock can change dramatically, causing the timeout to
@@ -139,9 +139,9 @@
* Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this
* function.
*/
-int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex,
- const struct timespec* __timeout) __INTRODUCED_IN_64(28);
-int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN_64(28);
+int pthread_cond_wait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex);
#if defined(__clang__)
/*
@@ -153,44 +153,44 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
#endif
-int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nonnull (* _Nonnull __start_routine)(void* _Nonnull), void* _Nullable);
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
int pthread_detach(pthread_t __pthread);
-void pthread_exit(void* __return_value) __noreturn;
+void pthread_exit(void* _Nullable __return_value) __noreturn;
int pthread_equal(pthread_t __lhs, pthread_t __rhs);
-int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* __attr);
+int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* _Nonnull __attr);
-int pthread_getcpuclockid(pthread_t __pthread, clockid_t* __clock);
+int pthread_getcpuclockid(pthread_t __pthread, clockid_t* _Nonnull __clock);
-void* pthread_getspecific(pthread_key_t __key);
+void* _Nullable pthread_getspecific(pthread_key_t __key);
pid_t pthread_gettid_np(pthread_t __pthread) __INTRODUCED_IN(21);
-int pthread_join(pthread_t __pthread, void** __return_value_ptr);
+int pthread_join(pthread_t __pthread, void* _Nullable * _Nullable __return_value_ptr);
-int pthread_key_create(pthread_key_t* __key_ptr, void (*__key_destructor)(void*));
+int pthread_key_create(pthread_key_t* _Nonnull __key_ptr, void (* _Nullable __key_destructor)(void* _Nullable));
int pthread_key_delete(pthread_key_t __key);
-int pthread_mutexattr_destroy(pthread_mutexattr_t* __attr);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t* __attr, int* __shared);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t* __attr, int* __type);
-int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __attr, int* __protocol) __INTRODUCED_IN(28);
-int pthread_mutexattr_init(pthread_mutexattr_t* __attr);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared);
-int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type);
-int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28);
+int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __type);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __protocol) __INTRODUCED_IN(28);
+int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull __attr, int __shared);
+int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull __attr, int __type);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* _Nonnull __attr, int __protocol) __INTRODUCED_IN(28);
-int pthread_mutex_clocklock(pthread_mutex_t* __mutex, clockid_t __clock,
- const struct timespec* __abstime) __INTRODUCED_IN(30);
-int pthread_mutex_destroy(pthread_mutex_t* __mutex);
-int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr);
-int pthread_mutex_lock(pthread_mutex_t* __mutex);
-int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __timeout)
+int pthread_mutex_clocklock(pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+ const struct timespec* _Nullable __abstime) __INTRODUCED_IN(30);
+int pthread_mutex_destroy(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_init(pthread_mutex_t* _Nonnull __mutex, const pthread_mutexattr_t* _Nullable __attr);
+int pthread_mutex_lock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_timedlock(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
__INTRODUCED_IN(21);
/*
@@ -202,69 +202,69 @@
* Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this
* function.
*/
-int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* __mutex, const struct timespec* __timeout)
+int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
__INTRODUCED_IN(28);
-int pthread_mutex_trylock(pthread_mutex_t* __mutex);
-int pthread_mutex_unlock(pthread_mutex_t* __mutex);
+int pthread_mutex_trylock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_unlock(pthread_mutex_t* _Nonnull __mutex);
-int pthread_once(pthread_once_t* __once, void (*__init_routine)(void));
+int pthread_once(pthread_once_t* _Nonnull __once, void (* _Nonnull __init_routine)(void));
-int pthread_rwlockattr_init(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* __attr, int* __shared);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* __attr, int __shared);
-int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kind)
+int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull __attr, int __shared);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __kind)
__INTRODUCED_IN(23);
-int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull __attr, int __kind) __INTRODUCED_IN(23);
-int pthread_rwlock_clockrdlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
- const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_rwlock_clockwrlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
- const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr);
-int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_clockrdlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_clockwrlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_init(pthread_rwlock_t* _Nonnull __rwlock, const pthread_rwlockattr_t* _Nullable __attr);
+int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* __rwlock,
- const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* __rwlock,
- const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_tryrdlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_trywrlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_unlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_wrlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull __rwlock);
#if __ANDROID_API__ >= 24
-int pthread_barrierattr_init(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_destroy(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_getpshared(const pthread_barrierattr_t* __attr, int* __shared) __INTRODUCED_IN(24);
-int pthread_barrierattr_setpshared(pthread_barrierattr_t* __attr, int __shared) __INTRODUCED_IN(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* __barrier, const pthread_barrierattr_t* __attr, unsigned __count) __INTRODUCED_IN(24);
-int pthread_barrier_destroy(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
-int pthread_barrier_wait(pthread_barrier_t* __barrier) __INTRODUCED_IN(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* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_init(pthread_spinlock_t* __spinlock, int __shared) __INTRODUCED_IN(24);
-int pthread_spin_lock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_trylock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_unlock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(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__;
#if defined(__USE_GNU)
-int pthread_getname_np(pthread_t __pthread, char* __buf, size_t __n) __INTRODUCED_IN(26);
+int pthread_getname_np(pthread_t __pthread, char* _Nonnull __buf, size_t __n) __INTRODUCED_IN(26);
#endif
/* TODO: this should be __USE_GNU too. */
-int pthread_setname_np(pthread_t __pthread, const char* __name);
+int pthread_setname_np(pthread_t __pthread, const char* _Nonnull __name);
/**
* [pthread_setschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html)
@@ -277,7 +277,7 @@
*
* Returns 0 on success and returns an error number on failure.
*/
-int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* __param);
+int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* _Nonnull __param);
/**
* [pthread_getschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_getschedparam.3.html)
@@ -285,7 +285,7 @@
*
* Returns 0 on success and returns an error number on failure.
*/
-int pthread_getschedparam(pthread_t __pthread, int* __policy, struct sched_param* __param);
+int pthread_getschedparam(pthread_t __pthread, int* _Nonnull __policy, struct sched_param* _Nonnull __param);
/**
* [pthread_setschedprio(3)](https://man7.org/linux/man-pages/man3/pthread_setschedprio.3.html)
@@ -302,18 +302,18 @@
*/
int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN(28);
-int pthread_setspecific(pthread_key_t __key, const void* __value);
+int pthread_setspecific(pthread_key_t __key, const void* _Nullable __value);
-typedef void (*__pthread_cleanup_func_t)(void*);
+typedef void (* _Nullable __pthread_cleanup_func_t)(void* _Nullable);
typedef struct __pthread_cleanup_t {
- struct __pthread_cleanup_t* __cleanup_prev;
- __pthread_cleanup_func_t __cleanup_routine;
- void* __cleanup_arg;
+ struct __pthread_cleanup_t* _Nullable __cleanup_prev;
+ __pthread_cleanup_func_t _Nullable __cleanup_routine;
+ void* _Nullable __cleanup_arg;
} __pthread_cleanup_t;
-void __pthread_cleanup_push(__pthread_cleanup_t* c, __pthread_cleanup_func_t, void*);
-void __pthread_cleanup_pop(__pthread_cleanup_t*, int);
+void __pthread_cleanup_push(__pthread_cleanup_t* _Nonnull c, __pthread_cleanup_func_t _Nullable, void* _Nullable);
+void __pthread_cleanup_pop(__pthread_cleanup_t* _Nonnull, int);
/* Believe or not, the definitions of pthread_cleanup_push and
* pthread_cleanup_pop below are correct. Posix states that these
diff --git a/libc/include/pwd.h b/libc/include/pwd.h
index d481aac..2b17fbf 100644
--- a/libc/include/pwd.h
+++ b/libc/include/pwd.h
@@ -66,31 +66,31 @@
__BEGIN_DECLS
struct passwd {
- char* pw_name;
- char* pw_passwd;
+ char* _Nullable pw_name;
+ char* _Nullable pw_passwd;
uid_t pw_uid;
gid_t pw_gid;
#ifdef __LP64__
- char* pw_gecos;
+ char* _Nullable pw_gecos;
#else
/* Note: On LP32, we define pw_gecos to pw_passwd since they're both NULL. */
# define pw_gecos pw_passwd
#endif
- char* pw_dir;
- char* pw_shell;
+ char* _Nullable pw_dir;
+ char* _Nullable pw_shell;
};
-struct passwd* getpwnam(const char* __name);
-struct passwd* getpwuid(uid_t __uid);
+struct passwd* _Nullable getpwnam(const char* _Nonnull __name);
+struct passwd* _Nullable getpwuid(uid_t __uid);
/* Note: Android has thousands and thousands of ids to iterate through */
-struct passwd* getpwent(void) __INTRODUCED_IN(26);
+struct passwd* _Nullable getpwent(void) __INTRODUCED_IN(26);
void setpwent(void) __INTRODUCED_IN(26);
void endpwent(void) __INTRODUCED_IN(26);
-int getpwnam_r(const char* __name, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result);
-int getpwuid_r(uid_t __uid, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result);
+int getpwnam_r(const char* _Nonnull __name, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
+int getpwuid_r(uid_t __uid, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
__END_DECLS
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 364ca10..26bc742 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -104,7 +104,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* __param);
+int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* _Nonnull __param);
/**
* [sched_getscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
@@ -145,7 +145,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_setparam(pid_t __pid, const struct sched_param* __param);
+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)
@@ -153,7 +153,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_getparam(pid_t __pid, struct sched_param* __param);
+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)
@@ -161,7 +161,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_rr_get_interval(pid_t __pid, struct timespec* __quantum);
+int sched_rr_get_interval(pid_t __pid, struct timespec* _Nonnull __quantum);
#if defined(__USE_GNU)
@@ -172,7 +172,7 @@
* Returns the pid of the child to the caller on success and
* returns -1 and sets `errno` on failure.
*/
-int clone(int (*__fn)(void*), void* __child_stack, int __flags, void* __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
+int clone(int (* __BIONIC_COMPLICATED_NULLNESS __fn)(void* __BIONIC_COMPLICATED_NULLNESS ), void* __BIONIC_COMPLICATED_NULLNESS __child_stack, int __flags, void* _Nullable __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
/**
* [unshare(2)](http://man7.org/linux/man-pages/man2/unshare.2.html)
@@ -228,7 +228,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* __set);
+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)
@@ -236,7 +236,7 @@
*
* Returns 0 on success and returns -1 and sets `errno` on failure.
*/
-int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* __set);
+int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* _Nonnull __set);
/**
* [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
@@ -308,7 +308,7 @@
* how many bits are set in a dynamic CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_COUNT_S(setsize, set) __sched_cpucount((setsize), (set))
-int __sched_cpucount(size_t __set_size, const cpu_set_t* __set);
+int __sched_cpucount(size_t __set_size, const cpu_set_t* _Nonnull __set);
/**
* [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
@@ -379,14 +379,14 @@
* allocates a CPU set large enough for CPUs in the range 0..count-1.
*/
#define CPU_ALLOC(count) __sched_cpualloc((count))
-cpu_set_t* __sched_cpualloc(size_t __count);
+cpu_set_t* _Nullable __sched_cpualloc(size_t __count);
/**
* [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
* deallocates a CPU set allocated by `CPU_ALLOC`.
*/
#define CPU_FREE(set) __sched_cpufree((set))
-void __sched_cpufree(cpu_set_t* __set);
+void __sched_cpufree(cpu_set_t* _Nonnull __set);
#endif /* __USE_GNU */
diff --git a/libc/include/search.h b/libc/include/search.h
index 7c4989a..00deef1 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -25,9 +25,9 @@
/** See hsearch()/hsearch_r(). */
typedef struct entry {
/** The string key. */
- char* key;
+ char* _Nullable key;
/** The associated data. */
- void* data;
+ void* _Nullable data;
} ENTRY;
/**
@@ -57,7 +57,7 @@
#if defined(__USE_BSD) || defined(__USE_GNU)
/** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */
struct hsearch_data {
- struct __hsearch* __hsearch;
+ struct __hsearch* _Nullable __hsearch;
};
#endif
@@ -69,7 +69,7 @@
*
* Available since API level 21.
*/
-void insque(void* __element, void* __previous) __INTRODUCED_IN(21);
+void insque(void* _Nonnull __element, void* _Nullable __previous) __INTRODUCED_IN(21);
/**
* [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
@@ -77,7 +77,7 @@
*
* Available since API level 21.
*/
-void remque(void* __element) __INTRODUCED_IN(21);
+void remque(void* _Nonnull __element) __INTRODUCED_IN(21);
/**
* [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
@@ -112,7 +112,7 @@
*
* Available since API level 28.
*/
-ENTRY* hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
+ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
#if defined(__USE_BSD) || defined(__USE_GNU)
@@ -124,7 +124,7 @@
*
* Available since API level 28.
*/
-int hcreate_r(size_t __n, struct hsearch_data* __table) __INTRODUCED_IN(28);
+int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
/**
* [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
@@ -132,7 +132,7 @@
*
* Available since API level 28.
*/
-void hdestroy_r(struct hsearch_data* __table) __INTRODUCED_IN(28);
+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
@@ -143,7 +143,7 @@
*
* Available since API level 28.
*/
-int hsearch_r(ENTRY __entry, ACTION __action, ENTRY** __result, struct hsearch_data* __table) __INTRODUCED_IN(28);
+int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
#endif
@@ -158,7 +158,7 @@
*
* Available since API level 21.
*/
-void* lfind(const void* __key, const void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
+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)) __INTRODUCED_IN(21);
/**
* [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
@@ -173,7 +173,7 @@
*
* Available since API level 21.
*/
-void* lsearch(const void* __key, void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
+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)) __INTRODUCED_IN(21);
/**
* [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
@@ -182,13 +182,13 @@
*
* Returns a pointer to the parent of the deleted node, or NULL on failure.
*/
-void* tdelete(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
+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
* the hash table `__root` using `__free_fn` on each node.
*/
-void tdestroy(void* __root, void (*__free_fn)(void*));
+void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
/**
* [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
@@ -197,7 +197,7 @@
*
* Returns a pointer to the matching node, or NULL on failure.
*/
-void* tfind(const void* __key, void* const* __root_ptr, int (*__comparator)(const void*, const void*));
+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
@@ -208,12 +208,12 @@
*
* Returns a pointer to the matching node, or to the newly-added node.
*/
-void* tsearch(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
+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
* `__visitor` on every node in the tree.
*/
-void twalk(const void* __root, void (*__visitor)(const void*, VISIT, int)) __INTRODUCED_IN(21);
+void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int)) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 5d66f7e..6ad9ea3 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -45,12 +45,12 @@
#define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
-int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30);
-int sem_destroy(sem_t* __sem);
-int sem_getvalue(sem_t* __sem, int* __value);
-int sem_init(sem_t* __sem, int __shared, unsigned int __value);
-int sem_post(sem_t* __sem);
-int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
+int sem_clockwait(sem_t* _Nonnull __sem, clockid_t __clock, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(30);
+int sem_destroy(sem_t* _Nonnull __sem);
+int sem_getvalue(sem_t* _Nonnull __sem, int* _Nonnull __value);
+int sem_init(sem_t* _Nonnull __sem, int __shared, unsigned int __value);
+int sem_post(sem_t* _Nonnull __sem);
+int sem_timedwait(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts);
/*
* POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is
* typically inappropriate, since that clock can change dramatically, causing the timeout to either
@@ -59,14 +59,14 @@
* Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this
* function.
*/
-int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28);
-int sem_trywait(sem_t* __sem);
-int sem_wait(sem_t* __sem);
+int sem_timedwait_monotonic_np(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(28);
+int sem_trywait(sem_t* _Nonnull __sem);
+int sem_wait(sem_t* _Nonnull __sem);
/* These aren't actually implemented. */
-sem_t* sem_open(const char* __name, int _flags, ...);
-int sem_close(sem_t* __sem);
-int sem_unlink(const char* __name);
+sem_t* _Nullable sem_open(const char* _Nonnull __name, int _flags, ...);
+int sem_close(sem_t* _Nonnull __sem);
+int sem_unlink(const char* _Nonnull __name);
__END_DECLS
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index a3de9c7..6d047ae 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -47,14 +47,33 @@
#include <sys/cdefs.h>
#if defined(__aarch64__)
+/**
+ * The size in words of an arm64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
#define _JBLEN 32
#elif defined(__arm__)
+/** The size in words of an arm32 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 64
#elif defined(__i386__)
+/** The size in words of an x86 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 10
#elif defined(__riscv)
-#define _JBLEN 29
+/**
+ * The size in words of a riscv64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
+#define _JBLEN 32
#elif defined(__x86_64__)
+/** The size in words of an x86-64 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 11
#endif
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index e445453..6c34b98 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -52,40 +52,43 @@
typedef struct __posix_spawnattr* posix_spawnattr_t;
typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
-int posix_spawn(pid_t* __pid, const char* __path, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN(28);
-int posix_spawnp(pid_t* __pid, const char* __file, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __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 _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_spawnattr_init(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
-int posix_spawnattr_destroy(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
+int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28);
+int posix_spawnattr_destroy(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28);
-int posix_spawnattr_setflags(posix_spawnattr_t* __attr, short __flags) __INTRODUCED_IN(28);
-int posix_spawnattr_getflags(const posix_spawnattr_t* __attr, short* __flags) __INTRODUCED_IN(28);
+int posix_spawnattr_setflags(posix_spawnattr_t _Nonnull * _Nonnull __attr, short __flags) __INTRODUCED_IN(28);
+int posix_spawnattr_getflags(const posix_spawnattr_t _Nonnull * _Nonnull __attr, short* _Nonnull __flags) __INTRODUCED_IN(28);
-int posix_spawnattr_setpgroup(posix_spawnattr_t* __attr, pid_t __pgroup) __INTRODUCED_IN(28);
-int posix_spawnattr_getpgroup(const posix_spawnattr_t* __attr, pid_t* __pgroup) __INTRODUCED_IN(28);
+int posix_spawnattr_setpgroup(posix_spawnattr_t _Nonnull * _Nonnull __attr, pid_t __pgroup) __INTRODUCED_IN(28);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t _Nonnull * _Nonnull __attr, pid_t* _Nonnull __pgroup) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigmask(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigmask64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigmask(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigmask64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigmask(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigmask64(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask64(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigdefault(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigdefault64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigdefault(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigdefault64(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault64(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setschedparam(posix_spawnattr_t* __attr, const struct sched_param* __param) __INTRODUCED_IN(28);
-int posix_spawnattr_getschedparam(const posix_spawnattr_t* __attr, struct sched_param* __param) __INTRODUCED_IN(28);
+int posix_spawnattr_setschedparam(posix_spawnattr_t _Nonnull * _Nonnull __attr, const struct sched_param* _Nonnull __param) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t _Nonnull * _Nonnull __attr, struct sched_param* _Nonnull __param) __INTRODUCED_IN(28);
-int posix_spawnattr_setschedpolicy(posix_spawnattr_t* __attr, int __policy) __INTRODUCED_IN(28);
-int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __attr, int* __policy) __INTRODUCED_IN(28);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t _Nonnull * _Nonnull __attr, int __policy) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t _Nonnull * _Nonnull __attr, int* _Nonnull __policy) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_init(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __actions, int __fd, const char* __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* __actions, int __fd) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, const char* _Nonnull __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, const char* _Nonnull __path) __INTRODUCED_IN(34);
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(34);
__END_DECLS
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index e748faa..d7b65e4 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -143,9 +143,9 @@
(defined(__cplusplus) && __cplusplus <= 201103L)
char* _Nullable gets(char* _Nonnull __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
#endif
-int sprintf(char* _Nonnull __s, const char* _Nonnull __fmt, ...)
+int sprintf(char* __BIONIC_COMPLICATED_NULLNESS __s, const char* _Nonnull __fmt, ...)
__printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
-int vsprintf(char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args)
+int vsprintf(char* __BIONIC_COMPLICATED_NULLNESS __s, const char* _Nonnull __fmt, va_list __args)
__printflike(2, 0) __warnattr_strict("vsprintf is often misused; please use vsnprintf");
char* _Nullable tmpnam(char* _Nullable __s)
__warnattr("tmpnam is unsafe, use mkstemp or tmpfile instead");
@@ -251,10 +251,10 @@
FILE* _Nullable tmpfile(void);
FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
-int snprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
+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);
int vscanf(const char* _Nonnull __fmt , va_list __args) __scanflike(1, 0);
-int vsnprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
+int vsnprintf(char* __BIONIC_COMPLICATED_NULLNESS __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
int vsscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
#define L_ctermid 1024 /* size for ctermid() */
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index b416f62..2bcb870 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -91,7 +91,7 @@
void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
-void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
+void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs));
uint32_t arc4random(void);
uint32_t arc4random_uniform(uint32_t __upper_bound);
diff --git a/libc/include/sys/capability.h b/libc/include/sys/capability.h
index 4cb698f..b43bbf0 100644
--- a/libc/include/sys/capability.h
+++ b/libc/include/sys/capability.h
@@ -44,7 +44,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int capget(cap_user_header_t __hdr_ptr, cap_user_data_t __data_ptr);
+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
@@ -52,6 +52,6 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int capset(cap_user_header_t __hdr_ptr, const cap_user_data_t __data_ptr);
+int capset(cap_user_header_t _Nonnull __hdr_ptr, const cap_user_data_t _Nullable __data_ptr);
__END_DECLS
diff --git a/libc/include/sys/inotify.h b/libc/include/sys/inotify.h
index c3cdc85..e834d07 100644
--- a/libc/include/sys/inotify.h
+++ b/libc/include/sys/inotify.h
@@ -42,7 +42,7 @@
int inotify_init(void);
int inotify_init1(int __flags) __INTRODUCED_IN(21);
-int inotify_add_watch(int __fd, const char* __path, uint32_t __mask);
+int inotify_add_watch(int __fd, const char* _Nonnull __path, uint32_t __mask);
int inotify_rm_watch(int __fd, uint32_t __watch_descriptor);
__END_DECLS
diff --git a/libc/include/sys/ipc.h b/libc/include/sys/ipc.h
index c81ec1a..2e2b8cf 100644
--- a/libc/include/sys/ipc.h
+++ b/libc/include/sys/ipc.h
@@ -52,6 +52,6 @@
*
* Returns a key on success, and returns -1 and sets `errno` on failure.
*/
-key_t ftok(const char* __path, int __id);
+key_t ftok(const char* _Nonnull __path, int __id);
__END_DECLS
diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h
index 4db1ac1..aace205 100644
--- a/libc/include/sys/mount.h
+++ b/libc/include/sys/mount.h
@@ -55,7 +55,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int mount(const char* __source, const char* __target, const char* __fs_type, unsigned long __flags, const void* __data);
+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
@@ -63,7 +63,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int umount(const char* __target);
+int umount(const char* _Nonnull __target);
/**
* [umount2(2)](http://man7.org/linux/man-pages/man2/umount2.2.html) unmounts the filesystem at
@@ -71,6 +71,6 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int umount2(const char* __target, int __flags);
+int umount2(const char* _Nonnull __target, int __flags);
__END_DECLS
diff --git a/libc/include/sys/msg.h b/libc/include/sys/msg.h
index e19452c..ad481a0 100644
--- a/libc/include/sys/msg.h
+++ b/libc/include/sys/msg.h
@@ -46,12 +46,12 @@
typedef __kernel_ulong_t msglen_t;
/** Not useful on Android; disallowed by SELinux. */
-int msgctl(int __msg_id, int __cmd, struct msqid_ds* __buf) __INTRODUCED_IN(26);
+int msgctl(int __msg_id, int __cmd, struct msqid_ds* _Nullable __buf) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
int msgget(key_t __key, int __flags) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
-ssize_t msgrcv(int __msg_id, void* __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
+ssize_t msgrcv(int __msg_id, void* _Nonnull __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
/** Not useful on Android; disallowed by SELinux. */
-int msgsnd(int __msg_id, const void* __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
+int msgsnd(int __msg_id, const void* _Nonnull __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index be52bd9..0251176 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -50,7 +50,7 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
/**
* [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
@@ -62,6 +62,6 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
+ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
__END_DECLS
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index ccb267d..0b540de 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -43,19 +43,19 @@
typedef unsigned long rlim_t;
typedef unsigned long long rlim64_t;
-int getrlimit(int __resource, struct rlimit* __limit);
-int setrlimit(int __resource, const struct rlimit* __limit);
+int getrlimit(int __resource, struct rlimit* _Nonnull __limit);
+int setrlimit(int __resource, const struct rlimit* _Nonnull __limit);
-int getrlimit64(int __resource, struct rlimit64* __limit) __INTRODUCED_IN(21);
-int setrlimit64(int __resource, const struct rlimit64* __limit) __INTRODUCED_IN(21);
+int getrlimit64(int __resource, struct rlimit64* _Nonnull __limit) __INTRODUCED_IN(21);
+int setrlimit64(int __resource, const struct rlimit64* _Nonnull __limit) __INTRODUCED_IN(21);
int getpriority(int __which, id_t __who);
int setpriority(int __which, id_t __who, int __priority);
-int getrusage(int __who, struct rusage* __usage);
+int getrusage(int __who, struct rusage* _Nonnull __usage);
-int prlimit(pid_t __pid, int __resource, const struct rlimit* __new_limit, struct rlimit* __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
-int prlimit64(pid_t __pid, int __resource, const struct rlimit64* __new_limit, struct rlimit64* __old_limit) __INTRODUCED_IN(21);
+int prlimit(pid_t __pid, int __resource, const struct rlimit* _Nullable __new_limit, struct rlimit* _Nullable __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
+int prlimit64(pid_t __pid, int __resource, const struct rlimit64* _Nullable __new_limit, struct rlimit64* _Nullable __old_limit) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index 06914a6..8c6c2ff 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -71,9 +71,9 @@
} \
} while (0)
-void __FD_CLR_chk(int, fd_set*, size_t) __INTRODUCED_IN(21);
-void __FD_SET_chk(int, fd_set*, size_t) __INTRODUCED_IN(21);
-int __FD_ISSET_chk(int, const fd_set*, size_t) __INTRODUCED_IN(21);
+void __FD_CLR_chk(int, fd_set* _Nonnull , size_t) __INTRODUCED_IN(21);
+void __FD_SET_chk(int, fd_set* _Nonnull, size_t) __INTRODUCED_IN(21);
+int __FD_ISSET_chk(int, const fd_set* _Nonnull, size_t) __INTRODUCED_IN(21);
#define __FD_CLR(fd, set) (__FDS_BITS(fd_set*,set)[__FDELT(fd)] &= ~__FDMASK(fd))
#define __FD_SET(fd, set) (__FDS_BITS(fd_set*,set)[__FDELT(fd)] |= __FDMASK(fd))
@@ -95,7 +95,7 @@
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
*/
-int select(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout);
+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
@@ -106,7 +106,7 @@
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
*/
-int pselect(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask);
+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
@@ -119,6 +119,6 @@
*
* Available since API level 28.
*/
-int pselect64(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28);
+int pselect64(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
__END_DECLS
diff --git a/libc/include/sys/sem.h b/libc/include/sys/sem.h
index cd62242..f4256e2 100644
--- a/libc/include/sys/sem.h
+++ b/libc/include/sys/sem.h
@@ -45,18 +45,18 @@
union semun {
int val;
- struct semid_ds* buf;
- unsigned short* array;
- struct seminfo* __buf;
- void* __pad;
+ struct semid_ds* _Nullable buf;
+ unsigned short* _Nullable array;
+ struct seminfo* _Nullable __buf;
+ void* _Nullable __pad;
};
int semctl(int __sem_id, int __sem_num, int __cmd, ...) __INTRODUCED_IN(26);
int semget(key_t __key, int __sem_count, int __flags) __INTRODUCED_IN(26);
-int semop(int __sem_id, struct sembuf* __ops, size_t __op_count) __INTRODUCED_IN(26);
+int semop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count) __INTRODUCED_IN(26);
#if defined(__USE_GNU)
-int semtimedop(int __sem_id, struct sembuf* __ops, size_t __op_count, const struct timespec* __timeout) __INTRODUCED_IN(26);
+int semtimedop(int __sem_id, struct sembuf* _Nonnull __ops, size_t __op_count, const struct timespec* _Nullable __timeout) __INTRODUCED_IN(26);
#endif
__END_DECLS
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 60bbde8..4b00d5d 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -40,7 +40,7 @@
/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
#if defined(__USE_FILE_OFFSET64)
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
#else
/**
* [sendfile(2)](http://man7.org/linux/man-pages/man2/sendfile.2.html) copies data directly
@@ -50,13 +50,13 @@
*
* Available since API level 21.
*/
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count);
#endif
/**
* Like sendfile() but allows using a 64-bit offset
* even from a 32-bit process without `__FILE_OFFSET_BITS=64`.
*/
-ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* __offset, size_t __count) __INTRODUCED_IN(21);
+ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* _Nullable __offset, size_t __count) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index 793ee13..d81f836 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -96,7 +96,7 @@
*
* Available since API level 19.
*/
-int statvfs(const char* __path, struct statvfs* __buf) __INTRODUCED_IN(19);
+int statvfs(const char* _Nonnull __path, struct statvfs* _Nonnull __buf) __INTRODUCED_IN(19);
/**
* [fstatvfs(3)](http://man7.org/linux/man-pages/man3/fstatvfs.3.html)
@@ -106,12 +106,12 @@
*
* Available since API level 19.
*/
-int fstatvfs(int __fd, struct statvfs* __buf) __INTRODUCED_IN(19);
+int fstatvfs(int __fd, struct statvfs* _Nonnull __buf) __INTRODUCED_IN(19);
/** Equivalent to statvfs() . */
-int statvfs64(const char* __path, struct statvfs64* __buf) __INTRODUCED_IN(21);
+int statvfs64(const char* _Nonnull __path, struct statvfs64* _Nonnull __buf) __INTRODUCED_IN(21);
/** Equivalent to fstatvfs(). */
-int fstatvfs64(int __fd, struct statvfs64* __buf) __INTRODUCED_IN(21);
+int fstatvfs64(int __fd, struct statvfs64* _Nonnull __buf) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 45190c3..6ba7a37 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -38,21 +38,34 @@
__BEGIN_DECLS
-int gettimeofday(struct timeval* __tv, struct timezone* __tz);
-int settimeofday(const struct timeval* __tv, const struct timezone* __tz);
+int gettimeofday(struct timeval* _Nullable __tv, struct timezone* _Nullable __tz);
+int settimeofday(const struct timeval* _Nullable __tv, const struct timezone* _Nullable __tz);
-int getitimer(int __which, struct itimerval* __current_value);
-int setitimer(int __which, const struct itimerval* __new_value, struct itimerval* __old_value);
+int getitimer(int __which, struct itimerval* _Nonnull __current_value);
+int setitimer(int __which, const struct itimerval* _Nonnull __new_value, struct itimerval* _Nullable __old_value);
-int utimes(const char* __path, const struct timeval __times[2]);
+int utimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]);
#if defined(__USE_BSD)
-int futimes(int __fd, const struct timeval __times[2]) __INTRODUCED_IN(26);
-int lutimes(const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
+int futimes(int __fd, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
+int lutimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
#endif
#if defined(__USE_GNU)
-int futimesat(int __dir_fd, const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
+/**
+ * [futimesat(2)](https://man7.org/linux/man-pages/man2/futimesat.2.html) sets
+ * file timestamps.
+ *
+ * Note: Linux supports `__path` being NULL (in which case `__dir_fd` need not
+ * be a directory), allowing futimensat() to be implemented with utimensat().
+ * Most callers should just use utimensat() directly, especially on Android
+ * where utimensat() has been available for longer than futimesat().
+ *
+ * Returns 0 on success and -1 and sets `errno` on failure.
+ *
+ * Available since API level 26.
+ */
+int futimesat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26);
#endif
#define timerclear(a) \
diff --git a/libc/include/sys/timerfd.h b/libc/include/sys/timerfd.h
index b89941b..aafcef2 100644
--- a/libc/include/sys/timerfd.h
+++ b/libc/include/sys/timerfd.h
@@ -68,7 +68,7 @@
*
* Available since API level 19.
*/
-int timerfd_settime(int __fd, int __flags, const struct itimerspec* __new_value, struct itimerspec* __old_value) __INTRODUCED_IN(19);
+int timerfd_settime(int __fd, int __flags, const struct itimerspec* _Nonnull __new_value, struct itimerspec* _Nullable __old_value) __INTRODUCED_IN(19);
/**
* [timerfd_gettime(2)](http://man7.org/linux/man-pages/man2/timerfd_gettime.2.html) queries the
@@ -78,6 +78,6 @@
*
* Available since API level 19.
*/
-int timerfd_gettime(int __fd, struct itimerspec* __current_value) __INTRODUCED_IN(19);
+int timerfd_gettime(int __fd, struct itimerspec* _Nonnull __current_value) __INTRODUCED_IN(19);
__END_DECLS
diff --git a/libc/include/sys/times.h b/libc/include/sys/times.h
index 25d03e3..8b6e91d 100644
--- a/libc/include/sys/times.h
+++ b/libc/include/sys/times.h
@@ -46,6 +46,6 @@
* Returns a (possibly overflowed) absolute time on success,
* and returns -1 and sets `errno` on failure.
*/
-clock_t times(struct tms* __buf);
+clock_t times(struct tms* _Nullable __buf);
__END_DECLS
diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h
index 52db5dc..4823edf 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -46,7 +46,7 @@
*
* Available since API level 24.
*/
-int adjtimex(struct timex* __buf) __INTRODUCED_IN(24);
+int adjtimex(struct timex* _Nonnull __buf) __INTRODUCED_IN(24);
/**
* clock_adjtime adjusts a specific kernel clock.
@@ -55,6 +55,6 @@
*
* Available since API level 24.
*/
-int clock_adjtime(clockid_t __clock, struct timex* __tx) __INTRODUCED_IN(24);
+int clock_adjtime(clockid_t __clock, struct timex* _Nonnull __tx) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index cefe177..4f4d5ce 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -318,12 +318,20 @@
#if defined(__USE_GNU)
-#define REG_PC 0
-#define REG_RA 1
-#define REG_SP 2
-#define REG_TP 4
-#define REG_S0 8
-#define REG_A0 10
+enum {
+ REG_PC = 0,
+#define REG_PC REG_PC
+ REG_RA = 1,
+#define REG_RA REG_RA
+ REG_SP = 2,
+#define REG_SP REG_SP
+ REG_TP = 4,
+#define REG_TP REG_TP
+ REG_S0 = 8,
+#define REG_S0 REG_S0
+ REG_A0 = 10,
+#define REG_A0 REG_A0
+};
#endif // defined(__USE_GNU)
@@ -366,9 +374,9 @@
/* This matches the kernel <asm/ucontext.h> but using mcontext_t. */
-typedef struct ucontext_t {
+typedef struct ucontext {
unsigned long uc_flags;
- struct ucontext_t* uc_link;
+ struct ucontext* uc_link;
stack_t uc_stack;
union {
sigset_t uc_sigmask;
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 583cfc6..c8c64ae 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -46,7 +46,7 @@
* Returns the number of bytes read on success,
* and returns -1 and sets `errno` on failure.
*/
-ssize_t readv(int __fd, const struct iovec* __iov, int __count);
+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
@@ -55,7 +55,7 @@
* Returns the number of bytes written on success,
* and returns -1 and sets `errno` on failure.
*/
-ssize_t writev(int __fd, const struct iovec* __iov, int __count);
+ssize_t writev(int __fd, const struct iovec* _Nonnull __iov, int __count);
#if defined(__USE_GNU)
@@ -69,7 +69,7 @@
*
* Available since API level 24.
*/
-ssize_t preadv(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
+ssize_t preadv(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
/**
* [pwritev(2)](http://man7.org/linux/man-pages/man2/pwritev.2.html) writes
@@ -81,21 +81,21 @@
*
* Available since API level 24.
*/
-ssize_t pwritev(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
+ssize_t pwritev(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
/**
* Like preadv() but with a 64-bit offset even in a 32-bit process.
*
* Available since API level 24.
*/
-ssize_t preadv64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+ssize_t preadv64(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
/**
* Like pwritev() but with a 64-bit offset even in a 32-bit process.
*
* Available since API level 24.
*/
-ssize_t pwritev64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+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
@@ -107,7 +107,7 @@
*
* Available since API level 33.
*/
-ssize_t preadv2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
+ssize_t preadv2(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
/**
* [pwritev2(2)](http://man7.org/linux/man-pages/man2/pwritev2.2.html) writes
@@ -119,21 +119,21 @@
*
* Available since API level 33.
*/
-ssize_t pwritev2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(pwritev64v2) __INTRODUCED_IN(33);
+ssize_t pwritev2(int __fd, const struct iovec* _Nonnull __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(pwritev64v2) __INTRODUCED_IN(33);
/**
* Like preadv2() but with a 64-bit offset even in a 32-bit process.
*
* Available since API level 33.
*/
-ssize_t preadv64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+ssize_t preadv64v2(int __fd, const struct iovec* _Nonnull __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
/**
* Like pwritev2() but with a 64-bit offset even in a 32-bit process.
*
* Available since API level 33.
*/
-ssize_t pwritev64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+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)
@@ -144,7 +144,7 @@
*
* Available since API level 23.
*/
-ssize_t process_vm_readv(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+ssize_t process_vm_readv(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
/**
* [process_vm_writev(2)](http://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
@@ -155,7 +155,7 @@
*
* Available since API level 23.
*/
-ssize_t process_vm_writev(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+ssize_t process_vm_writev(pid_t __pid, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __local_iov, unsigned long __local_iov_count, const struct iovec* __BIONIC_COMPLICATED_NULLNESS __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
#endif
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 96974a2..e6fb855 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -37,9 +37,9 @@
__BEGIN_DECLS
-pid_t wait(int* __status);
-pid_t waitpid(pid_t __pid, int* __status, int __options);
-pid_t wait4(pid_t __pid, int* __status, int __options, struct rusage* __rusage) __INTRODUCED_IN(18);
+pid_t wait(int* _Nullable __status);
+pid_t waitpid(pid_t __pid, int* _Nullable __status, int __options);
+pid_t wait4(pid_t __pid, int* _Nullable __status, int __options, struct rusage* _Nullable __rusage) __INTRODUCED_IN(18);
/* Posix states that idtype_t should be an enumeration type, but
* the kernel headers define P_ALL, P_PID and P_PGID as constant macros
@@ -47,6 +47,6 @@
*/
typedef int idtype_t;
-int waitid(idtype_t __type, id_t __id, siginfo_t* __info, int __options);
+int waitid(idtype_t __type, id_t __id, siginfo_t* _Nullable __info, int __options);
__END_DECLS
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index d89d769..90ea76e 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -112,17 +112,21 @@
*/
#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1)
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
#define LOG_PID 0x01
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
#define LOG_CONS 0x02
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
#define LOG_ODELAY 0x04
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
#define LOG_NDELAY 0x08
-/** openlog() options are currently ignored on Android. */
+/** openlog() option ignored on Android. */
#define LOG_NOWAIT 0x10
-/** openlog() options are currently ignored on Android. */
+/**
+ * openlog() option to log to stderr as well as the system log.
+ *
+ * Available since API level 34 (ignored before then).
+ */
#define LOG_PERROR 0x20
/**
diff --git a/libc/include/time.h b/libc/include/time.h
index 5339540..1c3ae4b 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _TIME_H_
-#define _TIME_H_
+#pragma once
#include <sys/cdefs.h>
#include <sys/time.h>
@@ -105,9 +104,52 @@
time_t timelocal(struct tm* _Nonnull __tm);
time_t timegm(struct tm* _Nonnull __tm);
-#define TIME_UTC 1
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_REALTIME.
+ *
+ * Available since API level 29.
+ */
+#define TIME_UTC (CLOCK_REALTIME+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_MONOTONIC.
+ *
+ * Available since API level 35.
+ */
+#define TIME_MONOTONIC (CLOCK_MONOTONIC+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_PROCESS_CPUTIME_ID.
+ *
+ * Available since API level 35.
+ */
+#define TIME_ACTIVE (CLOCK_PROCESS_CPUTIME_ID+1)
+
+/**
+ * The timebase for timespec_get() and timespec_getres() corresponding to CLOCK_THREAD_CPUTIME_ID.
+ *
+ * Available since API level 35.
+ */
+#define TIME_THREAD_ACTIVE (CLOCK_THREAD_CPUTIME_ID+1)
+
+/**
+ * timespec_get(3) is equivalent to clock_gettime() for the clock corresponding to the given base.
+ *
+ * Returns the base on success and returns 0 on failure.
+ *
+ * Available since API level 29 for TIME_UTC; other bases arrived later.
+ * Code for Android should prefer clock_gettime().
+ */
int timespec_get(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(29);
-__END_DECLS
+/**
+ * timespec_getres(3) is equivalent to clock_getres() for the clock corresponding to the given base.
+ *
+ * Returns the base on success and returns 0 on failure.
+ *
+ * Available since API level 35.
+ * Code for Android should prefer clock_gettime().
+ */
+int timespec_getres(struct timespec* _Nonnull __ts, int __base) __INTRODUCED_IN(35);
-#endif
+__END_DECLS
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index 7aa5718..d249f8a 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -30,7 +30,7 @@
/**
* @file utmp.h
- * @brief POSIX login records.
+ * @brief No-op implementation of non-POSIX login records. See <utmpx.h> for the POSIX equivalents.
*/
#include <sys/cdefs.h>
@@ -69,12 +69,12 @@
};
struct exit_status {
- short int e_termination;
- short int e_exit;
+ short e_termination;
+ short e_exit;
};
struct utmp {
- short int ut_type;
+ short ut_type;
pid_t ut_pid;
char ut_line[UT_LINESIZE];
char ut_id[4];
@@ -83,7 +83,7 @@
struct exit_status ut_exit;
- long int ut_session;
+ long ut_session;
struct timeval ut_tv;
int32_t ut_addr_v6[4];
@@ -97,21 +97,25 @@
__BEGIN_DECLS
/**
- * Does nothing.
+ * Returns -1 and sets errno to ENOTSUP.
*/
int utmpname(const char* _Nonnull __path);
+
/**
* Does nothing.
*/
void setutent(void);
+
/**
- * Does nothing.
+ * Does nothing and returns null.
*/
struct utmp* _Nullable getutent(void);
+
/**
- * Does nothing.
+ * Does nothing and returns null.
*/
struct utmp* _Nullable pututline(const struct utmp* _Nonnull __entry);
+
/**
* Does nothing.
*/
diff --git a/libc/include/utmpx.h b/libc/include/utmpx.h
new file mode 100644
index 0000000..5ed8e1a
--- /dev/null
+++ b/libc/include/utmpx.h
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/**
+ * @file utmpx.h
+ * @brief No-op implementation of POSIX login records.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <time.h>
+
+#define EMPTY 0
+#define RUN_LVL 1
+#define BOOT_TIME 2
+#define NEW_TIME 3
+#define OLD_TIME 4
+#define INIT_PROCESS 5
+#define LOGIN_PROCESS 6
+#define USER_PROCESS 7
+#define DEAD_PROCESS 8
+#define ACCOUNTING 9
+
+struct utmpx {
+ short ut_type;
+ pid_t ut_pid;
+ char ut_line[32];
+ char ut_id[4];
+ char ut_user[32];
+ char ut_host[256];
+
+ struct {
+ short e_termination;
+ short e_exit;
+ } ut_exit;
+
+ long ut_session;
+ struct timeval ut_tv;
+
+ int32_t ut_addr_v6[4];
+ char unused[20];
+};
+
+__BEGIN_DECLS
+
+/**
+ * Does nothing.
+ */
+void setutxent(void) __RENAME(setutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxent(void) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxid(const struct utmpx* _Nonnull __entry) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxline(const struct utmpx* _Nonnull __entry) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable pututxline(const struct utmpx* _Nonnull __entry) __RENAME(pututline);
+
+/**
+ * Does nothing.
+ */
+void endutxent(void) __RENAME(endutent);
+
+__END_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index add3606..39f9374 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -44,97 +44,96 @@
__BEGIN_DECLS
wint_t btowc(int __ch);
-int fwprintf(FILE* __fp, const wchar_t* __fmt, ...);
-int fwscanf(FILE* __fp, const wchar_t* __fmt, ...);
-wint_t fgetwc(FILE* __fp);
-wchar_t* fgetws(wchar_t* __buf, int __size, FILE* __fp);
-wint_t fputwc(wchar_t __wc, FILE* __fp);
-int fputws(const wchar_t* __s, FILE* __fp);
-int fwide(FILE* __fp, int __mode);
-wint_t getwc(FILE* __fp);
+int fwprintf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, ...);
+int fwscanf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, ...);
+wint_t fgetwc(FILE* _Nonnull __fp);
+wchar_t* _Nullable fgetws(wchar_t* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
+wint_t fputwc(wchar_t __wc, FILE* _Nonnull __fp);
+int fputws(const wchar_t* _Nonnull __s, FILE* _Nonnull __fp);
+int fwide(FILE* _Nonnull __fp, int __mode);
+wint_t getwc(FILE* _Nonnull __fp);
wint_t getwchar(void);
-int mbsinit(const mbstate_t* __ps);
-size_t mbrlen(const char* __s, size_t __n, mbstate_t* __ps);
-size_t mbrtowc(wchar_t* __buf, const char* __s, size_t __n, mbstate_t* __ps);
-size_t mbsrtowcs(wchar_t* __dst, const char** __src, size_t __dst_n, mbstate_t* __ps);
-size_t mbsnrtowcs(wchar_t* __dst, const char** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
-wint_t putwc(wchar_t __wc, FILE* __fp);
+int mbsinit(const mbstate_t* _Nullable __ps);
+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 mbsnrtowcs(wchar_t* _Nullable __dst, const char* _Nullable * _Nullable __src, size_t __src_n, size_t __dst_n, mbstate_t* _Nullable __ps) __INTRODUCED_IN(21);
+wint_t putwc(wchar_t __wc, FILE* _Nonnull __fp);
wint_t putwchar(wchar_t __wc);
-int swprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, ...);
-int swscanf(const wchar_t* __s, const wchar_t* __fmt, ...);
-wint_t ungetwc(wint_t __wc, FILE* __fp);
-int vfwprintf(FILE* __fp, const wchar_t* __fmt, va_list __args);
-int vfwscanf(FILE* __fp, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-int vswprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, va_list __args);
-int vswscanf(const wchar_t* __s, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-int vwprintf(const wchar_t* __fmt, va_list __args);
-int vwscanf(const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-wchar_t* wcpcpy(wchar_t* __dst, const wchar_t* __src);
-wchar_t* wcpncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcrtomb(char* __buf, wchar_t __wc, mbstate_t* __ps);
-int wcscasecmp(const wchar_t* __lhs, const wchar_t* __rhs);
-int wcscasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __INTRODUCED_IN(23);
-wchar_t* wcscat(wchar_t* __dst, const wchar_t* __src);
-wchar_t* wcschr(const wchar_t* __s, wchar_t __wc);
-int wcscmp(const wchar_t* __lhs, const wchar_t* __rhs);
-int wcscoll(const wchar_t* __lhs, const wchar_t* __rhs);
-wchar_t* wcscpy(wchar_t* __dst, const wchar_t* __src);
-size_t wcscspn(const wchar_t* __s, const wchar_t* __accept);
-size_t wcsftime(wchar_t* __buf, size_t __n, const wchar_t* __fmt, const struct tm* __tm);
-size_t wcsftime_l(wchar_t* __buf, size_t __n, const wchar_t* __fmt, const struct tm* __tm, locale_t __l) __INTRODUCED_IN(28);
-size_t wcslen(const wchar_t* __s);
-int wcsncasecmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-int wcsncasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n, locale_t __l) __INTRODUCED_IN(23);
-wchar_t* wcsncat(wchar_t* __dst, const wchar_t* __src, size_t __n);
-int wcsncmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-wchar_t* wcsncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcsnrtombs(char* __dst, const wchar_t** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
-wchar_t* wcspbrk(const wchar_t* __s, const wchar_t* __accept);
-wchar_t* wcsrchr(const wchar_t* __s, wchar_t __wc);
-size_t wcsrtombs(char* __dst, const wchar_t** __src, size_t __dst_n, mbstate_t* __ps);
-size_t wcsspn(const wchar_t* __s, const wchar_t* __accept);
-wchar_t* wcsstr(const wchar_t* __haystack, const wchar_t* __needle);
-double wcstod(const wchar_t* __s, wchar_t** __end_ptr);
-double wcstod_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(28);
-float wcstof(const wchar_t* __s, wchar_t** __end_ptr) __INTRODUCED_IN(21);
-float wcstof_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(28);
-wchar_t* wcstok(wchar_t* __s, const wchar_t* __delimiter, wchar_t** __ptr);
-long wcstol(const wchar_t* __s, wchar_t** __end_ptr, int __base);
-long wcstol_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(28);
-long long wcstoll(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
-long double wcstold(const wchar_t* __s, wchar_t** __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
-unsigned long wcstoul(const wchar_t* __s, wchar_t** __end_ptr, int __base);
-unsigned long wcstoul_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(28);
-unsigned long long wcstoull(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
-int wcswidth(const wchar_t* __s, size_t __n);
-size_t wcsxfrm(wchar_t* __dst, const wchar_t* __src, size_t __n);
+int swprintf(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nonnull __fmt, ...);
+int swscanf(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __fmt, ...);
+wint_t ungetwc(wint_t __wc, FILE* _Nonnull __fp);
+int vfwprintf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, va_list __args);
+int vfwscanf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+int vswprintf(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nonnull __fmt, va_list __args);
+int vswscanf(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+int vwprintf(const wchar_t* _Nonnull __fmt, va_list __args);
+int vwscanf(const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+wchar_t* _Nonnull wcpcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+wchar_t* _Nonnull wcpncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcrtomb(char* _Nullable __buf, wchar_t __wc, mbstate_t* _Nullable __ps);
+int wcscasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+int wcscasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wcscat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+wchar_t* _Nullable wcschr(const wchar_t * _Nonnull __s, wchar_t __wc);
+int wcscmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+int wcscoll(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+wchar_t* _Nonnull wcscpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+size_t wcscspn(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
+size_t wcsftime(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm);
+size_t wcsftime_l(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+size_t wcslen(const wchar_t* _Nonnull __s);
+int wcsncasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
+int wcsncasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wcsncat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+int wcsncmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
+wchar_t* _Nonnull wcsncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcsnrtombs(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __src_n, size_t __dst_n, mbstate_t* _Nullable __ps) __INTRODUCED_IN(21);
+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 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);
+float wcstof(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __INTRODUCED_IN(21);
+float wcstof_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+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 long wcstoll(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
+long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
+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 long wcstoull(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
+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);
int wctob(wint_t __wc);
int wcwidth(wchar_t __wc);
-wchar_t* wmemchr(const wchar_t* __src, wchar_t __wc, size_t __n);
-int wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-wchar_t* wmemcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
+wchar_t* _Nullable wmemchr(const wchar_t* _Nonnull __src, wchar_t __wc, size_t __n);
+int wmemcmp(const wchar_t* _Nullable __lhs, const wchar_t* _Nullable __rhs, size_t __n);
+wchar_t* _Nonnull wmemcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
#if defined(__USE_GNU)
-wchar_t* wmempcpy(wchar_t* __dst, const wchar_t* __src, size_t __n) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wmempcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n) __INTRODUCED_IN(23);
#endif
-wchar_t* wmemmove(wchar_t* __dst, const wchar_t* __src, size_t __n);
-wchar_t* wmemset(wchar_t* __dst, wchar_t __wc, size_t __n);
-int wprintf(const wchar_t* __fmt, ...);
-int wscanf(const wchar_t* __fmt, ...);
+wchar_t* _Nonnull wmemmove(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+wchar_t* _Nonnull wmemset(wchar_t* _Nonnull __dst, wchar_t __wc, size_t __n);
+int wprintf(const wchar_t* _Nonnull __fmt, ...);
+int wscanf(const wchar_t* _Nonnull __fmt, ...);
-long long wcstoll_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-unsigned long long wcstoull_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-long double wcstold_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
+long long wcstoll_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+unsigned long long wcstoull_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+long double wcstold_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(21);
-int wcscoll_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __attribute_pure__
+int wcscoll_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, locale_t _Nonnull __l) __attribute_pure__
__INTRODUCED_IN(21);
-size_t wcsxfrm_l(wchar_t* __dst, const wchar_t* __src, size_t __n, locale_t __l) __INTRODUCED_IN(21);
+size_t wcsxfrm_l(wchar_t* __BIONIC_COMPLICATED_NULLNESS __dst, const wchar_t* _Nonnull __src, size_t __n, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+size_t wcslcat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcslcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
-size_t wcslcat(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcslcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-
-FILE* open_wmemstream(wchar_t** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
-wchar_t* wcsdup(const wchar_t* __s);
-size_t wcsnlen(const wchar_t* __s, size_t __n);
+FILE* _Nullable open_wmemstream(wchar_t* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
+wchar_t* _Nullable wcsdup(const wchar_t* _Nonnull __s);
+size_t wcsnlen(const wchar_t* _Nonnull __s, size_t __n);
__END_DECLS
diff --git a/libc/kernel/android/scsi/scsi/sg.h b/libc/kernel/android/scsi/scsi/sg.h
index 6911b16..9ba6cd6 100644
--- a/libc/kernel/android/scsi/scsi/sg.h
+++ b/libc/kernel/android/scsi/scsi/sg.h
@@ -20,7 +20,7 @@
#define _SCSI_GENERIC_H
#include <linux/compiler.h>
typedef struct sg_iovec {
- void __user * iov_base;
+ void * iov_base;
size_t iov_len;
} sg_iovec_t;
typedef struct sg_io_hdr {
@@ -30,13 +30,13 @@
unsigned char mx_sb_len;
unsigned short iovec_count;
unsigned int dxfer_len;
- void __user * dxferp;
- unsigned char __user * cmdp;
- void __user * sbp;
+ void * dxferp;
+ unsigned char * cmdp;
+ void * sbp;
unsigned int timeout;
unsigned int flags;
int pack_id;
- void __user * usr_ptr;
+ void * usr_ptr;
unsigned char status;
unsigned char masked_status;
unsigned char msg_status;
@@ -96,7 +96,7 @@
char sg_io_owned;
char problem;
int pack_id;
- void __user * usr_ptr;
+ void * usr_ptr;
unsigned int duration;
int unused;
} sg_req_info_t;
diff --git a/libc/kernel/android/uapi/linux/compiler.h b/libc/kernel/android/uapi/linux/compiler.h
index 8e89655..42d59aa 100644
--- a/libc/kernel/android/uapi/linux/compiler.h
+++ b/libc/kernel/android/uapi/linux/compiler.h
@@ -1,18 +1,11 @@
-#ifndef _UAPI_LINUX_COMPILER_H
-#define _UAPI_LINUX_COMPILER_H
+#pragma once
/*
- * This file is not currently in the Linux kernel tree.
- * Upstream uapi headers refer to <linux/compiler.h> but there is
- * no such uapi file. We've sent this upstream, and are optimistically
- * adding it to bionic in the meantime. This should be replaced by
- * a scrubbed header from external/kernel-headers when possible.
+ * There is no `include/uapi/linux/compiler.h`, just `include/linux/compiler.h`.
*
- * An alternative to this file is to check in a symbolic link to the
- * non-uapi <linux/compiler.h>. That's fine for building bionic too.
+ * We don't need anything _in_ this file, but we do need this file.
+ * The two #defines are for backwards compatibility.
*/
-#define __user
#define __force
-
-#endif /* _UAPI_LINUX_COMPILER_H */
+#define __user
diff --git a/libc/kernel/android/uapi/linux/compiler_types.h b/libc/kernel/android/uapi/linux/compiler_types.h
index 94f4fbe..859ae05 100644
--- a/libc/kernel/android/uapi/linux/compiler_types.h
+++ b/libc/kernel/android/uapi/linux/compiler_types.h
@@ -1,5 +1,11 @@
+#pragma once
+
/*
- * The compiler.h file has been split into compiler.h and compiler_types.h.
- * However, to compile bionic we only need the compiler.h.
+ * There is no `include/uapi/linux/compiler_types.h`, just
+ * `include/linux/compiler_types.h`.
+ *
+ * We don't need anything _in_ this file, but we do need this file.
+ * The #include is for backwards compatibility.
*/
+
#include <linux/compiler.h>
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index d0fe157..91d26ce 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -1,9 +1,4 @@
-# this module contains all the defaults used by the generation of cleaned-up headers
-# for the Bionic C library
-#
-
-import time, os, sys
-from utils import *
+# All the defaults used to generate the cleaned-up uapi headers for bionic.
# the list of include directories that belong to the kernel
# tree. used when looking for sources...
@@ -48,6 +43,7 @@
"in_addr": False,
"ip_mreq_source": False,
"ip_msfilter": False,
+ "timespec": False,
}
# define to true if you want to remove all defined(CONFIG_FOO) tests
@@ -97,6 +93,9 @@
# Replace __packed with __attribute__((__packed__)) to avoid depending
# on sys/cdefs.h
"__packed": "__attribute__((__packed__))",
+ # Remove unused macros (http://b/262917450).
+ "__force": "",
+ "__user": "",
}
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index abc72a4..ae89a80 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -92,6 +92,7 @@
'kernel/uapi/asm-arm/asm/unistd.h',
'kernel/uapi/asm-arm/asm/unistd-eabi.h',
'kernel/uapi/asm-arm/asm/unistd-oabi.h',
+ 'kernel/uapi/asm-riscv/asm/unistd.h',
'kernel/uapi/asm-x86/asm/unistd_32.h',
'kernel/uapi/asm-x86/asm/unistd_64.h',
'kernel/uapi/asm-x86/asm/unistd_x32.h']:
diff --git a/libc/kernel/uapi/asm-arm/asm/signal.h b/libc/kernel/uapi/asm-arm/asm/signal.h
index 0424380..90cb8d6 100644
--- a/libc/kernel/uapi/asm-arm/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm/asm/signal.h
@@ -76,7 +76,7 @@
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
typedef struct sigaltstack {
- void __user * ss_sp;
+ void * ss_sp;
int ss_flags;
__kernel_size_t ss_size;
} stack_t;
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index bb592e4..3ec1354 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -87,4 +87,10 @@
#define HWCAP2_CSSC (1UL << 34)
#define HWCAP2_RPRFM (1UL << 35)
#define HWCAP2_SVE2P1 (1UL << 36)
+#define HWCAP2_SME2 (1UL << 37)
+#define HWCAP2_SME2P1 (1UL << 38)
+#define HWCAP2_SME_I16I32 (1UL << 39)
+#define HWCAP2_SME_BI32I32 (1UL << 40)
+#define HWCAP2_SME_B16B16 (1UL << 41)
+#define HWCAP2_SME_F16F16 (1UL << 42)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index ecc2e01..a413b36 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -74,6 +74,7 @@
#define KVM_ARM_VCPU_SVE 4
#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5
#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6
+#define KVM_ARM_VCPU_HAS_EL2 7
struct kvm_vcpu_init {
__u32 target;
__u32 features[7];
@@ -121,7 +122,7 @@
struct kvm_arm_copy_mte_tags {
__u64 guest_ipa;
__u64 length;
- void __user * addr;
+ void * addr;
__u64 flags;
__u64 reserved[2];
};
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 04aa593..84cd16d 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -59,12 +59,23 @@
__u16 __reserved[2];
};
#define SVE_SIG_FLAG_SM 0x1
+#define TPIDR2_MAGIC 0x54504902
+struct tpidr2_context {
+ struct _aarch64_ctx head;
+ __u64 tpidr2;
+};
#define ZA_MAGIC 0x54366345
struct za_context {
struct _aarch64_ctx head;
__u16 vl;
__u16 __reserved[3];
};
+#define ZT_MAGIC 0x5a544e01
+struct zt_context {
+ struct _aarch64_ctx head;
+ __u16 nregs;
+ __u16 __reserved[3];
+};
#endif
#include <asm/sve_context.h>
#define SVE_VQ_BYTES __SVE_VQ_BYTES
@@ -94,4 +105,9 @@
#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * n))
#define ZA_SIG_CONTEXT_SIZE(vq) (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
+#define ZT_SIG_REG_SIZE 512
+#define ZT_SIG_REG_BYTES (ZT_SIG_REG_SIZE / 8)
+#define ZT_SIG_REGS_OFFSET sizeof(struct zt_context)
+#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n)
+#define ZT_SIG_CONTEXT_SIZE(n) (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
#endif
diff --git a/libc/kernel/uapi/asm-generic/poll.h b/libc/kernel/uapi/asm-generic/poll.h
index 372bc77..ba6f2e9 100644
--- a/libc/kernel/uapi/asm-generic/poll.h
+++ b/libc/kernel/uapi/asm-generic/poll.h
@@ -41,8 +41,8 @@
#ifndef POLLRDHUP
#define POLLRDHUP 0x2000
#endif
-#define POLLFREE (__force __poll_t) 0x4000
-#define POLL_BUSY_LOOP (__force __poll_t) 0x8000
+#define POLLFREE ( __poll_t) 0x4000
+#define POLL_BUSY_LOOP ( __poll_t) 0x8000
struct pollfd {
int fd;
short events;
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index c5e4178..90393ba 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -22,7 +22,7 @@
#include <linux/types.h>
typedef union sigval {
int sival_int;
- void __user * sival_ptr;
+ void * sival_ptr;
} sigval_t;
#define SI_MAX_SIZE 128
#ifndef __ARCH_SI_BAND_T
@@ -58,7 +58,7 @@
__ARCH_SI_CLOCK_T _stime;
} _sigchld;
struct {
- void __user * _addr;
+ void * _addr;
#ifdef __ia64__
int _imm;
unsigned int _flags;
@@ -70,8 +70,8 @@
short _addr_lsb;
struct {
char _dummy_bnd[__ADDR_BND_PKEY_PAD];
- void __user * _lower;
- void __user * _upper;
+ void * _lower;
+ void * _upper;
} _addr_bnd;
struct {
char _dummy_pkey[__ADDR_BND_PKEY_PAD];
@@ -89,7 +89,7 @@
int _fd;
} _sigpoll;
struct {
- void __user * _call_addr;
+ void * _call_addr;
int _syscall;
unsigned int _arch;
} _sigsys;
diff --git a/libc/kernel/uapi/asm-generic/signal-defs.h b/libc/kernel/uapi/asm-generic/signal-defs.h
index c7e9504..dea8fbc 100644
--- a/libc/kernel/uapi/asm-generic/signal-defs.h
+++ b/libc/kernel/uapi/asm-generic/signal-defs.h
@@ -55,11 +55,11 @@
#endif
#ifndef __ASSEMBLY__
typedef void __signalfn_t(int);
-typedef __signalfn_t __user * __sighandler_t;
+typedef __signalfn_t * __sighandler_t;
typedef void __restorefn_t(void);
-typedef __restorefn_t __user * __sigrestore_t;
-#define SIG_DFL ((__force __sighandler_t) 0)
-#define SIG_IGN ((__force __sighandler_t) 1)
-#define SIG_ERR ((__force __sighandler_t) - 1)
+typedef __restorefn_t * __sigrestore_t;
+#define SIG_DFL (( __sighandler_t) 0)
+#define SIG_IGN (( __sighandler_t) 1)
+#define SIG_ERR (( __sighandler_t) - 1)
#endif
#endif
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index 5cb1dce..9cf393f 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -82,7 +82,7 @@
sigset_t sa_mask;
};
typedef struct sigaltstack {
- void __user * ss_sp;
+ void * ss_sp;
int ss_flags;
__kernel_size_t ss_size;
} stack_t;
diff --git a/libc/kernel/uapi/asm-riscv/asm/setup.h b/libc/kernel/uapi/asm-riscv/asm/setup.h
index 940c4db..faac9a6 100644
--- a/libc/kernel/uapi/asm-riscv/asm/setup.h
+++ b/libc/kernel/uapi/asm-riscv/asm/setup.h
@@ -16,4 +16,7 @@
***
****************************************************************************
****************************************************************************/
-#include <asm-generic/setup.h>
+#ifndef _UAPI_ASM_RISCV_SETUP_H
+#define _UAPI_ASM_RISCV_SETUP_H
+#define COMMAND_LINE_SIZE 1024
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 77d35fc..5c8f5a6 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -20,6 +20,7 @@
#define _ASM_X86_KVM_H
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/stddef.h>
#define KVM_PIO_PAGE_OFFSET 1
#define KVM_COALESCED_MMIO_PAGE_OFFSET 2
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
@@ -395,8 +396,8 @@
__u8 pad[120];
} hdr;
union {
- struct kvm_vmx_nested_state_data vmx[0];
- struct kvm_svm_nested_state_data svm[0];
+ __DECLARE_FLEX_ARRAY(struct kvm_vmx_nested_state_data, vmx);
+ __DECLARE_FLEX_ARRAY(struct kvm_svm_nested_state_data, svm);
} data;
};
struct kvm_pmu_event_filter {
@@ -409,6 +410,14 @@
};
#define KVM_PMU_EVENT_ALLOW 0
#define KVM_PMU_EVENT_DENY 1
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
+#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
+#define KVM_PMU_ENCODE_MASKED_ENTRY(event_select,mask,match,exclude) (((event_select) & 0xFFULL) | (((event_select) & 0XF00ULL) << 24) | (((mask) & 0xFFULL) << 56) | (((match) & 0xFFULL) << 8) | ((__u64) (! ! (exclude)) << 55))
+#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (GENMASK_ULL(63, 56))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (GENMASK_ULL(15, 8))
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE (BIT_ULL(55))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56)
#define KVM_VCPU_TSC_CTRL 0
#define KVM_VCPU_TSC_OFFSET 0
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/sigcontext.h b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
index 7d5b4d4..c790950 100644
--- a/libc/kernel/uapi/asm-x86/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
@@ -180,7 +180,7 @@
__u32 eflags;
__u32 esp_at_signal;
__u16 ss, __ssh;
- struct _fpstate __user * fpstate;
+ struct _fpstate * fpstate;
__u32 oldmask;
__u32 cr2;
};
@@ -215,7 +215,7 @@
__u64 trapno;
__u64 oldmask;
__u64 cr2;
- struct _fpstate __user * fpstate;
+ struct _fpstate * fpstate;
#ifdef __ILP32__
__u32 __fpstate_pad;
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index cbeeac4..37dce50 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -88,7 +88,7 @@
};
#endif
typedef struct sigaltstack {
- void __user * ss_sp;
+ void * ss_sp;
int ss_flags;
__kernel_size_t ss_size;
} stack_t;
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index fcd5ab8..8d0d0b0 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -428,6 +428,7 @@
#define AMDGPU_IDS_FLAGS_FUSION 0x1
#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
#define AMDGPU_IDS_FLAGS_TMZ 0x4
+#define AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD 0x8
#define AMDGPU_INFO_ACCEL_WORKING 0x00
#define AMDGPU_INFO_CRTC_FROM_ID 0x01
#define AMDGPU_INFO_HW_IP_INFO 0x02
@@ -486,6 +487,8 @@
#define AMDGPU_INFO_SENSOR_VDDGFX 0x7
#define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK 0x8
#define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9
+#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK 0xa
+#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK 0xb
#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
#define AMDGPU_INFO_RAS_ENABLED_FEATURES 0x20
@@ -616,7 +619,7 @@
__u32 enabled_rb_pipes_mask;
__u32 num_rb_pipes;
__u32 num_hw_gfx_contexts;
- __u32 _pad;
+ __u32 pcie_gen;
__u64 ids_flags;
__u64 virtual_address_offset;
__u64 virtual_address_max;
@@ -643,12 +646,22 @@
__u32 gs_vgt_table_depth;
__u32 gs_prim_buffer_depth;
__u32 max_gs_waves_per_vgt;
- __u32 _pad1;
+ __u32 pcie_num_lanes;
__u32 cu_ao_bitmap[4][4];
__u64 high_va_offset;
__u64 high_va_max;
__u32 pa_sc_tile_steering_override;
__u64 tcc_disabled_mask;
+ __u64 min_engine_clock;
+ __u64 min_memory_clock;
+ __u32 tcp_cache_size;
+ __u32 num_sqc_per_wgp;
+ __u32 sqc_data_cache_size;
+ __u32 sqc_inst_cache_size;
+ __u32 gl1c_cache_size;
+ __u32 gl2c_cache_size;
+ __u64 mall_size;
+ __u32 enabled_rb_pipes_mask_hi;
};
struct drm_amdgpu_info_hw_ip {
__u32 hw_ip_version_major;
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 878e899..1954452 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -78,19 +78,19 @@
int version_minor;
int version_patchlevel;
__kernel_size_t name_len;
- char __user * name;
+ char * name;
__kernel_size_t date_len;
- char __user * date;
+ char * date;
__kernel_size_t desc_len;
- char __user * desc;
+ char * desc;
};
struct drm_unique {
__kernel_size_t unique_len;
- char __user * unique;
+ char * unique;
};
struct drm_list {
int count;
- struct drm_version __user * version;
+ struct drm_version * version;
};
struct drm_block {
int unused;
@@ -202,37 +202,37 @@
};
struct drm_buf_info {
int count;
- struct drm_buf_desc __user * list;
+ struct drm_buf_desc * list;
};
struct drm_buf_free {
int count;
- int __user * list;
+ int * list;
};
struct drm_buf_pub {
int idx;
int total;
int used;
- void __user * address;
+ void * address;
};
struct drm_buf_map {
int count;
#ifdef __cplusplus
- void __user * virt;
+ void * virt;
#else
- void __user * __linux_virtual;
+ void * __linux_virtual;
#endif
- struct drm_buf_pub __user * list;
+ struct drm_buf_pub * list;
};
struct drm_dma {
int context;
int send_count;
- int __user * send_indices;
- int __user * send_sizes;
+ int * send_indices;
+ int * send_sizes;
enum drm_dma_flags flags;
int request_count;
int request_size;
- int __user * request_indices;
- int __user * request_sizes;
+ int * request_indices;
+ int * request_sizes;
int granted_count;
};
enum drm_ctx_flags {
@@ -245,7 +245,7 @@
};
struct drm_ctx_res {
int count;
- struct drm_ctx __user * contexts;
+ struct drm_ctx * contexts;
};
struct drm_draw {
drm_drawable_t handle;
diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/drm/habanalabs_accel.h
similarity index 98%
rename from libc/kernel/uapi/misc/habanalabs.h
rename to libc/kernel/uapi/drm/habanalabs_accel.h
index b25c833..d7dccef 100644
--- a/libc/kernel/uapi/misc/habanalabs.h
+++ b/libc/kernel/uapi/drm/habanalabs_accel.h
@@ -662,6 +662,7 @@
#define HL_INFO_ENGINE_STATUS 32
#define HL_INFO_PAGE_FAULT_EVENT 33
#define HL_INFO_USER_MAPPINGS 34
+#define HL_INFO_FW_GENERIC_REQ 35
#define HL_INFO_VERSION_MAX_LEN 128
#define HL_INFO_CARD_NAME_MAX_LEN 16
#define HL_ENGINES_DATA_MAX_SIZE SZ_1M
@@ -872,6 +873,7 @@
__u32 user_buffer_actual_size;
__u32 sec_attest_nonce;
__u32 array_size;
+ __u32 fw_sub_opcode;
};
__u32 pad;
};
@@ -935,6 +937,7 @@
#define HL_CS_FLAGS_RESERVE_SIGNALS_ONLY 0x1000
#define HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY 0x2000
#define HL_CS_FLAGS_ENGINE_CORE_COMMAND 0x4000
+#define HL_CS_FLAGS_FLUSH_PCI_HBW_WRITES 0x8000
#define HL_CS_STATUS_SUCCESS 0
#define HL_MAX_JOBS_PER_CS 512
#define HL_ENGINE_CORE_HALT (1 << 0)
@@ -1072,8 +1075,9 @@
__u64 device_virt_addr;
} unmap;
struct {
- __u64 handle;
+ __u64 addr;
__u64 mem_size;
+ __u64 offset;
} export_dmabuf_fd;
};
__u32 op;
diff --git a/libc/kernel/uapi/drm/i810_drm.h b/libc/kernel/uapi/drm/i810_drm.h
deleted file mode 100644
index e33387d..0000000
--- a/libc/kernel/uapi/drm/i810_drm.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _I810_DRM_H_
-#define _I810_DRM_H_
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef _I810_DEFINES_
-#define _I810_DEFINES_
-#define I810_DMA_BUF_ORDER 12
-#define I810_DMA_BUF_SZ (1 << I810_DMA_BUF_ORDER)
-#define I810_DMA_BUF_NR 256
-#define I810_NR_SAREA_CLIPRECTS 8
-#define I810_NR_TEX_REGIONS 64
-#define I810_LOG_MIN_TEX_REGION_SIZE 16
-#endif
-#define I810_UPLOAD_TEX0IMAGE 0x1
-#define I810_UPLOAD_TEX1IMAGE 0x2
-#define I810_UPLOAD_CTX 0x4
-#define I810_UPLOAD_BUFFERS 0x8
-#define I810_UPLOAD_TEX0 0x10
-#define I810_UPLOAD_TEX1 0x20
-#define I810_UPLOAD_CLIPRECTS 0x40
-#define I810_DESTREG_DI0 0
-#define I810_DESTREG_DI1 1
-#define I810_DESTREG_DV0 2
-#define I810_DESTREG_DV1 3
-#define I810_DESTREG_DR0 4
-#define I810_DESTREG_DR1 5
-#define I810_DESTREG_DR2 6
-#define I810_DESTREG_DR3 7
-#define I810_DESTREG_DR4 8
-#define I810_DEST_SETUP_SIZE 10
-#define I810_CTXREG_CF0 0
-#define I810_CTXREG_CF1 1
-#define I810_CTXREG_ST0 2
-#define I810_CTXREG_ST1 3
-#define I810_CTXREG_VF 4
-#define I810_CTXREG_MT 5
-#define I810_CTXREG_MC0 6
-#define I810_CTXREG_MC1 7
-#define I810_CTXREG_MC2 8
-#define I810_CTXREG_MA0 9
-#define I810_CTXREG_MA1 10
-#define I810_CTXREG_MA2 11
-#define I810_CTXREG_SDM 12
-#define I810_CTXREG_FOG 13
-#define I810_CTXREG_B1 14
-#define I810_CTXREG_B2 15
-#define I810_CTXREG_LCS 16
-#define I810_CTXREG_PV 17
-#define I810_CTXREG_ZA 18
-#define I810_CTXREG_AA 19
-#define I810_CTX_SETUP_SIZE 20
-#define I810_TEXREG_MI0 0
-#define I810_TEXREG_MI1 1
-#define I810_TEXREG_MI2 2
-#define I810_TEXREG_MI3 3
-#define I810_TEXREG_MF 4
-#define I810_TEXREG_MLC 5
-#define I810_TEXREG_MLL 6
-#define I810_TEXREG_MCS 7
-#define I810_TEX_SETUP_SIZE 8
-#define I810_FRONT 0x1
-#define I810_BACK 0x2
-#define I810_DEPTH 0x4
-typedef enum _drm_i810_init_func {
- I810_INIT_DMA = 0x01,
- I810_CLEANUP_DMA = 0x02,
- I810_INIT_DMA_1_4 = 0x03
-} drm_i810_init_func_t;
-typedef struct _drm_i810_init {
- drm_i810_init_func_t func;
- unsigned int mmio_offset;
- unsigned int buffers_offset;
- int sarea_priv_offset;
- unsigned int ring_start;
- unsigned int ring_end;
- unsigned int ring_size;
- unsigned int front_offset;
- unsigned int back_offset;
- unsigned int depth_offset;
- unsigned int overlay_offset;
- unsigned int overlay_physical;
- unsigned int w;
- unsigned int h;
- unsigned int pitch;
- unsigned int pitch_bits;
-} drm_i810_init_t;
-typedef struct _drm_i810_pre12_init {
- drm_i810_init_func_t func;
- unsigned int mmio_offset;
- unsigned int buffers_offset;
- int sarea_priv_offset;
- unsigned int ring_start;
- unsigned int ring_end;
- unsigned int ring_size;
- unsigned int front_offset;
- unsigned int back_offset;
- unsigned int depth_offset;
- unsigned int w;
- unsigned int h;
- unsigned int pitch;
- unsigned int pitch_bits;
-} drm_i810_pre12_init_t;
-typedef struct _drm_i810_tex_region {
- unsigned char next, prev;
- unsigned char in_use;
- int age;
-} drm_i810_tex_region_t;
-typedef struct _drm_i810_sarea {
- unsigned int ContextState[I810_CTX_SETUP_SIZE];
- unsigned int BufferState[I810_DEST_SETUP_SIZE];
- unsigned int TexState[2][I810_TEX_SETUP_SIZE];
- unsigned int dirty;
- unsigned int nbox;
- struct drm_clip_rect boxes[I810_NR_SAREA_CLIPRECTS];
- drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1];
- int texAge;
- int last_enqueue;
- int last_dispatch;
- int last_quiescent;
- int ctxOwner;
- int vertex_prim;
- int pf_enabled;
- int pf_active;
- int pf_current_page;
-} drm_i810_sarea_t;
-#define DRM_I810_INIT 0x00
-#define DRM_I810_VERTEX 0x01
-#define DRM_I810_CLEAR 0x02
-#define DRM_I810_FLUSH 0x03
-#define DRM_I810_GETAGE 0x04
-#define DRM_I810_GETBUF 0x05
-#define DRM_I810_SWAP 0x06
-#define DRM_I810_COPY 0x07
-#define DRM_I810_DOCOPY 0x08
-#define DRM_I810_OV0INFO 0x09
-#define DRM_I810_FSTATUS 0x0a
-#define DRM_I810_OV0FLIP 0x0b
-#define DRM_I810_MC 0x0c
-#define DRM_I810_RSTATUS 0x0d
-#define DRM_I810_FLIP 0x0e
-#define DRM_IOCTL_I810_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I810_INIT, drm_i810_init_t)
-#define DRM_IOCTL_I810_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
-#define DRM_IOCTL_I810_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_I810_CLEAR, drm_i810_clear_t)
-#define DRM_IOCTL_I810_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I810_FLUSH)
-#define DRM_IOCTL_I810_GETAGE DRM_IO(DRM_COMMAND_BASE + DRM_I810_GETAGE)
-#define DRM_IOCTL_I810_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
-#define DRM_IOCTL_I810_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_I810_SWAP)
-#define DRM_IOCTL_I810_COPY DRM_IOW(DRM_COMMAND_BASE + DRM_I810_COPY, drm_i810_copy_t)
-#define DRM_IOCTL_I810_DOCOPY DRM_IO(DRM_COMMAND_BASE + DRM_I810_DOCOPY)
-#define DRM_IOCTL_I810_OV0INFO DRM_IOR(DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
-#define DRM_IOCTL_I810_FSTATUS DRM_IO(DRM_COMMAND_BASE + DRM_I810_FSTATUS)
-#define DRM_IOCTL_I810_OV0FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I810_OV0FLIP)
-#define DRM_IOCTL_I810_MC DRM_IOW(DRM_COMMAND_BASE + DRM_I810_MC, drm_i810_mc_t)
-#define DRM_IOCTL_I810_RSTATUS DRM_IO(DRM_COMMAND_BASE + DRM_I810_RSTATUS)
-#define DRM_IOCTL_I810_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I810_FLIP)
-typedef struct _drm_i810_clear {
- int clear_color;
- int clear_depth;
- int flags;
-} drm_i810_clear_t;
-typedef struct _drm_i810_vertex {
- int idx;
- int used;
- int discard;
-} drm_i810_vertex_t;
-typedef struct _drm_i810_copy_t {
- int idx;
- int used;
- void * address;
-} drm_i810_copy_t;
-#define PR_TRIANGLES (0x0 << 18)
-#define PR_TRISTRIP_0 (0x1 << 18)
-#define PR_TRISTRIP_1 (0x2 << 18)
-#define PR_TRIFAN (0x3 << 18)
-#define PR_POLYGON (0x4 << 18)
-#define PR_LINES (0x5 << 18)
-#define PR_LINESTRIP (0x6 << 18)
-#define PR_RECTS (0x7 << 18)
-#define PR_MASK (0x7 << 18)
-typedef struct drm_i810_dma {
- void * __linux_virtual;
- int request_idx;
- int request_size;
- int granted;
-} drm_i810_dma_t;
-typedef struct _drm_i810_overlay_t {
- unsigned int offset;
- unsigned int physical;
-} drm_i810_overlay_t;
-typedef struct _drm_i810_mc {
- int idx;
- int used;
- int num_blocks;
- int * length;
- unsigned int last_render;
-} drm_i810_mc_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index a8982bf..794e784 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -287,18 +287,18 @@
int DR1;
int DR4;
int num_cliprects;
- struct drm_clip_rect __user * cliprects;
+ struct drm_clip_rect * cliprects;
} drm_i915_batchbuffer_t;
typedef struct _drm_i915_cmdbuffer {
- char __user * buf;
+ char * buf;
int sz;
int DR1;
int DR4;
int num_cliprects;
- struct drm_clip_rect __user * cliprects;
+ struct drm_clip_rect * cliprects;
} drm_i915_cmdbuffer_t;
typedef struct drm_i915_irq_emit {
- int __user * irq_seq;
+ int * irq_seq;
} drm_i915_irq_emit_t;
typedef struct drm_i915_irq_wait {
int irq_seq;
@@ -371,7 +371,7 @@
#define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
struct drm_i915_getparam {
__s32 param;
- int __user * value;
+ int * value;
};
typedef struct drm_i915_getparam drm_i915_getparam_t;
#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
@@ -387,7 +387,7 @@
int region;
int alignment;
int size;
- int __user * region_offset;
+ int * region_offset;
} drm_i915_mem_alloc_t;
typedef struct drm_i915_mem_free {
int region;
diff --git a/libc/kernel/uapi/drm/ivpu_accel.h b/libc/kernel/uapi/drm/ivpu_accel.h
new file mode 100644
index 0000000..e148a5b
--- /dev/null
+++ b/libc/kernel/uapi/drm/ivpu_accel.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __UAPI_IVPU_DRM_H__
+#define __UAPI_IVPU_DRM_H__
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define DRM_IVPU_DRIVER_MAJOR 1
+#define DRM_IVPU_DRIVER_MINOR 0
+#define DRM_IVPU_GET_PARAM 0x00
+#define DRM_IVPU_SET_PARAM 0x01
+#define DRM_IVPU_BO_CREATE 0x02
+#define DRM_IVPU_BO_INFO 0x03
+#define DRM_IVPU_SUBMIT 0x05
+#define DRM_IVPU_BO_WAIT 0x06
+#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_IVPU_PARAM_DEVICE_ID 0
+#define DRM_IVPU_PARAM_DEVICE_REVISION 1
+#define DRM_IVPU_PARAM_PLATFORM_TYPE 2
+#define DRM_IVPU_PARAM_CORE_CLOCK_RATE 3
+#define DRM_IVPU_PARAM_NUM_CONTEXTS 4
+#define DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS 5
+#define DRM_IVPU_PARAM_CONTEXT_PRIORITY 6
+#define DRM_IVPU_PARAM_CONTEXT_ID 7
+#define DRM_IVPU_PARAM_FW_API_VERSION 8
+#define DRM_IVPU_PARAM_ENGINE_HEARTBEAT 9
+#define DRM_IVPU_PARAM_UNIQUE_INFERENCE_ID 10
+#define DRM_IVPU_PARAM_TILE_CONFIG 11
+#define DRM_IVPU_PARAM_SKU 12
+#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
+#define DRM_IVPU_CONTEXT_PRIORITY_IDLE 0
+#define DRM_IVPU_CONTEXT_PRIORITY_NORMAL 1
+#define DRM_IVPU_CONTEXT_PRIORITY_FOCUS 2
+#define DRM_IVPU_CONTEXT_PRIORITY_REALTIME 3
+struct drm_ivpu_param {
+ __u32 param;
+ __u32 index;
+ __u64 value;
+};
+#define DRM_IVPU_BO_HIGH_MEM 0x00000001
+#define DRM_IVPU_BO_MAPPABLE 0x00000002
+#define DRM_IVPU_BO_CACHED 0x00000000
+#define DRM_IVPU_BO_UNCACHED 0x00010000
+#define DRM_IVPU_BO_WC 0x00020000
+#define DRM_IVPU_BO_CACHE_MASK 0x00030000
+#define DRM_IVPU_BO_FLAGS (DRM_IVPU_BO_HIGH_MEM | DRM_IVPU_BO_MAPPABLE | DRM_IVPU_BO_CACHE_MASK)
+struct drm_ivpu_bo_create {
+ __u64 size;
+ __u32 flags;
+ __u32 handle;
+ __u64 vpu_addr;
+};
+struct drm_ivpu_bo_info {
+ __u32 handle;
+ __u32 flags;
+ __u64 vpu_addr;
+ __u64 mmap_offset;
+ __u64 size;
+};
+#define DRM_IVPU_ENGINE_COMPUTE 0
+#define DRM_IVPU_ENGINE_COPY 1
+struct drm_ivpu_submit {
+ __u64 buffers_ptr;
+ __u32 buffer_count;
+ __u32 engine;
+ __u32 flags;
+ __u32 commands_offset;
+};
+#define DRM_IVPU_JOB_STATUS_SUCCESS 0
+struct drm_ivpu_bo_wait {
+ __u32 handle;
+ __u32 flags;
+ __s64 timeout_ns;
+ __u32 job_status;
+ __u32 pad;
+};
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/drm/mga_drm.h b/libc/kernel/uapi/drm/mga_drm.h
deleted file mode 100644
index dc62961..0000000
--- a/libc/kernel/uapi/drm/mga_drm.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __MGA_DRM_H__
-#define __MGA_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __MGA_SAREA_DEFINES__
-#define __MGA_SAREA_DEFINES__
-#define MGA_F 0x1
-#define MGA_A 0x2
-#define MGA_S 0x4
-#define MGA_T2 0x8
-#define MGA_WARP_TGZ 0
-#define MGA_WARP_TGZF (MGA_F)
-#define MGA_WARP_TGZA (MGA_A)
-#define MGA_WARP_TGZAF (MGA_F | MGA_A)
-#define MGA_WARP_TGZS (MGA_S)
-#define MGA_WARP_TGZSF (MGA_S | MGA_F)
-#define MGA_WARP_TGZSA (MGA_S | MGA_A)
-#define MGA_WARP_TGZSAF (MGA_S | MGA_F | MGA_A)
-#define MGA_WARP_T2GZ (MGA_T2)
-#define MGA_WARP_T2GZF (MGA_T2 | MGA_F)
-#define MGA_WARP_T2GZA (MGA_T2 | MGA_A)
-#define MGA_WARP_T2GZAF (MGA_T2 | MGA_A | MGA_F)
-#define MGA_WARP_T2GZS (MGA_T2 | MGA_S)
-#define MGA_WARP_T2GZSF (MGA_T2 | MGA_S | MGA_F)
-#define MGA_WARP_T2GZSA (MGA_T2 | MGA_S | MGA_A)
-#define MGA_WARP_T2GZSAF (MGA_T2 | MGA_S | MGA_F | MGA_A)
-#define MGA_MAX_G200_PIPES 8
-#define MGA_MAX_G400_PIPES 16
-#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
-#define MGA_WARP_UCODE_SIZE 32768
-#define MGA_CARD_TYPE_G200 1
-#define MGA_CARD_TYPE_G400 2
-#define MGA_CARD_TYPE_G450 3
-#define MGA_CARD_TYPE_G550 4
-#define MGA_FRONT 0x1
-#define MGA_BACK 0x2
-#define MGA_DEPTH 0x4
-#define MGA_UPLOAD_CONTEXT 0x1
-#define MGA_UPLOAD_TEX0 0x2
-#define MGA_UPLOAD_TEX1 0x4
-#define MGA_UPLOAD_PIPE 0x8
-#define MGA_UPLOAD_TEX0IMAGE 0x10
-#define MGA_UPLOAD_TEX1IMAGE 0x20
-#define MGA_UPLOAD_2D 0x40
-#define MGA_WAIT_AGE 0x80
-#define MGA_UPLOAD_CLIPRECTS 0x100
-#define MGA_BUFFER_SIZE (1 << 16)
-#define MGA_NUM_BUFFERS 128
-#define MGA_NR_SAREA_CLIPRECTS 8
-#define MGA_CARD_HEAP 0
-#define MGA_AGP_HEAP 1
-#define MGA_NR_TEX_HEAPS 2
-#define MGA_NR_TEX_REGIONS 16
-#define MGA_LOG_MIN_TEX_REGION_SIZE 16
-#define DRM_MGA_IDLE_RETRY 2048
-#endif
-typedef struct {
- unsigned int dstorg;
- unsigned int maccess;
- unsigned int plnwt;
- unsigned int dwgctl;
- unsigned int alphactrl;
- unsigned int fogcolor;
- unsigned int wflag;
- unsigned int tdualstage0;
- unsigned int tdualstage1;
- unsigned int fcol;
- unsigned int stencil;
- unsigned int stencilctl;
-} drm_mga_context_regs_t;
-typedef struct {
- unsigned int pitch;
-} drm_mga_server_regs_t;
-typedef struct {
- unsigned int texctl;
- unsigned int texctl2;
- unsigned int texfilter;
- unsigned int texbordercol;
- unsigned int texorg;
- unsigned int texwidth;
- unsigned int texheight;
- unsigned int texorg1;
- unsigned int texorg2;
- unsigned int texorg3;
- unsigned int texorg4;
-} drm_mga_texture_regs_t;
-typedef struct {
- unsigned int head;
- unsigned int wrap;
-} drm_mga_age_t;
-typedef struct _drm_mga_sarea {
- drm_mga_context_regs_t context_state;
- drm_mga_server_regs_t server_state;
- drm_mga_texture_regs_t tex_state[2];
- unsigned int warp_pipe;
- unsigned int dirty;
- unsigned int vertsize;
- struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS];
- unsigned int nbox;
- unsigned int req_drawable;
- unsigned int req_draw_buffer;
- unsigned int exported_drawable;
- unsigned int exported_index;
- unsigned int exported_stamp;
- unsigned int exported_buffers;
- unsigned int exported_nfront;
- unsigned int exported_nback;
- int exported_back_x, exported_front_x, exported_w;
- int exported_back_y, exported_front_y, exported_h;
- struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS];
- unsigned int status[4];
- unsigned int last_wrap;
- drm_mga_age_t last_frame;
- unsigned int last_enqueue;
- unsigned int last_dispatch;
- unsigned int last_quiescent;
- struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
- unsigned int texAge[MGA_NR_TEX_HEAPS];
- int ctxOwner;
-} drm_mga_sarea_t;
-#define DRM_MGA_INIT 0x00
-#define DRM_MGA_FLUSH 0x01
-#define DRM_MGA_RESET 0x02
-#define DRM_MGA_SWAP 0x03
-#define DRM_MGA_CLEAR 0x04
-#define DRM_MGA_VERTEX 0x05
-#define DRM_MGA_INDICES 0x06
-#define DRM_MGA_ILOAD 0x07
-#define DRM_MGA_BLIT 0x08
-#define DRM_MGA_GETPARAM 0x09
-#define DRM_MGA_SET_FENCE 0x0a
-#define DRM_MGA_WAIT_FENCE 0x0b
-#define DRM_MGA_DMA_BOOTSTRAP 0x0c
-#define DRM_IOCTL_MGA_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
-#define DRM_IOCTL_MGA_FLUSH DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock)
-#define DRM_IOCTL_MGA_RESET DRM_IO(DRM_COMMAND_BASE + DRM_MGA_RESET)
-#define DRM_IOCTL_MGA_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_MGA_SWAP)
-#define DRM_IOCTL_MGA_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
-#define DRM_IOCTL_MGA_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t)
-#define DRM_IOCTL_MGA_INDICES DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t)
-#define DRM_IOCTL_MGA_ILOAD DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t)
-#define DRM_IOCTL_MGA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t)
-#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t)
-#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, __u32)
-#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, __u32)
-#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
-typedef struct _drm_mga_warp_index {
- int installed;
- unsigned long phys_addr;
- int size;
-} drm_mga_warp_index_t;
-typedef struct drm_mga_init {
- enum {
- MGA_INIT_DMA = 0x01,
- MGA_CLEANUP_DMA = 0x02
- } func;
- unsigned long sarea_priv_offset;
- __struct_group(, always32bit,, int chipset;
- int sgram;
- unsigned int maccess;
- unsigned int fb_cpp;
- unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
- unsigned int depth_cpp;
- unsigned int depth_offset, depth_pitch;
- unsigned int texture_offset[MGA_NR_TEX_HEAPS];
- unsigned int texture_size[MGA_NR_TEX_HEAPS];
- );
- unsigned long fb_offset;
- unsigned long mmio_offset;
- unsigned long status_offset;
- unsigned long warp_offset;
- unsigned long primary_offset;
- unsigned long buffers_offset;
-} drm_mga_init_t;
-typedef struct drm_mga_dma_bootstrap {
- unsigned long texture_handle;
- __u32 texture_size;
- __u32 primary_size;
- __u32 secondary_bin_count;
- __u32 secondary_bin_size;
- __u32 agp_mode;
- __u8 agp_size;
-} drm_mga_dma_bootstrap_t;
-typedef struct drm_mga_clear {
- unsigned int flags;
- unsigned int clear_color;
- unsigned int clear_depth;
- unsigned int color_mask;
- unsigned int depth_mask;
-} drm_mga_clear_t;
-typedef struct drm_mga_vertex {
- int idx;
- int used;
- int discard;
-} drm_mga_vertex_t;
-typedef struct drm_mga_indices {
- int idx;
- unsigned int start;
- unsigned int end;
- int discard;
-} drm_mga_indices_t;
-typedef struct drm_mga_iload {
- int idx;
- unsigned int dstorg;
- unsigned int length;
-} drm_mga_iload_t;
-typedef struct _drm_mga_blit {
- unsigned int planemask;
- unsigned int srcorg;
- unsigned int dstorg;
- int src_pitch, dst_pitch;
- int delta_sx, delta_sy;
- int delta_dx, delta_dy;
- int height, ydir;
- int source_pitch, dest_pitch;
-} drm_mga_blit_t;
-#define MGA_PARAM_IRQ_NR 1
-#define MGA_PARAM_CARD_TYPE 2
-typedef struct drm_mga_getparam {
- int param;
- void __user * value;
-} drm_mga_getparam_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index ad3a971..f5a4627 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -116,7 +116,8 @@
#define MSM_SUBMIT_BO_READ 0x0001
#define MSM_SUBMIT_BO_WRITE 0x0002
#define MSM_SUBMIT_BO_DUMP 0x0004
-#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE | MSM_SUBMIT_BO_DUMP)
+#define MSM_SUBMIT_BO_NO_IMPLICIT 0x0008
+#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE | MSM_SUBMIT_BO_DUMP | MSM_SUBMIT_BO_NO_IMPLICIT)
struct drm_msm_gem_submit_bo {
__u32 flags;
__u32 handle;
diff --git a/libc/kernel/uapi/drm/r128_drm.h b/libc/kernel/uapi/drm/r128_drm.h
deleted file mode 100644
index 618b6dc..0000000
--- a/libc/kernel/uapi/drm/r128_drm.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __R128_DRM_H__
-#define __R128_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __R128_SAREA_DEFINES__
-#define __R128_SAREA_DEFINES__
-#define R128_UPLOAD_CONTEXT 0x001
-#define R128_UPLOAD_SETUP 0x002
-#define R128_UPLOAD_TEX0 0x004
-#define R128_UPLOAD_TEX1 0x008
-#define R128_UPLOAD_TEX0IMAGES 0x010
-#define R128_UPLOAD_TEX1IMAGES 0x020
-#define R128_UPLOAD_CORE 0x040
-#define R128_UPLOAD_MASKS 0x080
-#define R128_UPLOAD_WINDOW 0x100
-#define R128_UPLOAD_CLIPRECTS 0x200
-#define R128_REQUIRE_QUIESCENCE 0x400
-#define R128_UPLOAD_ALL 0x7ff
-#define R128_FRONT 0x1
-#define R128_BACK 0x2
-#define R128_DEPTH 0x4
-#define R128_POINTS 0x1
-#define R128_LINES 0x2
-#define R128_LINE_STRIP 0x3
-#define R128_TRIANGLES 0x4
-#define R128_TRIANGLE_FAN 0x5
-#define R128_TRIANGLE_STRIP 0x6
-#define R128_BUFFER_SIZE 16384
-#define R128_INDEX_PRIM_OFFSET 20
-#define R128_HOSTDATA_BLIT_OFFSET 32
-#define R128_NR_SAREA_CLIPRECTS 12
-#define R128_LOCAL_TEX_HEAP 0
-#define R128_AGP_TEX_HEAP 1
-#define R128_NR_TEX_HEAPS 2
-#define R128_NR_TEX_REGIONS 64
-#define R128_LOG_TEX_GRANULARITY 16
-#define R128_NR_CONTEXT_REGS 12
-#define R128_MAX_TEXTURE_LEVELS 11
-#define R128_MAX_TEXTURE_UNITS 2
-#endif
-typedef struct {
- unsigned int dst_pitch_offset_c;
- unsigned int dp_gui_master_cntl_c;
- unsigned int sc_top_left_c;
- unsigned int sc_bottom_right_c;
- unsigned int z_offset_c;
- unsigned int z_pitch_c;
- unsigned int z_sten_cntl_c;
- unsigned int tex_cntl_c;
- unsigned int misc_3d_state_cntl_reg;
- unsigned int texture_clr_cmp_clr_c;
- unsigned int texture_clr_cmp_msk_c;
- unsigned int fog_color_c;
- unsigned int tex_size_pitch_c;
- unsigned int constant_color_c;
- unsigned int pm4_vc_fpu_setup;
- unsigned int setup_cntl;
- unsigned int dp_write_mask;
- unsigned int sten_ref_mask_c;
- unsigned int plane_3d_mask_c;
- unsigned int window_xy_offset;
- unsigned int scale_3d_cntl;
-} drm_r128_context_regs_t;
-typedef struct {
- unsigned int tex_cntl;
- unsigned int tex_combine_cntl;
- unsigned int tex_size_pitch;
- unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
- unsigned int tex_border_color;
-} drm_r128_texture_regs_t;
-typedef struct drm_r128_sarea {
- drm_r128_context_regs_t context_state;
- drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS];
- unsigned int dirty;
- unsigned int vertsize;
- unsigned int vc_format;
- struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS];
- unsigned int nbox;
- unsigned int last_frame;
- unsigned int last_dispatch;
- struct drm_tex_region tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
- unsigned int tex_age[R128_NR_TEX_HEAPS];
- int ctx_owner;
- int pfAllowPageFlip;
- int pfCurrentPage;
-} drm_r128_sarea_t;
-#define DRM_R128_INIT 0x00
-#define DRM_R128_CCE_START 0x01
-#define DRM_R128_CCE_STOP 0x02
-#define DRM_R128_CCE_RESET 0x03
-#define DRM_R128_CCE_IDLE 0x04
-#define DRM_R128_RESET 0x06
-#define DRM_R128_SWAP 0x07
-#define DRM_R128_CLEAR 0x08
-#define DRM_R128_VERTEX 0x09
-#define DRM_R128_INDICES 0x0a
-#define DRM_R128_BLIT 0x0b
-#define DRM_R128_DEPTH 0x0c
-#define DRM_R128_STIPPLE 0x0d
-#define DRM_R128_INDIRECT 0x0f
-#define DRM_R128_FULLSCREEN 0x10
-#define DRM_R128_CLEAR2 0x11
-#define DRM_R128_GETPARAM 0x12
-#define DRM_R128_FLIP 0x13
-#define DRM_IOCTL_R128_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t)
-#define DRM_IOCTL_R128_CCE_START DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_START)
-#define DRM_IOCTL_R128_CCE_STOP DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t)
-#define DRM_IOCTL_R128_CCE_RESET DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_RESET)
-#define DRM_IOCTL_R128_CCE_IDLE DRM_IO(DRM_COMMAND_BASE + DRM_R128_CCE_IDLE)
-#define DRM_IOCTL_R128_RESET DRM_IO(DRM_COMMAND_BASE + DRM_R128_RESET)
-#define DRM_IOCTL_R128_SWAP DRM_IO(DRM_COMMAND_BASE + DRM_R128_SWAP)
-#define DRM_IOCTL_R128_CLEAR DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW(DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t)
-#define DRM_IOCTL_R128_INDICES DRM_IOW(DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t)
-#define DRM_IOCTL_R128_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t)
-#define DRM_IOCTL_R128_DEPTH DRM_IOW(DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t)
-#define DRM_IOCTL_R128_STIPPLE DRM_IOW(DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
-#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW(DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t)
-#define DRM_IOCTL_R128_CLEAR2 DRM_IOW(DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t)
-#define DRM_IOCTL_R128_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t)
-#define DRM_IOCTL_R128_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_R128_FLIP)
-typedef struct drm_r128_init {
- enum {
- R128_INIT_CCE = 0x01,
- R128_CLEANUP_CCE = 0x02
- } func;
- unsigned long sarea_priv_offset;
- int is_pci;
- int cce_mode;
- int cce_secure;
- int ring_size;
- int usec_timeout;
- unsigned int fb_bpp;
- unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
- unsigned int depth_bpp;
- unsigned int depth_offset, depth_pitch;
- unsigned int span_offset;
- unsigned long fb_offset;
- unsigned long mmio_offset;
- unsigned long ring_offset;
- unsigned long ring_rptr_offset;
- unsigned long buffers_offset;
- unsigned long agp_textures_offset;
-} drm_r128_init_t;
-typedef struct drm_r128_cce_stop {
- int flush;
- int idle;
-} drm_r128_cce_stop_t;
-typedef struct drm_r128_clear {
- unsigned int flags;
- unsigned int clear_color;
- unsigned int clear_depth;
- unsigned int color_mask;
- unsigned int depth_mask;
-} drm_r128_clear_t;
-typedef struct drm_r128_vertex {
- int prim;
- int idx;
- int count;
- int discard;
-} drm_r128_vertex_t;
-typedef struct drm_r128_indices {
- int prim;
- int idx;
- int start;
- int end;
- int discard;
-} drm_r128_indices_t;
-typedef struct drm_r128_blit {
- int idx;
- int pitch;
- int offset;
- int format;
- unsigned short x, y;
- unsigned short width, height;
-} drm_r128_blit_t;
-typedef struct drm_r128_depth {
- enum {
- R128_WRITE_SPAN = 0x01,
- R128_WRITE_PIXELS = 0x02,
- R128_READ_SPAN = 0x03,
- R128_READ_PIXELS = 0x04
- } func;
- int n;
- int __user * x;
- int __user * y;
- unsigned int __user * buffer;
- unsigned char __user * mask;
-} drm_r128_depth_t;
-typedef struct drm_r128_stipple {
- unsigned int __user * mask;
-} drm_r128_stipple_t;
-typedef struct drm_r128_indirect {
- int idx;
- int start;
- int end;
- int discard;
-} drm_r128_indirect_t;
-typedef struct drm_r128_fullscreen {
- enum {
- R128_INIT_FULLSCREEN = 0x01,
- R128_CLEANUP_FULLSCREEN = 0x02
- } func;
-} drm_r128_fullscreen_t;
-#define R128_PARAM_IRQ_NR 1
-typedef struct drm_r128_getparam {
- int param;
- void __user * value;
-} drm_r128_getparam_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/radeon_drm.h b/libc/kernel/uapi/drm/radeon_drm.h
index 9dc69ad..3ec6bb3 100644
--- a/libc/kernel/uapi/drm/radeon_drm.h
+++ b/libc/kernel/uapi/drm/radeon_drm.h
@@ -479,7 +479,7 @@
unsigned int clear_depth;
unsigned int color_mask;
unsigned int depth_mask;
- drm_radeon_clear_rect_t __user * depth_boxes;
+ drm_radeon_clear_rect_t * depth_boxes;
} drm_radeon_clear_t;
typedef struct drm_radeon_vertex {
int prim;
@@ -498,20 +498,20 @@
int idx;
int discard;
int nr_states;
- drm_radeon_state_t __user * state;
+ drm_radeon_state_t * state;
int nr_prims;
- drm_radeon_prim_t __user * prim;
+ drm_radeon_prim_t * prim;
} drm_radeon_vertex2_t;
typedef struct drm_radeon_cmd_buffer {
int bufsz;
- char __user * buf;
+ char * buf;
int nbox;
- struct drm_clip_rect __user * boxes;
+ struct drm_clip_rect * boxes;
} drm_radeon_cmd_buffer_t;
typedef struct drm_radeon_tex_image {
unsigned int x, y;
unsigned int width, height;
- const void __user * data;
+ const void * data;
} drm_radeon_tex_image_t;
typedef struct drm_radeon_texture {
unsigned int offset;
@@ -519,10 +519,10 @@
int format;
int width;
int height;
- drm_radeon_tex_image_t __user * image;
+ drm_radeon_tex_image_t * image;
} drm_radeon_texture_t;
typedef struct drm_radeon_stipple {
- unsigned int __user * mask;
+ unsigned int * mask;
} drm_radeon_stipple_t;
typedef struct drm_radeon_indirect {
int idx;
@@ -552,7 +552,7 @@
#define RADEON_PARAM_NUM_Z_PIPES 17
typedef struct drm_radeon_getparam {
int param;
- void __user * value;
+ void * value;
} drm_radeon_getparam_t;
#define RADEON_MEM_REGION_GART 1
#define RADEON_MEM_REGION_FB 2
@@ -560,7 +560,7 @@
int region;
int alignment;
int size;
- int __user * region_offset;
+ int * region_offset;
} drm_radeon_mem_alloc_t;
typedef struct drm_radeon_mem_free {
int region;
@@ -572,7 +572,7 @@
int start;
} drm_radeon_mem_init_heap_t;
typedef struct drm_radeon_irq_emit {
- int __user * irq_seq;
+ int * irq_seq;
} drm_radeon_irq_emit_t;
typedef struct drm_radeon_irq_wait {
int irq_seq;
diff --git a/libc/kernel/uapi/drm/savage_drm.h b/libc/kernel/uapi/drm/savage_drm.h
deleted file mode 100644
index ae87d21..0000000
--- a/libc/kernel/uapi/drm/savage_drm.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __SAVAGE_DRM_H__
-#define __SAVAGE_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef __SAVAGE_SAREA_DEFINES__
-#define __SAVAGE_SAREA_DEFINES__
-#define SAVAGE_CARD_HEAP 0
-#define SAVAGE_AGP_HEAP 1
-#define SAVAGE_NR_TEX_HEAPS 2
-#define SAVAGE_NR_TEX_REGIONS 16
-#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
-#endif
-typedef struct _drm_savage_sarea {
- struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS + 1];
- unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
- int ctxOwner;
-} drm_savage_sarea_t, * drm_savage_sarea_ptr;
-#define DRM_SAVAGE_BCI_INIT 0x00
-#define DRM_SAVAGE_BCI_CMDBUF 0x01
-#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
-#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
-#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
-#define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
-#define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
-#define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
-#define SAVAGE_DMA_PCI 1
-#define SAVAGE_DMA_AGP 3
-typedef struct drm_savage_init {
- enum {
- SAVAGE_INIT_BCI = 1,
- SAVAGE_CLEANUP_BCI = 2
- } func;
- unsigned int sarea_priv_offset;
- unsigned int cob_size;
- unsigned int bci_threshold_lo, bci_threshold_hi;
- unsigned int dma_type;
- unsigned int fb_bpp;
- unsigned int front_offset, front_pitch;
- unsigned int back_offset, back_pitch;
- unsigned int depth_bpp;
- unsigned int depth_offset, depth_pitch;
- unsigned int texture_offset;
- unsigned int texture_size;
- unsigned long status_offset;
- unsigned long buffers_offset;
- unsigned long agp_textures_offset;
- unsigned long cmd_dma_offset;
-} drm_savage_init_t;
-typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
-typedef struct drm_savage_cmdbuf {
- drm_savage_cmd_header_t __user * cmd_addr;
- unsigned int size;
- unsigned int dma_idx;
- int discard;
- unsigned int __user * vb_addr;
- unsigned int vb_size;
- unsigned int vb_stride;
- struct drm_clip_rect __user * box_addr;
- unsigned int nbox;
-} drm_savage_cmdbuf_t;
-#define SAVAGE_WAIT_2D 0x1
-#define SAVAGE_WAIT_3D 0x2
-#define SAVAGE_WAIT_IRQ 0x4
-typedef struct drm_savage_event {
- unsigned int count;
- unsigned int flags;
-} drm_savage_event_emit_t, drm_savage_event_wait_t;
-#define SAVAGE_CMD_STATE 0
-#define SAVAGE_CMD_DMA_PRIM 1
-#define SAVAGE_CMD_VB_PRIM 2
-#define SAVAGE_CMD_DMA_IDX 3
-#define SAVAGE_CMD_VB_IDX 4
-#define SAVAGE_CMD_CLEAR 5
-#define SAVAGE_CMD_SWAP 6
-#define SAVAGE_PRIM_TRILIST 0
-#define SAVAGE_PRIM_TRISTRIP 1
-#define SAVAGE_PRIM_TRIFAN 2
-#define SAVAGE_PRIM_TRILIST_201 3
-#define SAVAGE_SKIP_Z 0x01
-#define SAVAGE_SKIP_W 0x02
-#define SAVAGE_SKIP_C0 0x04
-#define SAVAGE_SKIP_C1 0x08
-#define SAVAGE_SKIP_S0 0x10
-#define SAVAGE_SKIP_T0 0x20
-#define SAVAGE_SKIP_ST0 0x30
-#define SAVAGE_SKIP_S1 0x40
-#define SAVAGE_SKIP_T1 0x80
-#define SAVAGE_SKIP_ST1 0xc0
-#define SAVAGE_SKIP_ALL_S3D 0x3f
-#define SAVAGE_SKIP_ALL_S4 0xff
-#define SAVAGE_FRONT 0x1
-#define SAVAGE_BACK 0x2
-#define SAVAGE_DEPTH 0x4
-union drm_savage_cmd_header {
- struct {
- unsigned char cmd;
- unsigned char pad0;
- unsigned short pad1;
- unsigned short pad2;
- unsigned short pad3;
- } cmd;
- struct {
- unsigned char cmd;
- unsigned char global;
- unsigned short count;
- unsigned short start;
- unsigned short pad3;
- } state;
- struct {
- unsigned char cmd;
- unsigned char prim;
- unsigned short skip;
- unsigned short count;
- unsigned short start;
- } prim;
- struct {
- unsigned char cmd;
- unsigned char prim;
- unsigned short skip;
- unsigned short count;
- unsigned short pad3;
- } idx;
- struct {
- unsigned char cmd;
- unsigned char pad0;
- unsigned short pad1;
- unsigned int flags;
- } clear0;
- struct {
- unsigned int mask;
- unsigned int value;
- } clear1;
-};
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/sis_drm.h b/libc/kernel/uapi/drm/sis_drm.h
deleted file mode 100644
index 1606a85..0000000
--- a/libc/kernel/uapi/drm/sis_drm.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef __SIS_DRM_H__
-#define __SIS_DRM_H__
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define NOT_USED_0_3
-#define DRM_SIS_FB_ALLOC 0x04
-#define DRM_SIS_FB_FREE 0x05
-#define NOT_USED_6_12
-#define DRM_SIS_AGP_INIT 0x13
-#define DRM_SIS_AGP_ALLOC 0x14
-#define DRM_SIS_AGP_FREE 0x15
-#define DRM_SIS_FB_INIT 0x16
-#define DRM_IOCTL_SIS_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t)
-#define DRM_IOCTL_SIS_AGP_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t)
-typedef struct {
- int context;
- unsigned long offset;
- unsigned long size;
- unsigned long free;
-} drm_sis_mem_t;
-typedef struct {
- unsigned long offset, size;
-} drm_sis_agp_t;
-typedef struct {
- unsigned long offset, size;
-} drm_sis_fb_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/drm/via_drm.h b/libc/kernel/uapi/drm/via_drm.h
deleted file mode 100644
index 9ef645a..0000000
--- a/libc/kernel/uapi/drm/via_drm.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _VIA_DRM_H_
-#define _VIA_DRM_H_
-#include "drm.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifndef _VIA_DEFINES_
-#define _VIA_DEFINES_
-#define VIA_NR_SAREA_CLIPRECTS 8
-#define VIA_NR_XVMC_PORTS 10
-#define VIA_NR_XVMC_LOCKS 5
-#define VIA_MAX_CACHELINE_SIZE 64
-#define XVMCLOCKPTR(saPriv,lockNo) ((volatile struct drm_hw_lock *) (((((unsigned long) (saPriv)->XvMCLockArea) + (VIA_MAX_CACHELINE_SIZE - 1)) & ~(VIA_MAX_CACHELINE_SIZE - 1)) + VIA_MAX_CACHELINE_SIZE * (lockNo)))
-#define VIA_NR_TEX_REGIONS 64
-#define VIA_LOG_MIN_TEX_REGION_SIZE 16
-#endif
-#define VIA_UPLOAD_TEX0IMAGE 0x1
-#define VIA_UPLOAD_TEX1IMAGE 0x2
-#define VIA_UPLOAD_CTX 0x4
-#define VIA_UPLOAD_BUFFERS 0x8
-#define VIA_UPLOAD_TEX0 0x10
-#define VIA_UPLOAD_TEX1 0x20
-#define VIA_UPLOAD_CLIPRECTS 0x40
-#define VIA_UPLOAD_ALL 0xff
-#define DRM_VIA_ALLOCMEM 0x00
-#define DRM_VIA_FREEMEM 0x01
-#define DRM_VIA_AGP_INIT 0x02
-#define DRM_VIA_FB_INIT 0x03
-#define DRM_VIA_MAP_INIT 0x04
-#define DRM_VIA_DEC_FUTEX 0x05
-#define NOT_USED
-#define DRM_VIA_DMA_INIT 0x07
-#define DRM_VIA_CMDBUFFER 0x08
-#define DRM_VIA_FLUSH 0x09
-#define DRM_VIA_PCICMD 0x0a
-#define DRM_VIA_CMDBUF_SIZE 0x0b
-#define NOT_USED
-#define DRM_VIA_WAIT_IRQ 0x0d
-#define DRM_VIA_DMA_BLIT 0x0e
-#define DRM_VIA_BLIT_SYNC 0x0f
-#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
-#define DRM_IOCTL_VIA_FREEMEM DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
-#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
-#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
-#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
-#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
-#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
-#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
-#define DRM_IOCTL_VIA_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_VIA_FLUSH)
-#define DRM_IOCTL_VIA_PCICMD DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
-#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, drm_via_cmdbuf_size_t)
-#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
-#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
-#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
-#define VIA_TEX_SETUP_SIZE 8
-#define VIA_FRONT 0x1
-#define VIA_BACK 0x2
-#define VIA_DEPTH 0x4
-#define VIA_STENCIL 0x8
-#define VIA_MEM_VIDEO 0
-#define VIA_MEM_AGP 1
-#define VIA_MEM_SYSTEM 2
-#define VIA_MEM_MIXED 3
-#define VIA_MEM_UNKNOWN 4
-typedef struct {
- __u32 offset;
- __u32 size;
-} drm_via_agp_t;
-typedef struct {
- __u32 offset;
- __u32 size;
-} drm_via_fb_t;
-typedef struct {
- __u32 context;
- __u32 type;
- __u32 size;
- unsigned long index;
- unsigned long offset;
-} drm_via_mem_t;
-typedef struct _drm_via_init {
- enum {
- VIA_INIT_MAP = 0x01,
- VIA_CLEANUP_MAP = 0x02
- } func;
- unsigned long sarea_priv_offset;
- unsigned long fb_offset;
- unsigned long mmio_offset;
- unsigned long agpAddr;
-} drm_via_init_t;
-typedef struct _drm_via_futex {
- enum {
- VIA_FUTEX_WAIT = 0x00,
- VIA_FUTEX_WAKE = 0X01
- } func;
- __u32 ms;
- __u32 lock;
- __u32 val;
-} drm_via_futex_t;
-typedef struct _drm_via_dma_init {
- enum {
- VIA_INIT_DMA = 0x01,
- VIA_CLEANUP_DMA = 0x02,
- VIA_DMA_INITIALIZED = 0x03
- } func;
- unsigned long offset;
- unsigned long size;
- unsigned long reg_pause_addr;
-} drm_via_dma_init_t;
-typedef struct _drm_via_cmdbuffer {
- char __user * buf;
- unsigned long size;
-} drm_via_cmdbuffer_t;
-typedef struct _drm_via_tex_region {
- unsigned char next, prev;
- unsigned char inUse;
- int age;
-} drm_via_tex_region_t;
-typedef struct _drm_via_sarea {
- unsigned int dirty;
- unsigned int nbox;
- struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS];
- drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
- int texAge;
- int ctxOwner;
- int vertexPrim;
- char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
- unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
- unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
- unsigned int XvMCCtxNoGrabbed;
- unsigned int pfCurrentOffset;
-} drm_via_sarea_t;
-typedef struct _drm_via_cmdbuf_size {
- enum {
- VIA_CMDBUF_SPACE = 0x01,
- VIA_CMDBUF_LAG = 0x02
- } func;
- int wait;
- __u32 size;
-} drm_via_cmdbuf_size_t;
-typedef enum {
- VIA_IRQ_ABSOLUTE = 0x0,
- VIA_IRQ_RELATIVE = 0x1,
- VIA_IRQ_SIGNAL = 0x10000000,
- VIA_IRQ_FORCE_SEQUENCE = 0x20000000
-} via_irq_seq_type_t;
-#define VIA_IRQ_FLAGS_MASK 0xF0000000
-enum drm_via_irqs {
- drm_via_irq_hqv0 = 0,
- drm_via_irq_hqv1,
- drm_via_irq_dma0_dd,
- drm_via_irq_dma0_td,
- drm_via_irq_dma1_dd,
- drm_via_irq_dma1_td,
- drm_via_irq_num
-};
-struct drm_via_wait_irq_request {
- unsigned irq;
- via_irq_seq_type_t type;
- __u32 sequence;
- __u32 signal;
-};
-typedef union drm_via_irqwait {
- struct drm_via_wait_irq_request request;
- struct drm_wait_vblank_reply reply;
-} drm_via_irqwait_t;
-typedef struct drm_via_blitsync {
- __u32 sync_handle;
- unsigned engine;
-} drm_via_blitsync_t;
-typedef struct drm_via_dmablit {
- __u32 num_lines;
- __u32 line_length;
- __u32 fb_addr;
- __u32 fb_stride;
- unsigned char * mem_addr;
- __u32 mem_stride;
- __u32 flags;
- int to_fb;
- drm_via_blitsync_t sync;
-} drm_via_dmablit_t;
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 52f4c6b..0d1f83d 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -221,6 +221,7 @@
BR_FAILED_REPLY = _IO('r', 17),
BR_FROZEN_REPLY = _IO('r', 18),
BR_ONEWAY_SPAM_SUSPECT = _IO('r', 19),
+ BR_TRANSACTION_PENDING_FROZEN = _IO('r', 20),
};
enum binder_driver_command_protocol {
BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
diff --git a/libc/kernel/uapi/linux/atm.h b/libc/kernel/uapi/linux/atm.h
index 488fa05..72d329d 100644
--- a/libc/kernel/uapi/linux/atm.h
+++ b/libc/kernel/uapi/linux/atm.h
@@ -140,7 +140,7 @@
struct atmif_sioc {
int number;
int length;
- void __user * arg;
+ void * arg;
};
typedef unsigned short atm_backend_t;
#endif
diff --git a/libc/kernel/uapi/linux/atmdev.h b/libc/kernel/uapi/linux/atmdev.h
index 69eb240..74cdfc1 100644
--- a/libc/kernel/uapi/linux/atmdev.h
+++ b/libc/kernel/uapi/linux/atmdev.h
@@ -86,7 +86,7 @@
#define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG)
struct atm_iobuf {
int length;
- void __user * buffer;
+ void * buffer;
};
#define ATM_CI_MAX - 1
struct atm_cirange {
diff --git a/libc/kernel/uapi/linux/auxvec.h b/libc/kernel/uapi/linux/auxvec.h
index c80c170..3ca56fc 100644
--- a/libc/kernel/uapi/linux/auxvec.h
+++ b/libc/kernel/uapi/linux/auxvec.h
@@ -41,6 +41,8 @@
#define AT_BASE_PLATFORM 24
#define AT_RANDOM 25
#define AT_HWCAP2 26
+#define AT_RSEQ_FEATURE_SIZE 27
+#define AT_RSEQ_ALIGN 28
#define AT_EXECFN 31
#ifndef AT_MINSIGSTKSZ
#define AT_MINSIGSTKSZ 51
diff --git a/libc/kernel/uapi/linux/batadv_packet.h b/libc/kernel/uapi/linux/batadv_packet.h
index ede53cf..9daed82 100644
--- a/libc/kernel/uapi/linux/batadv_packet.h
+++ b/libc/kernel/uapi/linux/batadv_packet.h
@@ -28,6 +28,7 @@
BATADV_CODED = 0x02,
BATADV_ELP = 0x03,
BATADV_OGM2 = 0x04,
+ BATADV_MCAST = 0x05,
#define BATADV_UNICAST_MIN 0x40
BATADV_UNICAST = 0x40,
BATADV_UNICAST_FRAG = 0x41,
diff --git a/libc/kernel/uapi/linux/blkpg.h b/libc/kernel/uapi/linux/blkpg.h
index fdde696..bfe504f 100644
--- a/libc/kernel/uapi/linux/blkpg.h
+++ b/libc/kernel/uapi/linux/blkpg.h
@@ -25,7 +25,7 @@
int op;
int flags;
int datalen;
- void __user * data;
+ void * data;
};
#define BLKPG_ADD_PARTITION 1
#define BLKPG_DEL_PARTITION 2
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 163dd1e..4131ce4 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -275,6 +275,7 @@
#define BPF_F_TEST_STATE_FREQ (1U << 3)
#define BPF_F_SLEEPABLE (1U << 4)
#define BPF_F_XDP_HAS_FRAGS (1U << 5)
+#define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)
#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
#define BPF_PSEUDO_MAP_FD 1
#define BPF_PSEUDO_MAP_IDX 5
@@ -557,6 +558,7 @@
BPF_F_ZERO_CSUM_TX = (1ULL << 1),
BPF_F_DONT_FRAGMENT = (1ULL << 2),
BPF_F_SEQ_NUMBER = (1ULL << 3),
+ BPF_F_NO_TUNNEL_KEY = (1ULL << 4),
};
enum {
BPF_F_TUNINFO_FLAGS = (1ULL << 4),
@@ -583,6 +585,8 @@
BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
BPF_F_ADJ_ROOM_NO_CSUM_RESET = (1ULL << 5),
BPF_F_ADJ_ROOM_ENCAP_L2_ETH = (1ULL << 6),
+ BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = (1ULL << 7),
+ BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = (1ULL << 8),
};
enum {
BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff,
@@ -1095,6 +1099,7 @@
enum {
BPF_FIB_LOOKUP_DIRECT = (1U << 0),
BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
+ BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
};
enum {
BPF_FIB_LKUP_RET_SUCCESS,
@@ -1218,6 +1223,15 @@
__u64 : 64;
__u64 : 64;
} __attribute__((aligned(8)));
+struct bpf_rb_root {
+ __u64 : 64;
+ __u64 : 64;
+} __attribute__((aligned(8)));
+struct bpf_rb_node {
+ __u64 : 64;
+ __u64 : 64;
+ __u64 : 64;
+} __attribute__((aligned(8)));
struct bpf_sysctl {
__u32 write;
__u32 file_pos;
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 8039625..5220647 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -79,7 +79,7 @@
union {
struct {
__u64 size;
- struct btrfs_qgroup_inherit __user * qgroup_inherit;
+ struct btrfs_qgroup_inherit * qgroup_inherit;
};
__u64 unused[4];
};
@@ -157,7 +157,8 @@
__u8 uuid[BTRFS_UUID_SIZE];
__u64 bytes_used;
__u64 total_bytes;
- __u64 unused[379];
+ __u8 fsid[BTRFS_UUID_SIZE];
+ __u64 unused[377];
__u8 path[BTRFS_DEVICE_PATH_NAME_MAX];
};
#define BTRFS_FS_INFO_FLAG_CSUM_INFO (1 << 0)
@@ -432,7 +433,7 @@
struct btrfs_ioctl_send_args {
__s64 send_fd;
__u64 clone_sources_count;
- __u64 __user * clone_sources;
+ __u64 * clone_sources;
__u64 parent_root;
__u64 flags;
__u32 version;
@@ -469,7 +470,7 @@
__u8 align[7];
};
struct btrfs_ioctl_encoded_io_args {
- const struct iovec __user * iov;
+ const struct iovec * iov;
unsigned long iovcnt;
__s64 offset;
__u64 flags;
diff --git a/libc/kernel/uapi/linux/byteorder/big_endian.h b/libc/kernel/uapi/linux/byteorder/big_endian.h
index b6c978b..82c5a4c 100644
--- a/libc/kernel/uapi/linux/byteorder/big_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/big_endian.h
@@ -27,34 +27,34 @@
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/swab.h>
-#define __constant_htonl(x) ((__force __be32) (__u32) (x))
-#define __constant_ntohl(x) ((__force __u32) (__be32) (x))
-#define __constant_htons(x) ((__force __be16) (__u16) (x))
-#define __constant_ntohs(x) ((__force __u16) (__be16) (x))
-#define __constant_cpu_to_le64(x) ((__force __le64) ___constant_swab64((x)))
-#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64) (__le64) (x))
-#define __constant_cpu_to_le32(x) ((__force __le32) ___constant_swab32((x)))
-#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32) (__le32) (x))
-#define __constant_cpu_to_le16(x) ((__force __le16) ___constant_swab16((x)))
-#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16) (__le16) (x))
-#define __constant_cpu_to_be64(x) ((__force __be64) (__u64) (x))
-#define __constant_be64_to_cpu(x) ((__force __u64) (__be64) (x))
-#define __constant_cpu_to_be32(x) ((__force __be32) (__u32) (x))
-#define __constant_be32_to_cpu(x) ((__force __u32) (__be32) (x))
-#define __constant_cpu_to_be16(x) ((__force __be16) (__u16) (x))
-#define __constant_be16_to_cpu(x) ((__force __u16) (__be16) (x))
-#define __cpu_to_le64(x) ((__force __le64) __swab64((x)))
-#define __le64_to_cpu(x) __swab64((__force __u64) (__le64) (x))
-#define __cpu_to_le32(x) ((__force __le32) __swab32((x)))
-#define __le32_to_cpu(x) __swab32((__force __u32) (__le32) (x))
-#define __cpu_to_le16(x) ((__force __le16) __swab16((x)))
-#define __le16_to_cpu(x) __swab16((__force __u16) (__le16) (x))
-#define __cpu_to_be64(x) ((__force __be64) (__u64) (x))
-#define __be64_to_cpu(x) ((__force __u64) (__be64) (x))
-#define __cpu_to_be32(x) ((__force __be32) (__u32) (x))
-#define __be32_to_cpu(x) ((__force __u32) (__be32) (x))
-#define __cpu_to_be16(x) ((__force __be16) (__u16) (x))
-#define __be16_to_cpu(x) ((__force __u16) (__be16) (x))
+#define __constant_htonl(x) (( __be32) (__u32) (x))
+#define __constant_ntohl(x) (( __u32) (__be32) (x))
+#define __constant_htons(x) (( __be16) (__u16) (x))
+#define __constant_ntohs(x) (( __u16) (__be16) (x))
+#define __constant_cpu_to_le64(x) (( __le64) ___constant_swab64((x)))
+#define __constant_le64_to_cpu(x) ___constant_swab64(( __u64) (__le64) (x))
+#define __constant_cpu_to_le32(x) (( __le32) ___constant_swab32((x)))
+#define __constant_le32_to_cpu(x) ___constant_swab32(( __u32) (__le32) (x))
+#define __constant_cpu_to_le16(x) (( __le16) ___constant_swab16((x)))
+#define __constant_le16_to_cpu(x) ___constant_swab16(( __u16) (__le16) (x))
+#define __constant_cpu_to_be64(x) (( __be64) (__u64) (x))
+#define __constant_be64_to_cpu(x) (( __u64) (__be64) (x))
+#define __constant_cpu_to_be32(x) (( __be32) (__u32) (x))
+#define __constant_be32_to_cpu(x) (( __u32) (__be32) (x))
+#define __constant_cpu_to_be16(x) (( __be16) (__u16) (x))
+#define __constant_be16_to_cpu(x) (( __u16) (__be16) (x))
+#define __cpu_to_le64(x) (( __le64) __swab64((x)))
+#define __le64_to_cpu(x) __swab64(( __u64) (__le64) (x))
+#define __cpu_to_le32(x) (( __le32) __swab32((x)))
+#define __le32_to_cpu(x) __swab32(( __u32) (__le32) (x))
+#define __cpu_to_le16(x) (( __le16) __swab16((x)))
+#define __le16_to_cpu(x) __swab16(( __u16) (__le16) (x))
+#define __cpu_to_be64(x) (( __be64) (__u64) (x))
+#define __be64_to_cpu(x) (( __u64) (__be64) (x))
+#define __cpu_to_be32(x) (( __be32) (__u32) (x))
+#define __be32_to_cpu(x) (( __u32) (__be32) (x))
+#define __cpu_to_be16(x) (( __be16) (__u16) (x))
+#define __be16_to_cpu(x) (( __u16) (__be16) (x))
#define __cpu_to_le64s(x) __swab64s((x))
#define __le64_to_cpus(x) __swab64s((x))
#define __cpu_to_le32s(x) __swab32s((x))
diff --git a/libc/kernel/uapi/linux/byteorder/little_endian.h b/libc/kernel/uapi/linux/byteorder/little_endian.h
index a272d4d..28155b5 100644
--- a/libc/kernel/uapi/linux/byteorder/little_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/little_endian.h
@@ -27,34 +27,34 @@
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/swab.h>
-#define __constant_htonl(x) ((__force __be32) ___constant_swab32((x)))
-#define __constant_ntohl(x) ___constant_swab32((__force __be32) (x))
-#define __constant_htons(x) ((__force __be16) ___constant_swab16((x)))
-#define __constant_ntohs(x) ___constant_swab16((__force __be16) (x))
-#define __constant_cpu_to_le64(x) ((__force __le64) (__u64) (x))
-#define __constant_le64_to_cpu(x) ((__force __u64) (__le64) (x))
-#define __constant_cpu_to_le32(x) ((__force __le32) (__u32) (x))
-#define __constant_le32_to_cpu(x) ((__force __u32) (__le32) (x))
-#define __constant_cpu_to_le16(x) ((__force __le16) (__u16) (x))
-#define __constant_le16_to_cpu(x) ((__force __u16) (__le16) (x))
-#define __constant_cpu_to_be64(x) ((__force __be64) ___constant_swab64((x)))
-#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64) (__be64) (x))
-#define __constant_cpu_to_be32(x) ((__force __be32) ___constant_swab32((x)))
-#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32) (__be32) (x))
-#define __constant_cpu_to_be16(x) ((__force __be16) ___constant_swab16((x)))
-#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16) (__be16) (x))
-#define __cpu_to_le64(x) ((__force __le64) (__u64) (x))
-#define __le64_to_cpu(x) ((__force __u64) (__le64) (x))
-#define __cpu_to_le32(x) ((__force __le32) (__u32) (x))
-#define __le32_to_cpu(x) ((__force __u32) (__le32) (x))
-#define __cpu_to_le16(x) ((__force __le16) (__u16) (x))
-#define __le16_to_cpu(x) ((__force __u16) (__le16) (x))
-#define __cpu_to_be64(x) ((__force __be64) __swab64((x)))
-#define __be64_to_cpu(x) __swab64((__force __u64) (__be64) (x))
-#define __cpu_to_be32(x) ((__force __be32) __swab32((x)))
-#define __be32_to_cpu(x) __swab32((__force __u32) (__be32) (x))
-#define __cpu_to_be16(x) ((__force __be16) __swab16((x)))
-#define __be16_to_cpu(x) __swab16((__force __u16) (__be16) (x))
+#define __constant_htonl(x) (( __be32) ___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32(( __be32) (x))
+#define __constant_htons(x) (( __be16) ___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16(( __be16) (x))
+#define __constant_cpu_to_le64(x) (( __le64) (__u64) (x))
+#define __constant_le64_to_cpu(x) (( __u64) (__le64) (x))
+#define __constant_cpu_to_le32(x) (( __le32) (__u32) (x))
+#define __constant_le32_to_cpu(x) (( __u32) (__le32) (x))
+#define __constant_cpu_to_le16(x) (( __le16) (__u16) (x))
+#define __constant_le16_to_cpu(x) (( __u16) (__le16) (x))
+#define __constant_cpu_to_be64(x) (( __be64) ___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64(( __u64) (__be64) (x))
+#define __constant_cpu_to_be32(x) (( __be32) ___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32(( __u32) (__be32) (x))
+#define __constant_cpu_to_be16(x) (( __be16) ___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16(( __u16) (__be16) (x))
+#define __cpu_to_le64(x) (( __le64) (__u64) (x))
+#define __le64_to_cpu(x) (( __u64) (__le64) (x))
+#define __cpu_to_le32(x) (( __le32) (__u32) (x))
+#define __le32_to_cpu(x) (( __u32) (__le32) (x))
+#define __cpu_to_le16(x) (( __le16) (__u16) (x))
+#define __le16_to_cpu(x) (( __u16) (__le16) (x))
+#define __cpu_to_be64(x) (( __be64) __swab64((x)))
+#define __be64_to_cpu(x) __swab64(( __u64) (__be64) (x))
+#define __cpu_to_be32(x) (( __be32) __swab32((x)))
+#define __be32_to_cpu(x) __swab32(( __u32) (__be32) (x))
+#define __cpu_to_be16(x) (( __be16) __swab16((x)))
+#define __be16_to_cpu(x) __swab16(( __u16) (__be16) (x))
#define __cpu_to_le64s(x) do { (void) (x); } while(0)
#define __le64_to_cpus(x) do { (void) (x); } while(0)
#define __cpu_to_le32s(x) do { (void) (x); } while(0)
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index c1b5dbf..8f3281e 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -28,12 +28,12 @@
typedef struct __user_cap_header_struct {
__u32 version;
int pid;
-} __user * cap_user_header_t;
+} * cap_user_header_t;
typedef struct __user_cap_data_struct {
__u32 effective;
__u32 permitted;
__u32 inheritable;
-} __user * cap_user_data_t;
+} * cap_user_data_t;
#define VFS_CAP_REVISION_MASK 0xFF000000
#define VFS_CAP_REVISION_SHIFT 24
#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
diff --git a/libc/kernel/uapi/linux/capi.h b/libc/kernel/uapi/linux/capi.h
index de2a839..a09f9bc 100644
--- a/libc/kernel/uapi/linux/capi.h
+++ b/libc/kernel/uapi/linux/capi.h
@@ -51,7 +51,7 @@
#define CAPI_GET_PROFILE _IOWR('C', 0x09, struct capi_profile)
typedef struct capi_manufacturer_cmd {
unsigned long cmd;
- void __user * data;
+ void * data;
} capi_manufacturer_cmd;
#define CAPI_MANUFACTURER_CMD _IOWR('C', 0x20, struct capi_manufacturer_cmd)
#define CAPI_GET_ERRCODE _IOR('C', 0x21, __u16)
diff --git a/libc/kernel/uapi/linux/cciss_ioctl.h b/libc/kernel/uapi/linux/cciss_ioctl.h
index 3e9bb3b..827e6a0 100644
--- a/libc/kernel/uapi/linux/cciss_ioctl.h
+++ b/libc/kernel/uapi/linux/cciss_ioctl.h
@@ -47,7 +47,7 @@
RequestBlock_struct Request;
ErrorInfo_struct error_info;
WORD buf_size;
- BYTE __user * buf;
+ BYTE * buf;
} IOCTL_Command_struct;
typedef struct _BIG_IOCTL_Command_struct {
LUNAddr_struct LUN_info;
@@ -55,7 +55,7 @@
ErrorInfo_struct error_info;
DWORD malloc_size;
DWORD buf_size;
- BYTE __user * buf;
+ BYTE * buf;
} BIG_IOCTL_Command_struct;
typedef struct _LogvolInfo_struct {
__u32 LunID;
diff --git a/libc/kernel/uapi/linux/cdrom.h b/libc/kernel/uapi/linux/cdrom.h
index 0fe0727..bd1d7df 100644
--- a/libc/kernel/uapi/linux/cdrom.h
+++ b/libc/kernel/uapi/linux/cdrom.h
@@ -128,7 +128,7 @@
union cdrom_addr addr;
__u8 addr_format;
int nframes;
- __u8 __user * buf;
+ __u8 * buf;
};
struct cdrom_multisession {
union cdrom_addr addr;
@@ -149,16 +149,16 @@
#define CGC_DATA_NONE 3
struct cdrom_generic_command {
unsigned char cmd[CDROM_PACKET_SIZE];
- unsigned char __user * buffer;
+ unsigned char * buffer;
unsigned int buflen;
int stat;
- struct request_sense __user * sense;
+ struct request_sense * sense;
unsigned char data_direction;
int quiet;
int timeout;
union {
- void __user * reserved[1];
- void __user * unused;
+ void * reserved[1];
+ void * unused;
};
};
struct cdrom_timed_media_change_info {
diff --git a/libc/kernel/uapi/linux/chio.h b/libc/kernel/uapi/linux/chio.h
index 725e760..74f286f 100644
--- a/libc/kernel/uapi/linux/chio.h
+++ b/libc/kernel/uapi/linux/chio.h
@@ -71,7 +71,7 @@
#define CP_INVERT 1
struct changer_element_status {
int ces_type;
- unsigned char __user * ces_data;
+ unsigned char * ces_data;
};
#define CESTATUS_FULL 0x01
#define CESTATUS_IMPEXP 0x02
diff --git a/libc/kernel/uapi/linux/coda.h b/libc/kernel/uapi/linux/coda.h
index aad1b97..5795cdf 100644
--- a/libc/kernel/uapi/linux/coda.h
+++ b/libc/kernel/uapi/linux/coda.h
@@ -505,13 +505,13 @@
};
#define PIOCPARM_MASK 0x0000ffff
struct ViceIoctl {
- void __user * in;
- void __user * out;
+ void * in;
+ void * out;
u_short in_size;
u_short out_size;
};
struct PioctlData {
- const char __user * path;
+ const char * path;
int follow;
struct ViceIoctl vi;
};
diff --git a/libc/kernel/uapi/linux/comedi.h b/libc/kernel/uapi/linux/comedi.h
index e0d015a..465d1bf 100644
--- a/libc/kernel/uapi/linux/comedi.h
+++ b/libc/kernel/uapi/linux/comedi.h
@@ -244,14 +244,14 @@
struct comedi_insn {
unsigned int insn;
unsigned int n;
- unsigned int __user * data;
+ unsigned int * data;
unsigned int subdev;
unsigned int chanspec;
unsigned int unused[3];
};
struct comedi_insnlist {
unsigned int n_insns;
- struct comedi_insn __user * insns;
+ struct comedi_insn * insns;
};
struct comedi_cmd {
unsigned int subdev;
@@ -268,19 +268,19 @@
unsigned int stop_arg;
unsigned int * chanlist;
unsigned int chanlist_len;
- short __user * data;
+ short * data;
unsigned int data_len;
};
struct comedi_chaninfo {
unsigned int subdev;
- unsigned int __user * maxdata_list;
- unsigned int __user * flaglist;
- unsigned int __user * rangelist;
+ unsigned int * maxdata_list;
+ unsigned int * flaglist;
+ unsigned int * rangelist;
unsigned int unused[4];
};
struct comedi_rangeinfo {
unsigned int range_type;
- void __user * range_ptr;
+ void * range_ptr;
};
struct comedi_krange {
int min;
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 578cefd..5a0a34e 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -37,14 +37,16 @@
struct cxl_command_info {
__u32 id;
__u32 flags;
-#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0)
+#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(1, 0)
+#define CXL_MEM_COMMAND_FLAG_ENABLED BIT(0)
+#define CXL_MEM_COMMAND_FLAG_EXCLUSIVE BIT(1)
__u32 size_in;
__u32 size_out;
};
struct cxl_mem_query_commands {
__u32 n_commands;
__u32 rsvd;
- struct cxl_command_info __user commands[];
+ struct cxl_command_info commands[];
};
struct cxl_send_command {
__u32 id;
diff --git a/libc/kernel/uapi/linux/dcbnl.h b/libc/kernel/uapi/linux/dcbnl.h
index bc88387..b2fec7b 100644
--- a/libc/kernel/uapi/linux/dcbnl.h
+++ b/libc/kernel/uapi/linux/dcbnl.h
@@ -181,6 +181,7 @@
DCB_ATTR_IEEE_QCN_STATS,
DCB_ATTR_DCB_BUFFER,
DCB_ATTR_DCB_APP_TRUST_TABLE,
+ DCB_ATTR_DCB_REWR_TABLE,
__DCB_ATTR_IEEE_MAX
};
#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
diff --git a/libc/kernel/uapi/linux/dlm_device.h b/libc/kernel/uapi/linux/dlm_device.h
index 5e54d2e..e1b0c6d 100644
--- a/libc/kernel/uapi/linux/dlm_device.h
+++ b/libc/kernel/uapi/linux/dlm_device.h
@@ -33,11 +33,11 @@
__u32 parent;
__u64 xid;
__u64 timeout;
- void __user * castparam;
- void __user * castaddr;
- void __user * bastparam;
- void __user * bastaddr;
- struct dlm_lksb __user * lksb;
+ void * castparam;
+ void * castaddr;
+ void * bastparam;
+ void * bastaddr;
+ struct dlm_lksb * lksb;
char lvb[DLM_USER_LVB_LEN];
char name[];
};
@@ -67,9 +67,9 @@
struct dlm_lock_result {
__u32 version[3];
__u32 length;
- void __user * user_astaddr;
- void __user * user_astparam;
- struct dlm_lksb __user * user_lksb;
+ void * user_astaddr;
+ void * user_astparam;
+ struct dlm_lksb * user_lksb;
struct dlm_lksb lksb;
__u8 bast_mode;
__u8 unused[3];
diff --git a/libc/kernel/uapi/linux/dvb/osd.h b/libc/kernel/uapi/linux/dvb/osd.h
index 84b268b..379294e 100644
--- a/libc/kernel/uapi/linux/dvb/osd.h
+++ b/libc/kernel/uapi/linux/dvb/osd.h
@@ -50,7 +50,7 @@
int x1;
int y1;
int color;
- void __user * data;
+ void * data;
} osd_cmd_t;
typedef enum {
OSD_BITMAP1,
diff --git a/libc/kernel/uapi/linux/dvb/video.h b/libc/kernel/uapi/linux/dvb/video.h
index 6577e1f..2458766 100644
--- a/libc/kernel/uapi/linux/dvb/video.h
+++ b/libc/kernel/uapi/linux/dvb/video.h
@@ -94,7 +94,7 @@
video_displayformat_t display_format;
};
struct video_still_picture {
- char __user * iFrame;
+ char * iFrame;
__s32 size;
};
typedef __u16 video_attributes_t;
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 28c8426..e4901d1 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -366,6 +366,7 @@
#define NT_ARM_PAC_ENABLED_KEYS 0x40a
#define NT_ARM_SSVE 0x40b
#define NT_ARM_ZA 0x40c
+#define NT_ARM_ZT 0x40d
#define NT_ARC_V2 0x600
#define NT_VMCOREDD 0x700
#define NT_MIPS_DSP 0x800
@@ -376,6 +377,8 @@
#define NT_LOONGARCH_LSX 0xa02
#define NT_LOONGARCH_LASX 0xa03
#define NT_LOONGARCH_LBT 0xa04
+#define NT_LOONGARCH_HW_BREAK 0xa05
+#define NT_LOONGARCH_HW_WATCH 0xa06
#define NT_GNU_PROPERTY_TYPE_0 5
typedef struct elf32_note {
Elf32_Word n_namesz;
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index a58be6f..eec750d 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -269,6 +269,11 @@
ETH_SS_STATS_RMON,
ETH_SS_COUNT
};
+enum ethtool_mac_stats_src {
+ ETHTOOL_MAC_STATS_SRC_AGGREGATE,
+ ETHTOOL_MAC_STATS_SRC_EMAC,
+ ETHTOOL_MAC_STATS_SRC_PMAC,
+};
enum ethtool_module_power_mode_policy {
ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH = 1,
ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO,
@@ -291,6 +296,14 @@
ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE,
ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR,
};
+enum ethtool_mm_verify_status {
+ ETHTOOL_MM_VERIFY_STATUS_UNKNOWN,
+ ETHTOOL_MM_VERIFY_STATUS_INITIAL,
+ ETHTOOL_MM_VERIFY_STATUS_VERIFYING,
+ ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED,
+ ETHTOOL_MM_VERIFY_STATUS_FAILED,
+ ETHTOOL_MM_VERIFY_STATUS_DISABLED,
+};
struct ethtool_gstrings {
__u32 cmd;
__u32 string_set;
@@ -419,7 +432,7 @@
__u32 rule_cnt;
__u32 rss_context;
};
- __u32 rule_locs[0];
+ __u32 rule_locs[];
};
struct ethtool_rxfh_indir {
__u32 cmd;
@@ -725,6 +738,9 @@
ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT = 96,
ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT = 97,
ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT = 98,
+ 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_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 cc9c53c..f1ef896 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -59,6 +59,11 @@
ETHTOOL_MSG_PSE_GET,
ETHTOOL_MSG_PSE_SET,
ETHTOOL_MSG_RSS_GET,
+ ETHTOOL_MSG_PLCA_GET_CFG,
+ ETHTOOL_MSG_PLCA_SET_CFG,
+ ETHTOOL_MSG_PLCA_GET_STATUS,
+ ETHTOOL_MSG_MM_GET,
+ ETHTOOL_MSG_MM_SET,
__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
};
@@ -102,6 +107,11 @@
ETHTOOL_MSG_MODULE_NTF,
ETHTOOL_MSG_PSE_GET_REPLY,
ETHTOOL_MSG_RSS_GET_REPLY,
+ ETHTOOL_MSG_PLCA_GET_CFG_REPLY,
+ ETHTOOL_MSG_PLCA_GET_STATUS_REPLY,
+ ETHTOOL_MSG_PLCA_NTF,
+ ETHTOOL_MSG_MM_GET_REPLY,
+ ETHTOOL_MSG_MM_NTF,
__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
};
@@ -266,6 +276,7 @@
ETHTOOL_A_RINGS_TCP_DATA_SPLIT,
ETHTOOL_A_RINGS_CQE_SIZE,
ETHTOOL_A_RINGS_TX_PUSH,
+ ETHTOOL_A_RINGS_RX_PUSH,
__ETHTOOL_A_RINGS_CNT,
ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
};
@@ -310,6 +321,9 @@
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,
ETHTOOL_A_COALESCE_USE_CQE_MODE_TX,
ETHTOOL_A_COALESCE_USE_CQE_MODE_RX,
+ ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES,
+ ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES,
+ ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS,
__ETHTOOL_A_COALESCE_CNT,
ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1)
};
@@ -320,6 +334,7 @@
ETHTOOL_A_PAUSE_RX,
ETHTOOL_A_PAUSE_TX,
ETHTOOL_A_PAUSE_STATS,
+ ETHTOOL_A_PAUSE_STATS_SRC,
__ETHTOOL_A_PAUSE_CNT,
ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1)
};
@@ -538,6 +553,7 @@
ETHTOOL_A_STATS_HEADER,
ETHTOOL_A_STATS_GROUPS,
ETHTOOL_A_STATS_GRP,
+ ETHTOOL_A_STATS_SRC,
__ETHTOOL_A_STATS_CNT,
ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1)
};
@@ -635,6 +651,48 @@
__ETHTOOL_A_RSS_CNT,
ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1),
};
+enum {
+ ETHTOOL_A_PLCA_UNSPEC,
+ ETHTOOL_A_PLCA_HEADER,
+ ETHTOOL_A_PLCA_VERSION,
+ ETHTOOL_A_PLCA_ENABLED,
+ ETHTOOL_A_PLCA_STATUS,
+ ETHTOOL_A_PLCA_NODE_CNT,
+ ETHTOOL_A_PLCA_NODE_ID,
+ ETHTOOL_A_PLCA_TO_TMR,
+ ETHTOOL_A_PLCA_BURST_CNT,
+ ETHTOOL_A_PLCA_BURST_TMR,
+ __ETHTOOL_A_PLCA_CNT,
+ ETHTOOL_A_PLCA_MAX = (__ETHTOOL_A_PLCA_CNT - 1)
+};
+enum {
+ ETHTOOL_A_MM_STAT_UNSPEC,
+ ETHTOOL_A_MM_STAT_PAD,
+ ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS,
+ ETHTOOL_A_MM_STAT_SMD_ERRORS,
+ ETHTOOL_A_MM_STAT_REASSEMBLY_OK,
+ ETHTOOL_A_MM_STAT_RX_FRAG_COUNT,
+ ETHTOOL_A_MM_STAT_TX_FRAG_COUNT,
+ ETHTOOL_A_MM_STAT_HOLD_COUNT,
+ __ETHTOOL_A_MM_STAT_CNT,
+ ETHTOOL_A_MM_STAT_MAX = (__ETHTOOL_A_MM_STAT_CNT - 1)
+};
+enum {
+ ETHTOOL_A_MM_UNSPEC,
+ ETHTOOL_A_MM_HEADER,
+ ETHTOOL_A_MM_PMAC_ENABLED,
+ ETHTOOL_A_MM_TX_ENABLED,
+ ETHTOOL_A_MM_TX_ACTIVE,
+ ETHTOOL_A_MM_TX_MIN_FRAG_SIZE,
+ ETHTOOL_A_MM_RX_MIN_FRAG_SIZE,
+ ETHTOOL_A_MM_VERIFY_ENABLED,
+ ETHTOOL_A_MM_VERIFY_STATUS,
+ ETHTOOL_A_MM_VERIFY_TIME,
+ ETHTOOL_A_MM_MAX_VERIFY_TIME,
+ ETHTOOL_A_MM_STATS,
+ __ETHTOOL_A_MM_CNT,
+ ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_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/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index 2a1a26a..de4c1f1 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -25,23 +25,23 @@
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_DEL 2
#define EPOLL_CTL_MOD 3
-#define EPOLLIN (__force __poll_t) 0x00000001
-#define EPOLLPRI (__force __poll_t) 0x00000002
-#define EPOLLOUT (__force __poll_t) 0x00000004
-#define EPOLLERR (__force __poll_t) 0x00000008
-#define EPOLLHUP (__force __poll_t) 0x00000010
-#define EPOLLNVAL (__force __poll_t) 0x00000020
-#define EPOLLRDNORM (__force __poll_t) 0x00000040
-#define EPOLLRDBAND (__force __poll_t) 0x00000080
-#define EPOLLWRNORM (__force __poll_t) 0x00000100
-#define EPOLLWRBAND (__force __poll_t) 0x00000200
-#define EPOLLMSG (__force __poll_t) 0x00000400
-#define EPOLLRDHUP (__force __poll_t) 0x00002000
-#define EPOLL_URING_WAKE ((__force __poll_t) (1U << 27))
-#define EPOLLEXCLUSIVE ((__force __poll_t) (1U << 28))
-#define EPOLLWAKEUP ((__force __poll_t) (1U << 29))
-#define EPOLLONESHOT ((__force __poll_t) (1U << 30))
-#define EPOLLET ((__force __poll_t) (1U << 31))
+#define EPOLLIN ( __poll_t) 0x00000001
+#define EPOLLPRI ( __poll_t) 0x00000002
+#define EPOLLOUT ( __poll_t) 0x00000004
+#define EPOLLERR ( __poll_t) 0x00000008
+#define EPOLLHUP ( __poll_t) 0x00000010
+#define EPOLLNVAL ( __poll_t) 0x00000020
+#define EPOLLRDNORM ( __poll_t) 0x00000040
+#define EPOLLRDBAND ( __poll_t) 0x00000080
+#define EPOLLWRNORM ( __poll_t) 0x00000100
+#define EPOLLWRBAND ( __poll_t) 0x00000200
+#define EPOLLMSG ( __poll_t) 0x00000400
+#define EPOLLRDHUP ( __poll_t) 0x00002000
+#define EPOLL_URING_WAKE (( __poll_t) (1U << 27))
+#define EPOLLEXCLUSIVE (( __poll_t) (1U << 28))
+#define EPOLLWAKEUP (( __poll_t) (1U << 29))
+#define EPOLLONESHOT (( __poll_t) (1U << 30))
+#define EPOLLET (( __poll_t) (1U << 31))
#ifdef __x86_64__
#define EPOLL_PACKED __attribute__((packed))
#else
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 9815a64..f9551a8 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -113,13 +113,27 @@
__s32 error;
__u32 error_count;
};
+#define FAN_RESPONSE_INFO_NONE 0
+#define FAN_RESPONSE_INFO_AUDIT_RULE 1
struct fanotify_response {
__s32 fd;
__u32 response;
};
+struct fanotify_response_info_header {
+ __u8 type;
+ __u8 pad;
+ __u16 len;
+};
+struct fanotify_response_info_audit_rule {
+ struct fanotify_response_info_header hdr;
+ __u32 rule_number;
+ __u32 subj_trust;
+ __u32 obj_trust;
+};
#define FAN_ALLOW 0x01
#define FAN_DENY 0x02
#define FAN_AUDIT 0x10
+#define FAN_INFO 0x20
#define FAN_NOFD - 1
#define FAN_NOPIDFD FAN_NOFD
#define FAN_EPIDFD - 2
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index a46726b..05393d5 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -34,6 +34,7 @@
#define F_SEAL_GROW 0x0004
#define F_SEAL_WRITE 0x0008
#define F_SEAL_FUTURE_WRITE 0x0010
+#define F_SEAL_EXEC 0x0020
#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11)
#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12)
#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
diff --git a/libc/kernel/uapi/linux/fd.h b/libc/kernel/uapi/linux/fd.h
index 4d72d69..dc1d444 100644
--- a/libc/kernel/uapi/linux/fd.h
+++ b/libc/kernel/uapi/linux/fd.h
@@ -175,7 +175,7 @@
#define FD_RAW_SOFTFAILURE 0x800
#define FD_RAW_FAILURE 0x10000
#define FD_RAW_HARDFAILURE 0x20000
- void __user * data;
+ void * data;
char * kernel_data;
struct floppy_raw_cmd * next;
long length;
diff --git a/libc/kernel/uapi/linux/filter.h b/libc/kernel/uapi/linux/filter.h
index d13c59d..57fe2fb 100644
--- a/libc/kernel/uapi/linux/filter.h
+++ b/libc/kernel/uapi/linux/filter.h
@@ -31,7 +31,7 @@
};
struct sock_fprog {
unsigned short len;
- struct sock_filter __user * filter;
+ struct sock_filter * filter;
};
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
diff --git a/libc/kernel/uapi/linux/fou.h b/libc/kernel/uapi/linux/fou.h
index a16b8c6..7b06cff 100644
--- a/libc/kernel/uapi/linux/fou.h
+++ b/libc/kernel/uapi/linux/fou.h
@@ -19,7 +19,12 @@
#ifndef _UAPI_LINUX_FOU_H
#define _UAPI_LINUX_FOU_H
#define FOU_GENL_NAME "fou"
-#define FOU_GENL_VERSION 0x1
+#define FOU_GENL_VERSION 1
+enum {
+ FOU_ENCAP_UNSPEC,
+ FOU_ENCAP_DIRECT,
+ FOU_ENCAP_GUE,
+};
enum {
FOU_ATTR_UNSPEC,
FOU_ATTR_PORT,
@@ -33,7 +38,7 @@
FOU_ATTR_PEER_V6,
FOU_ATTR_PEER_PORT,
FOU_ATTR_IFINDEX,
- __FOU_ATTR_MAX,
+ __FOU_ATTR_MAX
};
#define FOU_ATTR_MAX (__FOU_ATTR_MAX - 1)
enum {
@@ -41,12 +46,7 @@
FOU_CMD_ADD,
FOU_CMD_DEL,
FOU_CMD_GET,
- __FOU_CMD_MAX,
-};
-enum {
- FOU_ENCAP_UNSPEC,
- FOU_ENCAP_DIRECT,
- FOU_ENCAP_GUE,
+ __FOU_CMD_MAX
};
#define FOU_CMD_MAX (__FOU_CMD_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 96f9181..b8bfaac 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -190,10 +190,10 @@
#define SYNC_FILE_RANGE_WAIT_AFTER 4
#define SYNC_FILE_RANGE_WRITE_AND_WAIT (SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WAIT_AFTER)
typedef int __bitwise __kernel_rwf_t;
-#define RWF_HIPRI ((__force __kernel_rwf_t) 0x00000001)
-#define RWF_DSYNC ((__force __kernel_rwf_t) 0x00000002)
-#define RWF_SYNC ((__force __kernel_rwf_t) 0x00000004)
-#define RWF_NOWAIT ((__force __kernel_rwf_t) 0x00000008)
-#define RWF_APPEND ((__force __kernel_rwf_t) 0x00000010)
+#define RWF_HIPRI (( __kernel_rwf_t) 0x00000001)
+#define RWF_DSYNC (( __kernel_rwf_t) 0x00000002)
+#define RWF_SYNC (( __kernel_rwf_t) 0x00000004)
+#define RWF_NOWAIT (( __kernel_rwf_t) 0x00000008)
+#define RWF_APPEND (( __kernel_rwf_t) 0x00000010)
#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND)
#endif
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index f1eec4d..c3668e7 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -111,6 +111,7 @@
#define FUSE_INIT_RESERVED (1 << 31)
#define FUSE_SECURITY_CTX (1ULL << 32)
#define FUSE_HAS_INODE_DAX (1ULL << 33)
+#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
#if FUSE_KERNEL_VERSION > 7 || FUSE_KERNEL_VERSION == 7 && FUSE_KERNEL_MINOR_VERSION >= 36
#define FUSE_PASSTHROUGH (1ULL << 63)
#else
@@ -140,6 +141,10 @@
#define FUSE_OPEN_KILL_SUIDGID (1 << 0)
#define FUSE_SETXATTR_ACL_KILL_SGID (1 << 0)
#define FUSE_EXPIRE_ONLY (1 << 0)
+enum fuse_ext_type {
+ FUSE_MAX_NR_SECCTX = 31,
+ FUSE_EXT_GROUPS = 32,
+};
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2,
@@ -465,7 +470,8 @@
uint32_t uid;
uint32_t gid;
uint32_t pid;
- uint32_t padding;
+ uint16_t total_extlen;
+ uint16_t padding;
};
struct fuse_out_header {
uint32_t len;
@@ -575,4 +581,12 @@
uint32_t size;
uint32_t nr_secctx;
};
+struct fuse_ext_header {
+ uint32_t size;
+ uint32_t type;
+};
+struct fuse_supp_groups {
+ uint32_t nr_groups;
+ uint32_t groups[];
+};
#endif
diff --git a/libc/kernel/uapi/linux/futex.h b/libc/kernel/uapi/linux/futex.h
index c80b90c..8d1a2a4 100644
--- a/libc/kernel/uapi/linux/futex.h
+++ b/libc/kernel/uapi/linux/futex.h
@@ -59,12 +59,12 @@
__u32 __reserved;
};
struct robust_list {
- struct robust_list __user * next;
+ struct robust_list * next;
};
struct robust_list_head {
struct robust_list list;
long futex_offset;
- struct robust_list __user * list_op_pending;
+ struct robust_list * list_op_pending;
};
#define FUTEX_WAITERS 0x80000000
#define FUTEX_OWNER_DIED 0x40000000
diff --git a/libc/kernel/uapi/linux/gsmmux.h b/libc/kernel/uapi/linux/gsmmux.h
index 4e6920a..6ddf1b9 100644
--- a/libc/kernel/uapi/linux/gsmmux.h
+++ b/libc/kernel/uapi/linux/gsmmux.h
@@ -47,4 +47,10 @@
#define GSMIOC_ENABLE_NET _IOW('G', 2, struct gsm_netconfig)
#define GSMIOC_DISABLE_NET _IO('G', 3)
#define GSMIOC_GETFIRST _IOR('G', 4, __u32)
+struct gsm_config_ext {
+ __u32 keep_alive;
+ __u32 reserved[7];
+};
+#define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext)
+#define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext)
#endif
diff --git a/libc/kernel/uapi/linux/i2c-dev.h b/libc/kernel/uapi/linux/i2c-dev.h
index 07fdda2..7a25e20 100644
--- a/libc/kernel/uapi/linux/i2c-dev.h
+++ b/libc/kernel/uapi/linux/i2c-dev.h
@@ -33,10 +33,10 @@
__u8 read_write;
__u8 command;
__u32 size;
- union i2c_smbus_data __user * data;
+ union i2c_smbus_data * data;
};
struct i2c_rdwr_ioctl_data {
- struct i2c_msg __user * msgs;
+ struct i2c_msg * msgs;
__u32 nmsgs;
};
#define I2C_RDWR_IOCTL_MAX_MSGS 42
diff --git a/libc/kernel/uapi/linux/i2o-dev.h b/libc/kernel/uapi/linux/i2o-dev.h
index fc8b26d..afaae74 100644
--- a/libc/kernel/uapi/linux/i2o-dev.h
+++ b/libc/kernel/uapi/linux/i2o-dev.h
@@ -42,38 +42,38 @@
};
struct i2o_cmd_passthru {
unsigned int iop;
- void __user * msg;
+ void * msg;
};
struct i2o_cmd_hrtlct {
unsigned int iop;
- void __user * resbuf;
- unsigned int __user * reslen;
+ void * resbuf;
+ unsigned int * reslen;
};
struct i2o_cmd_psetget {
unsigned int iop;
unsigned int tid;
- void __user * opbuf;
+ void * opbuf;
unsigned int oplen;
- void __user * resbuf;
- unsigned int __user * reslen;
+ void * resbuf;
+ unsigned int * reslen;
};
struct i2o_sw_xfer {
unsigned int iop;
unsigned char flags;
unsigned char sw_type;
unsigned int sw_id;
- void __user * buf;
- unsigned int __user * swlen;
- unsigned int __user * maxfrag;
- unsigned int __user * curfrag;
+ void * buf;
+ unsigned int * swlen;
+ unsigned int * maxfrag;
+ unsigned int * curfrag;
};
struct i2o_html {
unsigned int iop;
unsigned int tid;
unsigned int page;
- void __user * resbuf;
- unsigned int __user * reslen;
- void __user * qbuf;
+ void * resbuf;
+ unsigned int * reslen;
+ void * qbuf;
unsigned int qlen;
};
#define I2O_EVT_Q_LEN 32
diff --git a/libc/kernel/uapi/linux/if.h b/libc/kernel/uapi/linux/if.h
index 63c77eb..fc6d20d 100644
--- a/libc/kernel/uapi/linux/if.h
+++ b/libc/kernel/uapi/linux/if.h
@@ -130,14 +130,14 @@
unsigned int type;
unsigned int size;
union {
- raw_hdlc_proto __user * raw_hdlc;
- cisco_proto __user * cisco;
- fr_proto __user * fr;
- fr_proto_pvc __user * fr_pvc;
- fr_proto_pvc_info __user * fr_pvc_info;
- x25_hdlc_proto __user * x25;
- sync_serial_settings __user * sync;
- te1_settings __user * te1;
+ raw_hdlc_proto * raw_hdlc;
+ cisco_proto * cisco;
+ fr_proto * fr;
+ fr_proto_pvc * fr_pvc;
+ fr_proto_pvc_info * fr_pvc_info;
+ x25_hdlc_proto * x25;
+ sync_serial_settings * sync;
+ te1_settings * te1;
} ifs_ifsu;
};
#if __UAPI_DEF_IF_IFREQ
@@ -158,7 +158,7 @@
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ];
char ifru_newname[IFNAMSIZ];
- void __user * ifru_data;
+ void * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
@@ -184,8 +184,8 @@
struct ifconf {
int ifc_len;
union {
- char __user * ifcu_buf;
- struct ifreq __user * ifcu_req;
+ char * ifcu_buf;
+ struct ifreq * ifcu_req;
} ifc_ifcu;
};
#endif
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 702363e..48f6345 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -435,6 +435,8 @@
BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
BRIDGE_VLANDB_ENTRY_STATS,
BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
+ BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
+ BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
__BRIDGE_VLANDB_ENTRY_MAX,
};
#define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 19c6346..fbb933b 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -167,6 +167,8 @@
IFLA_TSO_MAX_SEGS,
IFLA_ALLMULTI,
IFLA_DEVLINK_PORT,
+ IFLA_GSO_IPV4_MAX_SIZE,
+ IFLA_GRO_IPV4_MAX_SIZE,
__IFLA_MAX
};
#define IFLA_MAX (__IFLA_MAX - 1)
@@ -307,6 +309,8 @@
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
IFLA_BRPORT_LOCKED,
IFLA_BRPORT_MAB,
+ IFLA_BRPORT_MCAST_N_GROUPS,
+ IFLA_BRPORT_MCAST_MAX_GROUPS,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 340b2ee..719f596 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -113,6 +113,7 @@
#define TP_STATUS_BLK_TMO (1 << 5)
#define TP_STATUS_VLAN_TPID_VALID (1 << 6)
#define TP_STATUS_CSUM_VALID (1 << 7)
+#define TP_STATUS_GSO_TCP (1 << 8)
#define TP_STATUS_AVAILABLE 0
#define TP_STATUS_SEND_REQUEST (1 << 0)
#define TP_STATUS_SENDING (1 << 1)
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index 01c2dc9..9b85568 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -142,7 +142,7 @@
__IFLA_GRE_MAX,
};
#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
-#define VTI_ISVTI ((__force __be16) 0x0001)
+#define VTI_ISVTI (( __be16) 0x0001)
enum {
IFLA_VTI_UNSPEC,
IFLA_VTI_LINK,
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 53d3074..3947d5a 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -141,6 +141,7 @@
#define MCAST_MSFILTER 48
#define IP_MULTICAST_ALL 49
#define IP_UNICAST_IF 50
+#define IP_LOCAL_PORT_RANGE 51
#define MCAST_EXCLUDE 0
#define MCAST_INCLUDE 1
#define IP_DEFAULT_MULTICAST_TTL 1
diff --git a/libc/kernel/uapi/linux/input.h b/libc/kernel/uapi/linux/input.h
index 4858c81..1df1398 100644
--- a/libc/kernel/uapi/linux/input.h
+++ b/libc/kernel/uapi/linux/input.h
@@ -173,7 +173,7 @@
__u16 phase;
struct ff_envelope envelope;
__u32 custom_len;
- __s16 __user * custom_data;
+ __s16 * custom_data;
};
struct ff_rumble_effect {
__u16 strong_magnitude;
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 5561448..a2d4f5f 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -200,6 +200,7 @@
IORING_MSG_SEND_FD,
};
#define IORING_MSG_RING_CQE_SKIP (1U << 0)
+#define IORING_MSG_RING_FLAGS_PASS (1U << 1)
struct io_uring_cqe {
__u64 user_data;
__s32 res;
@@ -272,6 +273,7 @@
#define IORING_FEAT_RSRC_TAGS (1U << 10)
#define IORING_FEAT_CQE_SKIP (1U << 11)
#define IORING_FEAT_LINKED_FILE (1U << 12)
+#define IORING_FEAT_REG_REG_RING (1U << 13)
enum {
IORING_REGISTER_BUFFERS = 0,
IORING_UNREGISTER_BUFFERS = 1,
@@ -299,7 +301,8 @@
IORING_UNREGISTER_PBUF_RING = 23,
IORING_REGISTER_SYNC_CANCEL = 24,
IORING_REGISTER_FILE_ALLOC_RANGE = 25,
- IORING_REGISTER_LAST
+ IORING_REGISTER_LAST,
+ IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
};
enum {
IO_WQ_BOUND,
@@ -381,7 +384,7 @@
__u16 resv3;
__u16 tail;
};
- struct io_uring_buf bufs[0];
+ __DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
};
};
struct io_uring_buf_reg {
diff --git a/libc/kernel/uapi/linux/ioam6.h b/libc/kernel/uapi/linux/ioam6.h
index e32c8e9..8d2a25b 100644
--- a/libc/kernel/uapi/linux/ioam6.h
+++ b/libc/kernel/uapi/linux/ioam6.h
@@ -58,6 +58,6 @@
#error "Please fix <asm/byteorder.h>"
#endif
#define IOAM6_TRACE_DATA_SIZE_MAX 244
- __u8 data[0];
+ __u8 data[];
} __attribute__((packed));
#endif
diff --git a/libc/kernel/uapi/linux/ipc.h b/libc/kernel/uapi/linux/ipc.h
index a0699cf..4ca9ee1 100644
--- a/libc/kernel/uapi/linux/ipc.h
+++ b/libc/kernel/uapi/linux/ipc.h
@@ -42,7 +42,7 @@
#define IPC_OLD 0
#define IPC_64 0x0100
struct ipc_kludge {
- struct msgbuf __user * msgp;
+ struct msgbuf * msgp;
long msgtyp;
};
#define SEMOP 1
diff --git a/libc/kernel/uapi/linux/ipmi.h b/libc/kernel/uapi/linux/ipmi.h
index dd88f2f..bd73b3c 100644
--- a/libc/kernel/uapi/linux/ipmi.h
+++ b/libc/kernel/uapi/linux/ipmi.h
@@ -65,7 +65,7 @@
unsigned char netfn;
unsigned char cmd;
unsigned short data_len;
- unsigned char __user * data;
+ unsigned char * data;
};
struct kernel_ipmi_msg {
unsigned char netfn;
@@ -86,7 +86,7 @@
#define IPMI_MAINTENANCE_MODE_ON 2
#define IPMI_IOC_MAGIC 'i'
struct ipmi_req {
- unsigned char __user * addr;
+ unsigned char * addr;
unsigned int addr_len;
long msgid;
struct ipmi_msg msg;
@@ -100,7 +100,7 @@
#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, struct ipmi_req_settime)
struct ipmi_recv {
int recv_type;
- unsigned char __user * addr;
+ unsigned char * addr;
unsigned int addr_len;
long msgid;
struct ipmi_msg msg;
diff --git a/libc/kernel/uapi/linux/ivtv.h b/libc/kernel/uapi/linux/ivtv.h
index 549d6a8..bdd526e 100644
--- a/libc/kernel/uapi/linux/ivtv.h
+++ b/libc/kernel/uapi/linux/ivtv.h
@@ -24,8 +24,8 @@
struct ivtv_dma_frame {
enum v4l2_buf_type type;
__u32 pixelformat;
- void __user * y_source;
- void __user * uv_source;
+ void * y_source;
+ void * uv_source;
struct v4l2_rect src;
struct v4l2_rect dst;
__u32 src_width;
diff --git a/libc/kernel/uapi/linux/ivtvfb.h b/libc/kernel/uapi/linux/ivtvfb.h
index 9addcbf..171be74 100644
--- a/libc/kernel/uapi/linux/ivtvfb.h
+++ b/libc/kernel/uapi/linux/ivtvfb.h
@@ -21,7 +21,7 @@
#include <linux/compiler.h>
#include <linux/types.h>
struct ivtvfb_dma_frame {
- void __user * source;
+ void * source;
unsigned long dest_offset;
int count;
};
diff --git a/libc/kernel/uapi/linux/kd.h b/libc/kernel/uapi/linux/kd.h
index 2385037..a14cab6 100644
--- a/libc/kernel/uapi/linux/kd.h
+++ b/libc/kernel/uapi/linux/kd.h
@@ -27,7 +27,7 @@
struct consolefontdesc {
unsigned short charcount;
unsigned short charheight;
- char __user * chardata;
+ char * chardata;
};
#define PIO_FONTRESET 0x4B6D
#define GIO_CMAP 0x4B70
@@ -68,7 +68,7 @@
};
struct unimapdesc {
unsigned short entry_ct;
- struct unipair __user * entries;
+ struct unipair * entries;
};
#define PIO_UNIMAP 0x4B67
#define PIO_UNIMAPCLR 0x4B68
@@ -147,7 +147,7 @@
unsigned int flags;
unsigned int width, height;
unsigned int charcount;
- unsigned char __user * data;
+ unsigned char * data;
};
struct console_font {
unsigned int width, height;
@@ -158,5 +158,7 @@
#define KD_FONT_OP_GET 1
#define KD_FONT_OP_SET_DEFAULT 2
#define KD_FONT_OP_COPY 3
+#define KD_FONT_OP_SET_TALL 4
+#define KD_FONT_OP_GET_TALL 5
#define KD_FONT_FLAG_DONT_RECALC 1
#endif
diff --git a/libc/kernel/uapi/linux/keyctl.h b/libc/kernel/uapi/linux/keyctl.h
index 01ea576..b534f5e 100644
--- a/libc/kernel/uapi/linux/keyctl.h
+++ b/libc/kernel/uapi/linux/keyctl.h
@@ -80,8 +80,8 @@
__s32 base;
};
struct keyctl_kdf_params {
- char __user * hashname;
- char __user * otherinfo;
+ char * hashname;
+ char * otherinfo;
__u32 otherinfolen;
__u32 __spare[8];
};
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 9566f01..342c5c9 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -436,6 +436,8 @@
struct {
__u8 ar;
__u8 key;
+ __u8 pad1[6];
+ __u64 old_addr;
};
__u32 sida_offset;
__u8 reserved[32];
@@ -447,9 +449,12 @@
#define KVM_S390_MEMOP_SIDA_WRITE 3
#define KVM_S390_MEMOP_ABSOLUTE_READ 4
#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5
+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6
#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2)
+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0)
+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1)
struct kvm_interrupt {
__u32 irq;
};
@@ -457,7 +462,7 @@
__u32 slot;
__u32 padding1;
union {
- void __user * dirty_bitmap;
+ void * dirty_bitmap;
__u64 padding2;
};
};
@@ -466,7 +471,7 @@
__u32 num_pages;
__u64 first_page;
union {
- void __user * dirty_bitmap;
+ void * dirty_bitmap;
__u64 padding2;
};
};
@@ -926,6 +931,7 @@
#define KVM_CAP_DIRTY_LOG_RING_ACQ_REL 223
#define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
#define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
+#define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 7a2c9af..725eb1a 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -78,6 +78,8 @@
#define MDIO_AN_T1_LP_L 517
#define MDIO_AN_T1_LP_M 518
#define MDIO_AN_T1_LP_H 519
+#define MDIO_AN_10BT1_AN_CTRL 526
+#define MDIO_AN_10BT1_AN_STAT 527
#define MDIO_PMA_PMD_BT1_CTRL 2100
#define MDIO_PMA_LASI_RXCTRL 0x9000
#define MDIO_PMA_LASI_TXCTRL 0x9001
@@ -270,6 +272,8 @@
#define MDIO_AN_T1_LP_M_B10L 0x4000
#define MDIO_AN_T1_LP_H_10L_TX_HI_REQ 0x1000
#define MDIO_AN_T1_LP_H_10L_TX_HI 0x2000
+#define MDIO_AN_10BT1_AN_CTRL_ADV_EEE_T1L 0x4000
+#define MDIO_AN_10BT1_AN_STAT_LPA_EEE_T1L 0x4000
#define MDIO_PMA_PMD_BT1_CTRL_CFG_MST 0x4000
#define MDIO_AN_EEE_ADV_100TX 0x0002
#define MDIO_AN_EEE_ADV_1000T 0x0004
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index 87614cf..79d4cd5 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -30,8 +30,11 @@
#define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007
#define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008
#define MEDIA_BUS_FMT_RGB666_1X18 0x1009
+#define MEDIA_BUS_FMT_BGR666_1X18 0x1023
#define MEDIA_BUS_FMT_RBG888_1X24 0x100e
#define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015
+#define MEDIA_BUS_FMT_BGR666_1X24_CPADHI 0x1024
+#define MEDIA_BUS_FMT_RGB565_1X24_CPADHI 0x1022
#define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010
#define MEDIA_BUS_FMT_BGR888_1X24 0x1013
#define MEDIA_BUS_FMT_BGR888_3X8 0x101b
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 869d47b..fe97e90 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -125,8 +125,8 @@
};
struct media_links_enum {
__u32 entity;
- struct media_pad_desc __user * pads;
- struct media_link_desc __user * links;
+ struct media_pad_desc * pads;
+ struct media_link_desc * links;
__u32 reserved[4];
};
#define MEDIA_INTF_T_DVB_BASE 0x00000100
diff --git a/libc/kernel/uapi/linux/membarrier.h b/libc/kernel/uapi/linux/membarrier.h
index 43c103b..94dd797 100644
--- a/libc/kernel/uapi/linux/membarrier.h
+++ b/libc/kernel/uapi/linux/membarrier.h
@@ -29,6 +29,7 @@
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6),
MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7),
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8),
+ MEMBARRIER_CMD_GET_REGISTRATIONS = (1 << 9),
MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
};
enum membarrier_cmd_flag {
diff --git a/libc/kernel/uapi/linux/memfd.h b/libc/kernel/uapi/linux/memfd.h
index 914c076..28228df 100644
--- a/libc/kernel/uapi/linux/memfd.h
+++ b/libc/kernel/uapi/linux/memfd.h
@@ -22,6 +22,8 @@
#define MFD_CLOEXEC 0x0001U
#define MFD_ALLOW_SEALING 0x0002U
#define MFD_HUGETLB 0x0004U
+#define MFD_NOEXEC_SEAL 0x0008U
+#define MFD_EXEC 0x0010U
#define MFD_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
#define MFD_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
#define MFD_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
diff --git a/libc/kernel/uapi/linux/meye.h b/libc/kernel/uapi/linux/meye.h
deleted file mode 100644
index a1112c4..0000000
--- a/libc/kernel/uapi/linux/meye.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _MEYE_H_
-#define _MEYE_H_
-struct meye_params {
- unsigned char subsample;
- unsigned char quality;
- unsigned char sharpness;
- unsigned char agc;
- unsigned char picture;
- unsigned char framerate;
-};
-#define MEYEIOC_G_PARAMS _IOR('v', BASE_VIDIOC_PRIVATE + 0, struct meye_params)
-#define MEYEIOC_S_PARAMS _IOW('v', BASE_VIDIOC_PRIVATE + 1, struct meye_params)
-#define MEYEIOC_QBUF_CAPT _IOW('v', BASE_VIDIOC_PRIVATE + 2, int)
-#define MEYEIOC_SYNC _IOWR('v', BASE_VIDIOC_PRIVATE + 3, int)
-#define MEYEIOC_STILLCAPT _IO('v', BASE_VIDIOC_PRIVATE + 4)
-#define MEYEIOC_STILLJCAPT _IOR('v', BASE_VIDIOC_PRIVATE + 5, int)
-#define V4L2_CID_MEYE_AGC (V4L2_CID_USER_MEYE_BASE + 0)
-#define V4L2_CID_MEYE_PICTURE (V4L2_CID_USER_MEYE_BASE + 1)
-#define V4L2_CID_MEYE_FRAMERATE (V4L2_CID_USER_MEYE_BASE + 2)
-#endif
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
new file mode 100644
index 0000000..53a237b
--- /dev/null
+++ b/libc/kernel/uapi/linux/netdev.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_NETDEV_H
+#define _UAPI_LINUX_NETDEV_H
+#define NETDEV_FAMILY_NAME "netdev"
+#define NETDEV_FAMILY_VERSION 1
+enum netdev_xdp_act {
+ NETDEV_XDP_ACT_BASIC = 1,
+ NETDEV_XDP_ACT_REDIRECT = 2,
+ NETDEV_XDP_ACT_NDO_XMIT = 4,
+ NETDEV_XDP_ACT_XSK_ZEROCOPY = 8,
+ NETDEV_XDP_ACT_HW_OFFLOAD = 16,
+ NETDEV_XDP_ACT_RX_SG = 32,
+ NETDEV_XDP_ACT_NDO_XMIT_SG = 64,
+ NETDEV_XDP_ACT_MASK = 127,
+};
+enum {
+ NETDEV_A_DEV_IFINDEX = 1,
+ NETDEV_A_DEV_PAD,
+ NETDEV_A_DEV_XDP_FEATURES,
+ __NETDEV_A_DEV_MAX,
+ NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+};
+enum {
+ NETDEV_CMD_DEV_GET = 1,
+ NETDEV_CMD_DEV_ADD_NTF,
+ NETDEV_CMD_DEV_DEL_NTF,
+ NETDEV_CMD_DEV_CHANGE_NTF,
+ __NETDEV_CMD_MAX,
+ NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
+};
+#define NETDEV_MCGRP_MGMT "mgmt"
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index f07d7c7..33bfb7f 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -87,6 +87,13 @@
NFT_MSG_GETFLOWTABLE,
NFT_MSG_DELFLOWTABLE,
NFT_MSG_GETRULE_RESET,
+ NFT_MSG_DESTROYTABLE,
+ NFT_MSG_DESTROYCHAIN,
+ NFT_MSG_DESTROYRULE,
+ NFT_MSG_DESTROYSET,
+ NFT_MSG_DESTROYSETELEM,
+ NFT_MSG_DESTROYOBJ,
+ NFT_MSG_DESTROYFLOWTABLE,
NFT_MSG_MAX,
};
enum nft_list_attributes {
diff --git a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
index 862f514..b1fb537 100644
--- a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
@@ -98,7 +98,7 @@
unsigned int hook_entry[NF_ARP_NUMHOOKS];
unsigned int underflow[NF_ARP_NUMHOOKS];
unsigned int num_counters;
- struct xt_counters __user * counters;
+ struct xt_counters * counters;
struct arpt_entry entries[];
};
struct arpt_get_entries {
diff --git a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
index 7c8f435..d87d65e 100644
--- a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
+++ b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
@@ -42,10 +42,10 @@
unsigned int valid_hooks;
unsigned int nentries;
unsigned int entries_size;
- struct ebt_entries __user * hook_entry[NF_BR_NUMHOOKS];
+ struct ebt_entries * hook_entry[NF_BR_NUMHOOKS];
unsigned int num_counters;
- struct ebt_counter __user * counters;
- char __user * entries;
+ struct ebt_counter * counters;
+ char * entries;
};
struct ebt_replace_kernel {
char name[EBT_TABLE_MAXNAMELEN];
diff --git a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
index 14a65ad..5179be4 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -112,7 +112,7 @@
unsigned int hook_entry[NF_INET_NUMHOOKS];
unsigned int underflow[NF_INET_NUMHOOKS];
unsigned int num_counters;
- struct xt_counters __user * counters;
+ struct xt_counters * counters;
struct ipt_entry entries[];
};
struct ipt_get_entries {
diff --git a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
index 22071db..8c4ec88 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
@@ -132,7 +132,7 @@
unsigned int hook_entry[NF_INET_NUMHOOKS];
unsigned int underflow[NF_INET_NUMHOOKS];
unsigned int num_counters;
- struct xt_counters __user * counters;
+ struct xt_counters * counters;
struct ip6t_entry entries[];
};
struct ip6t_get_entries {
diff --git a/libc/kernel/uapi/linux/nfs4_mount.h b/libc/kernel/uapi/linux/nfs4_mount.h
index 0f794dd..9b9c9f8 100644
--- a/libc/kernel/uapi/linux/nfs4_mount.h
+++ b/libc/kernel/uapi/linux/nfs4_mount.h
@@ -21,7 +21,7 @@
#define NFS4_MOUNT_VERSION 1
struct nfs_string {
unsigned int len;
- const char __user * data;
+ const char * data;
};
struct nfs4_mount_data {
int version;
@@ -38,10 +38,10 @@
struct nfs_string mnt_path;
struct nfs_string hostname;
unsigned int host_addrlen;
- struct sockaddr __user * host_addr;
+ struct sockaddr * host_addr;
int proto;
int auth_flavourlen;
- int __user * auth_flavours;
+ int * auth_flavours;
};
#define NFS4_MOUNT_SOFT 0x0001
#define NFS4_MOUNT_INTR 0x0002
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 83fe597..d73922a 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -528,6 +528,7 @@
NL80211_ATTR_TX_HW_TIMESTAMP,
NL80211_ATTR_RX_HW_TIMESTAMP,
NL80211_ATTR_TD_BITMAP,
+ NL80211_ATTR_PUNCT_BITMAP,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -1396,6 +1397,7 @@
#define NL80211_KEK_LEN 16
#define NL80211_KCK_EXT_LEN 24
#define NL80211_KEK_EXT_LEN 32
+#define NL80211_KCK_EXT_LEN_32 32
#define NL80211_REPLAY_CTR_LEN 8
enum nl80211_rekey_data {
__NL80211_REKEY_DATA_INVALID,
@@ -1533,6 +1535,8 @@
NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
NL80211_EXT_FEATURE_RADAR_BACKGROUND,
NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
+ NL80211_EXT_FEATURE_PUNCT,
+ NL80211_EXT_FEATURE_SECURE_NAN,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
diff --git a/libc/kernel/uapi/linux/omap3isp.h b/libc/kernel/uapi/linux/omap3isp.h
index 53345e3..1834658 100644
--- a/libc/kernel/uapi/linux/omap3isp.h
+++ b/libc/kernel/uapi/linux/omap3isp.h
@@ -88,7 +88,7 @@
};
struct omap3isp_stat_data {
struct timeval ts;
- void __user * buf;
+ void * buf;
__struct_group(, frame,, __u32 buf_size;
__u16 frame_number;
__u16 cur_frame;
@@ -224,12 +224,12 @@
__u16 update;
__u16 flag;
enum omap3isp_alaw_ipwidth alawip;
- struct omap3isp_ccdc_bclamp __user * bclamp;
- struct omap3isp_ccdc_blcomp __user * blcomp;
- struct omap3isp_ccdc_fpc __user * fpc;
- struct omap3isp_ccdc_lsc_config __user * lsc_cfg;
- struct omap3isp_ccdc_culling __user * cull;
- __u8 __user * lsc;
+ struct omap3isp_ccdc_bclamp * bclamp;
+ struct omap3isp_ccdc_blcomp * blcomp;
+ struct omap3isp_ccdc_fpc * fpc;
+ struct omap3isp_ccdc_lsc_config * lsc_cfg;
+ struct omap3isp_ccdc_culling * cull;
+ __u8 * lsc;
};
#define OMAP3ISP_PREV_LUMAENH (1 << 0)
#define OMAP3ISP_PREV_INVALAW (1 << 1)
@@ -323,17 +323,17 @@
__u32 update;
__u32 flag;
__u32 shading_shift;
- struct omap3isp_prev_luma __user * luma;
- struct omap3isp_prev_hmed __user * hmed;
- struct omap3isp_prev_cfa __user * cfa;
- struct omap3isp_prev_csup __user * csup;
- struct omap3isp_prev_wbal __user * wbal;
- struct omap3isp_prev_blkadj __user * blkadj;
- struct omap3isp_prev_rgbtorgb __user * rgb2rgb;
- struct omap3isp_prev_csc __user * csc;
- struct omap3isp_prev_yclimit __user * yclimit;
- struct omap3isp_prev_dcor __user * dcor;
- struct omap3isp_prev_nf __user * nf;
- struct omap3isp_prev_gtables __user * gamma;
+ struct omap3isp_prev_luma * luma;
+ struct omap3isp_prev_hmed * hmed;
+ struct omap3isp_prev_cfa * cfa;
+ struct omap3isp_prev_csup * csup;
+ struct omap3isp_prev_wbal * wbal;
+ struct omap3isp_prev_blkadj * blkadj;
+ struct omap3isp_prev_rgbtorgb * rgb2rgb;
+ struct omap3isp_prev_csc * csc;
+ struct omap3isp_prev_yclimit * yclimit;
+ struct omap3isp_prev_dcor * dcor;
+ struct omap3isp_prev_nf * nf;
+ struct omap3isp_prev_gtables * gamma;
};
#endif
diff --git a/libc/kernel/uapi/linux/omapfb.h b/libc/kernel/uapi/linux/omapfb.h
index 6ebec08..632e468 100644
--- a/libc/kernel/uapi/linux/omapfb.h
+++ b/libc/kernel/uapi/linux/omapfb.h
@@ -153,7 +153,7 @@
__u16 w;
__u16 h;
size_t buffer_size;
- void __user * buffer;
+ void * buffer;
};
struct omapfb_ovl_colormode {
__u8 overlay_idx;
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index f932c18..44b0613 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -594,6 +594,7 @@
#define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380
#define PCI_EXP_LNKCTL2_HASD 0x0020
#define PCI_EXP_LNKSTA2 0x32
+#define PCI_EXP_LNKSTA2_FLIT 0x0400
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32
#define PCI_EXP_SLTCAP2 0x34
#define PCI_EXP_SLTCAP2_IBPD 0x00000001
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 8f081ed..9223bd7 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -237,6 +237,7 @@
#define PERF_ATTR_SIZE_VER5 112
#define PERF_ATTR_SIZE_VER6 120
#define PERF_ATTR_SIZE_VER7 128
+#define PERF_ATTR_SIZE_VER8 136
struct perf_event_attr {
__u32 type;
__u32 size;
@@ -276,6 +277,7 @@
__u32 aux_sample_size;
__u32 __reserved_3;
__u64 sig_data;
+ __u64 config3;
};
struct perf_event_query_bpf {
__u32 ids_len;
diff --git a/libc/kernel/uapi/linux/ppp-ioctl.h b/libc/kernel/uapi/linux/ppp-ioctl.h
index 69c6e6d..165d447 100644
--- a/libc/kernel/uapi/linux/ppp-ioctl.h
+++ b/libc/kernel/uapi/linux/ppp-ioctl.h
@@ -56,7 +56,7 @@
enum NPmode mode;
};
struct ppp_option_data {
- __u8 __user * ptr;
+ __u8 * ptr;
__u32 length;
int transmit;
};
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 1dac726..6ad1c04 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -184,6 +184,9 @@
#define PR_SME_GET_VL 64
#define PR_SME_VL_LEN_MASK 0xffff
#define PR_SME_VL_INHERIT (1 << 17)
+#define PR_SET_MDWE 65
+#define PR_MDWE_REFUSE_EXEC_GAIN 1
+#define PR_GET_MDWE 66
#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0
#endif
diff --git a/libc/kernel/uapi/linux/route.h b/libc/kernel/uapi/linux/route.h
index 4ba6023..f33327c 100644
--- a/libc/kernel/uapi/linux/route.h
+++ b/libc/kernel/uapi/linux/route.h
@@ -30,7 +30,7 @@
unsigned long rt_pad3;
void * rt_pad4;
short rt_metric;
- char __user * rt_dev;
+ char * rt_dev;
unsigned long rt_mtu;
#define rt_mss rt_mtu
unsigned long rt_window;
diff --git a/libc/kernel/uapi/linux/rpl.h b/libc/kernel/uapi/linux/rpl.h
index 3648bfc..4226297 100644
--- a/libc/kernel/uapi/linux/rpl.h
+++ b/libc/kernel/uapi/linux/rpl.h
@@ -34,8 +34,8 @@
#error "Please fix <asm/byteorder.h>"
#endif
union {
- struct in6_addr addr[0];
- __u8 data[0];
+ __DECLARE_FLEX_ARRAY(struct in6_addr, addr);
+ __DECLARE_FLEX_ARRAY(__u8, data);
} segments;
} __attribute__((packed));
#define rpl_segaddr segments.addr
diff --git a/libc/kernel/uapi/linux/rseq.h b/libc/kernel/uapi/linux/rseq.h
index 29a9457..f837720 100644
--- a/libc/kernel/uapi/linux/rseq.h
+++ b/libc/kernel/uapi/linux/rseq.h
@@ -49,5 +49,8 @@
__u32 cpu_id;
__u64 rseq_cs;
__u32 flags;
+ __u32 node_id;
+ __u32 mm_cid;
+ char end[];
} __attribute__((aligned(4 * sizeof(__u64))));
#endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 7201827..335a19a 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -463,6 +463,7 @@
TCA_INGRESS_BLOCK,
TCA_EGRESS_BLOCK,
TCA_DUMP_FLAGS,
+ TCA_EXT_WARN_MSG,
__TCA_MAX
};
#define TCA_MAX (__TCA_MAX - 1)
@@ -589,6 +590,7 @@
TCA_ROOT_FLAGS,
TCA_ROOT_COUNT,
TCA_ROOT_TIME_DELTA,
+ TCA_ROOT_EXT_WARN_MSG,
__TCA_ROOT_MAX,
#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/sed-opal.h b/libc/kernel/uapi/linux/sed-opal.h
index 4c66231..4685bb3 100644
--- a/libc/kernel/uapi/linux/sed-opal.h
+++ b/libc/kernel/uapi/linux/sed-opal.h
@@ -122,6 +122,7 @@
#define OPAL_FL_LOCKED 0x00000008
#define OPAL_FL_MBR_ENABLED 0x00000010
#define OPAL_FL_MBR_DONE 0x00000020
+#define OPAL_FL_SUM_SUPPORTED 0x00000040
struct opal_status {
__u32 flags;
__u32 reserved;
diff --git a/libc/kernel/uapi/linux/sem.h b/libc/kernel/uapi/linux/sem.h
index 98ed1bf..c2f25e7 100644
--- a/libc/kernel/uapi/linux/sem.h
+++ b/libc/kernel/uapi/linux/sem.h
@@ -48,10 +48,10 @@
};
union __kernel_legacy_semun {
int val;
- struct __kernel_legacy_semid_ds __user * buf;
- unsigned short __user * array;
- struct seminfo __user * __buf;
- void __user * __pad;
+ struct __kernel_legacy_semid_ds * buf;
+ unsigned short * array;
+ struct seminfo * __buf;
+ void * __pad;
};
struct seminfo {
int semmap;
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index 1e04429..ecd395c 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -99,6 +99,7 @@
#define PORT_VT8500 97
#define PORT_XUARTPS 98
#define PORT_AR933X 99
+#define PORT_MCHP16550A 100
#define PORT_ARC 101
#define PORT_RP2 102
#define PORT_LPUART 103
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index e41e649..36d778d 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -37,6 +37,11 @@
#define UART_IIR_RX_TIMEOUT 0x0c
#define UART_IIR_XOFF 0x10
#define UART_IIR_CTS_RTS_DSR 0x20
+#define UART_IIR_64BYTE_FIFO 0x20
+#define UART_IIR_FIFO_ENABLED 0xc0
+#define UART_IIR_FIFO_ENABLED_8250 0x00
+#define UART_IIR_FIFO_ENABLED_16550 0x80
+#define UART_IIR_FIFO_ENABLED_16550A 0xc0
#define UART_FCR 2
#define UART_FCR_ENABLE_FIFO 0x01
#define UART_FCR_CLEAR_RCVR 0x02
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index e3d6ee3..ea3f058 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -87,6 +87,8 @@
ICMP_MIB_OUTADDRMASKS,
ICMP_MIB_OUTADDRMASKREPS,
ICMP_MIB_CSUMERRORS,
+ ICMP_MIB_RATELIMITGLOBAL,
+ ICMP_MIB_RATELIMITHOST,
__ICMP_MIB_MAX
};
#define __ICMPMSG_MIB_MAX 512
@@ -97,6 +99,7 @@
ICMP6_MIB_OUTMSGS,
ICMP6_MIB_OUTERRORS,
ICMP6_MIB_CSUMERRORS,
+ ICMP6_MIB_RATELIMITHOST,
__ICMP6_MIB_MAX
};
#define __ICMP6MSG_MIB_MAX 512
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index ff17f7c..5714323 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -23,11 +23,11 @@
#include <linux/compiler.h>
#define CTL_MAXNAME 10
struct __sysctl_args {
- int __user * name;
+ int * name;
int nlen;
- void __user * oldval;
- size_t __user * oldlenp;
- void __user * newval;
+ void * oldval;
+ size_t * oldlenp;
+ void * newval;
size_t newlen;
unsigned long __linux_unused[4];
};
diff --git a/libc/kernel/uapi/linux/time.h b/libc/kernel/uapi/linux/time.h
index df52295..55d0e6e 100644
--- a/libc/kernel/uapi/linux/time.h
+++ b/libc/kernel/uapi/linux/time.h
@@ -18,14 +18,11 @@
****************************************************************************/
#ifndef _UAPI_LINUX_TIME_H
#define _UAPI_LINUX_TIME_H
+#include <bits/timespec.h>
#include <linux/types.h>
#include <linux/time_types.h>
#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
-struct timespec {
- __kernel_old_time_t tv_sec;
- long tv_nsec;
-};
#endif
struct timeval {
__kernel_old_time_t tv_sec;
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
index 8c9cbeb..6e0a9f8 100644
--- a/libc/kernel/uapi/linux/ublk_cmd.h
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -29,6 +29,7 @@
#define UBLK_CMD_GET_PARAMS 0x09
#define UBLK_CMD_START_USER_RECOVERY 0x10
#define UBLK_CMD_END_USER_RECOVERY 0x11
+#define UBLK_CMD_GET_DEV_INFO2 0x12
#define UBLK_IO_FETCH_REQ 0x20
#define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
#define UBLK_IO_NEED_GET_DATA 0x22
@@ -43,6 +44,7 @@
#define UBLK_F_NEED_GET_DATA (1UL << 2)
#define UBLK_F_USER_RECOVERY (1UL << 3)
#define UBLK_F_USER_RECOVERY_REISSUE (1UL << 4)
+#define UBLK_F_UNPRIVILEGED_DEV (1UL << 5)
#define UBLK_S_DEV_DEAD 0
#define UBLK_S_DEV_LIVE 1
#define UBLK_S_DEV_QUIESCED 2
@@ -51,7 +53,10 @@
__u16 queue_id;
__u16 len;
__u64 addr;
- __u64 data[2];
+ __u64 data[1];
+ __u16 dev_path_len;
+ __u16 pad;
+ __u32 reserved;
};
struct ublksrv_ctrl_dev_info {
__u16 nr_hw_queues;
@@ -64,7 +69,8 @@
__u32 pad1;
__u64 flags;
__u64 ublksrv_flags;
- __u64 reserved0;
+ __u32 owner_uid;
+ __u32 owner_gid;
__u64 reserved1;
__u64 reserved2;
};
@@ -116,12 +122,20 @@
__u16 max_discard_segments;
__u16 reserved0;
};
+struct ublk_param_devt {
+ __u32 char_major;
+ __u32 char_minor;
+ __u32 disk_major;
+ __u32 disk_minor;
+};
struct ublk_params {
__u32 len;
#define UBLK_PARAM_TYPE_BASIC (1 << 0)
#define UBLK_PARAM_TYPE_DISCARD (1 << 1)
+#define UBLK_PARAM_TYPE_DEVT (1 << 2)
__u32 types;
struct ublk_param_basic basic;
struct ublk_param_discard discard;
+ struct ublk_param_devt devt;
};
#endif
diff --git a/libc/kernel/uapi/linux/uhid.h b/libc/kernel/uapi/linux/uhid.h
index 228ee50..1d471f8 100644
--- a/libc/kernel/uapi/linux/uhid.h
+++ b/libc/kernel/uapi/linux/uhid.h
@@ -106,7 +106,7 @@
__u8 name[128];
__u8 phys[64];
__u8 uniq[64];
- __u8 __user * rd_data;
+ __u8 * rd_data;
__u16 rd_size;
__u16 bus;
__u32 vendor;
diff --git a/libc/kernel/uapi/linux/uio.h b/libc/kernel/uapi/linux/uio.h
index fa955cd..04814c7 100644
--- a/libc/kernel/uapi/linux/uio.h
+++ b/libc/kernel/uapi/linux/uio.h
@@ -21,7 +21,7 @@
#include <linux/compiler.h>
#include <linux/types.h>
struct iovec {
- void __user * iov_base;
+ void * iov_base;
__kernel_size_t iov_len;
};
#define UIO_FASTIOV 8
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 49eb5fa..9ddc640 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -417,6 +417,16 @@
__u8 ContainerID[16];
} __attribute__((packed));
#define USB_DT_USB_SS_CONTN_ID_SIZE 20
+#define USB_PLAT_DEV_CAP_TYPE 5
+struct usb_plat_dev_cap_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDevCapabilityType;
+ __u8 bReserved;
+ __u8 UUID[16];
+ __u8 CapabilityData[];
+} __attribute__((packed));
+#define USB_DT_USB_PLAT_DEV_CAP_SIZE(capability_data_size) (20 + capability_data_size)
#define USB_SSP_CAP_TYPE 0xa
struct usb_ssp_cap_descriptor {
__u8 bLength;
diff --git a/libc/kernel/uapi/linux/usb/tmc.h b/libc/kernel/uapi/linux/usb/tmc.h
index 6d0add1..b267290 100644
--- a/libc/kernel/uapi/linux/usb/tmc.h
+++ b/libc/kernel/uapi/linux/usb/tmc.h
@@ -46,7 +46,7 @@
} __attribute__((packed));
struct usbtmc_ctrlrequest {
struct usbtmc_request req;
- void __user * data;
+ void * data;
} __attribute__((packed));
struct usbtmc_termchar {
__u8 term_char;
@@ -59,7 +59,7 @@
__u32 transfer_size;
__u32 transferred;
__u32 flags;
- void __user * message;
+ void * message;
} __attribute__((packed));
#define USBTMC_IOC_NR 91
#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1)
diff --git a/libc/kernel/uapi/linux/usb/video.h b/libc/kernel/uapi/linux/usb/video.h
index c3d360a..0ceabe7 100644
--- a/libc/kernel/uapi/linux/usb/video.h
+++ b/libc/kernel/uapi/linux/usb/video.h
@@ -139,6 +139,32 @@
#define UVC_CONTROL_CAP_DISABLED (1 << 2)
#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
+enum uvc_color_primaries_values {
+ UVC_COLOR_PRIMARIES_UNSPECIFIED,
+ UVC_COLOR_PRIMARIES_BT_709_SRGB,
+ UVC_COLOR_PRIMARIES_BT_470_2_M,
+ UVC_COLOR_PRIMARIES_BT_470_2_B_G,
+ UVC_COLOR_PRIMARIES_SMPTE_170M,
+ UVC_COLOR_PRIMARIES_SMPTE_240M,
+};
+enum uvc_transfer_characteristics_values {
+ UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED,
+ UVC_TRANSFER_CHARACTERISTICS_BT_709,
+ UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M,
+ UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G,
+ UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M,
+ UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M,
+ UVC_TRANSFER_CHARACTERISTICS_LINEAR,
+ UVC_TRANSFER_CHARACTERISTICS_SRGB,
+};
+enum uvc_matrix_coefficients {
+ UVC_MATRIX_COEFFICIENTS_UNSPECIFIED,
+ UVC_MATRIX_COEFFICIENTS_BT_709,
+ UVC_MATRIX_COEFFICIENTS_FCC,
+ UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G,
+ UVC_MATRIX_COEFFICIENTS_SMPTE_170M,
+ UVC_MATRIX_COEFFICIENTS_SMPTE_240M,
+};
struct uvc_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 5fef522..af8681b 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -27,13 +27,13 @@
__u16 wIndex;
__u16 wLength;
__u32 timeout;
- void __user * data;
+ void * data;
};
struct usbdevfs_bulktransfer {
unsigned int ep;
unsigned int len;
unsigned int timeout;
- void __user * data;
+ void * data;
};
struct usbdevfs_setinterface {
unsigned int interface;
@@ -41,7 +41,7 @@
};
struct usbdevfs_disconnectsignal {
unsigned int signr;
- void __user * context;
+ void * context;
};
#define USBDEVFS_MAXDRIVERNAME 255
struct usbdevfs_getdriver {
@@ -80,7 +80,7 @@
unsigned char endpoint;
int status;
unsigned int flags;
- void __user * buffer;
+ void * buffer;
int buffer_length;
int actual_length;
int start_frame;
@@ -90,13 +90,13 @@
};
int error_count;
unsigned int signr;
- void __user * usercontext;
+ void * usercontext;
struct usbdevfs_iso_packet_desc iso_frame_desc[];
};
struct usbdevfs_ioctl {
int ifno;
int ioctl_code;
- void __user * data;
+ void * data;
};
struct usbdevfs_hub_portinfo {
char nports;
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index d0f82c1..1505137 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -21,11 +21,9 @@
#include <linux/types.h>
typedef struct {
__u8 b[16];
-} guid_t;
-#define GUID_INIT(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((guid_t) \
+} uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((uuid_le) \
{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-typedef guid_t uuid_le;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
#endif
diff --git a/libc/kernel/uapi/linux/uvcvideo.h b/libc/kernel/uapi/linux/uvcvideo.h
index 46528a9..b63858f 100644
--- a/libc/kernel/uapi/linux/uvcvideo.h
+++ b/libc/kernel/uapi/linux/uvcvideo.h
@@ -36,9 +36,10 @@
#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7)
#define UVC_CTRL_FLAG_ASYNCHRONOUS (1 << 8)
#define UVC_CTRL_FLAG_GET_RANGE (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF)
+#define UVC_MENU_NAME_LEN 32
struct uvc_menu_info {
__u32 value;
- __u8 name[32];
+ __u8 name[UVC_MENU_NAME_LEN];
};
struct uvc_xu_control_mapping {
__u32 id;
@@ -49,7 +50,7 @@
__u8 offset;
__u32 v4l2_type;
__u32 data_type;
- struct uvc_menu_info __user * menu_info;
+ struct uvc_menu_info * menu_info;
__u32 menu_count;
__u32 reserved[4];
};
@@ -58,7 +59,7 @@
__u8 selector;
__u8 query;
__u16 size;
- __u8 __user * data;
+ __u8 * data;
};
#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping)
#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 2954dc3..8b2c1bd 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef __LINUX_V4L2_SUBDEV_H
#define __LINUX_V4L2_SUBDEV_H
+#include <linux/const.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/v4l2-common.h>
@@ -30,13 +31,15 @@
__u32 which;
__u32 pad;
struct v4l2_mbus_framefmt format;
- __u32 reserved[8];
+ __u32 stream;
+ __u32 reserved[7];
};
struct v4l2_subdev_crop {
__u32 which;
__u32 pad;
struct v4l2_rect rect;
- __u32 reserved[8];
+ __u32 stream;
+ __u32 reserved[7];
};
#define V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE 0x00000001
#define V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC 0x00000002
@@ -49,7 +52,8 @@
__u32 code;
__u32 which;
__u32 flags;
- __u32 reserved[7];
+ __u32 stream;
+ __u32 reserved[6];
};
struct v4l2_subdev_frame_size_enum {
__u32 index;
@@ -60,12 +64,14 @@
__u32 min_height;
__u32 max_height;
__u32 which;
- __u32 reserved[8];
+ __u32 stream;
+ __u32 reserved[7];
};
struct v4l2_subdev_frame_interval {
__u32 pad;
struct v4l2_fract interval;
- __u32 reserved[9];
+ __u32 stream;
+ __u32 reserved[8];
};
struct v4l2_subdev_frame_interval_enum {
__u32 index;
@@ -75,7 +81,8 @@
__u32 height;
struct v4l2_fract interval;
__u32 which;
- __u32 reserved[8];
+ __u32 stream;
+ __u32 reserved[7];
};
struct v4l2_subdev_selection {
__u32 which;
@@ -83,7 +90,8 @@
__u32 target;
__u32 flags;
struct v4l2_rect r;
- __u32 reserved[8];
+ __u32 stream;
+ __u32 reserved[7];
};
struct v4l2_subdev_capability {
__u32 version;
@@ -91,6 +99,22 @@
__u32 reserved[14];
};
#define V4L2_SUBDEV_CAP_RO_SUBDEV 0x00000001
+#define V4L2_SUBDEV_CAP_STREAMS 0x00000002
+#define V4L2_SUBDEV_ROUTE_FL_ACTIVE (1U << 0)
+struct v4l2_subdev_route {
+ __u32 sink_pad;
+ __u32 sink_stream;
+ __u32 source_pad;
+ __u32 source_stream;
+ __u32 flags;
+ __u32 reserved[5];
+};
+struct v4l2_subdev_routing {
+ __u32 which;
+ __u32 num_routes;
+ __u64 routes;
+ __u32 reserved[6];
+};
#define v4l2_subdev_edid v4l2_edid
#define VIDIOC_SUBDEV_QUERYCAP _IOR('V', 0, struct v4l2_subdev_capability)
#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
@@ -104,6 +128,8 @@
#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
#define VIDIOC_SUBDEV_G_SELECTION _IOWR('V', 61, struct v4l2_subdev_selection)
#define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection)
+#define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing)
#define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id)
#define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id)
#define VIDIOC_SUBDEV_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 0d50613..9d48e3d 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 393728
+#define LINUX_VERSION_CODE 393984
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
#define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 2
+#define LINUX_VERSION_PATCHLEVEL 3
#define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 7dc3440..3c1821c 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -390,7 +390,7 @@
struct vfio_bitmap {
__u64 pgsize;
__u64 size;
- __u64 __user * data;
+ __u64 * data;
};
struct vfio_iommu_type1_dma_unmap {
__u32 argsz;
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index e5b1327..5138f0c 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -69,4 +69,5 @@
#define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, struct vhost_vring_state)
#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, struct vhost_vring_state)
#define VHOST_VDPA_SUSPEND _IO(VHOST_VIRTIO, 0x7D)
+#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
#endif
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
index 32efa85..1669c28 100644
--- a/libc/kernel/uapi/linux/vhost_types.h
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -106,4 +106,5 @@
#define VHOST_BACKEND_F_IOTLB_BATCH 0x2
#define VHOST_BACKEND_F_IOTLB_ASID 0x3
#define VHOST_BACKEND_F_SUSPEND 0x4
+#define VHOST_BACKEND_F_RESUME 0x5
#endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index d418fd2..95c2d94 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -244,6 +244,9 @@
#define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4')
#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4')
#define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4')
+#define V4L2_PIX_FMT_RGBX1010102 v4l2_fourcc('R', 'X', '3', '0')
+#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_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
@@ -275,6 +278,9 @@
#define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A')
#define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X')
#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
+#define V4L2_PIX_FMT_Y210 v4l2_fourcc('Y', '2', '1', '0')
+#define V4L2_PIX_FMT_Y212 v4l2_fourcc('Y', '2', '1', '2')
+#define V4L2_PIX_FMT_Y216 v4l2_fourcc('Y', '2', '1', '6')
#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2')
#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1')
#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6')
@@ -650,7 +656,7 @@
#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
struct v4l2_clip {
struct v4l2_rect c;
- struct v4l2_clip __user * next;
+ struct v4l2_clip * next;
};
struct v4l2_window {
struct v4l2_rect w;
@@ -658,7 +664,7 @@
__u32 chromakey;
struct v4l2_clip * clips;
__u32 clipcount;
- void __user * bitmap;
+ void * bitmap;
__u8 global_alpha;
};
struct v4l2_captureparm {
@@ -895,32 +901,32 @@
union {
__s32 value;
__s64 value64;
- char __user * string;
- __u8 __user * p_u8;
- __u16 __user * p_u16;
- __u32 __user * p_u32;
- __u32 __user * p_s32;
- __u32 __user * p_s64;
- struct v4l2_area __user * p_area;
- struct v4l2_ctrl_h264_sps __user * p_h264_sps;
+ char * string;
+ __u8 * p_u8;
+ __u16 * p_u16;
+ __u32 * p_u32;
+ __u32 * p_s32;
+ __u32 * p_s64;
+ struct v4l2_area * p_area;
+ struct v4l2_ctrl_h264_sps * p_h264_sps;
struct v4l2_ctrl_h264_pps * p_h264_pps;
- struct v4l2_ctrl_h264_scaling_matrix __user * p_h264_scaling_matrix;
- struct v4l2_ctrl_h264_pred_weights __user * p_h264_pred_weights;
- struct v4l2_ctrl_h264_slice_params __user * p_h264_slice_params;
- struct v4l2_ctrl_h264_decode_params __user * p_h264_decode_params;
- struct v4l2_ctrl_fwht_params __user * p_fwht_params;
- struct v4l2_ctrl_vp8_frame __user * p_vp8_frame;
- struct v4l2_ctrl_mpeg2_sequence __user * p_mpeg2_sequence;
- struct v4l2_ctrl_mpeg2_picture __user * p_mpeg2_picture;
- struct v4l2_ctrl_mpeg2_quantisation __user * p_mpeg2_quantisation;
- struct v4l2_ctrl_vp9_compressed_hdr __user * p_vp9_compressed_hdr_probs;
- struct v4l2_ctrl_vp9_frame __user * p_vp9_frame;
- struct v4l2_ctrl_hevc_sps __user * p_hevc_sps;
- struct v4l2_ctrl_hevc_pps __user * p_hevc_pps;
- struct v4l2_ctrl_hevc_slice_params __user * p_hevc_slice_params;
- struct v4l2_ctrl_hevc_scaling_matrix __user * p_hevc_scaling_matrix;
- struct v4l2_ctrl_hevc_decode_params __user * p_hevc_decode_params;
- void __user * ptr;
+ struct v4l2_ctrl_h264_scaling_matrix * p_h264_scaling_matrix;
+ struct v4l2_ctrl_h264_pred_weights * p_h264_pred_weights;
+ struct v4l2_ctrl_h264_slice_params * p_h264_slice_params;
+ struct v4l2_ctrl_h264_decode_params * p_h264_decode_params;
+ struct v4l2_ctrl_fwht_params * p_fwht_params;
+ struct v4l2_ctrl_vp8_frame * p_vp8_frame;
+ struct v4l2_ctrl_mpeg2_sequence * p_mpeg2_sequence;
+ struct v4l2_ctrl_mpeg2_picture * p_mpeg2_picture;
+ struct v4l2_ctrl_mpeg2_quantisation * p_mpeg2_quantisation;
+ struct v4l2_ctrl_vp9_compressed_hdr * p_vp9_compressed_hdr_probs;
+ struct v4l2_ctrl_vp9_frame * p_vp9_frame;
+ struct v4l2_ctrl_hevc_sps * p_hevc_sps;
+ struct v4l2_ctrl_hevc_pps * p_hevc_pps;
+ struct v4l2_ctrl_hevc_slice_params * p_hevc_slice_params;
+ struct v4l2_ctrl_hevc_scaling_matrix * p_hevc_scaling_matrix;
+ struct v4l2_ctrl_hevc_decode_params * p_hevc_decode_params;
+ void * ptr;
};
} __attribute__((packed));
struct v4l2_ext_controls {
diff --git a/libc/kernel/uapi/linux/virtio_blk.h b/libc/kernel/uapi/linux/virtio_blk.h
index 0dd08c5..1b7c7e9 100644
--- a/libc/kernel/uapi/linux/virtio_blk.h
+++ b/libc/kernel/uapi/linux/virtio_blk.h
@@ -32,6 +32,7 @@
#define VIRTIO_BLK_F_DISCARD 13
#define VIRTIO_BLK_F_WRITE_ZEROES 14
#define VIRTIO_BLK_F_SECURE_ERASE 16
+#define VIRTIO_BLK_F_ZONED 17
#ifndef VIRTIO_BLK_NO_LEGACY
#define VIRTIO_BLK_F_BARRIER 0
#define VIRTIO_BLK_F_SCSI 7
@@ -67,6 +68,15 @@
__virtio32 max_secure_erase_sectors;
__virtio32 max_secure_erase_seg;
__virtio32 secure_erase_sector_alignment;
+ struct virtio_blk_zoned_characteristics {
+ __virtio32 zone_sectors;
+ __virtio32 max_open_zones;
+ __virtio32 max_active_zones;
+ __virtio32 max_append_sectors;
+ __virtio32 write_granularity;
+ __u8 model;
+ __u8 unused2[3];
+ } zoned;
} __attribute__((packed));
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1
@@ -78,6 +88,13 @@
#define VIRTIO_BLK_T_DISCARD 11
#define VIRTIO_BLK_T_WRITE_ZEROES 13
#define VIRTIO_BLK_T_SECURE_ERASE 14
+#define VIRTIO_BLK_T_ZONE_APPEND 15
+#define VIRTIO_BLK_T_ZONE_REPORT 16
+#define VIRTIO_BLK_T_ZONE_OPEN 18
+#define VIRTIO_BLK_T_ZONE_CLOSE 20
+#define VIRTIO_BLK_T_ZONE_FINISH 22
+#define VIRTIO_BLK_T_ZONE_RESET 24
+#define VIRTIO_BLK_T_ZONE_RESET_ALL 26
#ifndef VIRTIO_BLK_NO_LEGACY
#define VIRTIO_BLK_T_BARRIER 0x80000000
#endif
@@ -86,6 +103,33 @@
__virtio32 ioprio;
__virtio64 sector;
};
+#define VIRTIO_BLK_Z_NONE 0
+#define VIRTIO_BLK_Z_HM 1
+#define VIRTIO_BLK_Z_HA 2
+struct virtio_blk_zone_descriptor {
+ __virtio64 z_cap;
+ __virtio64 z_start;
+ __virtio64 z_wp;
+ __u8 z_type;
+ __u8 z_state;
+ __u8 reserved[38];
+};
+struct virtio_blk_zone_report {
+ __virtio64 nr_zones;
+ __u8 reserved[56];
+ struct virtio_blk_zone_descriptor zones[];
+};
+#define VIRTIO_BLK_ZT_CONV 1
+#define VIRTIO_BLK_ZT_SWR 2
+#define VIRTIO_BLK_ZT_SWP 3
+#define VIRTIO_BLK_ZS_NOT_WP 0
+#define VIRTIO_BLK_ZS_EMPTY 1
+#define VIRTIO_BLK_ZS_IOPEN 2
+#define VIRTIO_BLK_ZS_EOPEN 3
+#define VIRTIO_BLK_ZS_CLOSED 4
+#define VIRTIO_BLK_ZS_RDONLY 13
+#define VIRTIO_BLK_ZS_FULL 14
+#define VIRTIO_BLK_ZS_OFFLINE 15
#define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001
struct virtio_blk_discard_write_zeroes {
__le64 sector;
@@ -103,4 +147,8 @@
#define VIRTIO_BLK_S_OK 0
#define VIRTIO_BLK_S_IOERR 1
#define VIRTIO_BLK_S_UNSUPP 2
+#define VIRTIO_BLK_S_ZONE_INVALID_CMD 3
+#define VIRTIO_BLK_S_ZONE_UNALIGNED_WP 4
+#define VIRTIO_BLK_S_ZONE_OPEN_RESOURCE 5
+#define VIRTIO_BLK_S_ZONE_ACTIVE_RESOURCE 6
#endif
diff --git a/libc/kernel/uapi/linux/wireless.h b/libc/kernel/uapi/linux/wireless.h
index ca31dd2..eb57fff 100644
--- a/libc/kernel/uapi/linux/wireless.h
+++ b/libc/kernel/uapi/linux/wireless.h
@@ -264,7 +264,7 @@
__u16 flags;
};
struct iw_point {
- void __user * pointer;
+ void * pointer;
__u16 length;
__u16 flags;
};
diff --git a/libc/kernel/uapi/mtd/mtd-abi.h b/libc/kernel/uapi/mtd/mtd-abi.h
index 6e26cae..aed2acc 100644
--- a/libc/kernel/uapi/mtd/mtd-abi.h
+++ b/libc/kernel/uapi/mtd/mtd-abi.h
@@ -30,7 +30,7 @@
struct mtd_oob_buf {
__u32 start;
__u32 length;
- unsigned char __user * ptr;
+ unsigned char * ptr;
};
struct mtd_oob_buf64 {
__u64 start;
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index 0407571..f778ef2 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -62,9 +62,13 @@
};
enum {
HNS_ROCE_EXSGE_FLAGS = 1 << 0,
+ HNS_ROCE_RQ_INLINE_FLAGS = 1 << 1,
+ HNS_ROCE_CQE_INLINE_FLAGS = 1 << 2,
};
enum {
HNS_ROCE_RSP_EXSGE_FLAGS = 1 << 0,
+ HNS_ROCE_RSP_RQ_INLINE_FLAGS = 1 << 1,
+ HNS_ROCE_RSP_CQE_INLINE_FLAGS = 1 << 2,
};
struct hns_roce_ib_alloc_ucontext_resp {
__u32 qp_tab_size;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_fc.h b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
index 2647249..3836282 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_fc.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
@@ -69,7 +69,7 @@
__u32 vendor_cmd[];
};
struct fc_bsg_host_vendor_reply {
- __u32 vendor_rsp[0];
+ __DECLARE_FLEX_ARRAY(__u32, vendor_rsp);
};
struct fc_bsg_rport_els {
__u8 els_code;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
index fcba8cd..48e88d3 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -220,9 +220,6 @@
struct mpi3mr_bsg_mptcmd mptcmd;
} cmd;
};
-#ifndef MPI3_NVME_ENCAP_CMD_MAX
-#define MPI3_NVME_ENCAP_CMD_MAX (1)
-#endif
struct mpi3_nvme_encapsulated_request {
__le16 host_tag;
__u8 ioc_use_only02;
@@ -236,7 +233,7 @@
__le16 flags;
__le32 data_length;
__le32 reserved14[3];
- __le32 command[MPI3_NVME_ENCAP_CMD_MAX];
+ __le32 command[];
};
struct mpi3_nvme_encapsulated_error_reply {
__le16 host_tag;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
index ae5c757..036243e 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
@@ -20,8 +20,22 @@
#define SCSI_BSG_UFS_H
#include <linux/types.h>
#define UFS_CDB_SIZE 16
-#define UPIU_TRANSACTION_UIC_CMD 0x1F
#define UIC_CMD_SIZE (sizeof(__u32) * 4)
+enum ufs_bsg_msg_code {
+ UPIU_TRANSACTION_UIC_CMD = 0x1F,
+ UPIU_TRANSACTION_ARPMB_CMD,
+};
+enum ufs_rpmb_op_type {
+ UFS_RPMB_WRITE_KEY = 0x01,
+ UFS_RPMB_READ_CNT = 0x02,
+ UFS_RPMB_WRITE = 0x03,
+ UFS_RPMB_READ = 0x04,
+ UFS_RPMB_READ_RESP = 0x05,
+ UFS_RPMB_SEC_CONF_WRITE = 0x06,
+ UFS_RPMB_SEC_CONF_READ = 0x07,
+ UFS_RPMB_PURGE_ENABLE = 0x08,
+ UFS_RPMB_PURGE_STATUS_READ = 0x09,
+};
struct utp_upiu_header {
__be32 dword_0;
__be32 dword_1;
@@ -49,13 +63,36 @@
struct utp_upiu_query uc;
};
};
+struct ufs_arpmb_meta {
+ __be16 req_resp_type;
+ __u8 nonce[16];
+ __be32 write_counter;
+ __be16 addr_lun;
+ __be16 block_count;
+ __be16 result;
+} __attribute__((__packed__));
+struct ufs_ehs {
+ __u8 length;
+ __u8 ehs_type;
+ __be16 ehssub_type;
+ struct ufs_arpmb_meta meta;
+ __u8 mac_key[32];
+} __attribute__((__packed__));
struct ufs_bsg_request {
__u32 msgcode;
struct utp_upiu_req upiu_req;
};
struct ufs_bsg_reply {
- __u32 result;
+ int result;
__u32 reply_payload_rcv_len;
struct utp_upiu_req upiu_rsp;
};
+struct ufs_rpmb_request {
+ struct ufs_bsg_request bsg_request;
+ struct ufs_ehs ehs_req;
+};
+struct ufs_rpmb_reply {
+ struct ufs_bsg_reply bsg_reply;
+ struct ufs_ehs ehs_rsp;
+};
#endif
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index 0076933..01a5058 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -209,9 +209,9 @@
#define SNDRV_SEQ_CLIENT_DUMMY 14
#define SNDRV_SEQ_CLIENT_OSS 15
typedef int __bitwise snd_seq_client_type_t;
-#define NO_CLIENT ((__force snd_seq_client_type_t) 0)
-#define USER_CLIENT ((__force snd_seq_client_type_t) 1)
-#define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2)
+#define NO_CLIENT (( snd_seq_client_type_t) 0)
+#define USER_CLIENT (( snd_seq_client_type_t) 1)
+#define KERNEL_CLIENT (( snd_seq_client_type_t) 2)
#define SNDRV_SEQ_FILTER_BROADCAST (1U << 0)
#define SNDRV_SEQ_FILTER_MULTICAST (1U << 1)
#define SNDRV_SEQ_FILTER_BOUNCE (1U << 2)
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 6e325e9..9c1a3ae 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -96,7 +96,7 @@
struct snd_hwdep_dsp_image {
unsigned int index;
unsigned char name[64];
- unsigned char __user * image;
+ unsigned char * image;
size_t length;
unsigned long driver_data;
};
@@ -125,64 +125,64 @@
SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
};
typedef int __bitwise snd_pcm_access_t;
-#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0)
-#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1)
-#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2)
-#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3)
-#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4)
+#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED (( snd_pcm_access_t) 0)
+#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED (( snd_pcm_access_t) 1)
+#define SNDRV_PCM_ACCESS_MMAP_COMPLEX (( snd_pcm_access_t) 2)
+#define SNDRV_PCM_ACCESS_RW_INTERLEAVED (( snd_pcm_access_t) 3)
+#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED (( snd_pcm_access_t) 4)
#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
typedef int __bitwise snd_pcm_format_t;
-#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0)
-#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1)
-#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2)
-#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3)
-#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4)
-#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5)
-#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6)
-#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7)
-#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8)
-#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9)
-#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10)
-#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11)
-#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12)
-#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13)
-#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14)
-#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15)
-#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16)
-#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17)
-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18)
-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19)
-#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20)
-#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21)
-#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
-#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
-#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
-#define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25)
-#define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26)
-#define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27)
-#define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28)
-#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
-#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32)
-#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33)
-#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34)
-#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35)
-#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36)
-#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37)
-#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38)
-#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39)
-#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40)
-#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41)
-#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42)
-#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43)
-#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44)
-#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45)
-#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46)
-#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47)
-#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48)
-#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49)
-#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50)
-#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51)
-#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52)
+#define SNDRV_PCM_FORMAT_S8 (( snd_pcm_format_t) 0)
+#define SNDRV_PCM_FORMAT_U8 (( snd_pcm_format_t) 1)
+#define SNDRV_PCM_FORMAT_S16_LE (( snd_pcm_format_t) 2)
+#define SNDRV_PCM_FORMAT_S16_BE (( snd_pcm_format_t) 3)
+#define SNDRV_PCM_FORMAT_U16_LE (( snd_pcm_format_t) 4)
+#define SNDRV_PCM_FORMAT_U16_BE (( snd_pcm_format_t) 5)
+#define SNDRV_PCM_FORMAT_S24_LE (( snd_pcm_format_t) 6)
+#define SNDRV_PCM_FORMAT_S24_BE (( snd_pcm_format_t) 7)
+#define SNDRV_PCM_FORMAT_U24_LE (( snd_pcm_format_t) 8)
+#define SNDRV_PCM_FORMAT_U24_BE (( snd_pcm_format_t) 9)
+#define SNDRV_PCM_FORMAT_S32_LE (( snd_pcm_format_t) 10)
+#define SNDRV_PCM_FORMAT_S32_BE (( snd_pcm_format_t) 11)
+#define SNDRV_PCM_FORMAT_U32_LE (( snd_pcm_format_t) 12)
+#define SNDRV_PCM_FORMAT_U32_BE (( snd_pcm_format_t) 13)
+#define SNDRV_PCM_FORMAT_FLOAT_LE (( snd_pcm_format_t) 14)
+#define SNDRV_PCM_FORMAT_FLOAT_BE (( snd_pcm_format_t) 15)
+#define SNDRV_PCM_FORMAT_FLOAT64_LE (( snd_pcm_format_t) 16)
+#define SNDRV_PCM_FORMAT_FLOAT64_BE (( snd_pcm_format_t) 17)
+#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE (( snd_pcm_format_t) 18)
+#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE (( snd_pcm_format_t) 19)
+#define SNDRV_PCM_FORMAT_MU_LAW (( snd_pcm_format_t) 20)
+#define SNDRV_PCM_FORMAT_A_LAW (( snd_pcm_format_t) 21)
+#define SNDRV_PCM_FORMAT_IMA_ADPCM (( snd_pcm_format_t) 22)
+#define SNDRV_PCM_FORMAT_MPEG (( snd_pcm_format_t) 23)
+#define SNDRV_PCM_FORMAT_GSM (( snd_pcm_format_t) 24)
+#define SNDRV_PCM_FORMAT_S20_LE (( snd_pcm_format_t) 25)
+#define SNDRV_PCM_FORMAT_S20_BE (( snd_pcm_format_t) 26)
+#define SNDRV_PCM_FORMAT_U20_LE (( snd_pcm_format_t) 27)
+#define SNDRV_PCM_FORMAT_U20_BE (( snd_pcm_format_t) 28)
+#define SNDRV_PCM_FORMAT_SPECIAL (( snd_pcm_format_t) 31)
+#define SNDRV_PCM_FORMAT_S24_3LE (( snd_pcm_format_t) 32)
+#define SNDRV_PCM_FORMAT_S24_3BE (( snd_pcm_format_t) 33)
+#define SNDRV_PCM_FORMAT_U24_3LE (( snd_pcm_format_t) 34)
+#define SNDRV_PCM_FORMAT_U24_3BE (( snd_pcm_format_t) 35)
+#define SNDRV_PCM_FORMAT_S20_3LE (( snd_pcm_format_t) 36)
+#define SNDRV_PCM_FORMAT_S20_3BE (( snd_pcm_format_t) 37)
+#define SNDRV_PCM_FORMAT_U20_3LE (( snd_pcm_format_t) 38)
+#define SNDRV_PCM_FORMAT_U20_3BE (( snd_pcm_format_t) 39)
+#define SNDRV_PCM_FORMAT_S18_3LE (( snd_pcm_format_t) 40)
+#define SNDRV_PCM_FORMAT_S18_3BE (( snd_pcm_format_t) 41)
+#define SNDRV_PCM_FORMAT_U18_3LE (( snd_pcm_format_t) 42)
+#define SNDRV_PCM_FORMAT_U18_3BE (( snd_pcm_format_t) 43)
+#define SNDRV_PCM_FORMAT_G723_24 (( snd_pcm_format_t) 44)
+#define SNDRV_PCM_FORMAT_G723_24_1B (( snd_pcm_format_t) 45)
+#define SNDRV_PCM_FORMAT_G723_40 (( snd_pcm_format_t) 46)
+#define SNDRV_PCM_FORMAT_G723_40_1B (( snd_pcm_format_t) 47)
+#define SNDRV_PCM_FORMAT_DSD_U8 (( snd_pcm_format_t) 48)
+#define SNDRV_PCM_FORMAT_DSD_U16_LE (( snd_pcm_format_t) 49)
+#define SNDRV_PCM_FORMAT_DSD_U32_LE (( snd_pcm_format_t) 50)
+#define SNDRV_PCM_FORMAT_DSD_U16_BE (( snd_pcm_format_t) 51)
+#define SNDRV_PCM_FORMAT_DSD_U32_BE (( snd_pcm_format_t) 52)
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE
#define SNDRV_PCM_FORMAT_FIRST SNDRV_PCM_FORMAT_S8
#ifdef SNDRV_LITTLE_ENDIAN
@@ -212,7 +212,7 @@
#define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_BE
#endif
typedef int __bitwise snd_pcm_subformat_t;
-#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
+#define SNDRV_PCM_SUBFORMAT_STD (( snd_pcm_subformat_t) 0)
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
#define SNDRV_PCM_INFO_MMAP 0x00000001
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
@@ -243,15 +243,15 @@
#define __SND_STRUCT_TIME64
#endif
typedef int __bitwise snd_pcm_state_t;
-#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
-#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
-#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2)
-#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
-#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4)
-#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5)
-#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6)
-#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
-#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8)
+#define SNDRV_PCM_STATE_OPEN (( snd_pcm_state_t) 0)
+#define SNDRV_PCM_STATE_SETUP (( snd_pcm_state_t) 1)
+#define SNDRV_PCM_STATE_PREPARED (( snd_pcm_state_t) 2)
+#define SNDRV_PCM_STATE_RUNNING (( snd_pcm_state_t) 3)
+#define SNDRV_PCM_STATE_XRUN (( snd_pcm_state_t) 4)
+#define SNDRV_PCM_STATE_DRAINING (( snd_pcm_state_t) 5)
+#define SNDRV_PCM_STATE_PAUSED (( snd_pcm_state_t) 6)
+#define SNDRV_PCM_STATE_SUSPENDED (( snd_pcm_state_t) 7)
+#define SNDRV_PCM_STATE_DISCONNECTED (( snd_pcm_state_t) 8)
#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
enum {
SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
@@ -475,12 +475,12 @@
};
struct snd_xferi {
snd_pcm_sframes_t result;
- void __user * buf;
+ void * buf;
snd_pcm_uframes_t frames;
};
struct snd_xfern {
snd_pcm_sframes_t result;
- void __user * __user * bufs;
+ void * * bufs;
snd_pcm_uframes_t frames;
};
enum {
@@ -776,22 +776,22 @@
unsigned char components[128];
};
typedef int __bitwise snd_ctl_elem_type_t;
-#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0)
-#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
-#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3)
-#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4)
-#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
+#define SNDRV_CTL_ELEM_TYPE_NONE (( snd_ctl_elem_type_t) 0)
+#define SNDRV_CTL_ELEM_TYPE_BOOLEAN (( snd_ctl_elem_type_t) 1)
+#define SNDRV_CTL_ELEM_TYPE_INTEGER (( snd_ctl_elem_type_t) 2)
+#define SNDRV_CTL_ELEM_TYPE_ENUMERATED (( snd_ctl_elem_type_t) 3)
+#define SNDRV_CTL_ELEM_TYPE_BYTES (( snd_ctl_elem_type_t) 4)
+#define SNDRV_CTL_ELEM_TYPE_IEC958 (( snd_ctl_elem_type_t) 5)
+#define SNDRV_CTL_ELEM_TYPE_INTEGER64 (( snd_ctl_elem_type_t) 6)
#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
typedef int __bitwise snd_ctl_elem_iface_t;
-#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0)
-#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
-#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2)
-#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3)
-#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4)
-#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
-#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6)
+#define SNDRV_CTL_ELEM_IFACE_CARD (( snd_ctl_elem_iface_t) 0)
+#define SNDRV_CTL_ELEM_IFACE_HWDEP (( snd_ctl_elem_iface_t) 1)
+#define SNDRV_CTL_ELEM_IFACE_MIXER (( snd_ctl_elem_iface_t) 2)
+#define SNDRV_CTL_ELEM_IFACE_PCM (( snd_ctl_elem_iface_t) 3)
+#define SNDRV_CTL_ELEM_IFACE_RAWMIDI (( snd_ctl_elem_iface_t) 4)
+#define SNDRV_CTL_ELEM_IFACE_TIMER (( snd_ctl_elem_iface_t) 5)
+#define SNDRV_CTL_ELEM_IFACE_SEQUENCER (( snd_ctl_elem_iface_t) 6)
#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
#define SNDRV_CTL_ELEM_ACCESS_READ (1 << 0)
#define SNDRV_CTL_ELEM_ACCESS_WRITE (1 << 1)
@@ -826,7 +826,7 @@
unsigned int space;
unsigned int used;
unsigned int count;
- struct snd_ctl_elem_id __user * pids;
+ struct snd_ctl_elem_id * pids;
unsigned char reserved[50];
};
struct snd_ctl_elem_info {
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index d26d722..cc13cb9 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -27,6 +27,7 @@
#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
#define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL 0x7473636d
#define SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE 0x4d545244
+#define SNDRV_FIREWIRE_EVENT_FF400_MESSAGE 0x4f6c6761
struct snd_firewire_event_common {
unsigned int type;
};
@@ -74,6 +75,14 @@
__u32 count;
__u32 changes[];
};
+struct snd_firewire_event_ff400_message {
+ unsigned int type;
+ unsigned int message_count;
+ struct {
+ __u32 message;
+ __u32 tstamp;
+ } messages[];
+};
union snd_firewire_event {
struct snd_firewire_event_common common;
struct snd_firewire_event_lock_status lock_status;
@@ -83,6 +92,7 @@
struct snd_firewire_event_tascam_control tascam_control;
struct snd_firewire_event_motu_notification motu_notification;
struct snd_firewire_event_motu_register_dsp_change motu_register_dsp_change;
+ struct snd_firewire_event_ff400_message ff400_message;
};
#define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
#define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
diff --git a/libc/kernel/uapi/sound/intel/avs/tokens.h b/libc/kernel/uapi/sound/intel/avs/tokens.h
index b6b3002..d524278 100644
--- a/libc/kernel/uapi/sound/intel/avs/tokens.h
+++ b/libc/kernel/uapi/sound/intel/avs/tokens.h
@@ -100,6 +100,7 @@
AVS_TKN_MOD_CORE_ID_U8 = 1704,
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
+ AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
AVS_TKN_PATH_ID_U32 = 1901,
AVS_TKN_PATH_FE_FMT_ID_U32 = 1902,
@@ -107,5 +108,6 @@
AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
+ AVS_TKN_KCONTROL_ID_U32 = 2301,
};
#endif
diff --git a/libc/kernel/uapi/xen/gntdev.h b/libc/kernel/uapi/xen/gntdev.h
index 1e78ac3..eada73c 100644
--- a/libc/kernel/uapi/xen/gntdev.h
+++ b/libc/kernel/uapi/xen/gntdev.h
@@ -55,7 +55,7 @@
};
struct gntdev_grant_copy_segment {
union {
- void __user * virt;
+ void * virt;
struct {
grant_ref_t ref;
__u16 offset;
@@ -69,7 +69,7 @@
#define IOCTL_GNTDEV_GRANT_COPY _IOC(_IOC_NONE, 'G', 8, sizeof(struct ioctl_gntdev_grant_copy))
struct ioctl_gntdev_grant_copy {
unsigned int count;
- struct gntdev_grant_copy_segment __user * segments;
+ struct gntdev_grant_copy_segment * segments;
};
#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
#define UNMAP_NOTIFY_SEND_EVENT 0x2
diff --git a/libc/kernel/uapi/xen/privcmd.h b/libc/kernel/uapi/xen/privcmd.h
index 145446b..21d9f84 100644
--- a/libc/kernel/uapi/xen/privcmd.h
+++ b/libc/kernel/uapi/xen/privcmd.h
@@ -33,13 +33,13 @@
struct privcmd_mmap {
int num;
domid_t dom;
- struct privcmd_mmap_entry __user * entry;
+ struct privcmd_mmap_entry * entry;
};
struct privcmd_mmapbatch {
int num;
domid_t dom;
__u64 addr;
- xen_pfn_t __user * arr;
+ xen_pfn_t * arr;
};
#define PRIVCMD_MMAPBATCH_MFN_ERROR 0xf0000000U
#define PRIVCMD_MMAPBATCH_PAGED_ERROR 0x80000000U
@@ -47,17 +47,17 @@
unsigned int num;
domid_t dom;
__u64 addr;
- const xen_pfn_t __user * arr;
- int __user * err;
+ const xen_pfn_t * arr;
+ int * err;
};
struct privcmd_dm_op_buf {
- void __user * uptr;
+ void * uptr;
size_t size;
};
struct privcmd_dm_op {
domid_t dom;
__u16 num;
- const struct privcmd_dm_op_buf __user * ubufs;
+ const struct privcmd_dm_op_buf * ubufs;
};
struct privcmd_mmap_resource {
domid_t dom;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4a4e607..0102b30 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1580,8 +1580,15 @@
close_range;
copy_file_range;
memset_explicit;
+ posix_spawn_file_actions_addchdir_np;
+ posix_spawn_file_actions_addfchdir_np;
} LIBC_T;
+LIBC_V { # introduced=VanillaIceCream
+ global:
+ timespec_getres;
+} LIBC_U;
+
LIBC_PRIVATE {
global:
__accept4; # arm x86
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 7b0f599..b06ec9e 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -496,7 +496,7 @@
g_dispatch->free(info);
// Purge the memory that was freed since a significant amount of
// memory could have been allocated and freed.
- g_dispatch->mallopt(M_PURGE, 0);
+ g_dispatch->mallopt(M_PURGE_ALL, 0);
}
size_t debug_malloc_usable_size(void* pointer) {
@@ -1123,7 +1123,7 @@
// Purge the memory that was allocated and freed during this operation
// since it can be large enough to expand the RSS significantly.
- g_dispatch->mallopt(M_PURGE, 0);
+ g_dispatch->mallopt(M_PURGE_ALL, 0);
}
bool debug_write_malloc_leak_info(FILE* fp) {
diff --git a/libc/bionic/timespec_get.cpp b/libc/private/bionic_asm_offsets.h
similarity index 86%
copy from libc/bionic/timespec_get.cpp
copy to libc/private/bionic_asm_offsets.h
index 7fc2182..c2f2b56 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/libc/private/bionic_asm_offsets.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,8 @@
* SUCH DAMAGE.
*/
-#include <time.h>
+#pragma once
-int timespec_get(timespec* ts, int base) {
- return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
-}
+#ifdef __aarch64__
+#define OFFSETOF_libc_globals_memtag_stack 80
+#endif
diff --git a/libc/private/bionic_constants.h b/libc/private/bionic_constants.h
index 09294b6..d7f4474 100644
--- a/libc/private/bionic_constants.h
+++ b/libc/private/bionic_constants.h
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-#ifndef _BIONIC_CONSTANTS_H_
-#define _BIONIC_CONSTANTS_H_
+#pragma once
#define NS_PER_S 1000000000
-// Size of the shadow call stack. This must be a power of 2.
+// Size of the shadow call stack. This can be small because these stacks only
+// contain return addresses. This must be a power of 2 so the mask trick works.
+// See the SCS commentary in pthread_internal.h for more detail.
#define SCS_SIZE (8 * 1024)
+#define SCS_MASK (SCS_SIZE - 1)
// The shadow call stack is allocated at an aligned address within a guard region of this size. The
// guard region must be large enough that we can allocate an SCS_SIZE-aligned SCS while ensuring
// that there is at least one guard page after the SCS so that a stack overflow results in a SIGSEGV
// instead of corrupting the allocation that comes after it.
#define SCS_GUARD_REGION_SIZE (16 * 1024 * 1024)
-
-#endif // _BIONIC_CONSTANTS_H_
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index c375cc4..510d556 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -38,6 +38,7 @@
#include "private/WriteProtected.h"
#include "private/bionic_allocator.h"
+#include "private/bionic_asm_offsets.h"
#include "private/bionic_elf_tls.h"
#include "private/bionic_fdsan.h"
#include "private/bionic_malloc_dispatch.h"
@@ -65,6 +66,10 @@
MallocDispatch malloc_dispatch_table;
};
+#ifdef __aarch64__
+static_assert(OFFSETOF_libc_globals_memtag_stack == offsetof(libc_globals, memtag_stack));
+#endif
+
__LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
struct abort_msg_t;
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 2fc12a0..a5eb636 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -290,17 +290,21 @@
#define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : (struct wchar_io_data*)0)
-#define _SET_ORIENTATION(fp, mode) \
- do { \
- struct wchar_io_data* _wcio = WCIO_GET(fp); \
- if (_wcio && _wcio->wcio_mode == 0) _wcio->wcio_mode = (mode); \
+#define ORIENT_BYTES (-1)
+#define ORIENT_UNKNOWN 0
+#define ORIENT_CHARS 1
+
+#define _SET_ORIENTATION(fp, mode) \
+ do { \
+ struct wchar_io_data* _wcio = WCIO_GET(fp); \
+ if (_wcio && _wcio->wcio_mode == ORIENT_UNKNOWN) _wcio->wcio_mode = (mode); \
} while (0)
#define WCIO_FREE(fp) \
do { \
struct wchar_io_data* _wcio = WCIO_GET(fp); \
if (_wcio) { \
- _wcio->wcio_mode = 0; \
+ _wcio->wcio_mode = ORIENT_UNKNOWN; \
_wcio->wcio_ungetwc_inbuf = 0; \
} \
} while (0)
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
index e761835..365728b 100644
--- a/libc/stdio/printf_common.h
+++ b/libc/stdio/printf_common.h
@@ -528,6 +528,29 @@
case 'b':
ADDUARG();
break;
+ case 'w': {
+ n = 0;
+ bool fast = false;
+ ch = *fmt++;
+ if (ch == 'f') {
+ fast = true;
+ ch = *fmt++;
+ }
+ while (is_digit(ch)) {
+ APPEND_DIGIT(n, ch);
+ ch = *fmt++;
+ }
+ if (n == 64) {
+ flags |= LLONGINT;
+ } else {
+ if (n != 8 && fast) {
+#if defined(__LP64__)
+ flags |= LLONGINT;
+#endif
+ }
+ }
+ goto reswitch;
+ }
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0') goto done;
break;
@@ -813,4 +836,15 @@
return convbuf;
}
+ // Trasnlate a fixed size integer argument for the %w/%wf format to a
+ // flag representation. Supported sizes are 8, 16, 32, and 64 so far.
+ // See details in bionic/libc/include/stdint.h
+ static int w_to_flag(int size, bool fast) {
+ static constexpr int fast_size = sizeof(void*) == 8 ? LLONGINT : 0;
+ if (size == 8) return CHARINT;
+ if (size == 16) return fast ? fast_size : SHORTINT;
+ if (size == 32) return fast ? fast_size : 0;
+ if (size == 64) return LLONGINT;
+ __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
+ }
};
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 645aefa..f18cd81 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -773,7 +773,7 @@
char* fgets_unlocked(char* buf, int n, FILE* fp) {
if (n <= 0) __fortify_fatal("fgets: buffer size %d <= 0", n);
- _SET_ORIENTATION(fp, -1);
+ _SET_ORIENTATION(fp, ORIENT_BYTES);
char* s = buf;
n--; // Leave space for NUL.
@@ -903,7 +903,7 @@
errno = EBADF;
return EOF;
}
- _SET_ORIENTATION(fp, -1);
+ _SET_ORIENTATION(fp, ORIENT_BYTES);
if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && c != '\n')) {
return (*fp->_p++ = c);
}
@@ -1098,7 +1098,7 @@
size_t total = desired_total;
if (total == 0) return 0;
- _SET_ORIENTATION(fp, -1);
+ _SET_ORIENTATION(fp, ORIENT_BYTES);
// TODO: how can this ever happen?!
if (fp->_r < 0) fp->_r = 0;
@@ -1165,7 +1165,7 @@
__siov iov = { .iov_base = const_cast<void*>(buf), .iov_len = n };
__suio uio = { .uio_iov = &iov, .uio_iovcnt = 1, .uio_resid = n };
- _SET_ORIENTATION(fp, -1);
+ _SET_ORIENTATION(fp, ORIENT_BYTES);
// The usual case is success (__sfvwrite returns 0); skip the divide if this happens,
// since divides are generally slow.
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index d83a5bf..12cceeb 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -39,7 +39,27 @@
#define CHAR_TYPE_inf "inf"
#define CHAR_TYPE_NAN "NAN"
#define CHAR_TYPE_nan "nan"
-#define CHAR_TYPE_ORIENTATION -1
+#define CHAR_TYPE_ORIENTATION ORIENT_BYTES
+
+#define PRINT(ptr, len) \
+ do { \
+ iovp->iov_base = (ptr); \
+ iovp->iov_len = (len); \
+ uio.uio_resid += (len); \
+ iovp++; \
+ if (++uio.uio_iovcnt >= NIOV) { \
+ if (helpers::sprint(fp, &uio)) goto error; \
+ iovp = iov; \
+ } \
+ } while (0)
+
+#define FLUSH() \
+ do { \
+ if (uio.uio_resid && helpers::sprint(fp, &uio)) goto error; \
+ uio.uio_iovcnt = 0; \
+ iovp = iov; \
+ } while (0)
+
#include "printf_common.h"
int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
@@ -115,24 +135,6 @@
static const char xdigs_lower[] = "0123456789abcdef";
static const char xdigs_upper[] = "0123456789ABCDEF";
-#define PRINT(ptr, len) \
- do { \
- iovp->iov_base = (ptr); \
- iovp->iov_len = (len); \
- uio.uio_resid += (len); \
- iovp++; \
- if (++uio.uio_iovcnt >= NIOV) { \
- if (helpers::sprint(fp, &uio)) goto error; \
- iovp = iov; \
- } \
- } while (0)
-#define FLUSH() \
- do { \
- if (uio.uio_resid && helpers::sprint(fp, &uio)) goto error; \
- uio.uio_iovcnt = 0; \
- iovp = iov; \
- } while (0)
-
_SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
// Writing "" to a read only file returns EOF, not 0.
@@ -359,14 +361,14 @@
if (dtoaresult) __freedtoa(dtoaresult);
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
- dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
+ dtoaresult = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend);
if (dtoaresult == nullptr) {
errno = ENOMEM;
goto error;
}
} else {
fparg.dbl = GETARG(double);
- dtoaresult = cp = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
+ dtoaresult = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend);
if (dtoaresult == nullptr) {
errno = ENOMEM;
goto error;
@@ -396,14 +398,14 @@
if (dtoaresult) __freedtoa(dtoaresult);
if (flags & LONGDBL) {
fparg.ldbl = GETARG(long double);
- dtoaresult = cp = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+ dtoaresult = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
if (dtoaresult == nullptr) {
errno = ENOMEM;
goto error;
}
} else {
fparg.dbl = GETARG(double);
- dtoaresult = cp = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
+ dtoaresult = __dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend);
if (dtoaresult == nullptr) {
errno = ENOMEM;
goto error;
@@ -411,6 +413,13 @@
if (expt == 9999) expt = INT_MAX;
}
fp_common:
+#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
+ cp = dtoaresult;
+#else
+ free(convbuf);
+ cp = convbuf = helpers::mbsconv(dtoaresult, -1);
+ if (cp == nullptr) goto error;
+#endif
if (signflag) sign = '-';
if (expt == INT_MAX) { /* inf or nan */
if (*cp == 'N') {
@@ -423,7 +432,7 @@
break;
}
flags |= FPT;
- ndig = dtoaend - cp;
+ ndig = dtoaend - dtoaresult;
if (ch == 'g' || ch == 'G') {
if (expt > -4 && expt <= prec) {
/* Make %[gG] smell like %[fF] */
@@ -521,6 +530,21 @@
_umax = UARG();
base = DEC;
goto nosign;
+ case 'w': {
+ n = 0;
+ bool fast = false;
+ ch = *fmt++;
+ if (ch == 'f') {
+ fast = true;
+ ch = *fmt++;
+ }
+ while (is_digit(ch)) {
+ APPEND_DIGIT(n, ch);
+ ch = *fmt++;
+ }
+ flags |= helpers::w_to_flag(n, fast);
+ goto reswitch;
+ }
case 'X':
xdigs = xdigs_upper;
goto hex;
@@ -645,6 +669,7 @@
} else { /* glue together f_p fragments */
if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ CHAR_TYPE* end = cp + ndig;
if (expt <= 0) {
PRINT(zeroes, 1);
if (prec || flags & ALT) PRINT(decimal_point, 1);
@@ -652,11 +677,11 @@
/* already handled initial 0's */
prec += expt;
} else {
- PRINTANDPAD(cp, dtoaend, lead, zeroes);
+ PRINTANDPAD(cp, end, lead, zeroes);
cp += lead;
if (prec || flags & ALT) PRINT(decimal_point, 1);
}
- PRINTANDPAD(cp, dtoaend, prec, zeroes);
+ PRINTANDPAD(cp, end, prec, zeroes);
} else { /* %[eE] or sufficiently long %[gG] */
if (prec > 1 || flags & ALT) {
buf[0] = *cp++;
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index d05a3a6..dfd001d 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -102,7 +102,7 @@
void* allocation = nullptr; // Allocated but unassigned result for %mc/%ms/%m[.
size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
- _SET_ORIENTATION(fp, -1);
+ _SET_ORIENTATION(fp, ORIENT_BYTES);
nassigned = 0;
nread = 0;
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index 9819a73..d6f6a6b 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -39,7 +39,17 @@
#define CHAR_TYPE_inf L"inf"
#define CHAR_TYPE_NAN L"NAN"
#define CHAR_TYPE_nan L"nan"
-#define CHAR_TYPE_ORIENTATION 1
+#define CHAR_TYPE_ORIENTATION ORIENT_CHARS
+
+#define PRINT(ptr, len) \
+ do { \
+ for (int n3 = 0; n3 < (len); n3++) { \
+ if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
+ } \
+ } while (0)
+
+#define FLUSH()
+
#include "printf_common.h"
int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
@@ -115,13 +125,6 @@
static const char xdigs_lower[] = "0123456789abcdef";
static const char xdigs_upper[] = "0123456789ABCDEF";
-#define PRINT(ptr, len) \
- do { \
- for (int n3 = 0; n3 < (len); n3++) { \
- if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
- } \
- } while (0)
-
_SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
// Writing "" to a read only file returns EOF, not 0.
@@ -352,10 +355,6 @@
}
if (prec < 0) prec = dtoaend - dtoaresult;
if (expt == INT_MAX) ox[1] = '\0';
- free(convbuf);
- cp = convbuf = helpers::mbsconv(dtoaresult, -1);
- if (cp == nullptr) goto error;
- ndig = dtoaend - dtoaresult;
goto fp_common;
case 'e':
case 'E':
@@ -392,11 +391,14 @@
}
if (expt == 9999) expt = INT_MAX;
}
+ fp_common:
+#if CHAR_TYPE_ORIENTATION == ORIENT_BYTES
+ cp = dtoaresult;
+#else
free(convbuf);
cp = convbuf = helpers::mbsconv(dtoaresult, -1);
if (cp == nullptr) goto error;
- ndig = dtoaend - dtoaresult;
- fp_common:
+#endif
if (signflag) sign = '-';
if (expt == INT_MAX) { /* inf or nan */
if (*cp == 'N') {
@@ -409,6 +411,7 @@
break;
}
flags |= FPT;
+ ndig = dtoaend - dtoaresult;
if (ch == 'g' || ch == 'G') {
if (expt > -4 && expt <= prec) {
/* Make %[gG] smell like %[fF] */
@@ -510,6 +513,21 @@
_umax = UARG();
base = DEC;
goto nosign;
+ case 'w': {
+ n = 0;
+ bool fast = false;
+ ch = *fmt++;
+ if (ch == 'f') {
+ fast = true;
+ ch = *fmt++;
+ }
+ while (is_digit(ch)) {
+ APPEND_DIGIT(n, ch);
+ ch = *fmt++;
+ }
+ flags |= helpers::w_to_flag(n, fast);
+ goto reswitch;
+ }
case 'X':
xdigs = xdigs_upper;
goto hex;
@@ -634,6 +652,7 @@
} else { /* glue together f_p fragments */
if (decimal_point == nullptr) decimal_point = nl_langinfo(RADIXCHAR);
if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ CHAR_TYPE* end = cp + ndig;
if (expt <= 0) {
PRINT(zeroes, 1);
if (prec || flags & ALT) PRINT(decimal_point, 1);
@@ -641,11 +660,11 @@
/* already handled initial 0's */
prec += expt;
} else {
- PRINTANDPAD(cp, convbuf + ndig, lead, zeroes);
+ PRINTANDPAD(cp, end, lead, zeroes);
cp += lead;
if (prec || flags & ALT) PRINT(decimal_point, 1);
}
- PRINTANDPAD(cp, convbuf + ndig, prec, zeroes);
+ PRINTANDPAD(cp, end, prec, zeroes);
} else { /* %[eE] or sufficiently long %[gG] */
if (prec > 1 || flags & ALT) {
buf[0] = *cp++;
@@ -666,8 +685,11 @@
if (width < realsz) width = realsz;
if (width > INT_MAX - ret) goto overflow;
ret += width;
+
+ FLUSH(); /* copy out the I/O vectors */
}
done:
+ FLUSH();
error:
va_end(orgap);
if (__sferror(fp)) ret = -1;
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 06f706a..5f21acd 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -150,7 +150,7 @@
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
mbstate_t mbs;
- _SET_ORIENTATION(fp, 1);
+ _SET_ORIENTATION(fp, ORIENT_CHARS);
nassigned = 0;
nconversions = 0;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 558b004..4f33777 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -88,7 +88,7 @@
ecall
li a7, -MAX_ERRNO
- bgtu a0, a7, 1f
+ bgeu a0, a7, 1f
ret
1:
diff --git a/libc/tzcode/asctime.c b/libc/tzcode/asctime.c
index ce5d4be..4cdfd13 100644
--- a/libc/tzcode/asctime.c
+++ b/libc/tzcode/asctime.c
@@ -17,12 +17,6 @@
#include <stdio.h>
/*
-** Some systems only handle "%.2d"; others only handle "%02d";
-** "%02.2d" makes (most) everybody happy.
-** At least some versions of gcc warn about the %02.2d;
-** we conditionalize below to avoid the warning.
-*/
-/*
** All years associated with 32-bit time_t values are exactly four digits long;
** some years associated with 64-bit time_t values are not.
** Vintage programs are coded for years that are always four digits long
@@ -34,24 +28,16 @@
** The ISO C and POSIX standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
*/
-#ifdef __GNUC__
-#define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT[] = "%s %s%3d %.2d:%.2d:%.2d %-4s\n";
/*
** For years that are more than four digits we put extra spaces before the year
** so that code trying to overwrite the newline won't end up overwriting
** a digit within a year and truncating the year (operating on the assumption
** that no output is better than wrong output).
*/
-#ifdef __GNUC__
-#define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n"
-#else /* !defined __GNUC__ */
-#define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n"
-#endif /* !defined __GNUC__ */
+static char const ASCTIME_FMT_B[] = "%s %s%3d %.2d:%.2d:%.2d %s\n";
-#define STD_ASCTIME_BUF_SIZE 26
+enum { STD_ASCTIME_BUF_SIZE = 26 };
/*
** Big enough for something such as
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
@@ -59,15 +45,23 @@
** seven explicit spaces, two explicit colons, a newline,
** and a trailing NUL byte).
** The values above are for systems where an int is 32 bits and are provided
-** as an example; the define below calculates the maximum for the system at
+** as an example; the size expression below is a bound for the system at
** hand.
*/
-#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
+static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
-static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
+/* A similar buffer for ctime.
+ C89 requires that they be the same buffer.
+ This requirement was removed in C99, so support it only if requested,
+ as support is more likely to lead to bugs in badly written programs. */
+#if SUPPORT_C89
+# define buf_ctime buf_asctime
+#else
+static char buf_ctime[sizeof buf_asctime];
+#endif
char *
-asctime_r(register const struct tm *timeptr, char *buf)
+asctime_r(struct tm const *restrict timeptr, char *restrict buf)
{
static const char wday_name[][4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
@@ -79,7 +73,7 @@
register const char * wn;
register const char * mn;
char year[INT_STRLEN_MAXIMUM(int) + 2];
- char result[MAX_ASCTIME_BUF_SIZE];
+ char result[sizeof buf_asctime];
if (timeptr == NULL) {
errno = EINVAL;
@@ -107,7 +101,8 @@
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
year);
- if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
+ if (strlen(result) < STD_ASCTIME_BUF_SIZE
+ || buf == buf_ctime || buf == buf_asctime)
return strcpy(buf, result);
else {
errno = EOVERFLOW;
@@ -120,3 +115,17 @@
{
return asctime_r(timeptr, buf_asctime);
}
+
+char *
+ctime_r(const time_t *timep, char *buf)
+{
+ struct tm mytm;
+ struct tm *tmp = localtime_r(timep, &mytm);
+ return tmp ? asctime_r(tmp, buf) : NULL;
+}
+
+char *
+ctime(const time_t *timep)
+{
+ return ctime_r(timep, buf_ctime);
+}
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 8ff5cee..5e1181f 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -28,29 +28,22 @@
static void unlock(void) { }
#endif
-#ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN 16
-#endif /* !defined TZ_ABBR_MAX_LEN */
-
#ifndef TZ_ABBR_CHAR_SET
-#define TZ_ABBR_CHAR_SET \
+# define TZ_ABBR_CHAR_SET \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
#endif /* !defined TZ_ABBR_CHAR_SET */
#ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR '_'
+# define TZ_ABBR_ERR_CHAR '_'
#endif /* !defined TZ_ABBR_ERR_CHAR */
/*
-** SunOS 4.1.1 headers lack O_BINARY.
++** Support non-POSIX platforms that distinguish between text and binary files.
*/
-#ifdef O_BINARY
-#define OPEN_MODE (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
#ifndef O_BINARY
-#define OPEN_MODE O_RDONLY
-#endif /* !defined O_BINARY */
+# define O_BINARY 0
+#endif
#ifndef WILDABBR
/*
@@ -72,12 +65,13 @@
** manual page of what this "time zone abbreviation" means (doing this so
** that tzname[0] has the "normal" length of three characters).
*/
-#define WILDABBR " "
+# define WILDABBR " "
#endif /* !defined WILDABBR */
static const char wildabbr[] = WILDABBR;
-static const char gmt[] = "GMT";
+static char const etc_utc[] = "Etc/UTC";
+static char const *utc = etc_utc + sizeof "Etc/" - 1;
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -86,7 +80,7 @@
** for historical reasons, US rules are a common default.
*/
#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
+# define TZDEFRULESTRING ",M3.2.0,M11.1.0"
#endif
struct ttinfo { /* time type information */
@@ -102,9 +96,6 @@
int_fast32_t ls_corr; /* correction to apply */
};
-#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
-#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
-
/* This abbreviation means local time is unspecified. */
static char const UNSPEC[] = "-00";
@@ -112,14 +103,13 @@
This needs to be at least 1 for null termination in case the input
data isn't properly terminated, and it also needs to be big enough
for ttunspecified to work without crashing. */
-enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 };
+enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX 255
-#endif /* !defined TZNAME_MAX */
+/* Limit to time zone abbreviation length in POSIX-style TZ strings.
+ This is distinct from TZ_MAX_CHARS, which limits TZif file contents. */
+#ifndef TZNAME_MAXIMUM
+# define TZNAME_MAXIMUM 255
+#endif
struct state {
int leapcnt;
@@ -131,9 +121,8 @@
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA,
- sizeof gmt),
- (2 * (MY_TZNAME_MAX + 1)))];
+ char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
+ 2 * (TZNAME_MAXIMUM + 1))];
struct lsinfo lsis[TZ_MAX_LEAPS];
/* The time type to use for early times or if no transitions.
It is always zero for recent tzdb releases.
@@ -174,12 +163,12 @@
#ifndef ALL_STATE
static struct state lclmem;
static struct state gmtmem;
-#define lclptr (&lclmem)
-#define gmtptr (&gmtmem)
+static struct state *const lclptr = &lclmem;
+static struct state *const gmtptr = &gmtmem;
#endif /* State Farm */
#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
+# define TZ_STRLEN_MAX 255
#endif /* !defined TZ_STRLEN_MAX */
static char lcl_TZname[TZ_STRLEN_MAX + 1];
@@ -191,9 +180,14 @@
** ctime, gmtime, localtime] return values in one of two static
** objects: a broken-down time structure and an array of char.
** Thanks to Paul Eggert for noting this.
+**
+** This requirement was removed in C99, so support it only if requested,
+** as support is more likely to lead to bugs in badly written programs.
*/
+#if SUPPORT_C89
static struct tm tm;
+#endif
#if 2 <= HAVE_TZNAME + TZ_TIME_T
char * tzname[2] = {
@@ -321,7 +315,7 @@
int stddst_mask = 0;
#if HAVE_TZNAME
- tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt);
+ tzname[0] = tzname[1] = (char *) (sp ? wildabbr : utc);
stddst_mask = 3;
#endif
#if USG_COMPAT
@@ -346,27 +340,28 @@
#endif
}
-static void
+/* Replace bogus characters in time zone abbreviations.
+ Return 0 on success, an errno value if a time zone abbreviation is
+ too long. */
+static int
scrub_abbrs(struct state *sp)
{
int i;
- /*
- ** First, replace bogus characters.
- */
+
+ /* Reject overlong abbreviations. */
+ for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
+ int len = strlen(&sp->chars[i]);
+ if (TZNAME_MAXIMUM < len)
+ return EOVERFLOW;
+ i += len + 1;
+ }
+
+ /* Replace bogus characters. */
for (i = 0; i < sp->charcnt; ++i)
if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
sp->chars[i] = TZ_ABBR_ERR_CHAR;
- /*
- ** Second, truncate long abbreviations.
- */
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
- char *cp = &sp->chars[ttisp->tt_desigidx];
- if (strlen(cp) > TZ_ABBR_MAX_LEN &&
- strcmp(cp, GRANDPARENTED) != 0)
- *(cp + TZ_ABBR_MAX_LEN) = '\0';
- }
+ return 0;
}
/* Input buffer for data read from a compiled tz file. */
@@ -399,8 +394,7 @@
// Android-removed: There is no directory with file-per-time zone on Android.
#ifndef __BIONIC__
/* The file name to be opened. */
- char fullname[BIGGEST(sizeof(struct file_analysis),
- sizeof tzdirslash + 1024)];
+ char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
#endif
};
@@ -446,8 +440,7 @@
#endif
if (!doaccess) {
char const *dot;
- size_t namelen = strlen(name);
- if (sizeof lsp->fullname - sizeof tzdirslash <= namelen)
+ if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name))
return ENAMETOOLONG;
/* Create a string "TZDIR/NAME". Using sprintf here
@@ -470,7 +463,7 @@
}
if (doaccess && access(name, R_OK) != 0)
return errno;
- fid = open(name, OPEN_MODE);
+ fid = open(name, O_RDONLY | O_BINARY);
#endif
if (fid < 0)
return errno;
@@ -828,12 +821,14 @@
b < 0 || b >= sp->typecnt)
result = false;
else {
+ /* Compare the relevant members of *AP and *BP.
+ Ignore tt_ttisstd and tt_ttisut, as they are
+ irrelevant now and counting them could cause
+ sp->goahead to mistakenly remain false. */
register const struct ttinfo * ap = &sp->ttis[a];
register const struct ttinfo * bp = &sp->ttis[b];
result = (ap->tt_utoff == bp->tt_utoff
&& ap->tt_isdst == bp->tt_isdst
- && ap->tt_ttisstd == bp->tt_ttisstd
- && ap->tt_ttisut == bp->tt_ttisut
&& (strcmp(&sp->chars[ap->tt_desigidx],
&sp->chars[bp->tt_desigidx])
== 0));
@@ -863,7 +858,7 @@
** Return a pointer to that character.
*/
-static ATTRIBUTE_PURE const char *
+ATTRIBUTE_REPRODUCIBLE static const char *
getzname(register const char *strp)
{
register char c;
@@ -884,7 +879,7 @@
** We don't do any checking here; checking is done later in common-case code.
*/
-static ATTRIBUTE_PURE const char *
+ATTRIBUTE_REPRODUCIBLE static const char *
getqzname(register const char *strp, const int delim)
{
register int c;
@@ -1122,7 +1117,7 @@
value += mon_lengths[leapyear][i] * SECSPERDAY;
break;
- default: UNREACHABLE();
+ default: unreachable();
}
/*
@@ -1144,13 +1139,11 @@
{
const char * stdname;
const char * dstname;
- size_t stdlen;
- size_t dstlen;
- size_t charcnt;
int_fast32_t stdoffset;
int_fast32_t dstoffset;
register char * cp;
register bool load_ok;
+ ptrdiff_t stdlen, dstlen, charcnt;
time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
stdname = name;
@@ -1166,14 +1159,12 @@
name = getzname(name);
stdlen = name - stdname;
}
- if (!stdlen)
+ if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
return false;
name = getoffset(name, &stdoffset);
if (name == NULL)
return false;
charcnt = stdlen + 1;
- if (sizeof sp->chars < charcnt)
- return false;
if (basep) {
if (0 < basep->timecnt)
atlo = basep->ats[basep->timecnt - 1];
@@ -1200,11 +1191,9 @@
name = getzname(name);
dstlen = name - dstname; /* length of DST abbr. */
}
- if (!dstlen)
+ if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
return false;
charcnt += dstlen + 1;
- if (sizeof sp->chars < charcnt)
- return false;
if (*name != '\0' && *name != ',' && *name != ';') {
name = getoffset(name, &dstoffset);
if (name == NULL)
@@ -1420,8 +1409,8 @@
static void
gmtload(struct state *const sp)
{
- if (tzload(gmt, sp, true) != 0)
- tzparse("GMT0", sp, NULL);
+ if (tzload(etc_utc, sp, true) != 0)
+ tzparse("UTC0", sp, NULL);
}
/* Initialize *SP to a value appropriate for the TZ setting NAME.
@@ -1439,7 +1428,7 @@
sp->charcnt = 0;
sp->goback = sp->goahead = false;
init_ttinfo(&sp->ttis[0], 0, false, 0);
- strcpy(sp->chars, gmt);
+ strcpy(sp->chars, utc);
sp->defaulttype = 0;
return 0;
} else {
@@ -1447,7 +1436,7 @@
if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
err = 0;
if (err == 0)
- scrub_abbrs(sp);
+ err = scrub_abbrs(sp);
return err;
}
}
@@ -1557,7 +1546,7 @@
** set the applicable parts of tzname, timezone and altzone;
** however, it's OK to omit this step if the timezone is POSIX-compatible,
** since in that case tzset should have already done this step correctly.
-** SETNAME's type is intfast32_t for compatibility with gmtsub,
+** SETNAME's type is int_fast32_t for compatibility with gmtsub,
** but it is actually a boolean and its value should be 0 or 1.
*/
@@ -1601,6 +1590,14 @@
return NULL; /* "cannot happen" */
result = localsub(sp, &newt, setname, tmp);
if (result) {
+#if defined ckd_add && defined ckd_sub
+ if (t < sp->ats[0]
+ ? ckd_sub(&result->tm_year,
+ result->tm_year, years)
+ : ckd_add(&result->tm_year,
+ result->tm_year, years))
+ return NULL;
+#else
register int_fast64_t newy;
newy = result->tm_year;
@@ -1610,6 +1607,7 @@
if (! (INT_MIN <= newy && newy <= INT_MAX))
return NULL;
result->tm_year = newy;
+#endif
}
return result;
}
@@ -1650,7 +1648,8 @@
#if NETBSD_INSPIRED
struct tm *
-localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
+localtime_rz(struct state *restrict sp, time_t const *restrict timep,
+ struct tm *restrict tmp)
{
return localsub(sp, timep, 0, tmp);
}
@@ -1681,11 +1680,14 @@
struct tm *
localtime(const time_t *timep)
{
+#if !SUPPORT_C89
+ static struct tm tm;
+#endif
return localtime_tzset(timep, &tm);
}
struct tm *
-localtime_r(const time_t *timep, struct tm *tmp)
+localtime_r(const time_t *restrict timep, struct tm *restrict tmp)
{
return localtime_tzset(timep, tmp);
}
@@ -1695,8 +1697,8 @@
*/
static struct tm *
-gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
- struct tm *tmp)
+gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
+ int_fast32_t offset, struct tm *tmp)
{
register struct tm * result;
@@ -1708,7 +1710,7 @@
** but this is no time for a treasure hunt.
*/
tmp->TM_ZONE = ((char *)
- (offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
+ (offset ? wildabbr : gmtptr ? gmtptr->chars : utc));
#endif /* defined TM_ZONE */
return result;
}
@@ -1718,7 +1720,7 @@
*/
struct tm *
-gmtime_r(const time_t *timep, struct tm *tmp)
+gmtime_r(time_t const *restrict timep, struct tm *restrict tmp)
{
gmtcheck();
return gmtsub(gmtptr, timep, 0, tmp);
@@ -1727,19 +1729,26 @@
struct tm *
gmtime(const time_t *timep)
{
+#if !SUPPORT_C89
+ static struct tm tm;
+#endif
return gmtime_r(timep, &tm);
}
-#ifdef STD_INSPIRED
+#if STD_INSPIRED
struct tm *
offtime(const time_t *timep, long offset)
{
gmtcheck();
+
+#if !SUPPORT_C89
+ static struct tm tm;
+#endif
return gmtsub(gmtptr, timep, offset, &tm);
}
-#endif /* defined STD_INSPIRED */
+#endif
/*
** Return the number of leap years through the end of the given year
@@ -1825,6 +1834,12 @@
y = newy;
}
+#ifdef ckd_add
+ if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
+ errno = EOVERFLOW;
+ return NULL;
+ }
+#else
if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
int signed_y = y;
tmp->tm_year = signed_y - TM_YEAR_BASE;
@@ -1835,6 +1850,7 @@
errno = EOVERFLOW;
return NULL;
}
+#endif
tmp->tm_yday = idays;
/*
** The "extra" mods below avoid overflow problems.
@@ -1868,27 +1884,6 @@
return tmp;
}
-char *
-ctime(const time_t *timep)
-{
-/*
-** Section 4.12.3.2 of X3.159-1989 requires that
-** The ctime function converts the calendar time pointed to by timer
-** to local time in the form of a string. It is equivalent to
-** asctime(localtime(timer))
-*/
- struct tm *tmp = localtime(timep);
- return tmp ? asctime(tmp) : NULL;
-}
-
-char *
-ctime_r(const time_t *timep, char *buf)
-{
- struct tm mytm;
- struct tm *tmp = localtime_r(timep, &mytm);
- return tmp ? asctime_r(tmp, buf) : NULL;
-}
-
/*
** Adapted from code provided by Robert Elz, who writes:
** The "best" way to do mktime I think is based on an idea of Bob
@@ -1899,7 +1894,7 @@
*/
#ifndef WRONG
-#define WRONG (-1)
+# define WRONG (-1)
#endif /* !defined WRONG */
/*
@@ -1909,6 +1904,9 @@
static bool
increment_overflow(int *ip, int j)
{
+#ifdef ckd_add
+ return ckd_add(ip, *ip, j);
+#else
register int const i = *ip;
/*
@@ -1921,22 +1919,30 @@
return true;
*ip += j;
return false;
+#endif
}
static bool
increment_overflow32(int_fast32_t *const lp, int const m)
{
+#ifdef ckd_add
+ return ckd_add(lp, *lp, m);
+#else
register int_fast32_t const l = *lp;
if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
return true;
*lp += m;
return false;
+#endif
}
static bool
increment_overflow_time(time_t *tp, int_fast32_t j)
{
+#ifdef ckd_add
+ return ckd_add(tp, *tp, j);
+#else
/*
** This is like
** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
@@ -1948,6 +1954,7 @@
return true;
*tp += j;
return false;
+#endif
}
static bool
@@ -1990,6 +1997,23 @@
return result;
}
+/* Copy to *DEST from *SRC. Copy only the members needed for mktime,
+ as other members might not be initialized. */
+static void
+mktmcpy(struct tm *dest, struct tm const *src)
+{
+ dest->tm_sec = src->tm_sec;
+ dest->tm_min = src->tm_min;
+ dest->tm_hour = src->tm_hour;
+ dest->tm_mday = src->tm_mday;
+ dest->tm_mon = src->tm_mon;
+ dest->tm_year = src->tm_year;
+ dest->tm_isdst = src->tm_isdst;
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+ dest->TM_GMTOFF = src->TM_GMTOFF;
+#endif
+}
+
static time_t
time2sub(struct tm *const tmp,
struct tm *(*funcp)(struct state const *, time_t const *,
@@ -2011,7 +2035,8 @@
struct tm yourtm, mytm;
*okayp = false;
- yourtm = *tmp;
+ mktmcpy(&yourtm, tmp);
+
if (do_norm_secs) {
if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
SECSPERMIN))
@@ -2053,14 +2078,19 @@
return WRONG;
}
}
+#ifdef ckd_add
+ if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
+ return WRONG;
+#else
if (increment_overflow32(&y, -TM_YEAR_BASE))
return WRONG;
if (! (INT_MIN <= y && y <= INT_MAX))
return WRONG;
yourtm.tm_year = y;
+#endif
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0;
- else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
+ else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) {
/*
** We can't set tm_sec to 0, because that might push the
** time below the minimum representable time.
@@ -2120,10 +2150,10 @@
&& (yourtm.TM_GMTOFF < 0
? (-SECSPERDAY <= yourtm.TM_GMTOFF
&& (mytm.TM_GMTOFF <=
- (SMALLEST(INT_FAST32_MAX, LONG_MAX)
+ (min(INT_FAST32_MAX, LONG_MAX)
+ yourtm.TM_GMTOFF)))
: (yourtm.TM_GMTOFF <= SECSPERDAY
- && ((BIGGEST(INT_FAST32_MIN, LONG_MIN)
+ && ((max(INT_FAST32_MIN, LONG_MIN)
+ yourtm.TM_GMTOFF)
<= mytm.TM_GMTOFF)))) {
/* MYTM matches YOURTM except with the wrong UT offset.
@@ -2294,7 +2324,7 @@
#if NETBSD_INSPIRED
time_t
-mktime_z(struct state *sp, struct tm *tmp)
+mktime_z(struct state *restrict sp, struct tm *restrict tmp)
{
return mktime_tzname(sp, tmp, false);
}
@@ -2324,8 +2354,7 @@
return t;
}
-#ifdef STD_INSPIRED
-
+#if STD_INSPIRED
time_t
timelocal(struct tm *tmp)
{
@@ -2333,13 +2362,9 @@
tmp->tm_isdst = -1; /* in case it wasn't initialized */
return mktime(tmp);
}
-
-time_t
-timegm(struct tm *tmp)
-{
- return timeoff(tmp, 0);
-}
-
+#else
+static
+#endif
time_t
timeoff(struct tm *tmp, long offset)
{
@@ -2349,7 +2374,18 @@
return time1(tmp, gmtsub, gmtptr, offset);
}
-#endif /* defined STD_INSPIRED */
+time_t
+timegm(struct tm *tmp)
+{
+ time_t t;
+ struct tm tmcpy;
+ mktmcpy(&tmcpy, tmp);
+ tmcpy.tm_wday = -1;
+ t = timeoff(&tmcpy, 0);
+ if (0 <= tmcpy.tm_wday)
+ *tmp = tmcpy;
+ return t;
+}
static int_fast32_t
leapcorr(struct state const *sp, time_t t)
@@ -2370,7 +2406,7 @@
** XXX--is the below the right way to conditionalize??
*/
-#ifdef STD_INSPIRED
+#if STD_INSPIRED
/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
NETBSD_INSPIRED is defined, and are private otherwise. */
@@ -2455,7 +2491,7 @@
return t;
}
-#endif /* defined STD_INSPIRED */
+#endif /* STD_INSPIRED */
#if TZ_TIME_T
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 4c03324..838ab2b 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -17,6 +17,36 @@
** Thank you!
*/
+/* PORT_TO_C89 means the code should work even if the underlying
+ compiler and library support only C89. SUPPORT_C89 means the
+ tzcode library should support C89 callers in addition to the usual
+ support for C99-and-later callers. These macros are obsolescent,
+ and the plan is to remove them along with any code needed only when
+ they are nonzero. */
+#ifndef PORT_TO_C89
+# define PORT_TO_C89 0
+#endif
+#ifndef SUPPORT_C89
+# define SUPPORT_C89 0
+#endif
+
+#ifndef __STDC_VERSION__
+# define __STDC_VERSION__ 0
+#endif
+
+/* Define true, false and bool if they don't work out of the box. */
+#if PORT_TO_C89 && __STDC_VERSION__ < 199901
+# define true 1
+# define false 0
+# define bool int
+#elif __STDC_VERSION__ < 202311
+# include <stdbool.h>
+#endif
+
+#if __STDC_VERSION__ < 202311
+# define static_assert(cond) extern int static_assert_check[(cond) ? 1 : -1]
+#endif
+
/*
** zdump has been made independent of the rest of the time
** conversion package to increase confidence in the verification it provides.
@@ -36,79 +66,86 @@
*/
#ifndef HAVE_DECL_ASCTIME_R
-#define HAVE_DECL_ASCTIME_R 1
+# define HAVE_DECL_ASCTIME_R 1
#endif
-#if !defined HAVE_GENERIC && defined __has_extension
+#if !defined HAVE__GENERIC && defined __has_extension
# if __has_extension(c_generic_selections)
-# define HAVE_GENERIC 1
+# define HAVE__GENERIC 1
# else
-# define HAVE_GENERIC 0
+# define HAVE__GENERIC 0
# endif
#endif
/* _Generic is buggy in pre-4.9 GCC. */
-#if !defined HAVE_GENERIC && defined __GNUC__
-# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
+#if !defined HAVE__GENERIC && defined __GNUC__ && !defined __STRICT_ANSI__
+# define HAVE__GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
#endif
-#ifndef HAVE_GENERIC
-# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
+#ifndef HAVE__GENERIC
+# define HAVE__GENERIC (201112 <= __STDC_VERSION__)
#endif
+#if !defined HAVE_GETTEXT && defined __has_include
+# if __has_include(<libintl.h>)
+# define HAVE_GETTEXT true
+# endif
+#endif
#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
-#endif /* !defined HAVE_GETTEXT */
+# define HAVE_GETTEXT false
+#endif
#ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R 0
+# define HAVE_INCOMPATIBLE_CTIME_R 0
#endif
#ifndef HAVE_LINK
-#define HAVE_LINK 1
+# define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
#ifndef HAVE_MALLOC_ERRNO
-#define HAVE_MALLOC_ERRNO 1
+# define HAVE_MALLOC_ERRNO 1
#endif
#ifndef HAVE_POSIX_DECLS
-#define HAVE_POSIX_DECLS 1
+# define HAVE_POSIX_DECLS 1
#endif
-#ifndef HAVE_STDBOOL_H
-#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+#ifndef HAVE_SETENV
+# define HAVE_SETENV 1
#endif
#ifndef HAVE_STRDUP
-#define HAVE_STRDUP 1
-#endif
-
-#ifndef HAVE_STRTOLL
-#define HAVE_STRTOLL 1
+# define HAVE_STRDUP 1
#endif
#ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK 1
+# define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
+#if !defined HAVE_SYS_STAT_H && defined __has_include
+# if !__has_include(<sys/stat.h>)
+# define HAVE_SYS_STAT_H false
+# endif
+#endif
#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H 1
-#endif /* !defined HAVE_SYS_STAT_H */
+# define HAVE_SYS_STAT_H true
+#endif
+#if !defined HAVE_UNISTD_H && defined __has_include
+# if !__has_include(<unistd.h>)
+# define HAVE_UNISTD_H false
+# endif
+#endif
#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H 1
-#endif /* !defined HAVE_UNISTD_H */
-
-#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H 1
-#endif /* !defined HAVE_UTMPX_H */
+# define HAVE_UNISTD_H true
+#endif
#ifndef NETBSD_INSPIRED
# define NETBSD_INSPIRED 1
#endif
#if HAVE_INCOMPATIBLE_CTIME_R
-#define asctime_r _incompatible_asctime_r
-#define ctime_r _incompatible_ctime_r
+# define asctime_r _incompatible_asctime_r
+# define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
@@ -118,15 +155,17 @@
/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
-/* To avoid having 'stat' fail unnecessarily with errno == EOVERFLOW,
- enable large files on GNUish systems ... */
+/* On GNUish systems where time_t might be 32 or 64 bits, use 64.
+ On these platforms _FILE_OFFSET_BITS must also be 64; otherwise
+ setting _TIME_BITS to 64 does not work. The code does not
+ otherwise rely on _FILE_OFFSET_BITS being 64, since it does not
+ use off_t or functions like 'stat' that depend on off_t. */
#ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
#endif
-/* ... and on AIX ... */
-#define _LARGE_FILES 1
-/* ... and enable large inode numbers on Mac OS X 10.5 and later. */
-#define _DARWIN_USE_64_BIT_INODE 1
+#if !defined _TIME_BITS && _FILE_OFFSET_BITS == 64
+# define _TIME_BITS 64
+#endif
/*
** Nested includes
@@ -157,8 +196,11 @@
#undef tzalloc
#undef tzfree
-#include <sys/types.h> /* for time_t */
+#include <stddef.h>
#include <string.h>
+#if !PORT_TO_C89
+# include <inttypes.h>
+#endif
#include <limits.h> /* for CHAR_BIT et al. */
#include <stdlib.h>
@@ -168,6 +210,9 @@
# define EINVAL ERANGE
#endif
+#ifndef ELOOP
+# define ELOOP EINVAL
+#endif
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
@@ -182,11 +227,11 @@
#endif
#if HAVE_GETTEXT
-#include <libintl.h>
+# include <libintl.h>
#endif /* HAVE_GETTEXT */
#if HAVE_UNISTD_H
-#include <unistd.h> /* for R_OK, and other POSIX goodness */
+# include <unistd.h> /* for R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#ifndef HAVE_STRFTIME_L
@@ -222,24 +267,29 @@
#endif
#ifndef R_OK
-#define R_OK 4
+# define R_OK 4
#endif /* !defined R_OK */
+#if PORT_TO_C89
+
/*
** Define HAVE_STDINT_H's default value here, rather than at the
** start, since __GLIBC__ and INTMAX_MAX's values depend on
-** previously-included files. glibc 2.1 and Solaris 10 and later have
+** previously included files. glibc 2.1 and Solaris 10 and later have
** stdint.h, even with pre-C99 compilers.
*/
+#if !defined HAVE_STDINT_H && defined __has_include
+# define HAVE_STDINT_H true /* C23 __has_include implies C99 stdint.h. */
+#endif
#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
+# define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
- || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
+ || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
|| __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
-#include <stdint.h>
+# include <stdint.h>
#endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
@@ -250,36 +300,36 @@
#endif
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
-#ifdef __LONG_LONG_MAX__
+#if defined __LONG_LONG_MAX__ && !defined __STRICT_ANSI__
# ifndef LLONG_MAX
# define LLONG_MAX __LONG_LONG_MAX__
# endif
# ifndef LLONG_MIN
# define LLONG_MIN (-1 - LLONG_MAX)
# endif
+# ifndef ULLONG_MAX
+# define ULLONG_MAX (LLONG_MAX * 2ull + 1)
+# endif
#endif
#ifndef INT_FAST64_MAX
-# ifdef LLONG_MAX
-typedef long long int_fast64_t;
-# define INT_FAST64_MIN LLONG_MIN
-# define INT_FAST64_MAX LLONG_MAX
-# else
-# if LONG_MAX >> 31 < 0xffffffff
-Please use a compiler that supports a 64-bit integer type (or wider);
-you may need to compile with "-DHAVE_STDINT_H".
-# endif
-typedef long int_fast64_t;
+# if 1 <= LONG_MAX >> 31 >> 31
+typedef long int_fast64_t;
# define INT_FAST64_MIN LONG_MIN
# define INT_FAST64_MAX LONG_MAX
+# else
+/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
+typedef long long int_fast64_t;
+# define INT_FAST64_MIN LLONG_MIN
+# define INT_FAST64_MAX LLONG_MAX
# endif
#endif
#ifndef PRIdFAST64
-# if INT_FAST64_MAX == LLONG_MAX
-# define PRIdFAST64 "lld"
-# else
+# if INT_FAST64_MAX == LONG_MAX
# define PRIdFAST64 "ld"
+# else
+# define PRIdFAST64 "lld"
# endif
#endif
@@ -302,6 +352,9 @@
#ifndef INTMAX_MAX
# ifdef LLONG_MAX
typedef long long intmax_t;
+# ifndef HAVE_STRTOLL
+# define HAVE_STRTOLL true
+# endif
# if HAVE_STRTOLL
# define strtoimax strtoll
# endif
@@ -325,70 +378,183 @@
# endif
#endif
+#ifndef PTRDIFF_MAX
+# define PTRDIFF_MAX MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t))
+#endif
+
#ifndef UINT_FAST32_MAX
typedef unsigned long uint_fast32_t;
#endif
#ifndef UINT_FAST64_MAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
-typedef unsigned long long uint_fast64_t;
+# if 3 <= ULONG_MAX >> 31 >> 31
+typedef unsigned long uint_fast64_t;
+# define UINT_FAST64_MAX ULONG_MAX
# else
-# if ULONG_MAX >> 31 >> 1 < 0xffffffff
-Please use a compiler that supports a 64-bit integer type (or wider);
-you may need to compile with "-DHAVE_STDINT_H".
-# endif
-typedef unsigned long uint_fast64_t;
+/* If this fails, compile with -DHAVE_STDINT_H or with a better compiler. */
+typedef unsigned long long uint_fast64_t;
+# define UINT_FAST64_MAX ULLONG_MAX
# endif
#endif
#ifndef UINTMAX_MAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef ULLONG_MAX
typedef unsigned long long uintmax_t;
+# define UINTMAX_MAX ULLONG_MAX
# else
typedef unsigned long uintmax_t;
+# define UINTMAX_MAX ULONG_MAX
# endif
#endif
#ifndef PRIuMAX
-# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
+# ifdef ULLONG_MAX
# define PRIuMAX "llu"
# else
# define PRIuMAX "lu"
# endif
#endif
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
-#endif /* !defined INT32_MAX */
-#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
-#endif /* !defined INT32_MIN */
-
#ifndef SIZE_MAX
-#define SIZE_MAX ((size_t) -1)
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#endif /* PORT_TO_C89 */
+
+/* The maximum size of any created object, as a signed integer.
+ Although the C standard does not outright prohibit larger objects,
+ behavior is undefined if the result of pointer subtraction does not
+ fit into ptrdiff_t, and the code assumes in several places that
+ pointer subtraction works. As a practical matter it's OK to not
+ support objects larger than this. */
+#define INDEX_MAX ((ptrdiff_t) min(PTRDIFF_MAX, SIZE_MAX))
+
+/* Support ckd_add, ckd_sub, ckd_mul on C23 or recent-enough GCC-like
+ hosts, unless compiled with -DHAVE_STDCKDINT_H=0 or with pre-C23 EDG. */
+#if !defined HAVE_STDCKDINT_H && defined __has_include
+# if __has_include(<stdckdint.h>)
+# define HAVE_STDCKDINT_H true
+# endif
+#endif
+#ifdef HAVE_STDCKDINT_H
+# if HAVE_STDCKDINT_H
+# include <stdckdint.h>
+# endif
+#elif defined __EDG__
+/* Do nothing, to work around EDG bug <https://bugs.gnu.org/53256>. */
+#elif defined __has_builtin
+# if __has_builtin(__builtin_add_overflow)
+# define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
+# endif
+# if __has_builtin(__builtin_sub_overflow)
+# define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
+# endif
+# if __has_builtin(__builtin_mul_overflow)
+# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
+# endif
+#elif 7 <= __GNUC__
+# define ckd_add(r, a, b) __builtin_add_overflow(a, b, r)
+# define ckd_sub(r, a, b) __builtin_sub_overflow(a, b, r)
+# define ckd_mul(r, a, b) __builtin_mul_overflow(a, b, r)
#endif
#if 3 <= __GNUC__
-# define ATTRIBUTE_CONST __attribute__((const))
-# define ATTRIBUTE_MALLOC __attribute__((__malloc__))
-# define ATTRIBUTE_PURE __attribute__((__pure__))
-# define ATTRIBUTE_FORMAT(spec) __attribute__((__format__ spec))
+# define ATTRIBUTE_MALLOC __attribute__((malloc))
+# define ATTRIBUTE_FORMAT(spec) __attribute__((format spec))
#else
-# define ATTRIBUTE_CONST /* empty */
# define ATTRIBUTE_MALLOC /* empty */
-# define ATTRIBUTE_PURE /* empty */
# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif
-#if !defined _Noreturn && __STDC_VERSION__ < 201112
-# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
-# define _Noreturn __attribute__((__noreturn__))
+#if (defined __has_c_attribute \
+ && (202311 <= __STDC_VERSION__ || !defined __STRICT_ANSI__))
+# define HAVE___HAS_C_ATTRIBUTE true
+#else
+# define HAVE___HAS_C_ATTRIBUTE false
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(deprecated)
+# define ATTRIBUTE_DEPRECATED [[deprecated]]
+# endif
+#endif
+#ifndef ATTRIBUTE_DEPRECATED
+# if 3 < __GNUC__ + (2 <= __GNUC_MINOR__)
+# define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
# else
-# define _Noreturn
+# define ATTRIBUTE_DEPRECATED /* empty */
# endif
#endif
-#if __STDC_VERSION__ < 199901 && !defined restrict
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(fallthrough)
+# define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
+# endif
+#endif
+#ifndef ATTRIBUTE_FALLTHROUGH
+# if 7 <= __GNUC__
+# define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
+# else
+# define ATTRIBUTE_FALLTHROUGH ((void) 0)
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(maybe_unused)
+# define ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
+# endif
+#endif
+#ifndef ATTRIBUTE_MAYBE_UNUSED
+# if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define ATTRIBUTE_MAYBE_UNUSED __attribute__((unused))
+# else
+# define ATTRIBUTE_MAYBE_UNUSED /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(noreturn)
+# define ATTRIBUTE_NORETURN [[noreturn]]
+# endif
+#endif
+#ifndef ATTRIBUTE_NORETURN
+# if 201112 <= __STDC_VERSION__
+# define ATTRIBUTE_NORETURN _Noreturn
+# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
+# define ATTRIBUTE_NORETURN __attribute__((noreturn))
+# else
+# define ATTRIBUTE_NORETURN /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(reproducible)
+# define ATTRIBUTE_REPRODUCIBLE [[reproducible]]
+# endif
+#endif
+#ifndef ATTRIBUTE_REPRODUCIBLE
+# if 3 <= __GNUC__
+# define ATTRIBUTE_REPRODUCIBLE __attribute__((pure))
+# else
+# define ATTRIBUTE_REPRODUCIBLE /* empty */
+# endif
+#endif
+
+#if HAVE___HAS_C_ATTRIBUTE
+# if __has_c_attribute(unsequenced)
+# define ATTRIBUTE_UNSEQUENCED [[unsequenced]]
+# endif
+#endif
+#ifndef ATTRIBUTE_UNSEQUENCED
+# if 3 <= __GNUC__
+# define ATTRIBUTE_UNSEQUENCED __attribute__((const))
+# else
+# define ATTRIBUTE_UNSEQUENCED /* empty */
+# endif
+#endif
+
+#if (__STDC_VERSION__ < 199901 && !defined restrict \
+ && (PORT_TO_C89 || defined _MSC_VER))
# define restrict /* empty */
#endif
@@ -505,11 +671,16 @@
# define altzone tz_altzone
# endif
-char *asctime(struct tm const *);
+# if __STDC_VERSION__ < 202311
+# define DEPRECATED_IN_C23 /* empty */
+# else
+# define DEPRECATED_IN_C23 ATTRIBUTE_DEPRECATED
+# endif
+DEPRECATED_IN_C23 char *asctime(struct tm const *);
char *asctime_r(struct tm const *restrict, char *restrict);
-char *ctime(time_t const *);
+DEPRECATED_IN_C23 char *ctime(time_t const *);
char *ctime_r(time_t const *, char *);
-double difftime(time_t, time_t) ATTRIBUTE_CONST;
+ATTRIBUTE_UNSEQUENCED double difftime(time_t, time_t);
size_t strftime(char *restrict, size_t, char const *restrict,
struct tm const *restrict);
# if HAVE_STRFTIME_L
@@ -522,9 +693,24 @@
struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
time_t mktime(struct tm *);
time_t time(time_t *);
+time_t timegm(struct tm *);
void tzset(void);
#endif
+#ifndef HAVE_DECL_TIMEGM
+# if (202311 <= __STDC_VERSION__ \
+ || defined __GLIBC__ || defined __tm_zone /* musl */ \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__))
+# define HAVE_DECL_TIMEGM true
+# else
+# define HAVE_DECL_TIMEGM false
+# endif
+#endif
+#if !HAVE_DECL_TIMEGM && !defined timegm
+time_t timegm(struct tm *);
+#endif
+
#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
extern char *asctime_r(struct tm const *restrict, char *restrict);
#endif
@@ -557,13 +743,13 @@
** declarations if time_tz is defined.
*/
-#ifdef STD_INSPIRED
+#ifndef STD_INSPIRED
+# define STD_INSPIRED 0
+#endif
+#if STD_INSPIRED
# if TZ_TIME_T || !defined offtime
struct tm *offtime(time_t const *, long);
# endif
-# if TZ_TIME_T || !defined timegm
-time_t timegm(struct tm *);
-# endif
# if TZ_TIME_T || !defined timelocal
time_t timelocal(struct tm *);
# endif
@@ -581,6 +767,7 @@
/* Infer TM_ZONE on systems where this information is known, but suppress
guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
#if (defined __GLIBC__ \
+ || defined __tm_zone /* musl */ \
|| defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__))
# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
@@ -606,12 +793,12 @@
time_t mktime_z(timezone_t restrict, struct tm *restrict);
timezone_t tzalloc(char const *);
void tzfree(timezone_t);
-# ifdef STD_INSPIRED
+# if STD_INSPIRED
# if TZ_TIME_T || !defined posix2time_z
-time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
+ATTRIBUTE_REPRODUCIBLE time_t posix2time_z(timezone_t, time_t);
# endif
# if TZ_TIME_T || !defined time2posix_z
-time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
+ATTRIBUTE_REPRODUCIBLE time_t time2posix_z(timezone_t, time_t);
# endif
# endif
#endif
@@ -620,18 +807,15 @@
** Finally, some convenience items.
*/
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#else
-# define true 1
-# define false 0
-# define bool int
-#endif
-
-#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
+#define TYPE_BIT(type) (CHAR_BIT * (ptrdiff_t) sizeof(type))
#define TYPE_SIGNED(type) (((type) -1) < 0)
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
+/* Minimum and maximum of two values. Use lower case to avoid
+ naming clashes with standard include files. */
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
/* Max and min values of the integer type T, of which only the bottom
B bits are used, and where the highest-order used bit is considered
to be a sign bit if T is signed. */
@@ -651,7 +835,7 @@
This implementation assumes no padding if time_t is signed and
either the compiler lacks support for _Generic or time_t is not one
of the standard signed integer types. */
-#if HAVE_GENERIC
+#if HAVE__GENERIC
# define TIME_T_MIN \
_Generic((time_t) 0, \
signed char: SCHAR_MIN, short: SHRT_MIN, \
@@ -664,10 +848,23 @@
int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
default: TIME_T_MAX_NO_PADDING) \
: (time_t) -1)
+enum { SIGNED_PADDING_CHECK_NEEDED
+ = _Generic((time_t) 0,
+ signed char: false, short: false,
+ int: false, long: false, long long: false,
+ default: true) };
#else
# define TIME_T_MIN TIME_T_MIN_NO_PADDING
# define TIME_T_MAX TIME_T_MAX_NO_PADDING
+enum { SIGNED_PADDING_CHECK_NEEDED = true };
#endif
+/* Try to check the padding assumptions. Although TIME_T_MAX and the
+ following check can both have undefined behavior on oddball
+ platforms due to shifts exceeding widths of signed integers, these
+ platforms' compilers are likely to diagnose these issues in integer
+ constant expressions, so it shouldn't hurt to check statically. */
+static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED
+ || TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1);
/*
** 302 / 1000 is log10(2.0) rounded up.
@@ -689,21 +886,30 @@
# define INITIALIZE(x)
#endif
+/* Whether memory access must strictly follow the C standard.
+ If 0, it's OK to read uninitialized storage so long as the value is
+ not relied upon. Defining it to 0 lets mktime access parts of
+ struct tm that might be uninitialized, as a heuristic when the
+ standard doesn't say what to return and when tm_gmtoff can help
+ mktime likely infer a better value. */
#ifndef UNINIT_TRAP
# define UNINIT_TRAP 0
#endif
#ifdef DEBUG
-# define UNREACHABLE() abort()
-#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
-# define UNREACHABLE() __builtin_unreachable()
-#elif defined __has_builtin
-# if __has_builtin(__builtin_unreachable)
-# define UNREACHABLE() __builtin_unreachable()
+# undef unreachable
+# define unreachable() abort()
+#elif !defined unreachable
+# ifdef __has_builtin
+# if __has_builtin(__builtin_unreachable)
+# define unreachable() __builtin_unreachable()
+# endif
+# elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
+# define unreachable() __builtin_unreachable()
# endif
-#endif
-#ifndef UNREACHABLE
-# define UNREACHABLE() ((void) 0)
+# ifndef unreachable
+# define unreachable() ((void) 0)
+# endif
#endif
/*
@@ -725,53 +931,61 @@
#if HAVE_INCOMPATIBLE_CTIME_R
#undef asctime_r
#undef ctime_r
-char *asctime_r(struct tm const *, char *);
+char *asctime_r(struct tm const *restrict, char *restrict);
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
/* Handy macros that are independent of tzfile implementation. */
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
+enum {
+ SECSPERMIN = 60,
+ MINSPERHOUR = 60,
+ SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
+ HOURSPERDAY = 24,
+ DAYSPERWEEK = 7,
+ DAYSPERNYEAR = 365,
+ DAYSPERLYEAR = DAYSPERNYEAR + 1,
+ MONSPERYEAR = 12,
+ YEARSPERREPEAT = 400 /* years before a Gregorian repeat */
+};
-#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+
#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1)
#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
+enum {
+ TM_SUNDAY,
+ TM_MONDAY,
+ TM_TUESDAY,
+ TM_WEDNESDAY,
+ TM_THURSDAY,
+ TM_FRIDAY,
+ TM_SATURDAY
+};
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
+enum {
+ TM_JANUARY,
+ TM_FEBRUARY,
+ TM_MARCH,
+ TM_APRIL,
+ TM_MAY,
+ TM_JUNE,
+ TM_JULY,
+ TM_AUGUST,
+ TM_SEPTEMBER,
+ TM_OCTOBER,
+ TM_NOVEMBER,
+ TM_DECEMBER
+};
-#define TM_YEAR_BASE 1900
-#define TM_WDAY_BASE TM_MONDAY
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
+enum {
+ TM_YEAR_BASE = 1900,
+ TM_WDAY_BASE = TM_MONDAY,
+ EPOCH_YEAR = 1970,
+ EPOCH_WDAY = TM_THURSDAY
+};
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index d04c5ba..4cde556 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -71,8 +71,6 @@
const char * date_fmt;
};
-#define Locale (&C_time_locale)
-
static const struct lc_time_T C_time_locale = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -128,13 +126,14 @@
static char * _yconv(int, int, bool, bool, char *, const char *, int);
#ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+# define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
#endif /* !defined YEAR_2000_NAME */
#if HAVE_STRFTIME_L
size_t
-strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
- locale_t locale)
+strftime_l(char *restrict s, size_t maxsize, char const *restrict format,
+ struct tm const *restrict t,
+ ATTRIBUTE_MAYBE_UNUSED locale_t locale)
{
/* Just call strftime, as only the C locale is supported. */
return strftime(s, maxsize, format, t);
@@ -144,7 +143,8 @@
#define FORCE_LOWER_CASE 0x100 /* Android extension. */
size_t
-strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
+strftime(char *restrict s, size_t maxsize, char const *restrict format,
+ struct tm const *restrict t)
{
char * p;
int saved_errno = errno;
@@ -217,6 +217,8 @@
_fmt(const char *format, const struct tm *t, char *pt,
const char *ptlim, enum warn *warnp)
{
+ struct lc_time_T const *Locale = &C_time_locale;
+
for ( ; *format; ++format) {
if (*format == '%') {
int modifier = 0;
@@ -378,12 +380,21 @@
char buf[INT_STRLEN_MAXIMUM(time64_t) + 1] __attribute__((__uninitialized__));
time64_t mkt;
- tm = *t;
+ tm.tm_sec = t->tm_sec;
+ tm.tm_min = t->tm_min;
+ tm.tm_hour = t->tm_hour;
+ tm.tm_mday = t->tm_mday;
+ tm.tm_mon = t->tm_mon;
+ tm.tm_year = t->tm_year;
+ tm.tm_isdst = t->tm_isdst;
+#if defined TM_GMTOFF && ! UNINIT_TRAP
+ tm.TM_GMTOFF = t->TM_GMTOFF;
+#endif
mkt = mktime64(&tm);
- /* There is no portable, definitive
- test for whether whether mktime
- succeeded, so treat (time_t) -1 as
- the success that it might be. */
+ /* If mktime fails, %s expands to the
+ value of (time_t) -1 as a failure
+ marker; this is better in practice
+ than strftime failing. */
if (TYPE_SIGNED(time64_t)) {
intmax_t n = mkt;
sprintf(buf, "%"PRIdMAX, n);
@@ -607,19 +618,19 @@
# endif
negative = diff < 0;
if (diff == 0) {
-#ifdef TM_ZONE
+# ifdef TM_ZONE
// Android-changed: do not use TM_ZONE as it is as it may be null.
{
const char* zone = _safe_tm_zone(t);
negative = zone[0] == '-';
}
-#else
+# else
negative = t->tm_isdst < 0;
-# if HAVE_TZNAME
+# if HAVE_TZNAME
if (tzname[t->tm_isdst != 0][0] == '-')
negative = true;
+# endif
# endif
-#endif
}
if (negative) {
sign = "-";
@@ -748,7 +759,7 @@
register int lead;
register int trail;
-#define DIVISOR 100
+ int DIVISOR = 100;
trail = a % DIVISOR + b % DIVISOR;
lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
trail %= DIVISOR;
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index c5f9967..7ac8b51 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -22,15 +22,15 @@
*/
#ifndef TZDIR
-#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
+# define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
-#define TZDEFAULT "/etc/localtime"
+# define TZDEFAULT "/etc/localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
-#define TZDEFRULES "posixrules"
+# define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
@@ -103,21 +103,25 @@
*/
#ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES 2000
+/* This must be at least 242 for Europe/London with 'zic -b fat'. */
+# define TZ_MAX_TIMES 2000
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
-/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+/* This must be at least 18 for Europe/Vilnius with 'zic -b fat'. */
+# define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+/* This must be at least 40 for America/Anchorage. */
+# define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
/* (limited by what unsigned chars can hold) */
#endif /* !defined TZ_MAX_CHARS */
#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+/* This must be at least 27 for leap seconds from 1972 through mid-2023.
+ There's a plan to discontinue leap seconds by 2035. */
+# define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
#define SECSPERMIN 60
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 4cdec44..fde3dfc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -244,7 +244,7 @@
genrule {
name: "libdl.arm.map",
- out: ["libdl.arm.map"],
+ out: ["libdl.arm.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -252,7 +252,7 @@
genrule {
name: "libdl.arm64.map",
- out: ["libdl.arm64.map"],
+ out: ["libdl.arm64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -260,7 +260,7 @@
genrule {
name: "libdl.riscv64.map",
- out: ["libdl.riscv64.map"],
+ out: ["libdl.riscv64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -268,7 +268,7 @@
genrule {
name: "libdl.x86.map",
- out: ["libdl.x86.map"],
+ out: ["libdl.x86.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -276,7 +276,7 @@
genrule {
name: "libdl.x86_64.map",
- out: ["libdl.x86_64.map"],
+ out: ["libdl.x86_64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/Android.bp b/libm/Android.bp
index cc0d666..13fbf9a 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -94,8 +94,6 @@
"upstream-freebsd/lib/msun/src/s_cbrtf.c",
"upstream-freebsd/lib/msun/src/s_ccosh.c",
"upstream-freebsd/lib/msun/src/s_ccoshf.c",
- "upstream-freebsd/lib/msun/src/s_ceil.c",
- "upstream-freebsd/lib/msun/src/s_ceilf.c",
"upstream-freebsd/lib/msun/src/s_cexp.c",
"upstream-freebsd/lib/msun/src/s_cexpf.c",
"upstream-freebsd/lib/msun/src/s_cimag.c",
@@ -130,8 +128,6 @@
"upstream-freebsd/lib/msun/src/s_fdim.c",
"upstream-freebsd/lib/msun/src/s_finite.c",
"upstream-freebsd/lib/msun/src/s_finitef.c",
- "upstream-freebsd/lib/msun/src/s_floor.c",
- "upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
"upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -282,10 +278,8 @@
arm: {
srcs: [
"arm/fenv.c",
- ],
- exclude_srcs: [
- "upstream-freebsd/lib/msun/src/s_floor.c",
- "upstream-freebsd/lib/msun/src/s_floorf.c",
+ "upstream-freebsd/lib/msun/src/s_ceil.c",
+ "upstream-freebsd/lib/msun/src/s_ceilf.c",
],
instruction_set: "arm",
pack_relocations: false,
@@ -303,10 +297,6 @@
"arm64/fenv.c",
],
exclude_srcs: [
- "upstream-freebsd/lib/msun/src/s_ceil.c",
- "upstream-freebsd/lib/msun/src/s_ceilf.c",
- "upstream-freebsd/lib/msun/src/s_floor.c",
- "upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
"upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -337,11 +327,6 @@
],
exclude_srcs: [
- // TODO: do the rest when our clang has https://reviews.llvm.org/D136508.
- // TODO: "upstream-freebsd/lib/msun/src/s_ceil.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_ceilf.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_floor.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
"upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -356,12 +341,12 @@
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_lround.c",
"upstream-freebsd/lib/msun/src/s_lroundf.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_rint.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_rintf.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_round.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_roundf.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_trunc.c",
- // TODO: "upstream-freebsd/lib/msun/src/s_truncf.c",
+ "upstream-freebsd/lib/msun/src/s_rint.c",
+ "upstream-freebsd/lib/msun/src/s_rintf.c",
+ "upstream-freebsd/lib/msun/src/s_round.c",
+ "upstream-freebsd/lib/msun/src/s_roundf.c",
+ "upstream-freebsd/lib/msun/src/s_trunc.c",
+ "upstream-freebsd/lib/msun/src/s_truncf.c",
],
version_script: ":libm.riscv64.map",
},
@@ -373,10 +358,6 @@
"x86/lrintf.S",
],
exclude_srcs: [
- "upstream-freebsd/lib/msun/src/s_ceil.c",
- "upstream-freebsd/lib/msun/src/s_ceilf.c",
- "upstream-freebsd/lib/msun/src/s_floor.c",
- "upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_rint.c",
@@ -400,10 +381,6 @@
"x86_64/lrintf.S",
],
exclude_srcs: [
- "upstream-freebsd/lib/msun/src/s_ceil.c",
- "upstream-freebsd/lib/msun/src/s_ceilf.c",
- "upstream-freebsd/lib/msun/src/s_floor.c",
- "upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
@@ -496,7 +473,7 @@
genrule {
name: "libm.arm.map",
- out: ["libm.arm.map"],
+ out: ["libm.arm.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -504,7 +481,7 @@
genrule {
name: "libm.arm64.map",
- out: ["libm.arm64.map"],
+ out: ["libm.arm64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -512,7 +489,7 @@
genrule {
name: "libm.riscv64.map",
- out: ["libm.riscv64.map"],
+ out: ["libm.riscv64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -520,7 +497,7 @@
genrule {
name: "libm.x86.map",
- out: ["libm.x86.map"],
+ out: ["libm.x86.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -528,7 +505,7 @@
genrule {
name: "libm.x86_64.map",
- out: ["libm.x86_64.map"],
+ out: ["libm.x86_64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 96c006d..41e145b 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -22,7 +22,7 @@
float fabsf(float x) { return __builtin_fabsf(x); }
long double fabsl(long double x) { return __builtin_fabsl(x); }
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
float ceilf(float x) { return __builtin_ceilf(x); }
double ceil(double x) { return __builtin_ceil(x); }
#if defined(__ILP32__)
@@ -46,7 +46,7 @@
}
float floorf(float x) { return s_floorf::floorf(x); }
double floor(double x) { return s_floor::floor(x); }
-#elif defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#else
float floorf(float x) { return __builtin_floorf(x); }
double floor(double x) { return __builtin_floor(x); }
#if defined(__ILP32__)
@@ -79,7 +79,7 @@
long long llroundf(float x) { return __builtin_llroundf(x); }
#endif
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
float rintf(float x) { return __builtin_rintf(x); }
double rint(double x) { return __builtin_rint(x); }
#if defined(__ILP32__)
@@ -87,7 +87,7 @@
#endif
#endif
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
float roundf(float x) { return __builtin_roundf(x); }
double round(double x) { return __builtin_round(x); }
#endif
@@ -98,7 +98,7 @@
__weak_reference(sqrt, sqrtl);
#endif
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
float truncf(float x) { return __builtin_truncf(x); }
double trunc(double x) { return __builtin_trunc(x); }
#if defined(__ILP32__)
diff --git a/linker/Android.bp b/linker/Android.bp
index 83077c6..020bd7d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -374,6 +374,11 @@
],
symlinks: ["linker_asan"],
+ arch: {
+ arm64: {
+ symlinks: ["linker_hwasan"],
+ },
+ },
multilib: {
lib64: {
suffix: "64",
diff --git a/linker/arch/arm64/tlsdesc_resolver.S b/linker/arch/arm64/tlsdesc_resolver.S
index 96eff8e..ad155e2 100644
--- a/linker/arch/arm64/tlsdesc_resolver.S
+++ b/linker/arch/arm64/tlsdesc_resolver.S
@@ -58,9 +58,9 @@
cmp x21, x22
b.lo .fallback
- ldr x21, [x0, #8] // TlsIndex::module
+ ldr x21, [x0, #8] // TlsIndex::module_id
ldr x22, [x0, #16] // TlsIndex::offset
- ldr x21, [x20, x21, lsl #3] // TlsDtv::modules[module]
+ ldr x21, [x20, x21, lsl #3] // TlsDtv::modules[module_id]
cbz x21, .fallback
add x0, x21, x22
sub x0, x0, x19
diff --git a/linker/arch/riscv64/begin.S b/linker/arch/riscv64/begin.S
index f7509c6..21665cb 100644
--- a/linker/arch/riscv64/begin.S
+++ b/linker/arch/riscv64/begin.S
@@ -33,7 +33,7 @@
.cfi_undefined ra
mv a0, sp
- jal __linker_init
+ call __linker_init
// __linker_init returns the address of the entry point in the main image.
jr a0
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 6246f8c..17b574f 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/vfs.h>
@@ -133,6 +134,36 @@
nullptr
};
+#if defined(__aarch64__)
+static const char* const kHwasanSystemLibDir = "/system/lib64/hwasan";
+static const char* const kHwasanOdmLibDir = "/odm/lib64/hwasan";
+static const char* const kHwasanVendorLibDir = "/vendor/lib64/hwasan";
+
+// HWASan is only supported on aarch64.
+static const char* const kHwsanDefaultLdPaths[] = {
+ kHwasanSystemLibDir,
+ kSystemLibDir,
+ kHwasanOdmLibDir,
+ kOdmLibDir,
+ kHwasanVendorLibDir,
+ kVendorLibDir,
+ nullptr
+};
+
+// Is HWASAN enabled?
+static bool g_is_hwasan = false;
+#else
+static const char* const kHwsanDefaultLdPaths[] = {
+ kSystemLibDir,
+ kOdmLibDir,
+ kVendorLibDir,
+ nullptr
+};
+
+// Never any HWASan. Help the compiler remove the code we don't need.
+constexpr bool g_is_hwasan = false;
+#endif
+
// Is ASAN enabled?
static bool g_is_asan = false;
@@ -2134,26 +2165,46 @@
}
// End Workaround for dlopen(/system/lib/<soname>) when .so is in /apex.
- std::string asan_name_holder;
+ std::string translated_name_holder;
+ assert(!g_is_hwasan || !g_is_asan);
const char* translated_name = name;
if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
char original_path[PATH_MAX];
if (realpath(name, original_path) != nullptr) {
- asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
- if (file_exists(asan_name_holder.c_str())) {
+ translated_name_holder = std::string(kAsanLibDirPrefix) + original_path;
+ 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,
- asan_name_holder.c_str());
+ translated_name_holder.c_str());
} else {
PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
- translated_name = asan_name_holder.c_str();
+ translated_name = translated_name_holder.c_str();
+ }
+ }
+ }
+ } else if (g_is_hwasan && translated_name != nullptr && translated_name[0] == '/') {
+ char original_path[PATH_MAX];
+ if (realpath(name, original_path) != nullptr) {
+ // Keep this the same as CreateHwasanPath in system/linkerconfig/modules/namespace.cc.
+ std::string path(original_path);
+ auto slash = path.rfind('/');
+ if (slash != std::string::npos || slash != path.size() - 1) {
+ translated_name_holder = path.substr(0, slash) + "/hwasan" + path.substr(slash);
+ }
+ 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());
+ } else {
+ PRINT("linker_hwasan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ translated_name = translated_name_holder.c_str();
}
}
}
}
-
ProtectedDataGuard guard;
soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
loading_trace.End();
@@ -3142,6 +3193,14 @@
case DT_AARCH64_VARIANT_PCS:
// Ignored: AArch64 processor-specific dynamic array tags.
break;
+ // TODO(mitchp): Add support to libc_init_mte to use these dynamic array entries instead of
+ // the Android-specific ELF note.
+ case DT_AARCH64_MEMTAG_MODE:
+ case DT_AARCH64_MEMTAG_HEAP:
+ case DT_AARCH64_MEMTAG_STACK:
+ case DT_AARCH64_MEMTAG_GLOBALS:
+ case DT_AARCH64_MEMTAG_GLOBALSSZ:
+ break;
#endif
default:
@@ -3327,9 +3386,10 @@
return true;
}
-static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan, bool is_hwasan) {
g_default_namespace.set_isolated(false);
- auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
+ auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : (
+ is_hwasan ? kHwsanDefaultLdPaths : kDefaultLdPaths);
char real_path[PATH_MAX];
std::vector<std::string> ld_default_paths;
@@ -3433,6 +3493,7 @@
return kLdConfigFilePath;
}
+
std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
g_default_namespace.set_name("(default)");
@@ -3446,6 +3507,16 @@
(strcmp(bname, "linker_asan") == 0 ||
strcmp(bname, "linker_asan64") == 0);
+#if defined(__aarch64__)
+ // HWASan is only supported on AArch64.
+ // The AT_SECURE restriction is because this is a debug feature that does
+ // not need to work on secure binaries, it doesn't hurt to disallow the
+ // environment variable for them, as it impacts the program execution.
+ char* hwasan_env = getenv("LD_HWASAN");
+ g_is_hwasan = (bname != nullptr &&
+ strcmp(bname, "linker_hwasan64") == 0) ||
+ (hwasan_env != nullptr && !getauxval(AT_SECURE) && strcmp(hwasan_env, "1") == 0);
+#endif
const Config* config = nullptr;
{
@@ -3453,7 +3524,7 @@
INFO("[ 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,
+ if (!Config::read_binary_config(ld_config_file_path.c_str(), executable_path, g_is_asan, g_is_hwasan,
&config, &error_msg)) {
if (!error_msg.empty()) {
DL_WARN("Warning: couldn't read '%s' for '%s' (using default configuration instead): %s",
@@ -3464,7 +3535,7 @@
}
if (config == nullptr) {
- return init_default_namespace_no_config(g_is_asan);
+ return init_default_namespace_no_config(g_is_asan, g_is_hwasan);
}
const auto& namespace_configs = config->namespace_configs();
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 1771e87..ad40c50 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -463,6 +463,7 @@
bool Config::read_binary_config(const char* ld_config_file_path,
const char* binary_realpath,
bool is_asan,
+ bool is_hwasan,
const Config** config,
std::string* error_msg) {
g_config.clear();
@@ -579,6 +580,8 @@
// these are affected by is_asan flag
if (is_asan) {
property_name_prefix += ".asan";
+ } else if (is_hwasan) {
+ property_name_prefix += ".hwasan";
}
// search paths are resolved (canonicalized). This is required mainly for
diff --git a/linker/linker_config.h b/linker/linker_config.h
index fe23ec1..09fea45 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -166,6 +166,7 @@
static bool read_binary_config(const char* ld_config_file_path,
const char* binary_realpath,
bool is_asan,
+ bool is_hwasan,
const Config** config,
std::string* error_msg);
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index acdf641..7e947f3 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -40,6 +40,7 @@
#include <android-base/file.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
+#include <vector>
#if defined(__LP64__)
#define ARCH_SUFFIX "64"
@@ -64,6 +65,10 @@
"namespace.default.asan.search.paths = /data\n"
"namespace.default.asan.search.paths += /vendor/${LIB}\n"
"namespace.default.asan.permitted.paths = /data:/vendor\n"
+ "namespace.default.hwasan.search.paths = /vendor/${LIB}/hwasan\n"
+ "namespace.default.hwasan.search.paths += /vendor/${LIB}\n"
+ "namespace.default.hwasan.permitted.paths = /vendor/${LIB}/hwasan\n"
+ "namespace.default.hwasan.permitted.paths += /vendor/${LIB}\n"
"namespace.default.links = system\n"
"namespace.default.links += vndk\n"
// irregular whitespaces are added intentionally for testing purpose
@@ -77,11 +82,17 @@
"namespace.system.permitted.paths = /system/${LIB}\n"
"namespace.system.asan.search.paths = /data:/system/${LIB}\n"
"namespace.system.asan.permitted.paths = /data:/system\n"
+ "namespace.system.hwasan.search.paths = /system/${LIB}/hwasan\n"
+ "namespace.system.hwasan.search.paths += /system/${LIB}\n"
+ "namespace.system.hwasan.permitted.paths = /system/${LIB}/hwasan\n"
+ "namespace.system.hwasan.permitted.paths += /system/${LIB}\n"
"namespace.vndk.isolated = tr\n"
"namespace.vndk.isolated += ue\n" // should be ignored and return as 'false'.
"namespace.vndk.search.paths = /system/${LIB}/vndk\n"
"namespace.vndk.asan.search.paths = /data\n"
"namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
+ "namespace.vndk.hwasan.search.paths = /system/${LIB}/vndk/hwasan\n"
+ "namespace.vndk.hwasan.search.paths += /system/${LIB}/vndk\n"
"namespace.vndk.links = default\n"
"namespace.vndk.link.default.allow_all_shared_libs = true\n"
"namespace.vndk.link.vndk_in_system.allow_all_shared_libs = true\n"
@@ -107,26 +118,50 @@
return resolved_paths;
}
-static void run_linker_config_smoke_test(bool is_asan) {
- const std::vector<std::string> kExpectedDefaultSearchPath =
- resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor/lib" ARCH_SUFFIX }) :
- std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
+enum class SmokeTestType {
+ None,
+ Asan,
+ Hwasan,
+};
- const std::vector<std::string> kExpectedDefaultPermittedPath =
- resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor" }) :
- std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
+static void run_linker_config_smoke_test(SmokeTestType type) {
+ std::vector<std::string> expected_default_search_path;
+ std::vector<std::string> expected_default_permitted_path;
+ std::vector<std::string> expected_system_search_path;
+ std::vector<std::string> expected_system_permitted_path;
+ std::vector<std::string> expected_vndk_search_path;
- const std::vector<std::string> kExpectedSystemSearchPath =
- resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system/lib" ARCH_SUFFIX }) :
- std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
+ switch (type) {
+ case SmokeTestType::None:
+ expected_default_search_path = { "/vendor/lib" ARCH_SUFFIX };
+ expected_default_permitted_path = { "/vendor/lib" ARCH_SUFFIX };
+ expected_system_search_path = { "/system/lib" ARCH_SUFFIX };
+ expected_system_permitted_path = { "/system/lib" ARCH_SUFFIX };
+ expected_vndk_search_path = { "/system/lib" ARCH_SUFFIX "/vndk" };
+ break;
+ case SmokeTestType::Asan:
+ expected_default_search_path = { "/data", "/vendor/lib" ARCH_SUFFIX };
+ expected_default_permitted_path = { "/data", "/vendor" };
+ expected_system_search_path = { "/data", "/system/lib" ARCH_SUFFIX };
+ expected_system_permitted_path = { "/data", "/system" };
+ expected_vndk_search_path = { "/data", "/system/lib" ARCH_SUFFIX "/vndk" };
+ break;
+ case SmokeTestType::Hwasan:
+ expected_default_search_path = { "/vendor/lib" ARCH_SUFFIX "/hwasan", "/vendor/lib" ARCH_SUFFIX };
+ expected_default_permitted_path = { "/vendor/lib" ARCH_SUFFIX "/hwasan", "/vendor/lib" ARCH_SUFFIX };
+ expected_system_search_path = { "/system/lib" ARCH_SUFFIX "/hwasan" , "/system/lib" ARCH_SUFFIX };
+ expected_system_permitted_path = { "/system/lib" ARCH_SUFFIX "/hwasan", "/system/lib" ARCH_SUFFIX };
+ expected_vndk_search_path = { "/system/lib" ARCH_SUFFIX "/vndk/hwasan", "/system/lib" ARCH_SUFFIX "/vndk" };
+ break;
+ }
- const std::vector<std::string> kExpectedSystemPermittedPath =
- resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system" }) :
- std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
-
- const std::vector<std::string> kExpectedVndkSearchPath =
- resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system/lib" ARCH_SUFFIX "/vndk"}) :
- std::vector<std::string>({ "/system/lib" ARCH_SUFFIX "/vndk"}));
+ expected_default_search_path = resolve_paths(expected_default_search_path);
+ // expected_default_permitted_path is skipped on purpose, permitted paths
+ // do not get resolved in linker_config.cpp
+ expected_system_search_path = resolve_paths(expected_system_search_path);
+ // expected_system_permitted_path is skipped on purpose, permitted paths
+ // do not get resolved in linker_config.cpp
+ expected_vndk_search_path = resolve_paths(expected_vndk_search_path);
TemporaryFile tmp_file;
close(tmp_file.fd);
@@ -149,7 +184,8 @@
std::string error_msg;
ASSERT_TRUE(Config::read_binary_config(tmp_file.path,
executable_path.c_str(),
- is_asan,
+ type == SmokeTestType::Asan,
+ type == SmokeTestType::Hwasan,
&config,
&error_msg)) << error_msg;
ASSERT_TRUE(config != nullptr);
@@ -162,8 +198,8 @@
ASSERT_TRUE(default_ns_config->isolated());
ASSERT_FALSE(default_ns_config->visible());
- ASSERT_EQ(kExpectedDefaultSearchPath, default_ns_config->search_paths());
- ASSERT_EQ(kExpectedDefaultPermittedPath, default_ns_config->permitted_paths());
+ ASSERT_EQ(expected_default_search_path, default_ns_config->search_paths());
+ ASSERT_EQ(expected_default_permitted_path, default_ns_config->permitted_paths());
const auto& default_ns_links = default_ns_config->links();
ASSERT_EQ(2U, default_ns_links.size());
@@ -202,14 +238,14 @@
ASSERT_TRUE(ns_system->isolated());
ASSERT_TRUE(ns_system->visible());
- ASSERT_EQ(kExpectedSystemSearchPath, ns_system->search_paths());
- ASSERT_EQ(kExpectedSystemPermittedPath, ns_system->permitted_paths());
+ ASSERT_EQ(expected_system_search_path, ns_system->search_paths());
+ ASSERT_EQ(expected_system_permitted_path, ns_system->permitted_paths());
ASSERT_TRUE(ns_vndk != nullptr) << "vndk namespace was not found";
ASSERT_FALSE(ns_vndk->isolated()); // malformed bool property
ASSERT_FALSE(ns_vndk->visible()); // undefined bool property
- ASSERT_EQ(kExpectedVndkSearchPath, ns_vndk->search_paths());
+ ASSERT_EQ(expected_vndk_search_path, ns_vndk->search_paths());
const auto& ns_vndk_links = ns_vndk->links();
ASSERT_EQ(1U, ns_vndk_links.size());
@@ -223,11 +259,15 @@
}
TEST(linker_config, smoke) {
- run_linker_config_smoke_test(false);
+ run_linker_config_smoke_test(SmokeTestType::None);
}
TEST(linker_config, asan_smoke) {
- run_linker_config_smoke_test(true);
+ run_linker_config_smoke_test(SmokeTestType::Asan);
+}
+
+TEST(linker_config, hwasan_smoke) {
+ run_linker_config_smoke_test(SmokeTestType::Hwasan);
}
TEST(linker_config, ns_link_shared_libs_invalid_settings) {
@@ -259,6 +299,7 @@
ASSERT_FALSE(Config::read_binary_config(tmp_file.path,
executable_path.c_str(),
false,
+ false,
&config,
&error_msg));
ASSERT_TRUE(config == nullptr);
@@ -304,6 +345,7 @@
ASSERT_TRUE(Config::read_binary_config(tmp_file.path,
executable_path.c_str(),
false,
+ false,
&config,
&error_msg)) << error_msg;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 833157e..26e2228 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -43,7 +43,6 @@
#include "linker_tls.h"
#include "linker_utils.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_call_ifunc_resolver.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
diff --git a/tests/Android.bp b/tests/Android.bp
index 8c6057f..281e29d 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -66,18 +66,20 @@
"libcutils_headers",
"gwp_asan_headers"
],
- // Ensure that the tests exercise shadow call stack support and
- // the hint space PAC/BTI instructions.
+ stl: "libc++",
+
+ // Ensure that the tests exercise shadow call stack support.
+ // We don't use `scs: true` here because that would give us a second
+ // variant of this library where we actually just want to say "this
+ // library should always be built this way".
arch: {
arm64: {
- cflags: [
- "-fsanitize=shadow-call-stack",
- // Disable this option for now: see b/151372823
- //"-mbranch-protection=standard",
- ],
+ cflags: ["-fsanitize=shadow-call-stack"],
+ },
+ riscv64: {
+ cflags: ["-fsanitize=shadow-call-stack"],
},
},
- stl: "libc++",
sanitize: {
address: false,
},
@@ -501,6 +503,7 @@
"sys_vfs_test.cpp",
"sys_wait_test.cpp",
"sys_xattr_test.cpp",
+ "syslog_test.cpp",
"system_properties_test.cpp",
"system_properties_test2.cpp",
"termios_test.cpp",
@@ -512,6 +515,7 @@
"unistd_test.cpp",
"utils.cpp",
"utmp_test.cpp",
+ "utmpx_test.cpp",
"wchar_test.cpp",
"wctype_test.cpp",
],
@@ -538,6 +542,10 @@
// unsupported relocation type 37
"ifunc_test.cpp",
+
+ // musl #defines utmp to utmpx, causing a collision with
+ // utmpx_test.cpp
+ "utmp_test.cpp",
],
},
},
@@ -1109,6 +1117,30 @@
}
cc_test {
+ name: "hwasan_test",
+ enabled: false,
+ // This does not use bionic_tests_defaults because it is not supported on
+ // host.
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+ sanitize: {
+ hwaddress: true,
+ },
+ srcs: [
+ "hwasan_test.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ ],
+ data_libs: ["libtest_simple_hwasan", "libtest_simple_hwasan_nohwasan"],
+ header_libs: ["bionic_libc_platform_headers"],
+ test_suites: ["device-tests"],
+}
+
+cc_test {
name: "bionic-stress-tests",
defaults: [
"bionic_tests_defaults",
diff --git a/tests/NOTICE b/tests/NOTICE
index 167f90b..cc99d20 100644
--- a/tests/NOTICE
+++ b/tests/NOTICE
@@ -426,3 +426,31 @@
-------------------------------------------------------------------
+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.
+
+-------------------------------------------------------------------
+
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index f52387e..dc4db07 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -16,6 +16,8 @@
#include <gtest/gtest.h>
+#include <errno.h>
+
#if defined(__BIONIC__)
#include <async_safe/log.h>
#endif // __BIONIC__
@@ -227,3 +229,19 @@
GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
+
+// Verify that using %m is never cut off.
+TEST(async_safe_format_buffer, percent_m_fits_in_buffer) {
+#if defined(__BIONIC__)
+ for (int i = 0; i < 256; i++) {
+ errno = i;
+ char async_buf[256];
+ async_safe_format_buffer(async_buf, sizeof(async_buf), "%m");
+ char strerror_buf[1024];
+ strerror_r(errno, strerror_buf, sizeof(strerror_buf));
+ ASSERT_STREQ(strerror_buf, async_buf);
+ }
+#else // __BIONIC__
+ GTEST_SKIP() << "bionic-only test";
+#endif // __BIONIC__
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 3f70279..b68ee7b 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -971,9 +971,15 @@
}
#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/" ABI_STRING "/"
+#if __has_feature(hwaddress_sanitizer)
+#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "hwasan/libc.so"
+#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/hwasan/libc.so"
+#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "hwasan/libc.so"
+#else
#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/libc.so"
#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
+#endif
TEST(dlfcn, dladdr_libc) {
#if defined(__GLIBC__)
@@ -981,24 +987,25 @@
#endif
Dl_info info;
- void* addr = reinterpret_cast<void*>(puts); // well-known libc function
+ void* addr = reinterpret_cast<void*>(puts); // An arbitrary libc function.
ASSERT_TRUE(dladdr(addr, &info) != 0);
- char libc_realpath[PATH_MAX];
-
// Check if libc is in canonical path or in alternate path.
+ const char* expected_path;
if (strncmp(ALTERNATE_PATH_TO_SYSTEM_LIB,
info.dli_fname,
sizeof(ALTERNATE_PATH_TO_SYSTEM_LIB) - 1) == 0) {
// Platform with emulated architecture. Symlink on ARC++.
- ASSERT_TRUE(realpath(ALTERNATE_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+ expected_path = ALTERNATE_PATH_TO_LIBC;
} else if (strncmp(PATH_TO_BOOTSTRAP_LIBC, info.dli_fname,
sizeof(PATH_TO_BOOTSTRAP_LIBC) - 1) == 0) {
- ASSERT_TRUE(realpath(PATH_TO_BOOTSTRAP_LIBC, libc_realpath) == libc_realpath);
+ expected_path = PATH_TO_BOOTSTRAP_LIBC;
} else {
// /system/lib is symlink when this test is executed on host.
- ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);
+ expected_path = PATH_TO_LIBC;
}
+ char libc_realpath[PATH_MAX];
+ ASSERT_TRUE(realpath(expected_path, libc_realpath) != nullptr) << strerror(errno);
ASSERT_STREQ(libc_realpath, info.dli_fname);
// TODO: add check for dfi_fbase
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 4abee67..cc3080d 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -670,6 +670,10 @@
ASSERT_FORTIFY(readlinkat(AT_FDCWD, "/dev/null", buf, ct));
}
+TEST(TEST_NAME, snprintf_nullptr_valid) {
+ ASSERT_EQ(10, snprintf(nullptr, 0, "0123456789"));
+}
+
extern "C" char* __strncat_chk(char*, const char*, size_t, size_t);
extern "C" char* __strcat_chk(char*, const char*, size_t);
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index 8b12bec..c31f48c 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -143,6 +143,16 @@
EXPECT_DEATH({ *x = 7; }, "");
}
+// A weaker version of the above tests, only checking that GWP-ASan is enabled
+// for any pointer, not *our* pointer. This allows us to test the system_default
+// sysprops without potentially OOM-ing other random processes:
+// b/273904016#comment5
+TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled_weaker) {
+ std::string maps;
+ EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
+ EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
+}
+
TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_disabled) {
std::string maps;
EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
@@ -184,32 +194,6 @@
RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
}
-TEST(gwp_asan_integration, sysprops_system) {
- // Do not override HWASan with GWP ASan.
- SKIP_WITH_HWASAN;
-
- SyspropRestorer restorer;
-
- __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
- __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
- __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
-
- RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
-}
-
-TEST(gwp_asan_integration, sysprops_persist_system) {
- // Do not override HWASan with GWP ASan.
- SKIP_WITH_HWASAN;
-
- SyspropRestorer restorer;
-
- __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
- __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "1");
- __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "40000");
-
- RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
-}
-
TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
// Do not override HWASan with GWP ASan.
SKIP_WITH_HWASAN;
@@ -218,13 +202,18 @@
__system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
__system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
- __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
+ // Note, any processes launched elsewhere on the system right now will have
+ // GWP-ASan enabled. Make sure that we only use a single slot, otherwise we
+ // could end up causing said badly-timed processes to use up to 163MiB extra
+ // penalty that 40,000 allocs would cause. See b/273904016#comment5 for more
+ // context.
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "1");
__system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "0");
__system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "0");
__system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "0");
- RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled_weaker");
}
TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
diff --git a/tests/headers/posix/README.md b/tests/headers/posix/README.md
new file mode 100644
index 0000000..e7c171a
--- /dev/null
+++ b/tests/headers/posix/README.md
@@ -0,0 +1,8 @@
+# POSIX header tests
+
+These compile-time tests check that each POSIX header contains _at
+least_ what POSIX says. Every POSIX header file gets a corresponding
+`.c` file in this directory. Every constant, macro, type, struct field,
+and function in the header gets a corresponding assertion in the file.
+
+See `header_checks.h` for the implementation of the assertions.
diff --git a/tests/headers/posix/utmpx_h.c b/tests/headers/posix/utmpx_h.c
new file mode 100644
index 0000000..44dfac9
--- /dev/null
+++ b/tests/headers/posix/utmpx_h.c
@@ -0,0 +1,63 @@
+/*
+ * 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 <utmpx.h>
+
+#include "header_checks.h"
+
+static void utmpx_h() {
+ TYPE(struct utmpx);
+ STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_user);
+ STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_id);
+ STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_line);
+ STRUCT_MEMBER(struct utmpx, pid_t, ut_pid);
+ STRUCT_MEMBER(struct utmpx, short, ut_type);
+#if !defined(__GLIBC__)
+ // POSIX says struct timeval, but glibc has an anonymous struct.
+ STRUCT_MEMBER(struct utmpx, struct timeval, ut_tv);
+#endif
+
+ TYPE(pid_t);
+ TYPE(struct timeval);
+
+ MACRO(EMPTY);
+ MACRO(BOOT_TIME);
+ MACRO(OLD_TIME);
+ MACRO(NEW_TIME);
+ MACRO(USER_PROCESS);
+ MACRO(INIT_PROCESS);
+ MACRO(LOGIN_PROCESS);
+ MACRO(DEAD_PROCESS);
+
+ FUNCTION(endutxent, void (*f)(void));
+ FUNCTION(getutxent, struct utmpx* (*f)(void));
+ FUNCTION(getutxid, struct utmpx* (*f)(const struct utmpx*));
+ FUNCTION(getutxline, struct utmpx* (*f)(const struct utmpx*));
+ FUNCTION(pututxline, struct utmpx* (*f)(const struct utmpx*));
+ FUNCTION(setutxent, void (*f)(void));
+}
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index ae678b7..917be37 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -26,6 +26,7 @@
#include "SignalUtils.h"
+#include <android-base/properties.h>
#include <android-base/test_utils.h>
#include <bionic/malloc_tagged_pointers.h>
@@ -223,6 +224,9 @@
TEST_P(MemtagNoteTest, SEGV) {
#if defined(__BIONIC__) && defined(__aarch64__)
SKIP_WITH_NATIVE_BRIDGE; // http://b/242170715
+ if (android::base::GetProperty("persist.arm64.memtag.default", "") != "") {
+ GTEST_SKIP() << "not supported when overriding memtag mode with property";
+ }
// Note that we do not check running_with_hwasan() - what matters here is whether the test binary
// itself is built with HWASan.
bool withHWASAN = __has_feature(hwaddress_sanitizer);
diff --git a/tests/hwasan_test.cpp b/tests/hwasan_test.cpp
new file mode 100644
index 0000000..e32534e
--- /dev/null
+++ b/tests/hwasan_test.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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 <dlfcn.h>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+
+#include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
+
+using HwasanDeathTest = SilentDeathTest;
+
+TEST_F(HwasanDeathTest, UseAfterFree) {
+ EXPECT_DEATH(
+ {
+ void* m = malloc(1);
+ volatile char* x = const_cast<volatile char*>(reinterpret_cast<char*>(m));
+ *x = 1;
+ free(m);
+ *x = 2;
+ },
+ "use-after-free");
+}
+
+TEST_F(HwasanDeathTest, OutOfBounds) {
+ EXPECT_DEATH(
+ {
+ void* m = malloc(1);
+ volatile char* x = const_cast<volatile char*>(reinterpret_cast<char*>(m));
+ x[1] = 1;
+ },
+ "buffer-overflow");
+}
+
+// Check whether dlopen of /foo/bar.so checks /foo/hwasan/bar.so first.
+TEST(HwasanTest, 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 =
+ android::base::GetExecutableDirectory() + "/hwasan/libtest_simple_hwasan.so";
+ ASSERT_EQ(0, access(hwasan_path.c_str(), F_OK)); // Verify test setup.
+
+ void* handle = dlopen(path.c_str(), RTLD_NOW);
+ ASSERT_TRUE(handle != nullptr);
+ uint32_t* compiled_with_hwasan =
+ reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_compiled_with_hwasan"));
+ EXPECT_TRUE(*compiled_with_hwasan);
+ dlclose(handle);
+}
+
+TEST(HwasanTest, IsRunningWithHWasan) {
+ EXPECT_TRUE(running_with_hwasan());
+}
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 8ae2257..a2fbe55 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -243,6 +243,38 @@
}
// -----------------------------------------------------------------------------
+// Libraries used by hwasan_test
+// -----------------------------------------------------------------------------
+cc_test_library {
+ name: "libtest_simple_hwasan",
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+ sanitize: {
+ hwaddress: true,
+ },
+ relative_install_path: "hwasan",
+ enabled: false,
+ srcs: ["dlopen_testlib_simple_hwasan.cpp"],
+}
+
+cc_test_library {
+ // A weird name. This is the vanilla (non-HWASan) copy of the library that
+ // is used for the hwasan test.
+ name: "libtest_simple_hwasan_nohwasan",
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+ stem: "libtest_simple_hwasan",
+ enabled: false,
+ srcs: ["dlopen_testlib_simple_hwasan.cpp"],
+}
+
+// -----------------------------------------------------------------------------
// Library used by dlext direct unload on the namespace boundary tests
// -----------------------------------------------------------------------------
cc_test_library {
diff --git a/libc/bionic/timespec_get.cpp b/tests/libs/dlopen_testlib_simple_hwasan.cpp
similarity index 79%
copy from libc/bionic/timespec_get.cpp
copy to tests/libs/dlopen_testlib_simple_hwasan.cpp
index 7fc2182..ddf8a31 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/tests/libs/dlopen_testlib_simple_hwasan.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,14 @@
* SUCH DAMAGE.
*/
-#include <time.h>
+#include <stdint.h>
-int timespec_get(timespec* ts, int base) {
- return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
+#if __has_feature(hwaddress_sanitizer)
+extern "C" uint32_t dlopen_testlib_compiled_with_hwasan = true;
+#else
+extern "C" uint32_t dlopen_testlib_compiled_with_hwasan = false;
+#endif
+
+extern "C" bool dlopen_testlib_simple_hwasan_func() {
+ return true;
}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 63ad99d..22905f4 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -36,7 +36,10 @@
#include <algorithm>
#include <atomic>
#include <functional>
+#include <string>
#include <thread>
+#include <unordered_map>
+#include <utility>
#include <vector>
#include <tinyxml2.h>
@@ -695,6 +698,44 @@
#endif
}
+TEST(malloc, mallopt_purge_all) {
+#if defined(__BIONIC__)
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
+ errno = 0;
+ ASSERT_EQ(1, mallopt(M_PURGE_ALL, 0));
+#else
+ GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
+// Verify that all of the mallopt values are unique.
+TEST(malloc, mallopt_unique_params) {
+#if defined(__BIONIC__)
+ std::vector<std::pair<int, std::string>> params{
+ std::make_pair(M_DECAY_TIME, "M_DECAY_TIME"),
+ std::make_pair(M_PURGE, "M_PURGE"),
+ std::make_pair(M_PURGE_ALL, "M_PURGE_ALL"),
+ std::make_pair(M_MEMTAG_TUNING, "M_MEMTAG_TUNING"),
+ std::make_pair(M_THREAD_DISABLE_MEM_INIT, "M_THREAD_DISABLE_MEM_INIT"),
+ std::make_pair(M_CACHE_COUNT_MAX, "M_CACHE_COUNT_MAX"),
+ std::make_pair(M_CACHE_SIZE_MAX, "M_CACHE_SIZE_MAX"),
+ std::make_pair(M_TSDS_COUNT_MAX, "M_TSDS_COUNT_MAX"),
+ std::make_pair(M_BIONIC_ZERO_INIT, "M_BIONIC_ZERO_INIT"),
+ std::make_pair(M_BIONIC_SET_HEAP_TAGGING_LEVEL, "M_BIONIC_SET_HEAP_TAGGING_LEVEL"),
+ };
+
+ std::unordered_map<int, std::string> all_params;
+ for (const auto& param : params) {
+ EXPECT_TRUE(all_params.count(param.first) == 0)
+ << "mallopt params " << all_params[param.first] << " and " << param.second
+ << " have the same value " << param.first;
+ all_params.insert(param);
+ }
+#else
+ GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
#if defined(__BIONIC__)
static void GetAllocatorVersion(bool* allocator_scudo) {
TemporaryFile tf;
@@ -1572,6 +1613,7 @@
}
// Verify that small and medium allocations are always zero.
+// @CddTest = 9.7/C-4-1
TEST(malloc, zeroed_allocations_small_medium_sizes) {
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
@@ -1601,6 +1643,7 @@
}
// Verify that large allocations are always zero.
+// @CddTest = 9.7/C-4-1
TEST(malloc, zeroed_allocations_large_sizes) {
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
@@ -1629,6 +1672,8 @@
"posix_memalign", test_sizes, kMaxAllocations);
}
+// Verify that reallocs are zeroed when expanded.
+// @CddTest = 9.7/C-4-1
TEST(malloc, zeroed_allocations_realloc) {
#if !defined(__BIONIC__)
GTEST_SKIP() << "Only valid on bionic";
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 06a0f3d..aad2a4d 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -195,12 +195,12 @@
SKIP_WITH_HWASAN; // TODO(b/148982147): Re-enable when fixed.
size_t stack_size = 640 * 1024;
- std::vector<char> stack_vec(stack_size, '\xff');
- void* stack = stack_vec.data();
+ std::unique_ptr<char[]> stack(new (std::align_val_t(getpagesize())) char[stack_size]);
+ memset(stack.get(), '\xff', stack_size);
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
- ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size));
+ ASSERT_EQ(0, pthread_attr_setstack(&attr, stack.get(), stack_size));
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, &attr, FnWithStackFrame, nullptr));
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 03e8062..fa1a07f 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -303,5 +303,8 @@
}
TEST(sched, sched_getaffinity_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+#pragma clang diagnostic pop
}
diff --git a/tests/scs_test.cpp b/tests/scs_test.cpp
index 24cb347..0776a43 100644
--- a/tests/scs_test.cpp
+++ b/tests/scs_test.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#if __has_feature(shadow_call_stack)
-
#include <gtest/gtest.h>
#include "private/bionic_constants.h"
@@ -33,7 +31,9 @@
}
TEST(scs_test, stack_overflow) {
+#if defined(__aarch64__) || defined(__riscv)
ASSERT_EXIT(recurse1(SCS_SIZE), testing::KilledBySignal(SIGSEGV), "");
-}
-
+#else
+ GTEST_SKIP() << "no SCS on this architecture";
#endif
+}
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index f3f6020..6f8797f 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -165,8 +165,10 @@
TEST_F(semaphore_DeathTest, sem_timedwait_null_timeout) {
sem_t s;
ASSERT_EQ(0, sem_init(&s, 0, 0));
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
+#pragma clang diagnostic pop
}
TEST(semaphore, sem_getvalue) {
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 2f891ec..6ae8bfd 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -278,7 +278,6 @@
}
TEST(setjmp, bug_152210274) {
- SKIP_WITH_HWASAN; // b/227390656
// Ensure that we never have a mangled value in the stack pointer.
#if defined(__BIONIC__)
struct sigaction sa = {.sa_flags = SA_SIGINFO, .sa_sigaction = [](int, siginfo_t*, void*) {}};
@@ -299,15 +298,19 @@
perror("setjmp");
abort();
}
- if (*static_cast<pid_t*>(arg) == 100) longjmp(buf, 1);
+ // This will never be true, but the compiler doesn't know that, so the
+ // setjmp won't be removed by DCE. With HWASan/MTE this also acts as a
+ // kind of enforcement that the threads are done before leaving the test.
+ if (*static_cast<size_t*>(arg) != 123) longjmp(buf, 1);
}
return nullptr;
};
+ pthread_t threads[kNumThreads];
pid_t tids[kNumThreads] = {};
+ size_t var = 123;
for (size_t i = 0; i < kNumThreads; ++i) {
- pthread_t t;
- ASSERT_EQ(0, pthread_create(&t, nullptr, jumper, &tids[i]));
- tids[i] = pthread_gettid_np(t);
+ ASSERT_EQ(0, pthread_create(&threads[i], nullptr, jumper, &var));
+ tids[i] = pthread_gettid_np(threads[i]);
}
// Start the interrupter thread.
@@ -327,6 +330,9 @@
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, nullptr, interrupter, tids));
pthread_join(t, nullptr);
+ for (size_t i = 0; i < kNumThreads; i++) {
+ pthread_join(threads[i], nullptr);
+ }
#else
GTEST_SKIP() << "tests uses functions not in glibc";
#endif
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index a9563b8..ab3e877 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -232,18 +232,28 @@
}
TEST(spawn, posix_spawn_file_actions) {
+#if !defined(__GLIBC__)
int fds[2];
ASSERT_NE(-1, pipe(fds));
posix_spawn_file_actions_t fa;
ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
+ // Test addclose and adddup2 by redirecting output to the pipe created above.
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
// Check that close(2) failures are ignored by closing the same fd again.
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
+ // Open a file directly, to test addopen.
ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 56, "/proc/version", O_RDONLY, 0));
+ // Test addfchdir by opening the same file a second way...
+ ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 57, "/proc", O_PATH, 0));
+ ASSERT_EQ(0, posix_spawn_file_actions_addfchdir_np(&fa, 57));
+ ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 58, "version", O_RDONLY, 0));
+ // Test addchdir by opening the same file a third way...
+ ASSERT_EQ(0, posix_spawn_file_actions_addchdir_np(&fa, "/"));
+ ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 59, "proc/version", O_RDONLY, 0));
ExecTestHelper eth;
eth.SetArgs({"ls", "-l", "/proc/self/fd", nullptr});
@@ -259,12 +269,21 @@
AssertChildExited(pid, 0);
// We'll know the dup2 worked if we see any ls(1) output in our pipe.
- // The open we can check manually...
+ // The opens we can check manually (and they implicitly check the chdirs)...
bool open_to_fd_56_worked = false;
+ bool open_to_fd_58_worked = false;
+ bool open_to_fd_59_worked = false;
for (const auto& line : android::base::Split(content, "\n")) {
if (line.find(" 56 -> /proc/version") != std::string::npos) open_to_fd_56_worked = true;
+ if (line.find(" 58 -> /proc/version") != std::string::npos) open_to_fd_58_worked = true;
+ if (line.find(" 59 -> /proc/version") != std::string::npos) open_to_fd_59_worked = true;
}
- ASSERT_TRUE(open_to_fd_56_worked);
+ ASSERT_TRUE(open_to_fd_56_worked) << content;
+ ASSERT_TRUE(open_to_fd_58_worked) << content;
+ ASSERT_TRUE(open_to_fd_59_worked) << content;
+#else
+ GTEST_SKIP() << "our old glibc doesn't have the chdirs; newer versions and musl do.";
+#endif
}
static void CatFileToString(posix_spawnattr_t* sa, const char* path, std::string* content) {
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index fb6bce9..b85edfb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -36,6 +36,7 @@
#include <android-base/file.h>
#include <android-base/silent_death_test.h>
+#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
@@ -98,6 +99,27 @@
ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line;
}
+#define EXPECT_SNPRINTF_N(expected, n, fmt, ...) \
+ { \
+ char buf[BUFSIZ]; \
+ int w = snprintf(buf, sizeof(buf), fmt __VA_OPT__(, ) __VA_ARGS__); \
+ EXPECT_EQ(n, w); \
+ EXPECT_STREQ(expected, buf); \
+ }
+
+#define EXPECT_SNPRINTF(expected, fmt, ...) \
+ EXPECT_SNPRINTF_N(expected, static_cast<int>(strlen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
+
+#define EXPECT_SWPRINTF_N(expected, n, fmt, ...) \
+ { \
+ wchar_t buf[BUFSIZ]; \
+ int w = swprintf(buf, sizeof(buf), fmt __VA_OPT__(, ) __VA_ARGS__); \
+ EXPECT_EQ(n, w); \
+ EXPECT_EQ(std::wstring(expected), std::wstring(buf, w)); \
+ }
+#define EXPECT_SWPRINTF(expected, fmt, ...) \
+ EXPECT_SWPRINTF_N(expected, static_cast<int>(wcslen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
+
TEST(STDIO_TEST, flockfile_18208568_stderr) {
// Check that we have a _recursive_ mutex for flockfile.
flockfile(stderr);
@@ -140,6 +162,22 @@
fclose(fp);
}
+TEST(STDIO_TEST, tmpfile_TMPDIR) {
+ TemporaryDir td;
+ setenv("TMPDIR", td.path, 1);
+
+ FILE* fp = tmpfile();
+ ASSERT_TRUE(fp != nullptr);
+
+ std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fileno(fp));
+ char path[PATH_MAX];
+ ASSERT_GT(readlink(fd_path.c_str(), path, sizeof(path)), 0);
+ // $TMPDIR influenced where our temporary file ended up?
+ ASSERT_TRUE(android::base::StartsWith(path, td.path)) << path;
+ // And we used O_TMPFILE, right?
+ ASSERT_TRUE(android::base::EndsWith(path, " (deleted)")) << path;
+}
+
TEST(STDIO_TEST, dprintf) {
TemporaryFile tf;
@@ -292,21 +330,23 @@
// error: format '%zd' expects argument of type 'signed size_t',
// but argument 4 has type 'ssize_t {aka long int}' [-Werror=format]
ssize_t v = 1;
- char buf[32];
- snprintf(buf, sizeof(buf), "%zd", v);
+ EXPECT_SNPRINTF("1", "%zd", v);
+ EXPECT_SWPRINTF(L"1", L"%zd", v);
}
// https://code.google.com/p/android/issues/detail?id=64886
TEST(STDIO_TEST, snprintf_a) {
- char buf[BUFSIZ];
- EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
- EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
+ EXPECT_SNPRINTF("<0x1.3831e147ae148p+13>", "<%a>", 9990.235);
+}
+
+// https://code.google.com/p/android/issues/detail?id=64886
+TEST(STDIO_TEST, swprintf_a) {
+ EXPECT_SWPRINTF(L"<0x1.3831e147ae148p+13>", L"<%a>", 9990.235);
}
// http://b/152588929
TEST(STDIO_TEST, snprintf_La) {
#if defined(__LP64__)
- char buf[BUFSIZ];
union {
uint64_t a[2];
long double v;
@@ -314,59 +354,98 @@
u.a[0] = UINT64_C(0x9b9b9b9b9b9b9b9b);
u.a[1] = UINT64_C(0xdfdfdfdfdfdfdfdf);
- EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
- EXPECT_STREQ("<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", buf);
+ EXPECT_SNPRINTF("<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", "<%La>", u.v);
u.a[0] = UINT64_C(0xffffffffffffffff);
u.a[1] = UINT64_C(0x7ffeffffffffffff);
- EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
- EXPECT_STREQ("<0x1.ffffffffffffffffffffffffffffp+16383>", buf);
+ EXPECT_SNPRINTF("<0x1.ffffffffffffffffffffffffffffp+16383>", "<%La>", u.v);
u.a[0] = UINT64_C(0x0000000000000000);
u.a[1] = UINT64_C(0x0000000000000000);
- EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%La>", u.v));
- EXPECT_STREQ("<0x0p+0>", buf);
+ EXPECT_SNPRINTF("<0x0p+0>", "<%La>", u.v);
+#else
+ GTEST_SKIP() << "no ld128";
+#endif
+}
+
+// http://b/152588929
+TEST(STDIO_TEST, swprintf_La) {
+#if defined(__LP64__)
+ union {
+ uint64_t a[2];
+ long double v;
+ } u;
+
+ u.a[0] = UINT64_C(0x9b9b9b9b9b9b9b9b);
+ u.a[1] = UINT64_C(0xdfdfdfdfdfdfdfdf);
+ EXPECT_SWPRINTF(L"<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", L"<%La>", u.v);
+
+ u.a[0] = UINT64_C(0xffffffffffffffff);
+ u.a[1] = UINT64_C(0x7ffeffffffffffff);
+ EXPECT_SWPRINTF(L"<0x1.ffffffffffffffffffffffffffffp+16383>", L"<%La>", u.v);
+
+ u.a[0] = UINT64_C(0x0000000000000000);
+ u.a[1] = UINT64_C(0x0000000000000000);
+ EXPECT_SWPRINTF(L"<0x0p+0>", L"<%La>", u.v);
#else
GTEST_SKIP() << "no ld128";
#endif
}
TEST(STDIO_TEST, snprintf_lc) {
- char buf[BUFSIZ];
wint_t wc = L'a';
- EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc));
- EXPECT_STREQ("<a>", buf);
+ EXPECT_SNPRINTF("<a>", "<%lc>", wc);
}
-TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc.
- char buf[BUFSIZ];
+TEST(STDIO_TEST, swprintf_lc) {
+ wint_t wc = L'a';
+ EXPECT_SWPRINTF(L"<a>", L"<%lc>", wc);
+}
+
+TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc.
wchar_t wc = L'a';
- EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%C>", wc));
- EXPECT_STREQ("<a>", buf);
+ EXPECT_SNPRINTF("<a>", "<%C>", wc);
+}
+
+TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc.
+ wchar_t wc = L'a';
+ EXPECT_SWPRINTF(L"<a>", L"<%C>", wc);
+}
+
+TEST(STDIO_TEST, snprintf_ls_null) {
+ EXPECT_SNPRINTF("<(null)>", "<%ls>", static_cast<wchar_t*>(nullptr));
+}
+
+TEST(STDIO_TEST, swprintf_ls_null) {
+ EXPECT_SWPRINTF(L"<(null)>", L"<%ls>", static_cast<wchar_t*>(nullptr));
}
TEST(STDIO_TEST, snprintf_ls) {
- char buf[BUFSIZ];
- wchar_t* ws = nullptr;
- EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
- EXPECT_STREQ("<(null)>", buf);
+ static const wchar_t chars[] = L"Hello\u0666 World";
+ EXPECT_SNPRINTF("<Hello\xd9\xa6 World>", "<%ls>", chars);
+}
- wchar_t chars[] = { L'h', L'i', 0 };
- ws = chars;
- EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws));
- EXPECT_STREQ("<hi>", buf);
+TEST(STDIO_TEST, swprintf_ls) {
+ static const wchar_t chars[] = L"Hello\u0666 World";
+ EXPECT_SWPRINTF(L"<Hello\u0666 World>", L"<%ls>", chars);
+}
+
+TEST(STDIO_TEST, snprintf_S_nullptr) { // Synonym for %ls.
+ EXPECT_SNPRINTF("<(null)>", "<%S>", static_cast<wchar_t*>(nullptr));
+}
+
+TEST(STDIO_TEST, swprintf_S_nullptr) { // Synonym for %ls.
+ EXPECT_SWPRINTF(L"<(null)>", L"<%S>", static_cast<wchar_t*>(nullptr));
}
TEST(STDIO_TEST, snprintf_S) { // Synonym for %ls.
- char buf[BUFSIZ];
- wchar_t* ws = nullptr;
- EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%S>", ws));
- EXPECT_STREQ("<(null)>", buf);
+ static const wchar_t chars[] = L"Hello\u0666 World";
+ EXPECT_SNPRINTF("<Hello\xd9\xa6 World>", "<%S>", chars);
+}
- wchar_t chars[] = { L'h', L'i', 0 };
- ws = chars;
- EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%S>", ws));
- EXPECT_STREQ("<hi>", buf);
+TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls.
+ static const wchar_t chars[] = L"Hello\u0666 World";
+ EXPECT_SWPRINTF(L"<Hello\u0666 World>", L"<%S>", chars);
}
TEST_F(STDIO_DEATHTEST, snprintf_n) {
@@ -383,106 +462,111 @@
#endif
}
+TEST_F(STDIO_DEATHTEST, swprintf_n) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+ // http://b/14492135 and http://b/31832608.
+ wchar_t buf[32];
+ int i = 1234;
+ EXPECT_DEATH(swprintf(buf, sizeof(buf), L"a %n b", &i), "%n not allowed on Android");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "glibc does allow %n";
+#endif
+}
+
TEST(STDIO_TEST, snprintf_measure) {
- char buf[16];
+ char buf[1] = {'x'};
ASSERT_EQ(11, snprintf(buf, 0, "Hello %s", "world"));
+ ASSERT_EQ('x', buf[0]);
+}
+
+// Unlike snprintf(), you *can't* use swprintf() to measure.
+TEST(STDIO_TEST, swprintf_measure) {
+ wchar_t buf[1] = {L'x'};
+ ASSERT_EQ(-1, swprintf(buf, 0, L"Hello %S", L"world"));
+ ASSERT_EQ(L'x', buf[0]);
}
TEST(STDIO_TEST, snprintf_smoke) {
- char buf[BUFSIZ];
+ EXPECT_SNPRINTF("a", "a");
+ EXPECT_SNPRINTF("%", "%%");
+ EXPECT_SNPRINTF("01234", "01234");
+ EXPECT_SNPRINTF("a01234b", "a%sb", "01234");
- snprintf(buf, sizeof(buf), "a");
- EXPECT_STREQ("a", buf);
+ EXPECT_SNPRINTF("a(null)b", "a%sb", static_cast<char*>(nullptr));
+ EXPECT_SNPRINTF("aabbcc", "aa%scc", "bb");
+ EXPECT_SNPRINTF("abc", "a%cc", 'b');
+ EXPECT_SNPRINTF("a1234b", "a%db", 1234);
+ EXPECT_SNPRINTF("a-8123b", "a%db", -8123);
+ EXPECT_SNPRINTF("a16b", "a%hdb", static_cast<short>(0x7fff0010));
+ EXPECT_SNPRINTF("a16b", "a%hhdb", static_cast<char>(0x7fffff10));
+ EXPECT_SNPRINTF("a68719476736b", "a%lldb", 0x1000000000LL);
+ EXPECT_SNPRINTF("a70000b", "a%ldb", 70000L);
+ EXPECT_SNPRINTF("a0xb0001234b", "a%pb", reinterpret_cast<void*>(0xb0001234));
+ EXPECT_SNPRINTF("a12abz", "a%xz", 0x12ab);
+ EXPECT_SNPRINTF("a12ABz", "a%Xz", 0x12ab);
+ EXPECT_SNPRINTF("a00123456z", "a%08xz", 0x123456);
+ EXPECT_SNPRINTF("a 1234z", "a%5dz", 1234);
+ EXPECT_SNPRINTF("a01234z", "a%05dz", 1234);
+ EXPECT_SNPRINTF("a 1234z", "a%8dz", 1234);
+ EXPECT_SNPRINTF("a1234 z", "a%-8dz", 1234);
+ EXPECT_SNPRINTF("Aabcdef Z", "A%-11sZ", "abcdef");
+ EXPECT_SNPRINTF("Ahello:1234Z", "A%s:%dZ", "hello", 1234);
+ EXPECT_SNPRINTF("a005:5:05z", "a%03d:%d:%02dz", 5, 5, 5);
- snprintf(buf, sizeof(buf), "%%");
- EXPECT_STREQ("%", buf);
-
- snprintf(buf, sizeof(buf), "01234");
- EXPECT_STREQ("01234", buf);
-
- snprintf(buf, sizeof(buf), "a%sb", "01234");
- EXPECT_STREQ("a01234b", buf);
-
- char* s = nullptr;
- snprintf(buf, sizeof(buf), "a%sb", s);
- EXPECT_STREQ("a(null)b", buf);
-
- snprintf(buf, sizeof(buf), "aa%scc", "bb");
- EXPECT_STREQ("aabbcc", buf);
-
- snprintf(buf, sizeof(buf), "a%cc", 'b');
- EXPECT_STREQ("abc", buf);
-
- snprintf(buf, sizeof(buf), "a%db", 1234);
- EXPECT_STREQ("a1234b", buf);
-
- snprintf(buf, sizeof(buf), "a%db", -8123);
- EXPECT_STREQ("a-8123b", buf);
-
- snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010));
- EXPECT_STREQ("a16b", buf);
-
- snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10));
- EXPECT_STREQ("a16b", buf);
-
- snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL);
- EXPECT_STREQ("a68719476736b", buf);
-
- snprintf(buf, sizeof(buf), "a%ldb", 70000L);
- EXPECT_STREQ("a70000b", buf);
-
- snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
- EXPECT_STREQ("a0xb0001234b", buf);
-
- snprintf(buf, sizeof(buf), "a%xz", 0x12ab);
- EXPECT_STREQ("a12abz", buf);
-
- snprintf(buf, sizeof(buf), "a%Xz", 0x12ab);
- EXPECT_STREQ("a12ABz", buf);
-
- snprintf(buf, sizeof(buf), "a%08xz", 0x123456);
- EXPECT_STREQ("a00123456z", buf);
-
- snprintf(buf, sizeof(buf), "a%5dz", 1234);
- EXPECT_STREQ("a 1234z", buf);
-
- snprintf(buf, sizeof(buf), "a%05dz", 1234);
- EXPECT_STREQ("a01234z", buf);
-
- snprintf(buf, sizeof(buf), "a%8dz", 1234);
- EXPECT_STREQ("a 1234z", buf);
-
- snprintf(buf, sizeof(buf), "a%-8dz", 1234);
- EXPECT_STREQ("a1234 z", buf);
-
- snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef");
- EXPECT_STREQ("Aabcdef Z", buf);
-
- snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234);
- EXPECT_STREQ("Ahello:1234Z", buf);
-
- snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
- EXPECT_STREQ("a005:5:05z", buf);
-
- void* p = nullptr;
- snprintf(buf, sizeof(buf), "a%d,%pz", 5, p);
#if defined(__BIONIC__)
- EXPECT_STREQ("a5,0x0z", buf);
+ EXPECT_SNPRINTF("a5,0x0z", "a%d,%pz", 5, static_cast<void*>(nullptr));
#else // __BIONIC__
- EXPECT_STREQ("a5,(nil)z", buf);
+ EXPECT_SNPRINTF("a5,(nil)z", "a%d,%pz", 5, static_cast<void*>(nullptr));
#endif // __BIONIC__
- snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
- EXPECT_STREQ("a68719476736,6,7,8z", buf);
+ EXPECT_SNPRINTF("a68719476736,6,7,8z", "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
- snprintf(buf, sizeof(buf), "a_%f_b", 1.23f);
- EXPECT_STREQ("a_1.230000_b", buf);
+ EXPECT_SNPRINTF("a_1.230000_b", "a_%f_b", 1.23f);
+ EXPECT_SNPRINTF("a_3.14_b", "a_%g_b", 3.14);
+ EXPECT_SNPRINTF("print_me_twice print_me_twice", "%1$s %1$s", "print_me_twice");
+}
- snprintf(buf, sizeof(buf), "a_%g_b", 3.14);
- EXPECT_STREQ("a_3.14_b", buf);
+TEST(STDIO_TEST, swprintf_smoke) {
+ EXPECT_SWPRINTF(L"a", L"a");
+ EXPECT_SWPRINTF(L"%", L"%%");
+ EXPECT_SWPRINTF(L"01234", L"01234");
+ EXPECT_SWPRINTF(L"a01234b", L"a%sb", "01234");
- snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice");
- EXPECT_STREQ("print_me_twice print_me_twice", buf);
+ EXPECT_SWPRINTF(L"a(null)b", L"a%sb", static_cast<char*>(nullptr));
+ EXPECT_SWPRINTF(L"aabbcc", L"aa%scc", "bb");
+ EXPECT_SWPRINTF(L"abc", L"a%cc", 'b');
+ EXPECT_SWPRINTF(L"a1234b", L"a%db", 1234);
+ EXPECT_SWPRINTF(L"a-8123b", L"a%db", -8123);
+ EXPECT_SWPRINTF(L"a16b", L"a%hdb", static_cast<short>(0x7fff0010));
+ EXPECT_SWPRINTF(L"a16b", L"a%hhdb", static_cast<char>(0x7fffff10));
+ EXPECT_SWPRINTF(L"a68719476736b", L"a%lldb", 0x1000000000LL);
+ EXPECT_SWPRINTF(L"a70000b", L"a%ldb", 70000L);
+ EXPECT_SWPRINTF(L"a0xb0001234b", L"a%pb", reinterpret_cast<void*>(0xb0001234));
+ EXPECT_SWPRINTF(L"a12abz", L"a%xz", 0x12ab);
+ EXPECT_SWPRINTF(L"a12ABz", L"a%Xz", 0x12ab);
+ EXPECT_SWPRINTF(L"a00123456z", L"a%08xz", 0x123456);
+ EXPECT_SWPRINTF(L"a 1234z", L"a%5dz", 1234);
+ EXPECT_SWPRINTF(L"a01234z", L"a%05dz", 1234);
+ EXPECT_SWPRINTF(L"a 1234z", L"a%8dz", 1234);
+ EXPECT_SWPRINTF(L"a1234 z", L"a%-8dz", 1234);
+ EXPECT_SWPRINTF(L"Aabcdef Z", L"A%-11sZ", "abcdef");
+ EXPECT_SWPRINTF(L"Ahello:1234Z", L"A%s:%dZ", "hello", 1234);
+ EXPECT_SWPRINTF(L"a005:5:05z", L"a%03d:%d:%02dz", 5, 5, 5);
+
+#if defined(__BIONIC__)
+ EXPECT_SWPRINTF(L"a5,0x0z", L"a%d,%pz", 5, static_cast<void*>(nullptr));
+#else // __BIONIC__
+ EXPECT_SWPRINTF(L"a5,(nil)z", L"a%d,%pz", 5, static_cast<void*>(nullptr));
+#endif // __BIONIC__
+
+ EXPECT_SWPRINTF(L"a68719476736,6,7,8z", L"a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
+
+ EXPECT_SWPRINTF(L"a_1.230000_b", L"a_%f_b", 1.23f);
+ EXPECT_SWPRINTF(L"a_3.14_b", L"a_%g_b", 3.14);
+ EXPECT_SWPRINTF(L"print_me_twice print_me_twice", L"%1$s %1$s", "print_me_twice");
}
template <typename T>
@@ -617,227 +701,164 @@
L"[-NAN]", L"[NAN]", L"[+NAN]");
}
-TEST(STDIO_TEST, swprintf) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- ASSERT_EQ(2, swprintf(buf, nchars, L"ab")) << strerror(errno);
- ASSERT_EQ(std::wstring(L"ab"), buf);
- ASSERT_EQ(5, swprintf(buf, nchars, L"%s", "abcde"));
- ASSERT_EQ(std::wstring(L"abcde"), buf);
-
- // Unlike swprintf(), swprintf() returns -1 in case of truncation
- // and doesn't necessarily zero-terminate the output!
- ASSERT_EQ(-1, swprintf(buf, 4, L"%s", "abcde"));
-
- const char kString[] = "Hello, World";
- ASSERT_EQ(12, swprintf(buf, nchars, L"%s", kString));
- ASSERT_EQ(std::wstring(L"Hello, World"), buf);
- ASSERT_EQ(12, swprintf(buf, 13, L"%s", kString));
- ASSERT_EQ(std::wstring(L"Hello, World"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_a) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- ASSERT_EQ(20, swprintf(buf, nchars, L"%a", 3.1415926535));
- ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_lc) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- wint_t wc = L'a';
- EXPECT_EQ(3, swprintf(buf, nchars, L"<%lc>", wc));
- EXPECT_EQ(std::wstring(L"<a>"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc.
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- wint_t wc = L'a';
- EXPECT_EQ(3, swprintf(buf, nchars, L"<%C>", wc));
- EXPECT_EQ(std::wstring(L"<a>"), buf);
+TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
+ EXPECT_SNPRINTF("9223372036854775807", "%jd", INTMAX_MAX);
}
TEST(STDIO_TEST, swprintf_jd_INTMAX_MAX) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- swprintf(buf, nchars, L"%jd", INTMAX_MAX);
- EXPECT_EQ(std::wstring(L"9223372036854775807"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- swprintf(buf, nchars, L"%jd", INTMAX_MIN);
- EXPECT_EQ(std::wstring(L"-9223372036854775808"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- swprintf(buf, nchars, L"%ju", UINTMAX_MAX);
- EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- swprintf(buf, nchars, L"%1$ju", UINTMAX_MAX);
- EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
-}
-
-TEST(STDIO_TEST, swprintf_ls) {
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- static const wchar_t kWideString[] = L"Hello\uff41 World";
- ASSERT_EQ(12, swprintf(buf, nchars, L"%ls", kWideString));
- ASSERT_EQ(std::wstring(kWideString), buf);
- ASSERT_EQ(12, swprintf(buf, 13, L"%ls", kWideString));
- ASSERT_EQ(std::wstring(kWideString), buf);
-}
-
-TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls.
- constexpr size_t nchars = 32;
- wchar_t buf[nchars];
-
- static const wchar_t kWideString[] = L"Hello\uff41 World";
- ASSERT_EQ(12, swprintf(buf, nchars, L"%S", kWideString));
- ASSERT_EQ(std::wstring(kWideString), buf);
- ASSERT_EQ(12, swprintf(buf, 13, L"%S", kWideString));
- ASSERT_EQ(std::wstring(kWideString), buf);
-}
-
-TEST(STDIO_TEST, snprintf_d_INT_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%d", INT_MAX);
- EXPECT_STREQ("2147483647", buf);
-}
-
-TEST(STDIO_TEST, snprintf_d_INT_MIN) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%d", INT_MIN);
- EXPECT_STREQ("-2147483648", buf);
-}
-
-TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%jd", INTMAX_MAX);
- EXPECT_STREQ("9223372036854775807", buf);
+ EXPECT_SWPRINTF(L"9223372036854775807", L"%jd", INTMAX_MAX);
}
TEST(STDIO_TEST, snprintf_jd_INTMAX_MIN) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%jd", INTMAX_MIN);
- EXPECT_STREQ("-9223372036854775808", buf);
+ EXPECT_SNPRINTF("-9223372036854775808", "%jd", INTMAX_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
+ EXPECT_SWPRINTF(L"-9223372036854775808", L"%jd", INTMAX_MIN);
}
TEST(STDIO_TEST, snprintf_ju_UINTMAX_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%ju", UINTMAX_MAX);
- EXPECT_STREQ("18446744073709551615", buf);
+ EXPECT_SNPRINTF("18446744073709551615", "%ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
+ EXPECT_SWPRINTF(L"18446744073709551615", L"%ju", UINTMAX_MAX);
}
TEST(STDIO_TEST, snprintf_1$ju_UINTMAX_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%1$ju", UINTMAX_MAX);
- EXPECT_STREQ("18446744073709551615", buf);
+ EXPECT_SNPRINTF("18446744073709551615", "%1$ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
+ EXPECT_SWPRINTF(L"18446744073709551615", L"%1$ju", UINTMAX_MAX);
+}
+
+TEST(STDIO_TEST, snprintf_d_INT_MAX) {
+ EXPECT_SNPRINTF("2147483647", "%d", INT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_d_INT_MAX) {
+ EXPECT_SWPRINTF(L"2147483647", L"%d", INT_MAX);
+}
+
+TEST(STDIO_TEST, snprintf_d_INT_MIN) {
+ EXPECT_SNPRINTF("-2147483648", "%d", INT_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_d_INT_MIN) {
+ EXPECT_SWPRINTF(L"-2147483648", L"%d", INT_MIN);
}
TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
#if defined(__LP64__)
- EXPECT_STREQ("9223372036854775807", buf);
+ EXPECT_SNPRINTF("9223372036854775807", "%ld", LONG_MAX);
#else
- EXPECT_STREQ("2147483647", buf);
+ EXPECT_SNPRINTF("2147483647", "%ld", LONG_MAX);
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_ld_LONG_MAX) {
+#if defined(__LP64__)
+ EXPECT_SWPRINTF(L"9223372036854775807", L"%ld", LONG_MAX);
+#else
+ EXPECT_SWPRINTF(L"2147483647", L"%ld", LONG_MAX);
#endif
}
TEST(STDIO_TEST, snprintf_ld_LONG_MIN) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
#if defined(__LP64__)
- EXPECT_STREQ("-9223372036854775808", buf);
+ EXPECT_SNPRINTF("-9223372036854775808", "%ld", LONG_MIN);
#else
- EXPECT_STREQ("-2147483648", buf);
+ EXPECT_SNPRINTF("-2147483648", "%ld", LONG_MIN);
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_ld_LONG_MIN) {
+#if defined(__LP64__)
+ EXPECT_SWPRINTF(L"-9223372036854775808", L"%ld", LONG_MIN);
+#else
+ EXPECT_SWPRINTF(L"-2147483648", L"%ld", LONG_MIN);
#endif
}
TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
- EXPECT_STREQ("9223372036854775807", buf);
+ EXPECT_SNPRINTF("9223372036854775807", "%lld", LLONG_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_lld_LLONG_MAX) {
+ EXPECT_SWPRINTF(L"9223372036854775807", L"%lld", LLONG_MAX);
}
TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
- EXPECT_STREQ("-9223372036854775808", buf);
+ EXPECT_SNPRINTF("-9223372036854775808", "%lld", LLONG_MIN);
+}
+
+TEST(STDIO_TEST, swprintf_lld_LLONG_MIN) {
+ EXPECT_SWPRINTF(L"-9223372036854775808", L"%lld", LLONG_MIN);
}
TEST(STDIO_TEST, snprintf_o_UINT_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%o", UINT_MAX);
- EXPECT_STREQ("37777777777", buf);
+ EXPECT_SNPRINTF("37777777777", "%o", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_o_UINT_MAX) {
+ EXPECT_SWPRINTF(L"37777777777", L"%o", UINT_MAX);
}
TEST(STDIO_TEST, snprintf_u_UINT_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%u", UINT_MAX);
- EXPECT_STREQ("4294967295", buf);
+ EXPECT_SNPRINTF("4294967295", "%u", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_u_UINT_MAX) {
+ EXPECT_SWPRINTF(L"4294967295", L"%u", UINT_MAX);
}
TEST(STDIO_TEST, snprintf_x_UINT_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%x", UINT_MAX);
- EXPECT_STREQ("ffffffff", buf);
+ EXPECT_SNPRINTF("ffffffff", "%x", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_x_UINT_MAX) {
+ EXPECT_SWPRINTF(L"ffffffff", L"%x", UINT_MAX);
}
TEST(STDIO_TEST, snprintf_X_UINT_MAX) {
- char buf[BUFSIZ];
- snprintf(buf, sizeof(buf), "%X", UINT_MAX);
- EXPECT_STREQ("FFFFFFFF", buf);
+ EXPECT_SNPRINTF("FFFFFFFF", "%X", UINT_MAX);
+}
+
+TEST(STDIO_TEST, swprintf_X_UINT_MAX) {
+ EXPECT_SWPRINTF(L"FFFFFFFF", L"%X", UINT_MAX);
}
TEST(STDIO_TEST, snprintf_e) {
- char buf[BUFSIZ];
+ EXPECT_SNPRINTF("1.500000e+00", "%e", 1.5);
+ EXPECT_SNPRINTF("1.500000e+00", "%Le", 1.5L);
+}
- snprintf(buf, sizeof(buf), "%e", 1.5);
- EXPECT_STREQ("1.500000e+00", buf);
-
- snprintf(buf, sizeof(buf), "%Le", 1.5L);
- EXPECT_STREQ("1.500000e+00", buf);
+TEST(STDIO_TEST, swprintf_e) {
+ EXPECT_SWPRINTF(L"1.500000e+00", L"%e", 1.5);
+ EXPECT_SWPRINTF(L"1.500000e+00", L"%Le", 1.5L);
}
TEST(STDIO_TEST, snprintf_negative_zero_5084292) {
- char buf[BUFSIZ];
+ EXPECT_SNPRINTF("-0.000000e+00", "%e", -0.0);
+ EXPECT_SNPRINTF("-0.000000E+00", "%E", -0.0);
+ EXPECT_SNPRINTF("-0.000000", "%f", -0.0);
+ EXPECT_SNPRINTF("-0.000000", "%F", -0.0);
+ EXPECT_SNPRINTF("-0", "%g", -0.0);
+ EXPECT_SNPRINTF("-0", "%G", -0.0);
+ EXPECT_SNPRINTF("-0x0p+0", "%a", -0.0);
+ EXPECT_SNPRINTF("-0X0P+0", "%A", -0.0);
+}
- snprintf(buf, sizeof(buf), "%e", -0.0);
- EXPECT_STREQ("-0.000000e+00", buf);
- snprintf(buf, sizeof(buf), "%E", -0.0);
- EXPECT_STREQ("-0.000000E+00", buf);
- snprintf(buf, sizeof(buf), "%f", -0.0);
- EXPECT_STREQ("-0.000000", buf);
- snprintf(buf, sizeof(buf), "%F", -0.0);
- EXPECT_STREQ("-0.000000", buf);
- snprintf(buf, sizeof(buf), "%g", -0.0);
- EXPECT_STREQ("-0", buf);
- snprintf(buf, sizeof(buf), "%G", -0.0);
- EXPECT_STREQ("-0", buf);
- snprintf(buf, sizeof(buf), "%a", -0.0);
- EXPECT_STREQ("-0x0p+0", buf);
- snprintf(buf, sizeof(buf), "%A", -0.0);
- EXPECT_STREQ("-0X0P+0", buf);
+TEST(STDIO_TEST, swprintf_negative_zero_5084292) {
+ EXPECT_SWPRINTF(L"-0.000000e+00", L"%e", -0.0);
+ EXPECT_SWPRINTF(L"-0.000000E+00", L"%E", -0.0);
+ EXPECT_SWPRINTF(L"-0.000000", L"%f", -0.0);
+ EXPECT_SWPRINTF(L"-0.000000", L"%F", -0.0);
+ EXPECT_SWPRINTF(L"-0", L"%g", -0.0);
+ EXPECT_SWPRINTF(L"-0", L"%G", -0.0);
+ EXPECT_SWPRINTF(L"-0x0p+0", L"%a", -0.0);
+ EXPECT_SWPRINTF(L"-0X0P+0", L"%A", -0.0);
}
TEST(STDIO_TEST, snprintf_utf8_15439554) {
@@ -898,18 +919,36 @@
ASSERT_EQ(ENOMEM, errno);
}
+TEST(STDIO_TEST, swprintf_asterisk_overflow) {
+ wchar_t buf[128];
+ ASSERT_EQ(5, swprintf(buf, sizeof(buf), L"%.*s%c", 4, "hello world", '!'));
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX / 2, "hello world", '!'));
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX - 1, "hello world", '!'));
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", INT_MAX, "hello world", '!'));
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.*s%c", -1, "hello world", '!'));
+
+ // INT_MAX-1, INT_MAX, INT_MAX+1.
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.2147483646s%c", "hello world", '!'));
+ ASSERT_EQ(12, swprintf(buf, sizeof(buf), L"%.2147483647s%c", "hello world", '!'));
+ ASSERT_EQ(-1, swprintf(buf, sizeof(buf), L"%.2147483648s%c", "hello world", '!'));
+ ASSERT_EQ(ENOMEM, errno);
+}
+
// Inspired by https://github.com/landley/toybox/issues/163.
TEST(STDIO_TEST, printf_NULL) {
- char buf[128];
char* null = nullptr;
- EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%*.*s>", 2, 2, null));
- EXPECT_STREQ("<(n>", buf);
- EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%*.*s>", 2, 8, null));
- EXPECT_STREQ("<(null)>", buf);
- EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%*.*s>", 8, 2, null));
- EXPECT_STREQ("< (n>", buf);
- EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%*.*s>", 8, 8, null));
- EXPECT_STREQ("< (null)>", buf);
+ EXPECT_SNPRINTF("<(n>", "<%*.*s>", 2, 2, null);
+ EXPECT_SNPRINTF("<(null)>", "<%*.*s>", 2, 8, null);
+ EXPECT_SNPRINTF("< (n>", "<%*.*s>", 8, 2, null);
+ EXPECT_SNPRINTF("< (null)>", "<%*.*s>", 8, 8, null);
+}
+
+TEST(STDIO_TEST, wprintf_NULL) {
+ char* null = nullptr;
+ EXPECT_SWPRINTF(L"<(n>", L"<%*.*s>", 2, 2, null);
+ EXPECT_SWPRINTF(L"<(null)>", L"<%*.*s>", 2, 8, null);
+ EXPECT_SWPRINTF(L"< (n>", L"<%*.*s>", 8, 2, null);
+ EXPECT_SWPRINTF(L"< (null)>", L"<%*.*s>", 8, 8, null);
}
TEST(STDIO_TEST, fprintf) {
@@ -2452,7 +2491,7 @@
}
TEST_F(STDIO_DEATHTEST, snprintf_30445072_unknown_buffer_size) {
- std::string buf = "world";
+ std::string buf = "hello"; // So the compiler doesn't know the buffer size.
ASSERT_EXIT(snprintf(&buf[0], atol("-1"), "hello"),
testing::KilledBySignal(SIGABRT),
"FORTIFY: vsnprintf: size .* > SSIZE_MAX");
@@ -2465,48 +2504,36 @@
}
TEST(STDIO_TEST, printf_m) {
- char buf[BUFSIZ];
errno = 0;
- snprintf(buf, sizeof(buf), "<%m>");
- ASSERT_STREQ("<Success>", buf);
+ EXPECT_SNPRINTF("<Success>", "<%m>");
errno = -1;
- snprintf(buf, sizeof(buf), "<%m>");
- ASSERT_STREQ("<Unknown error -1>", buf);
+ EXPECT_SNPRINTF("<Unknown error -1>", "<%m>");
errno = EINVAL;
- snprintf(buf, sizeof(buf), "<%m>");
- ASSERT_STREQ("<Invalid argument>", buf);
-}
-
-TEST(STDIO_TEST, printf_m_does_not_clobber_strerror) {
- char buf[BUFSIZ];
- const char* m = strerror(-1);
- ASSERT_STREQ("Unknown error -1", m);
- errno = -2;
- snprintf(buf, sizeof(buf), "<%m>");
- ASSERT_STREQ("<Unknown error -2>", buf);
- ASSERT_STREQ("Unknown error -1", m);
+ EXPECT_SNPRINTF("<Invalid argument>", "<%m>");
}
TEST(STDIO_TEST, wprintf_m) {
- wchar_t buf[BUFSIZ];
errno = 0;
- swprintf(buf, sizeof(buf), L"<%m>");
- ASSERT_EQ(std::wstring(L"<Success>"), buf);
+ EXPECT_SWPRINTF(L"<Success>", L"<%m>");
errno = -1;
- swprintf(buf, sizeof(buf), L"<%m>");
- ASSERT_EQ(std::wstring(L"<Unknown error -1>"), buf);
+ EXPECT_SWPRINTF(L"<Unknown error -1>", L"<%m>");
errno = EINVAL;
- swprintf(buf, sizeof(buf), L"<%m>");
- ASSERT_EQ(std::wstring(L"<Invalid argument>"), buf);
+ EXPECT_SWPRINTF(L"<Invalid argument>", L"<%m>");
}
-TEST(STDIO_TEST, wprintf_m_does_not_clobber_strerror) {
- wchar_t buf[BUFSIZ];
+TEST(STDIO_TEST, printf_m_does_not_clobber_strerror) {
const char* m = strerror(-1);
ASSERT_STREQ("Unknown error -1", m);
errno = -2;
- swprintf(buf, sizeof(buf), L"<%m>");
- ASSERT_EQ(std::wstring(L"<Unknown error -2>"), buf);
+ EXPECT_SNPRINTF("<Unknown error -2>", "<%m>");
+ ASSERT_STREQ("Unknown error -1", m);
+}
+
+TEST(STDIO_TEST, wprintf_m_does_not_clobber_strerror) {
+ const char* m = strerror(-1);
+ ASSERT_STREQ("Unknown error -1", m);
+ errno = -2;
+ EXPECT_SWPRINTF(L"<Unknown error -2>", L"<%m>");
ASSERT_STREQ("Unknown error -1", m);
}
@@ -2983,60 +3010,84 @@
#endif
}
-TEST(STDIO_TEST, snprintf_b) {
- char buf[BUFSIZ];
- EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%b>", 5));
- EXPECT_STREQ("<101>", buf);
- EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08b>", 5));
- EXPECT_STREQ("<00000101>", buf);
- EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%b>", 0xaaaaaaaa));
- EXPECT_STREQ("<10101010101010101010101010101010>", buf);
- EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#b>", 0xaaaaaaaa));
- EXPECT_STREQ("<0b10101010101010101010101010101010>", buf);
- EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
- EXPECT_STREQ("<0>", buf);
+TEST(STDIO_TEST, snprintf_b_B) {
+#if defined(__BIONIC__)
+ uint8_t b = 5;
+ EXPECT_SNPRINTF("<101>", "<%" PRIb8 ">", b);
+ EXPECT_SNPRINTF("<101>", "<%" PRIB8 ">", b);
+ EXPECT_SNPRINTF("<00000101>", "<%08" PRIb8 ">", b);
+ EXPECT_SNPRINTF("<00000101>", "<%08" PRIB8 ">", b);
+
+ uint16_t s = 0xaaaa;
+ EXPECT_SNPRINTF("<1010101010101010>", "<%" PRIb16 ">", s);
+ EXPECT_SNPRINTF("<1010101010101010>", "<%" PRIB16 ">", s);
+ EXPECT_SNPRINTF("<0b1010101010101010>", "<%#" PRIb16 ">", s);
+ EXPECT_SNPRINTF("<0B1010101010101010>", "<%#" PRIB16 ">", s);
+
+ EXPECT_SNPRINTF("<10101010101010101010101010101010>", "<%" PRIb32 ">", 0xaaaaaaaa);
+ EXPECT_SNPRINTF("<10101010101010101010101010101010>", "<%" PRIB32 ">", 0xaaaaaaaa);
+ EXPECT_SNPRINTF("<0b10101010101010101010101010101010>", "<%#" PRIb32 ">", 0xaaaaaaaa);
+ EXPECT_SNPRINTF("<0B10101010101010101010101010101010>", "<%#" PRIB32 ">", 0xaaaaaaaa);
+
+ // clang doesn't like "%lb" (https://github.com/llvm/llvm-project/issues/62247)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+ EXPECT_SNPRINTF("<1010101010101010101010101010101010101010101010101010101010101010>",
+ "<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SNPRINTF("<1010101010101010101010101010101010101010101010101010101010101010>",
+ "<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SNPRINTF("<0b1010101010101010101010101010101010101010101010101010101010101010>",
+ "<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SNPRINTF("<0B1010101010101010101010101010101010101010101010101010101010101010>",
+ "<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+#pragma clang diagnostic pop
+
+ EXPECT_SNPRINTF("<0>", "<%#b>", 0);
+ EXPECT_SNPRINTF("<0>", "<%#B>", 0);
+#else
+ GTEST_SKIP() << "no %b in glibc";
+#endif
}
-TEST(STDIO_TEST, snprintf_B) {
- char buf[BUFSIZ];
- EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%B>", 5));
- EXPECT_STREQ("<101>", buf);
- EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08B>", 5));
- EXPECT_STREQ("<00000101>", buf);
- EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%B>", 0xaaaaaaaa));
- EXPECT_STREQ("<10101010101010101010101010101010>", buf);
- EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#B>", 0xaaaaaaaa));
- EXPECT_STREQ("<0B10101010101010101010101010101010>", buf);
- EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#B>", 0));
- EXPECT_STREQ("<0>", buf);
-}
+TEST(STDIO_TEST, swprintf_b_B) {
+#if defined(__BIONIC__)
+ uint8_t b = 5;
+ EXPECT_SWPRINTF(L"<101>", L"<%" PRIb8 ">", b);
+ EXPECT_SWPRINTF(L"<101>", L"<%" PRIB8 ">", b);
+ EXPECT_SWPRINTF(L"<0b101>", L"<%#" PRIb8 ">", b);
+ EXPECT_SWPRINTF(L"<0B101>", L"<%#" PRIB8 ">", b);
+ EXPECT_SWPRINTF(L"<00000101>", L"<%08" PRIb8 ">", b);
+ EXPECT_SWPRINTF(L"<00000101>", L"<%08" PRIB8 ">", b);
-TEST(STDIO_TEST, swprintf_b) {
- wchar_t buf[BUFSIZ];
- EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%b>", 5));
- EXPECT_EQ(std::wstring(L"<101>"), buf);
- EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08b>", 5));
- EXPECT_EQ(std::wstring(L"<00000101>"), buf);
- EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%b>", 0xaaaaaaaa));
- EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
- EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#b>", 0xaaaaaaaa));
- EXPECT_EQ(std::wstring(L"<0b10101010101010101010101010101010>"), buf);
- EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#b>", 0));
- EXPECT_EQ(std::wstring(L"<0>"), buf);
-}
+ uint16_t s = 0xaaaa;
+ EXPECT_SWPRINTF(L"<1010101010101010>", L"<%" PRIb16 ">", s);
+ EXPECT_SWPRINTF(L"<1010101010101010>", L"<%" PRIB16 ">", s);
+ EXPECT_SWPRINTF(L"<0b1010101010101010>", L"<%#" PRIb16 ">", s);
+ EXPECT_SWPRINTF(L"<0B1010101010101010>", L"<%#" PRIB16 ">", s);
-TEST(STDIO_TEST, swprintf_B) {
- wchar_t buf[BUFSIZ];
- EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%B>", 5));
- EXPECT_EQ(std::wstring(L"<101>"), buf);
- EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08B>", 5));
- EXPECT_EQ(std::wstring(L"<00000101>"), buf);
- EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%B>", 0xaaaaaaaa));
- EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
- EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#B>", 0xaaaaaaaa));
- EXPECT_EQ(std::wstring(L"<0B10101010101010101010101010101010>"), buf);
- EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#B>", 0));
- EXPECT_EQ(std::wstring(L"<0>"), buf);
+ EXPECT_SWPRINTF(L"<10101010101010101010101010101010>", L"<%" PRIb32 ">", 0xaaaaaaaa);
+ EXPECT_SWPRINTF(L"<10101010101010101010101010101010>", L"<%" PRIB32 ">", 0xaaaaaaaa);
+ EXPECT_SWPRINTF(L"<0b10101010101010101010101010101010>", L"<%#" PRIb32 ">", 0xaaaaaaaa);
+ EXPECT_SWPRINTF(L"<0B10101010101010101010101010101010>", L"<%#" PRIB32 ">", 0xaaaaaaaa);
+
+ // clang doesn't like "%lb" (https://github.com/llvm/llvm-project/issues/62247)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+ EXPECT_SWPRINTF(L"<1010101010101010101010101010101010101010101010101010101010101010>",
+ L"<%" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SWPRINTF(L"<1010101010101010101010101010101010101010101010101010101010101010>",
+ L"<%" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SWPRINTF(L"<0b1010101010101010101010101010101010101010101010101010101010101010>",
+ L"<%#" PRIb64 ">", 0xaaaaaaaa'aaaaaaaa);
+ EXPECT_SWPRINTF(L"<0B1010101010101010101010101010101010101010101010101010101010101010>",
+ L"<%#" PRIB64 ">", 0xaaaaaaaa'aaaaaaaa);
+#pragma clang diagnostic pop
+
+ EXPECT_SWPRINTF(L"<0>", L"<%#b>", 0);
+ EXPECT_SWPRINTF(L"<0>", L"<%#B>", 0);
+#else
+ GTEST_SKIP() << "no %b in glibc";
+#endif
}
TEST(STDIO_TEST, scanf_i_decimal) {
@@ -3164,3 +3215,274 @@
EXPECT_EQ(0, i);
EXPECT_EQ('b', ch);
}
+
+TEST(STDIO_TEST, snprintf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+ int8_t a = 0b101;
+ EXPECT_SNPRINTF("<101>", "<%w8b>", a);
+ int8_t b1 = 0xFF;
+ EXPECT_SNPRINTF("<-1>", "<%w8d>", b1);
+ int8_t b2 = 0x1FF;
+ EXPECT_SNPRINTF("<-1>", "<%w8d>", b2);
+ int16_t c = 0xFFFF;
+ EXPECT_SNPRINTF("<-1>", "<%w16i>", c);
+ int32_t d = 021;
+ EXPECT_SNPRINTF("<21>", "<%w32o>", d);
+ uint32_t e = -1;
+ EXPECT_SNPRINTF("<4294967295>", "<%w32u>", e);
+ int64_t f = 0x3b;
+ EXPECT_SNPRINTF("<3b>", "<%w64x>", f);
+ EXPECT_SNPRINTF("<3B>", "<%w64X>", f);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_w_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+ int8_t a = 0b101;
+ EXPECT_SWPRINTF(L"<101>", L"<%w8b>", a);
+ int8_t b1 = 0xFF;
+ EXPECT_SWPRINTF(L"<-1>", L"<%w8d>", b1);
+ int8_t b2 = 0x1FF;
+ EXPECT_SWPRINTF(L"<-1>", L"<%w8d>", b2);
+ int16_t c = 0xFFFF;
+ EXPECT_SWPRINTF(L"<-1>", L"<%w16i>", c);
+ int32_t d = 021;
+ EXPECT_SWPRINTF(L"<21>", L"<%w32o>", d);
+ uint32_t e = -1;
+ EXPECT_SWPRINTF(L"<4294967295>", L"<%w32u>", e);
+ int64_t f = 0x3b;
+ EXPECT_SWPRINTF(L"<3b>", L"<%w64x>", f);
+ EXPECT_SWPRINTF(L"<3B>", L"<%w64X>", f);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_w_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+ int32_t a = 0xaaaaaaaa;
+ int64_t b = 0x11111111'22222222;
+ int64_t c = 0x33333333'44444444;
+ int64_t d = 0xaaaaaaaa'aaaaaaaa;
+ EXPECT_SNPRINTF("<10101010101010101010101010101010 --- 3333333344444444>",
+ "<%2$w32b --- %1$w64x>", c, a);
+ EXPECT_SNPRINTF(
+ "<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+ "3333333344444444>",
+ "<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_w_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+ int32_t a = 0xaaaaaaaa;
+ int64_t b = 0x11111111'22222222;
+ int64_t c = 0x33333333'44444444;
+ int64_t d = 0xaaaaaaaa'aaaaaaaa;
+ EXPECT_SWPRINTF(L"<10101010101010101010101010101010 --- 3333333344444444>",
+ L"<%2$w32b --- %1$w64x>", c, a);
+ EXPECT_SWPRINTF(
+ L"<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+ L"3333333344444444>",
+ L"<%3$w64b --- %1$w64x --- %2$w64x>", b, c, d);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ char buf[BUFSIZ];
+ int32_t a = 100;
+ EXPECT_DEATH(snprintf(buf, sizeof(buf), "%w20d", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_invalid_w_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ wchar_t buf[BUFSIZ];
+ int32_t a = 100;
+ EXPECT_DEATH(swprintf(buf, sizeof(buf), L"%w20d", &a), "%w20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_wf_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int_fast8_t a = 0b101;
+ EXPECT_SNPRINTF("<101>", "<%wf8b>", a);
+ int_fast8_t b = 0x12341234'12341234;
+ EXPECT_SNPRINTF("<34>", "<%wf8x>", b);
+ uint_fast16_t c = 0x11111111'22222222;
+#if defined(__LP64__)
+ EXPECT_SNPRINTF("<1111111122222222>", "<%wf16x>", c);
+#else
+ EXPECT_SNPRINTF("<22222222>", "<%wf16x>", c);
+#endif
+ int_fast32_t d = 0x33333333'44444444;
+#if defined(__LP64__)
+ EXPECT_SNPRINTF("<3333333344444444>", "<%wf32x>", d);
+#else
+ EXPECT_SNPRINTF("<44444444>", "<%wf32x>", d);
+#endif
+ int_fast64_t e = 0xaaaaaaaa'aaaaaaaa;
+ EXPECT_SNPRINTF("<aaaaaaaaaaaaaaaa>", "<%wf64x>", e);
+ EXPECT_SNPRINTF("<AAAAAAAAAAAAAAAA>", "<%wf64X>", e);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %wf in glibc";
+#endif
+}
+TEST(STDIO_TEST, swprintf_wf_base) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int_fast8_t a = 0b101;
+ EXPECT_SWPRINTF(L"<101>", L"<%wf8b>", a);
+ int_fast8_t b = 0x12341234'12341234;
+ EXPECT_SWPRINTF(L"<34>", L"<%wf8x>", b);
+ uint_fast16_t c = 0x11111111'22222222;
+#if defined(__LP64__)
+ EXPECT_SWPRINTF(L"<1111111122222222>", L"<%wf16x>", c);
+#else
+ EXPECT_SWPRINTF(L"<22222222>", L"<%wf16x>", c);
+#endif
+ int_fast32_t d = 0x33333333'44444444;
+#if defined(__LP64__)
+ EXPECT_SWPRINTF(L"<3333333344444444>", L"<%wf32x>", d);
+#else
+ EXPECT_SWPRINTF(L"<44444444>", L"<%wf32x>", d);
+#endif
+ int_fast64_t e = 0xaaaaaaaa'aaaaaaaa;
+ EXPECT_SWPRINTF(L"<aaaaaaaaaaaaaaaa>", L"<%wf64x>", e);
+ EXPECT_SWPRINTF(L"<AAAAAAAAAAAAAAAA>", L"<%wf64X>", e);
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %wf in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_wf_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int_fast16_t a = 0x11111111'22222222;
+ int_fast32_t b = 0x33333333'44444444;
+ int_fast32_t c = 0xaaaaaaaa'aaaaaaaa;
+#if defined(__LP64__)
+ EXPECT_SNPRINTF(
+ "<3333333344444444 --- 1010101010101010101010101010101010101010101010101010101010101010>",
+ "<%2$wf32x --- %1$wf32b>", c, b);
+
+ EXPECT_SNPRINTF(
+ "<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+ "3333333344444444>",
+ "<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#else
+ EXPECT_SNPRINTF("<44444444 --- 10101010101010101010101010101010>", "<%2$wf32x --- %1$wf32b>", c,
+ b);
+ EXPECT_SNPRINTF("<10101010101010101010101010101010 --- 22222222 --- 44444444>",
+ "<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#endif
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_wf_arguments_reordering) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconstant-conversion"
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int_fast16_t a = 0x11111111'22222222;
+ int_fast32_t b = 0x33333333'44444444;
+ int_fast32_t c = 0xaaaaaaaa'aaaaaaaa;
+#if defined(__LP64__)
+ EXPECT_SWPRINTF(
+ L"<3333333344444444 --- 1010101010101010101010101010101010101010101010101010101010101010>",
+ L"<%2$wf32x --- %1$wf32b>", c, b);
+
+ EXPECT_SWPRINTF(
+ L"<1010101010101010101010101010101010101010101010101010101010101010 --- 1111111122222222 --- "
+ L"3333333344444444>",
+ L"<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#else
+ EXPECT_SWPRINTF(L"<44444444 --- 10101010101010101010101010101010>", L"<%2$wf32x --- %1$wf32b>", c,
+ b);
+ EXPECT_SWPRINTF(L"<10101010101010101010101010101010 --- 22222222 --- 44444444>",
+ L"<%3$wf32b --- %1$wf16x --- %2$wf32x>", a, b, c);
+#endif
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_invalid_wf_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ char buf[BUFSIZ];
+ int_fast32_t a = 100;
+ EXPECT_DEATH(snprintf(buf, sizeof(buf), "%wf20d", &a), "%wf20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
+
+TEST(STDIO_TEST, swprintf_invalid_wf_width) {
+#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ wchar_t buf[BUFSIZ];
+ int_fast32_t a = 100;
+ EXPECT_DEATH(swprintf(buf, sizeof(buf), L"%wf20d", &a), "%wf20 is unsupported");
+#pragma clang diagnostic pop
+#else
+ GTEST_SKIP() << "no %w in glibc";
+#endif
+}
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 10c100a..0123ed9 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -30,7 +30,7 @@
#define CHECK_OFFSET(name, field, offset) \
check_offset(#name, #field, offsetof(name, field), offset);
#ifdef __LP64__
- CHECK_SIZE(pthread_internal_t, 784);
+ CHECK_SIZE(pthread_internal_t, 776);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 8);
CHECK_OFFSET(pthread_internal_t, tid, 16);
@@ -55,7 +55,6 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 248);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 760);
CHECK_OFFSET(pthread_internal_t, errno_value, 768);
- CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 776);
CHECK_SIZE(bionic_tls, 12200);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 2080);
@@ -73,7 +72,7 @@
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
CHECK_OFFSET(bionic_tls, padding, 12194);
#else
- CHECK_SIZE(pthread_internal_t, 672);
+ CHECK_SIZE(pthread_internal_t, 668);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 4);
CHECK_OFFSET(pthread_internal_t, tid, 8);
@@ -98,7 +97,6 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 148);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 660);
CHECK_OFFSET(pthread_internal_t, errno_value, 664);
- CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 668);
CHECK_SIZE(bionic_tls, 11080);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 1040);
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index 200f654..da45087 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -74,9 +74,12 @@
}
TEST(sys_msg, msgctl_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
errno = 0;
ASSERT_EQ(-1, msgctl(-1, IPC_STAT, nullptr));
ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
}
TEST(sys_msg, msgget_failure) {
@@ -86,9 +89,12 @@
}
TEST(sys_msg, msgrcv_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
errno = 0;
ASSERT_EQ(-1, msgrcv(-1, nullptr, 0, 0, 0));
ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
}
TEST(sys_msg, msgsnd_failure) {
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
index 2e2665b..e0cbf78 100644
--- a/tests/sys_random_test.cpp
+++ b/tests/sys_random_test.cpp
@@ -48,6 +48,8 @@
}
TEST(sys_random, getentropy_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
#if defined(HAVE_SYS_RANDOM)
errno = 0;
ASSERT_EQ(-1, getentropy(nullptr, 1));
@@ -55,6 +57,7 @@
#else
GTEST_SKIP() << "<sys/random.h> not available";
#endif
+#pragma clang diagnostic pop
}
TEST(sys_random, getentropy_EIO) {
@@ -84,6 +87,8 @@
}
TEST(sys_random, getrandom_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
#if defined(HAVE_SYS_RANDOM)
errno = 0;
ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
@@ -91,6 +96,7 @@
#else
GTEST_SKIP() << "<sys/random.h> not available";
#endif
+#pragma clang diagnostic pop
}
TEST(sys_random, getrandom_EINVAL) {
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index b98926b..4bac92f 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -87,15 +87,21 @@
}
TEST(sys_sem, semop_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
errno = 0;
ASSERT_EQ(-1, semop(-1, nullptr, 0));
ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
}
TEST(sys_sem, semtimedop_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
errno = 0;
ASSERT_EQ(-1, semtimedop(-1, nullptr, 0, nullptr));
ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
}
TEST(sys_sem, union_semun) {
diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp
index 1340ea4..44b73c9 100644
--- a/tests/sys_timex_test.cpp
+++ b/tests/sys_timex_test.cpp
@@ -27,21 +27,9 @@
ASSERT_NE(-1, adjtimex(&t));
}
-TEST(sys_timex, adjtimex_EFAULT) {
- errno = 0;
- ASSERT_EQ(-1, adjtimex(nullptr));
- ASSERT_EQ(EFAULT, errno);
-}
-
TEST(sys_timex, clock_adjtime_smoke) {
timex t;
memset(&t, 0, sizeof(t));
// adjtimex/clock_adjtime return the clock state on success, -1 on failure.
ASSERT_NE(-1, clock_adjtime(CLOCK_REALTIME, &t));
}
-
-TEST(sys_timex, clock_adjtime_EFAULT) {
- errno = 0;
- ASSERT_EQ(-1, clock_adjtime(CLOCK_REALTIME, nullptr));
- ASSERT_EQ(EFAULT, errno);
-}
diff --git a/tests/sys_wait_test.cpp b/tests/sys_wait_test.cpp
index c006972..200fabe 100644
--- a/tests/sys_wait_test.cpp
+++ b/tests/sys_wait_test.cpp
@@ -42,3 +42,22 @@
ASSERT_EQ(66, si.si_status);
ASSERT_EQ(CLD_EXITED, si.si_code);
}
+
+// https://github.com/android/ndk/issues/1878
+TEST(sys_wait, macros) {
+#if defined(__GLIBC__)
+ // glibc before 2016 requires an lvalue.
+#else
+ ASSERT_FALSE(WIFEXITED(0x7f));
+ ASSERT_TRUE(WIFSTOPPED(0x7f));
+ ASSERT_FALSE(WIFCONTINUED(0x7f));
+
+ ASSERT_TRUE(WIFEXITED(0x80));
+ ASSERT_FALSE(WIFSTOPPED(0x80));
+ ASSERT_FALSE(WIFCONTINUED(0x80));
+
+ ASSERT_FALSE(WIFEXITED(0xffff));
+ ASSERT_FALSE(WIFSTOPPED(0xffff));
+ ASSERT_TRUE(WIFCONTINUED(0xffff));
+#endif
+}
diff --git a/tests/syslog_test.cpp b/tests/syslog_test.cpp
new file mode 100644
index 0000000..3ec3337
--- /dev/null
+++ b/tests/syslog_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 <syslog.h>
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+#include "utils.h"
+
+TEST(syslog, syslog_percent_m) {
+ ExecTestHelper eth;
+ eth.Run(
+ [&]() {
+ openlog("foo", LOG_PERROR, LOG_AUTH);
+ errno = EINVAL;
+ syslog(LOG_ERR, "a b c: %m");
+ closelog();
+ exit(0);
+ },
+ 0, "foo: a b c: Invalid argument\n");
+}
+
+TEST(syslog, syslog_empty) {
+ ExecTestHelper eth;
+ eth.Run(
+ [&]() {
+ openlog("foo", LOG_PERROR, LOG_AUTH);
+ errno = EINVAL;
+ syslog(LOG_ERR, "");
+ closelog();
+ exit(0);
+ },
+ 0, "foo: \n");
+}
+
+TEST(syslog, syslog_truncation) {
+ ExecTestHelper eth;
+ eth.Run(
+ [&]() {
+ openlog("bar", LOG_PERROR, LOG_AUTH);
+ char too_long[2048] = {};
+ memset(too_long, 'x', sizeof(too_long) - 1);
+ syslog(LOG_ERR, "%s", too_long);
+ closelog();
+ exit(0);
+ },
+ 0, "bar: x{1023}\n");
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index f0ad937..d16600c 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -181,10 +181,25 @@
ASSERT_NE(static_cast<time_t>(-1), mktime(&t));
ASSERT_EQ(0, errno);
- // This will overflow for LP32 or LP64.
+ // This will overflow for LP32.
t.tm_year = INT_MAX;
errno = 0;
+#if !defined(__LP64__)
+ ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
+ ASSERT_EQ(EOVERFLOW, errno);
+#else
+ ASSERT_EQ(static_cast<time_t>(67768036166016000U), mktime(&t));
+ ASSERT_EQ(0, errno);
+#endif
+
+ // This will overflow for LP32 or LP64.
+ // tm_year is int, this t struct points to INT_MAX + 1 no matter what TZ is.
+ t.tm_year = INT_MAX;
+ t.tm_mon = 11;
+ t.tm_mday = 45;
+
+ errno = 0;
ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
ASSERT_EQ(EOVERFLOW, errno);
}
@@ -1254,8 +1269,39 @@
TEST(time, timespec_get) {
#if __BIONIC__
timespec ts = {};
- ASSERT_EQ(0, timespec_get(&ts, 123));
ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
+ ASSERT_EQ(TIME_MONOTONIC, timespec_get(&ts, TIME_MONOTONIC));
+ ASSERT_EQ(TIME_ACTIVE, timespec_get(&ts, TIME_ACTIVE));
+ ASSERT_EQ(TIME_THREAD_ACTIVE, timespec_get(&ts, TIME_THREAD_ACTIVE));
+#else
+ GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_get_invalid) {
+#if __BIONIC__
+ timespec ts = {};
+ ASSERT_EQ(0, timespec_get(&ts, 123));
+#else
+ GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_getres) {
+#if __BIONIC__
+ timespec ts = {};
+ ASSERT_EQ(TIME_UTC, timespec_getres(&ts, TIME_UTC));
+ ASSERT_EQ(1, ts.tv_nsec);
+ ASSERT_EQ(0, ts.tv_sec);
+#else
+ GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
+#endif
+}
+
+TEST(time, timespec_getres_invalid) {
+#if __BIONIC__
+ timespec ts = {};
+ ASSERT_EQ(0, timespec_getres(&ts, 123));
#else
GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
#endif
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 2a36460..4c21627 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -589,9 +589,10 @@
TestGetTidCachingWithFork(CloneAndSetTid, exit);
}
+__attribute__((no_sanitize("hwaddress", "memtag")))
static int CloneStartRoutine(int (*start_routine)(void*)) {
void* child_stack[1024];
- return clone(start_routine, untag_address(&child_stack[1024]), SIGCHLD, nullptr);
+ return clone(start_routine, &child_stack[1024], SIGCHLD, nullptr);
}
static int GetPidCachingCloneStartRoutine(void*) {
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
index b024818..459f9c3 100644
--- a/tests/utmp_test.cpp
+++ b/tests/utmp_test.cpp
@@ -25,6 +25,7 @@
}
TEST(utmp, smoke) {
+ // The rest of <utmp.h> is just no-op implementations, so testing is trivial.
ASSERT_EQ(-1, utmpname("hello"));
setutent();
ASSERT_EQ(NULL, getutent());
diff --git a/libc/bionic/timespec_get.cpp b/tests/utmpx_test.cpp
similarity index 76%
copy from libc/bionic/timespec_get.cpp
copy to tests/utmpx_test.cpp
index 7fc2182..55427a6 100644
--- a/libc/bionic/timespec_get.cpp
+++ b/tests/utmpx_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,17 @@
* SUCH DAMAGE.
*/
-#include <time.h>
+#include <gtest/gtest.h>
-int timespec_get(timespec* ts, int base) {
- return (base == TIME_UTC && clock_gettime(CLOCK_REALTIME, ts) != -1) ? base : 0;
+#include <utmpx.h>
+
+TEST(utmpx, smoke) {
+ // Our utmpx "implementation" just calls the utmp no-op functions.
+ setutxent();
+ utmpx empty = {.ut_type = EMPTY};
+ ASSERT_EQ(NULL, getutxent());
+ ASSERT_EQ(NULL, getutxid(&empty));
+ ASSERT_EQ(NULL, getutxline(&empty));
+ endutxent();
+ ASSERT_EQ(NULL, pututxline(&empty));
}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 16d4348..8716810 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -714,7 +714,8 @@
#if defined(__BIONIC__)
wchar_t* p;
size_t size;
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
// Invalid buffer.
errno = 0;
ASSERT_EQ(nullptr, open_wmemstream(nullptr, &size));
@@ -724,6 +725,7 @@
errno = 0;
ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
#else
GTEST_SKIP() << "This test is bionic-specific";
#endif