Merge "Lay the groundwork for enabling EDNS0 in queries."
diff --git a/Android.bp b/Android.bp
index dbe5c97..b44c296 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,2 +1 @@
subdirs = ["*"]
-
diff --git a/README.md b/README.md
index f0be759..a6cf467 100644
--- a/README.md
+++ b/README.md
@@ -144,8 +144,23 @@
</pre>
-Adding system calls
--------------------
+Adding libc wrappers for system calls
+-------------------------------------
+
+The first question you should ask is "should I add a libc wrapper for
+this system call?". The answer is usually "no".
+
+The answer is "yes" if the system call is part of the POSIX standard.
+
+The answer is probably "yes" if the system call has a wrapper in at
+least one other C library.
+
+The answer may be "yes" if the system call has three/four distinct
+users in different projects, and there isn't a more specific library
+that would make more sense as the place to add the wrapper.
+
+In all other cases, you should use
+[syscall(3)](http://man7.org/linux/man-pages/man2/syscall.2.html) instead.
Adding a system call usually involves:
@@ -157,7 +172,8 @@
kernel uapi header files, in which case you just need to make sure that
the appropriate POSIX header file in libc/include/ includes the
relevant file or files.
- 4. Add function declarations to the appropriate header file.
+ 4. Add function declarations to the appropriate header file. Don't forget
+ to include the appropriate `__INTRODUCED_IN()`.
5. Add the function name to the correct section in libc/libc.map.txt and
run `./libc/tools/genversion-scripts.py`.
6. Add at least basic tests. Even a test that deliberately supplies
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 115236b..f6d0e4d 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -67,7 +67,7 @@
"libsystemproperties",
"libasync_safe",
],
- include_dirs: ["bionic/libc",],
+ include_dirs: ["bionic/libc"],
}
// We don't build a static benchmark executable because it's not usually
@@ -107,5 +107,8 @@
"libbase",
"libBionicBenchmarksUtils",
],
- data: ["suites/*", "test_suites/*"],
+ data: [
+ "suites/*",
+ "test_suites/*",
+ ],
}
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 9868765..17e37b0 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -98,7 +98,7 @@
return;
}
- system_properties_.contexts()->FreeAndUnmap();
+ system_properties_.contexts_->FreeAndUnmap();
for (int i = 0; i < nprops; i++) {
delete names[i];
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 46d6e64..c72736e 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -96,7 +96,6 @@
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
-#if defined(__LP64__)
namespace {
struct PIMutex {
pthread_mutex_t mutex;
@@ -145,7 +144,6 @@
}
}
BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI);
-#endif // defined(__LP64__)
static void BM_pthread_rwlock_read(benchmark::State& state) {
pthread_rwlock_t lock;
diff --git a/benchmarks/util.h b/benchmarks/util.h
index 3225bc2..d9e10f4 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _BIONIC_BENCHMARKS_UTIL_H_
-#define _BIONIC_BENCHMARKS_UTIL_H_
+#pragma once
#include <map>
#include <mutex>
@@ -62,5 +61,3 @@
char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte);
bool LockToCPU(long cpu_to_lock);
-
-#endif // _BIONIC_BENCHMARKS_UTIL_H
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 21f9b71..0ea94d4 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -59,6 +59,9 @@
In the 64-bit ABI, `off_t` is always 64-bit.
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
## `sigset_t` is too small for real-time signals
@@ -68,8 +71,15 @@
for every function that takes a `sigset_t` (so `sigprocmask64` takes a
`sigset64_t` where `sigprocmask` takes a `sigset_t`).
+On 32-bit Android, `struct sigaction` is also too small because it contains
+a `sigset_t`. We also offer a `struct sigaction64` and `sigaction64` function
+to work around this.
+
In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
## `time_t` is 32-bit
diff --git a/docs/status.md b/docs/status.md
index 8cef5b7..a0e6824 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -49,11 +49,15 @@
* `iconv`/`iconv_close`/`iconv_open` (adding <iconv.h>)
* `pthread_attr_getinheritsched`/`pthread_attr_setinheritsched`/`pthread_setschedprio`
* `pthread_mutexattr_getprotocol`/`pthread_mutexattr_setprotocol` (mutex priority inheritance)
+ * <signal.h> support for `sigaction64_t` and `sigset64_t` allowing LP32 access to real-time signals
* <spawn.h>
* `swab`
* `syncfs`
- * `%C` and `%S` support in the printf family (previously only the wprintf family supported these).
- * `%mc`/`%ms`/`%m[` support in the scanf family.
+
+New libc behavior in P:
+ * `%C` and `%S` support in the printf family (previously only the wprintf family supported these)
+ * `%mc`/`%ms`/`%m[` support in the scanf family
+ * `%s` support in strptime (strftime already supported it)
New libc functions in O:
* `sendto` FORTIFY support
diff --git a/libc/Android.bp b/libc/Android.bp
index 0f58204..20df52c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -33,6 +33,7 @@
libc_common_flags = [
"-D_LIBC=1",
+ "-D__BIONIC_LP32_USE_STAT64",
"-Wall",
"-Wextra",
"-Wunused",
@@ -46,6 +47,10 @@
"-Werror=int-to-pointer-cast",
"-Werror=type-limits",
"-Werror",
+
+ // Clang's exit-time destructor registration hides __dso_handle, but
+ // __dso_handle needs to have default visibility on ARM32. See b/73485611.
+ "-Wexit-time-destructors",
]
// Define some common cflags
@@ -476,7 +481,6 @@
"upstream-openbsd/lib/libc/stdlib/reallocarray.c",
"upstream-openbsd/lib/libc/stdlib/remque.c",
"upstream-openbsd/lib/libc/stdlib/setenv.c",
- "upstream-openbsd/lib/libc/stdlib/system.c",
"upstream-openbsd/lib/libc/stdlib/tfind.c",
"upstream-openbsd/lib/libc/stdlib/tsearch.c",
"upstream-openbsd/lib/libc/string/strcasecmp.c",
@@ -538,7 +542,7 @@
cc_library_static {
defaults: ["libc_defaults"],
srcs: [
- // These two depend on getentropy_linux.c, which isn't in libc_ndk.a.
+ // These two depend on getentropy, which isn't in libc_ndk.a.
"upstream-openbsd/lib/libc/crypt/arc4random.c",
"upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
@@ -709,7 +713,10 @@
// Disable FORTIFY for the compilation of these, so we don't end up having
// FORTIFY silently call itself.
- cflags: ["-U_FORTIFY_SOURCE", "-D__BIONIC_DECLARE_FORTIFY_HELPERS"],
+ cflags: [
+ "-U_FORTIFY_SOURCE",
+ "-D__BIONIC_DECLARE_FORTIFY_HELPERS",
+ ],
arch: {
arm: {
@@ -718,7 +725,10 @@
"arch-arm/generic/bionic/__memcpy_chk.S",
],
neon: {
- cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ cflags: [
+ "-DNO___STRCAT_CHK",
+ "-DNO___STRCPY_CHK",
+ ],
srcs: [
"arch-arm/cortex-a15/bionic/__strcat_chk.S",
"arch-arm/cortex-a15/bionic/__strcpy_chk.S",
@@ -817,9 +827,7 @@
// initialized, resulting in nullptr dereferences.
"bionic/getauxval.cpp",
- // These four require getauxval, which isn't available on older
- // platforms.
- "bionic/getentropy_linux.c",
+ // These require getauxval, which isn't available on older platforms.
"bionic/sysconf.cpp",
"bionic/vdso.cpp",
"bionic/setjmp_cookie.cpp",
@@ -1266,6 +1274,7 @@
"bionic/futimens.cpp",
"bionic/getcwd.cpp",
"bionic/getdomainname.cpp",
+ "bionic/getentropy.cpp",
"bionic/gethostname.cpp",
"bionic/getpagesize.cpp",
"bionic/getpgrp.cpp",
@@ -1273,6 +1282,7 @@
"bionic/getpriority.cpp",
"bionic/gettid.cpp",
"bionic/grp_pwd.cpp",
+ "bionic/grp_pwd_file.cpp",
"bionic/iconv.cpp",
"bionic/icu_wrappers.cpp",
"bionic/ifaddrs.cpp",
@@ -1331,6 +1341,7 @@
"bionic/setpgrp.cpp",
"bionic/sigaction.cpp",
"bionic/signal.cpp",
+ "bionic/sigprocmask.cpp",
"bionic/socket.cpp",
"bionic/spawn.cpp",
"bionic/stat.cpp",
@@ -1357,6 +1368,7 @@
"bionic/sys_time.cpp",
"bionic/sysinfo.cpp",
"bionic/syslog.cpp",
+ "bionic/system.cpp",
"bionic/system_property_api.cpp",
"bionic/system_property_set.cpp",
"bionic/tdestroy.cpp",
@@ -1696,7 +1708,10 @@
"ld-android",
"libdl",
],
- whole_static_libs: ["libc_common", "libjemalloc"],
+ whole_static_libs: [
+ "libc_common",
+ "libjemalloc",
+ ],
nocrt: true,
@@ -1794,7 +1809,11 @@
defaults: ["linux_bionic_supported"],
vendor_available: true,
- cflags: ["-Wno-gcc-compat", "-Wall", "-Werror"],
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
}
cc_defaults {
diff --git a/libc/NOTICE b/libc/NOTICE
index daf8491..f9a2aff 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -5511,26 +5511,6 @@
-------------------------------------------------------------------
-Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
-Copyright (c) 2014 Bob Beck <beck@obtuse.com>
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Emulation of getentropy(2) as documented at:
-http://man.openbsd.org/getentropy.2
-
--------------------------------------------------------------------
-
Copyright (c) 2014, Intel Corporation
All rights reserved.
diff --git a/libc/SECCOMP_WHITELIST_APP.TXT b/libc/SECCOMP_WHITELIST_APP.TXT
index 2f3618c..21839a6 100644
--- a/libc/SECCOMP_WHITELIST_APP.TXT
+++ b/libc/SECCOMP_WHITELIST_APP.TXT
@@ -24,3 +24,57 @@
# - Each parameter type is assumed to be stored in 32 bits.
#
# This file is processed by a python script named genseccomp.py.
+
+# Needed for debugging 32-bit Chrome
+int pipe:pipe(int pipefd[2]) arm,x86,mips
+
+# b/34651972
+int access:access(const char *pathname, int mode) arm,x86,mips
+int stat64:stat64(const char*, struct stat64*) arm,x86,mips
+
+# b/34813887
+int open:open(const char *path, int oflag, ... ) arm,x86,mips
+int getdents:getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) arm,x86,mips
+
+# b/34719286
+int eventfd:eventfd(unsigned int initval, int flags) arm,x86,mips
+
+# b/34817266
+int epoll_wait:epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) arm,x86,mips
+
+# b/34908783
+int epoll_create:epoll_create(int size) arm,x86,mips
+
+# b/34979910
+int creat:creat(const char *pathname, mode_t mode) arm,x86,mips
+int unlink:unlink(const char *pathname) arm,x86,mips
+
+# b/35059702
+int lstat64:lstat64(const char*, struct stat64*) arm,x86,mips
+
+# b/35217603
+int fcntl:fcntl(int fd, int cmd, ... /* arg */ ) arm,x86,mips
+pid_t fork:fork() arm,x86,mips
+int poll:poll(struct pollfd *fds, nfds_t nfds, int timeout) arm,x86,mips
+
+# b/35906875. Note mips already has getuid from SYSCALLS.TXT
+int inotify_init() arm,x86,mips
+uid_t getuid() arm,x86
+
+# b/36435222
+int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags) arm,x86,mips
+
+# b/36449658
+int rename(const char *oldpath, const char *newpath) arm,x86,mips
+
+# b/36726183. Note arm does not support mmap
+void* mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) x86,mips
+
+# b/37769298
+int dup2(int oldfd, int newfd) arm,x86,mips
+
+# b/62779795
+int compat_select:_newselect(int n, unsigned long* inp, unsigned long* outp, unsigned long* exp, struct timeval* timeout) arm,x86,mips
+
+# b/62090571
+int mkdir(const char *pathname, mode_t mode) arm,x86,mips
diff --git a/libc/SECCOMP_WHITELIST_COMMON.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT
index a620b44..08a2c2b 100644
--- a/libc/SECCOMP_WHITELIST_COMMON.TXT
+++ b/libc/SECCOMP_WHITELIST_COMMON.TXT
@@ -39,6 +39,9 @@
int fstat64|fstat:fstat(int, struct stat*) mips64
int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips64
+# vfork is used by java.lang.ProcessBuilder
+pid_t vfork:vfork() arm,x86,x86_64
+
# Needed for performance tools
int perf_event_open:perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) all
@@ -51,59 +54,11 @@
# syscalls needed to boot android
int sigreturn:sigreturn(unsigned long __unused) arm,x86,mips
-# Syscalls needed to run GFXBenchmark
-pid_t vfork:vfork() arm,x86,x86_64
-
-# Needed for debugging 32-bit Chrome
-int pipe:pipe(int pipefd[2]) arm,x86,mips
-
-# b/34651972
-int access:access(const char *pathname, int mode) arm,x86,mips
-int stat64:stat64(const char*, struct stat64*) arm,x86,mips
-
-# b/34813887
-int open:open(const char *path, int oflag, ... ) arm,x86,mips
-int getdents:getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) arm,x86,mips
-
-# b/34719286
-int eventfd:eventfd(unsigned int initval, int flags) arm,x86,mips
-
-# b/34817266
-int epoll_wait:epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) arm,x86,mips
-
# Needed by sanitizers (b/34606909)
# 5 (__NR_open) and 195 (__NR_stat64) are also required, but they are
# already allowed.
ssize_t readlink:readlink(const char *path, char *buf, size_t bufsiz) arm,x86,mips
-# b/34908783
-int epoll_create:epoll_create(int size) arm,x86,mips
-
-# b/34979910
-int creat:creat(const char *pathname, mode_t mode) arm,x86,mips
-int unlink:unlink(const char *pathname) arm,x86,mips
-
-# b/35059702
-int lstat64:lstat64(const char*, struct stat64*) arm,x86,mips
-
-# b/35217603
-int fcntl:fcntl(int fd, int cmd, ... /* arg */ ) arm,x86,mips
-pid_t fork:fork() arm,x86,mips
-int poll:poll(struct pollfd *fds, nfds_t nfds, int timeout) arm,x86,mips
-
-# b/35906875. Note mips already has getuid from SYSCALLS.TXT
-int inotify_init() arm,x86,mips
-uid_t getuid() arm,x86
-
-# b/36435222
-int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags) arm,x86,mips
-
-# b/36449658
-int rename(const char *oldpath, const char *newpath) arm,x86,mips
-
-# b/36726183. Note arm does not support mmap
-void* mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) x86,mips
-
# Useful new syscalls which we don't yet use in bionic.
int sched_getattr(pid_t pid, struct sched_attr* attr, unsigned int flags) all
int sched_setattr(pid_t pid, struct sched_attr* attr, unsigned int size, unsigned int flags) all
@@ -119,12 +74,3 @@
int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) all
int io_getevents(aio_context_t ctx, long min_nr, long max_nr, struct io_event *events, struct timespec *timeout) all
int io_cancel(aio_context_t ctx, struct iocb *, struct io_event *result) all
-
-# b/37769298
-int dup2(int oldfd, int newfd) arm,x86,mips
-
-# b/62779795
-int compat_select:_newselect(int n, unsigned long* inp, unsigned long* outp, unsigned long* exp, struct timeval* timeout) arm,x86,mips
-
-# b/62090571
-int mkdir(const char *pathname, mode_t mode) arm,x86,mips
diff --git a/libc/arch-arm/bionic/exidx_static.c b/libc/arch-arm/bionic/exidx_static.c
index 1686d6a..ef3745f 100644
--- a/libc/arch-arm/bionic/exidx_static.c
+++ b/libc/arch-arm/bionic/exidx_static.c
@@ -35,10 +35,15 @@
* EXIDX section.
*/
-extern unsigned __exidx_end;
-extern unsigned __exidx_start;
+struct exidx_entry {
+ uint32_t key;
+ uint32_t value;
+};
+
+extern struct exidx_entry __exidx_end;
+extern struct exidx_entry __exidx_start;
_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc __attribute__((unused)), int* pcount) {
- *pcount = (&__exidx_end - &__exidx_start) / 8;
+ *pcount = (&__exidx_end - &__exidx_start);
return (_Unwind_Ptr)&__exidx_start;
}
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 30e7e23..5fbcaf3 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -58,17 +58,15 @@
// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
// 1 sigmask 64-bit signal mask (not used with _setjmp / _longjmp)
// 2 " "
-// 3 reserved (unused to allow float_base to be maximally aligned)
+// 3 reserved (unused to allow float_base to be maximally aligned;
+// this avoids software emulation of unaligned loads/stores)
// 4 float_base base of float registers (d8 to d15)
// 20 float_state floating-point status and control register
// 21 core_base base of core registers (r4-r11, r13-r14)
-// 31 checksum checksum of all of the core registers, to give better error messages.
+// 31 checksum checksum of all of the core registers, to give better error messages
// 32 reserved reserved entries (room to grow)
-// 64
-//
-// NOTE: float_base must be at an even word index, since the
-// FP registers will be loaded/stored with instructions
-// that expect 8-byte alignment.
+// ...
+// 63 " "
#define _JB_SIGFLAG 0
#define _JB_SIGMASK (_JB_SIGFLAG + 1)
diff --git a/libc/arch-arm/generic/bionic/strlen.c b/libc/arch-arm/generic/bionic/strlen.c
index dccd564..44bd72f 100644
--- a/libc/arch-arm/generic/bionic/strlen.c
+++ b/libc/arch-arm/generic/bionic/strlen.c
@@ -29,7 +29,7 @@
#include <string.h>
#include <stdint.h>
-size_t strlen(const char *s) __overloadable
+size_t strlen(const char *s)
{
__builtin_prefetch(s);
__builtin_prefetch(s+32);
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index 31ad621..c4d2a5a 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -53,7 +53,7 @@
#elif defined(__arm__)
__asm__(PRE "mov r0,sp; b _start_main" POST);
#elif defined(__i386__)
-__asm__(PRE "movl %esp,%eax; andl $~0xf,%esp; pushl %eax; calll _start_main" POST);
+__asm__(PRE "movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax; calll _start_main" POST);
#elif defined(__x86_64__)
__asm__(PRE "movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
#else
diff --git a/libc/arch-common/bionic/pthread_atfork.h b/libc/arch-common/bionic/pthread_atfork.h
index c6a33ff..742d078 100644
--- a/libc/arch-common/bionic/pthread_atfork.h
+++ b/libc/arch-common/bionic/pthread_atfork.h
@@ -16,9 +16,9 @@
#include <android/api-level.h>
-// __register_atfork wasn't available until android-23. We need to build a
-// pre-23 and 23+ version of crtbegin.
-#if __ANDROID_API__ >= __ANDROID_API_M__
+// __register_atfork wasn't available until android-23. When using libc.a, we're
+// using the latest library regardless of target API level.
+#if defined(_FORCE_CRT_ATFORK) || __ANDROID_API__ >= __ANDROID_API_M__
extern void* __dso_handle;
diff --git a/libc/arch-mips/string/memchr.c b/libc/arch-mips/string/memchr.c
index 6b4c8cc..bc24f79 100644
--- a/libc/arch-mips/string/memchr.c
+++ b/libc/arch-mips/string/memchr.c
@@ -100,7 +100,7 @@
}
void *
-memchr (void const *s, int c_in, size_t n) __overloadable
+memchr (void const *s, int c_in, size_t n)
{
if (n != 0) {
const unsigned char *p = (const unsigned char *) s;
diff --git a/libc/arch-mips/string/memcpy.c b/libc/arch-mips/string/memcpy.c
index 68827b6..bb0d179 100644
--- a/libc/arch-mips/string/memcpy.c
+++ b/libc/arch-mips/string/memcpy.c
@@ -286,7 +286,7 @@
}
void *
-memcpy (void *a, const void *b, size_t len) __overloadable
+memcpy (void *a, const void *b, size_t len)
{
unsigned long bytes, words;
void *ret = a;
diff --git a/libc/arch-mips/string/memmove.c b/libc/arch-mips/string/memmove.c
index fbff297..74d4cd0 100644
--- a/libc/arch-mips/string/memmove.c
+++ b/libc/arch-mips/string/memmove.c
@@ -383,7 +383,7 @@
}
void *
-memmove (void *dst0, const void *src0, size_t length) __overloadable
+memmove (void *dst0, const void *src0, size_t length)
{
unsigned long bytes, words;
void *ret = dst0;
diff --git a/libc/arch-mips/string/strchr.c b/libc/arch-mips/string/strchr.c
index c9397e7..3458f66 100644
--- a/libc/arch-mips/string/strchr.c
+++ b/libc/arch-mips/string/strchr.c
@@ -92,7 +92,7 @@
return (char *)p;
}
-char* strchr(const char* s, int c) __overloadable
+char* strchr(const char* s, int c)
{
const op_t *w;
op_t mask_1, mask_128, mask_c;
diff --git a/libc/arch-mips/string/strcpy.c b/libc/arch-mips/string/strcpy.c
index 7b5dee3..b77105e 100644
--- a/libc/arch-mips/string/strcpy.c
+++ b/libc/arch-mips/string/strcpy.c
@@ -167,7 +167,7 @@
}
char *
-strcpy (char *to, const char *from) __overloadable
+strcpy (char *to, const char *from)
{
char *ret = to;
op_t mask_1, mask_128;
diff --git a/libc/arch-mips/string/strlen.c b/libc/arch-mips/string/strlen.c
index 491efae..28463f6 100644
--- a/libc/arch-mips/string/strlen.c
+++ b/libc/arch-mips/string/strlen.c
@@ -79,7 +79,7 @@
#endif
size_t
-strlen (const char *str) __overloadable
+strlen (const char *str)
{
if (*str) {
const char *p = (const char *) str;
diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h
index 10833e4..415b48e 100644
--- a/libc/async_safe/include/async_safe/log.h
+++ b/libc/async_safe/include/async_safe/log.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _ASYNC_SAFE_LOG_LOG_H
-#define _ASYNC_SAFE_LOG_LOG_H
+#pragma once
#include <sys/cdefs.h>
#include <stdarg.h>
@@ -104,5 +103,3 @@
} while(0)
__END_DECLS
-
-#endif
diff --git a/libc/bionic/__libc_current_sigrtmin.cpp b/libc/bionic/__libc_current_sigrtmin.cpp
index 04caa89..d2ea75d 100644
--- a/libc/bionic/__libc_current_sigrtmin.cpp
+++ b/libc/bionic/__libc_current_sigrtmin.cpp
@@ -28,14 +28,8 @@
#include <signal.h>
-// Realtime signals reserved for internal use:
-// 32 (__SIGRTMIN + 0) POSIX timers
-// 33 (__SIGRTMIN + 1) libbacktrace
-// 34 (__SIGRTMIN + 2) libcore
-// 35 (__SIGRTMIN + 3) debuggerd -b
+#include "private/sigrtmin.h"
-int __libc_current_sigrtmin(void) {
- // If you change this, also change __ndk_legacy___libc_current_sigrtmin
- // in <android/legacy_signal_inlines.h> to match.
- return __SIGRTMIN + 4;
+int __libc_current_sigrtmin() {
+ return __SIGRTMIN + __SIGRT_RESERVED;
}
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index ec26a50..d2c99a5 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -67,13 +67,10 @@
sigprocmask64(SIG_SETMASK, &mask, nullptr);
inline_tgkill(pid, tid, SIGABRT);
- // If SIGABRT ignored, or caught and the handler returns,
+ // If SIGABRT is ignored or it's caught and the handler returns,
// remove the SIGABRT signal handler and raise SIGABRT again.
- struct sigaction sa;
- sa.sa_handler = SIG_DFL;
- sa.sa_flags = SA_RESTART;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGABRT, &sa, &sa);
+ struct sigaction64 sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART };
+ sigaction64(SIGABRT, &sa, nullptr);
sigprocmask64(SIG_SETMASK, &mask, nullptr);
inline_tgkill(pid, tid, SIGABRT);
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
index 391eb0c..fa2617f 100644
--- a/libc/bionic/bionic_arc4random.cpp
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -28,8 +28,6 @@
#include "private/bionic_arc4random.h"
-#include <errno.h>
-#include <stdatomic.h>
#include <stdlib.h>
#include <string.h>
#include <sys/auxv.h>
@@ -39,15 +37,12 @@
#include "private/KernelArgumentBlock.h"
-bool __libc_arc4random_has_unlimited_entropy() {
- static bool have_urandom = access("/dev/urandom", R_OK) == 0;
- return have_urandom;
-}
-
void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args) {
- // Only call arc4random_buf once we `have_urandom', since in getentropy_getrandom we may fallback
- // to use /dev/urandom, if the kernel entropy pool hasn't been initialized or not enough bytes
- if (__libc_arc4random_has_unlimited_entropy()) {
+ // Only call arc4random_buf once we have `/dev/urandom` because getentropy(3)
+ // will fall back to using `/dev/urandom` if getrandom(2) fails, and abort if
+ // if can't use `/dev/urandom`.
+ static bool have_urandom = access("/dev/urandom", R_OK) == 0;
+ if (have_urandom) {
arc4random_buf(buf, n);
return;
}
diff --git a/libc/bionic/bionic_netlink.h b/libc/bionic/bionic_netlink.h
index bc0e3f0..a21200e 100644
--- a/libc/bionic/bionic_netlink.h
+++ b/libc/bionic/bionic_netlink.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef BIONIC_NETLINK_H
-#define BIONIC_NETLINK_H
+#pragma once
#include <sys/types.h>
@@ -49,5 +48,3 @@
char* data_;
size_t size_;
};
-
-#endif
diff --git a/libc/bionic/getcwd.cpp b/libc/bionic/getcwd.cpp
index 50487ec..a8bbcf3 100644
--- a/libc/bionic/getcwd.cpp
+++ b/libc/bionic/getcwd.cpp
@@ -33,7 +33,7 @@
extern "C" int __getcwd(char* buf, size_t size);
-char* getcwd(char* buf, size_t size) __overloadable {
+char* getcwd(char* buf, size_t size) {
// You can't specify size 0 unless you're asking us to allocate for you.
if (buf != NULL && size == 0) {
errno = EINVAL;
diff --git a/libc/bionic/getentropy.cpp b/libc/bionic/getentropy.cpp
new file mode 100644
index 0000000..2c6e417
--- /dev/null
+++ b/libc/bionic/getentropy.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/random.h>
+#include <unistd.h>
+
+static int getentropy_urandom(void* buffer, size_t buffer_size, int saved_errno) {
+ int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0));
+ if (fd == -1) return -1;
+
+ size_t collected = 0;
+ while (collected < buffer_size) {
+ ssize_t count = TEMP_FAILURE_RETRY(read(fd, static_cast<char*>(buffer) + collected,
+ buffer_size - collected));
+ if (count == -1) {
+ close(fd);
+ return -1;
+ }
+ collected += count;
+ }
+
+ close(fd);
+ errno = saved_errno;
+ return 0;
+}
+
+int getentropy(void* buffer, size_t buffer_size) {
+ if (buffer_size > 256) {
+ errno = EIO;
+ return -1;
+ }
+
+ int saved_errno = errno;
+
+ size_t collected = 0;
+ while (collected < buffer_size) {
+ long count = TEMP_FAILURE_RETRY(getrandom(static_cast<char*>(buffer) + collected,
+ buffer_size - collected, GRND_NONBLOCK));
+ if (count == -1) {
+ // EAGAIN: there isn't enough entropy right now.
+ // ENOSYS/EINVAL: getrandom(2) or GRND_NONBLOCK isn't supported.
+ // EFAULT: `buffer` is invalid.
+ // Try /dev/urandom regardless because it can't hurt,
+ // and we don't need to optimize the EFAULT case.
+ // See http://b/33059407 and http://b/67015565.
+ return getentropy_urandom(buffer, buffer_size, saved_errno);
+ }
+ collected += count;
+ }
+
+ errno = saved_errno;
+ return 0;
+}
diff --git a/libc/bionic/getentropy_linux.c b/libc/bionic/getentropy_linux.c
deleted file mode 100644
index cf0aa45..0000000
--- a/libc/bionic/getentropy_linux.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/* $OpenBSD: getentropy_linux.c,v 1.42 2016/04/19 20:20:24 tj Exp $ */
-
-/*
- * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
- * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Emulation of getentropy(2) as documented at:
- * http://man.openbsd.org/getentropy.2
- */
-
-#define _POSIX_C_SOURCE 199309L
-#define _GNU_SOURCE 1
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#ifdef SYS__sysctl
-#include <linux/sysctl.h>
-#endif
-#include <sys/statvfs.h>
-#include <sys/socket.h>
-#include <sys/mount.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <link.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#ifdef HAVE_OPENSSL
-#include <openssl/sha.h>
-#endif
-
-#include <linux/types.h>
-#include <linux/random.h>
-#ifdef HAVE_GETAUXVAL
-#include <sys/auxv.h>
-#endif
-#include <sys/vfs.h>
-
-#define REPEAT 5
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-
-#define HX(a, b) \
- do { \
- if ((a)) \
- HD(errno); \
- else \
- HD(b); \
- } while (0)
-
-#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
-#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
-#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
-
-int getentropy(void *buf, size_t len);
-
-static int gotdata(char *buf, size_t len);
-static int getentropy_getrandom(void *buf, size_t len);
-static int getentropy_urandom(void *buf, size_t len);
-#ifdef SYS__sysctl
-static int getentropy_sysctl(void *buf, size_t len);
-#endif
-#ifdef HAVE_OPENSSL
-static int getentropy_fallback(void *buf, size_t len);
-static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
-#endif
-
-int
-getentropy(void *buf, size_t len)
-{
- int ret = -1;
-
- if (len > 256) {
- errno = EIO;
- return (-1);
- }
-
- /*
- * Try descriptor-less getrandom()
- */
- ret = getentropy_getrandom(buf, len);
- if (ret != -1)
- return (ret);
- if (errno != ENOSYS && errno != EAGAIN)
- return (-1);
-
- /*
- * Try to get entropy with /dev/urandom
- *
- * This can fail if the process is inside a chroot or if file
- * descriptors are exhausted.
- */
- ret = getentropy_urandom(buf, len);
- if (ret != -1)
- return (ret);
-
-#ifdef SYS__sysctl
- /*
- * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
- * sysctl is a failsafe API, so it guarantees a result. This
- * should work inside a chroot, or when file descriptors are
- * exhausted.
- *
- * However this can fail if the Linux kernel removes support
- * for sysctl. Starting in 2007, there have been efforts to
- * deprecate the sysctl API/ABI, and push callers towards use
- * of the chroot-unavailable fd-using /proc mechanism --
- * essentially the same problems as /dev/urandom.
- *
- * Numerous setbacks have been encountered in their deprecation
- * schedule, so as of June 2014 the kernel ABI still exists on
- * most Linux architectures. The sysctl() stub in libc is missing
- * on some systems. There are also reports that some kernels
- * spew messages to the console.
- */
- ret = getentropy_sysctl(buf, len);
- if (ret != -1)
- return (ret);
-#endif /* SYS__sysctl */
-
- /*
- * Entropy collection via /dev/urandom and sysctl have failed.
- *
- * No other API exists for collecting entropy. See the large
- * comment block above.
- *
- * We have very few options:
- * - Even syslog_r is unsafe to call at this low level, so
- * there is no way to alert the user or program.
- * - Cannot call abort() because some systems have unsafe
- * corefiles.
- * - Could raise(SIGKILL) resulting in silent program termination.
- * - Return EIO, to hint that arc4random's stir function
- * should raise(SIGKILL)
- * - Do the best under the circumstances....
- *
- * This code path exists to bring light to the issue that Linux
- * does not provide a failsafe API for entropy collection.
- *
- * We hope this demonstrates that Linux should either retain their
- * sysctl ABI, or consider providing a new failsafe API which
- * works in a chroot or when file descriptors are exhausted.
- */
-#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
-#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
- raise(SIGKILL);
-#endif
-#ifdef HAVE_OPENSSL
- ret = getentropy_fallback(buf, len);
- if (ret != -1)
- return (ret);
-#endif
-
- errno = EIO;
- return (ret);
-}
-
-/*
- * Basic sanity checking; wish we could do better.
- */
-static int
-gotdata(char *buf, size_t len)
-{
- char any_set = 0;
- size_t i;
-
- for (i = 0; i < len; ++i)
- any_set |= buf[i];
- if (any_set == 0)
- return (-1);
- return (0);
-}
-
-static int
-getentropy_getrandom(void *buf, size_t len)
-{
- int pre_errno = errno;
- int ret;
- if (len > 256)
- return (-1);
- do {
- /*
- * Use GRND_NONBLOCK to avoid blocking before the
- * entropy pool has been initialized
- */
- ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
- } while (ret == -1 && errno == EINTR);
-
- if ((size_t)ret != len)
- return (-1);
- errno = pre_errno;
- return (0);
-}
-
-static int
-getentropy_urandom(void *buf, size_t len)
-{
- struct stat st;
- size_t i;
- int fd, cnt, flags;
- int save_errno = errno;
-
-start:
-
- flags = O_RDONLY;
-#ifdef O_NOFOLLOW
- flags |= O_NOFOLLOW;
-#endif
-#ifdef O_CLOEXEC
- flags |= O_CLOEXEC;
-#endif
- fd = open("/dev/urandom", flags, 0);
- if (fd == -1) {
- if (errno == EINTR)
- goto start;
- goto nodevrandom;
- }
-#ifndef O_CLOEXEC
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-#endif
-
- /* Lightly verify that the device node looks sane */
- if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
- close(fd);
- goto nodevrandom;
- }
- if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
- close(fd);
- goto nodevrandom;
- }
- for (i = 0; i < len; ) {
- size_t wanted = len - i;
- ssize_t ret = read(fd, (char *)buf + i, wanted);
-
- if (ret == -1) {
- if (errno == EAGAIN || errno == EINTR)
- continue;
- close(fd);
- goto nodevrandom;
- }
- i += ret;
- }
- close(fd);
- if (gotdata(buf, len) == 0) {
- errno = save_errno;
- return (0); /* satisfied */
- }
-nodevrandom:
- errno = EIO;
- return (-1);
-}
-
-#ifdef SYS__sysctl
-static int
-getentropy_sysctl(void *buf, size_t len)
-{
- static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
- size_t i;
- int save_errno = errno;
-
- for (i = 0; i < len; ) {
- size_t chunk = min(len - i, 16);
-
- /* SYS__sysctl because some systems already removed sysctl() */
- struct __sysctl_args args = {
- .name = mib,
- .nlen = 3,
- .oldval = (char *)buf + i,
- .oldlenp = &chunk,
- };
- if (syscall(SYS__sysctl, &args) != 0)
- goto sysctlfailed;
- i += chunk;
- }
- if (gotdata(buf, len) == 0) {
- errno = save_errno;
- return (0); /* satisfied */
- }
-sysctlfailed:
- errno = EIO;
- return (-1);
-}
-#endif /* SYS__sysctl */
-
-#ifdef HAVE_OPENSSL
-static const int cl[] = {
- CLOCK_REALTIME,
-#ifdef CLOCK_MONOTONIC
- CLOCK_MONOTONIC,
-#endif
-#ifdef CLOCK_MONOTONIC_RAW
- CLOCK_MONOTONIC_RAW,
-#endif
-#ifdef CLOCK_TAI
- CLOCK_TAI,
-#endif
-#ifdef CLOCK_VIRTUAL
- CLOCK_VIRTUAL,
-#endif
-#ifdef CLOCK_UPTIME
- CLOCK_UPTIME,
-#endif
-#ifdef CLOCK_PROCESS_CPUTIME_ID
- CLOCK_PROCESS_CPUTIME_ID,
-#endif
-#ifdef CLOCK_THREAD_CPUTIME_ID
- CLOCK_THREAD_CPUTIME_ID,
-#endif
-};
-
-static int
-getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
-{
- SHA512_CTX *ctx = data;
-
- SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
- return (0);
-}
-
-static int
-getentropy_fallback(void *buf, size_t len)
-{
- uint8_t results[SHA512_DIGEST_LENGTH];
- int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
- static int cnt;
- struct timespec ts;
- struct timeval tv;
- struct rusage ru;
- sigset_t sigset;
- struct stat st;
- SHA512_CTX ctx;
- static pid_t lastpid;
- pid_t pid;
- size_t i, ii, m;
- char *p;
-
- pid = getpid();
- if (lastpid == pid) {
- faster = 1;
- repeat = 2;
- } else {
- faster = 0;
- lastpid = pid;
- repeat = REPEAT;
- }
- for (i = 0; i < len; ) {
- int j;
- SHA512_Init(&ctx);
- for (j = 0; j < repeat; j++) {
- HX((e = gettimeofday(&tv, NULL)) == -1, tv);
- if (e != -1) {
- cnt += (int)tv.tv_sec;
- cnt += (int)tv.tv_usec;
- }
-
- dl_iterate_phdr(getentropy_phdr, &ctx);
-
- for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
- HX(clock_gettime(cl[ii], &ts) == -1, ts);
-
- HX((pid = getpid()) == -1, pid);
- HX((pid = getsid(pid)) == -1, pid);
- HX((pid = getppid()) == -1, pid);
- HX((pid = getpgid(0)) == -1, pid);
- HX((e = getpriority(0, 0)) == -1, e);
-
- if (!faster) {
- ts.tv_sec = 0;
- ts.tv_nsec = 1;
- (void) nanosleep(&ts, NULL);
- }
-
- HX(sigpending(&sigset) == -1, sigset);
- HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
- sigset);
-
- HF(getentropy); /* an addr in this library */
- HF(printf); /* an addr in libc */
- p = (char *)&p;
- HD(p); /* an addr on stack */
- p = (char *)&errno;
- HD(p); /* the addr of errno */
-
- if (i == 0) {
- struct sockaddr_storage ss;
- struct statvfs stvfs;
- struct termios tios;
- struct statfs stfs;
- socklen_t ssl;
- off_t off;
-
- /*
- * Prime-sized mappings encourage fragmentation;
- * thus exposing some address entropy.
- */
- struct mm {
- size_t npg;
- void *p;
- } mm[] = {
- { 17, MAP_FAILED }, { 3, MAP_FAILED },
- { 11, MAP_FAILED }, { 2, MAP_FAILED },
- { 5, MAP_FAILED }, { 3, MAP_FAILED },
- { 7, MAP_FAILED }, { 1, MAP_FAILED },
- { 57, MAP_FAILED }, { 3, MAP_FAILED },
- { 131, MAP_FAILED }, { 1, MAP_FAILED },
- };
-
- for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
- HX(mm[m].p = mmap(NULL,
- mm[m].npg * pgs,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANON, -1,
- (off_t)0), mm[m].p);
- if (mm[m].p != MAP_FAILED) {
- size_t mo;
-
- /* Touch some memory... */
- p = mm[m].p;
- mo = cnt %
- (mm[m].npg * pgs - 1);
- p[mo] = 1;
- cnt += (int)((long)(mm[m].p)
- / pgs);
- }
-
- /* Check cnts and times... */
- for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
- ii++) {
- HX((e = clock_gettime(cl[ii],
- &ts)) == -1, ts);
- if (e != -1)
- cnt += (int)ts.tv_nsec;
- }
-
- HX((e = getrusage(RUSAGE_SELF,
- &ru)) == -1, ru);
- if (e != -1) {
- cnt += (int)ru.ru_utime.tv_sec;
- cnt += (int)ru.ru_utime.tv_usec;
- }
- }
-
- for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
- if (mm[m].p != MAP_FAILED)
- munmap(mm[m].p, mm[m].npg * pgs);
- mm[m].p = MAP_FAILED;
- }
-
- HX(stat(".", &st) == -1, st);
- HX(statvfs(".", &stvfs) == -1, stvfs);
- HX(statfs(".", &stfs) == -1, stfs);
-
- HX(stat("/", &st) == -1, st);
- HX(statvfs("/", &stvfs) == -1, stvfs);
- HX(statfs("/", &stfs) == -1, stfs);
-
- HX((e = fstat(0, &st)) == -1, st);
- if (e == -1) {
- if (S_ISREG(st.st_mode) ||
- S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode)) {
- HX(fstatvfs(0, &stvfs) == -1,
- stvfs);
- HX(fstatfs(0, &stfs) == -1,
- stfs);
- HX((off = lseek(0, (off_t)0,
- SEEK_CUR)) < 0, off);
- }
- if (S_ISCHR(st.st_mode)) {
- HX(tcgetattr(0, &tios) == -1,
- tios);
- } else if (S_ISSOCK(st.st_mode)) {
- memset(&ss, 0, sizeof ss);
- ssl = sizeof(ss);
- HX(getpeername(0,
- (void *)&ss, &ssl) == -1,
- ss);
- }
- }
-
- HX((e = getrusage(RUSAGE_CHILDREN,
- &ru)) == -1, ru);
- if (e != -1) {
- cnt += (int)ru.ru_utime.tv_sec;
- cnt += (int)ru.ru_utime.tv_usec;
- }
- } else {
- /* Subsequent hashes absorb previous result */
- HD(results);
- }
-
- HX((e = gettimeofday(&tv, NULL)) == -1, tv);
- if (e != -1) {
- cnt += (int)tv.tv_sec;
- cnt += (int)tv.tv_usec;
- }
-
- HD(cnt);
- }
-#ifdef HAVE_GETAUXVAL
-#ifdef AT_RANDOM
- /* Not as random as you think but we take what we are given */
- p = (char *) getauxval(AT_RANDOM);
- if (p)
- HR(p, 16);
-#endif
-#ifdef AT_SYSINFO_EHDR
- p = (char *) getauxval(AT_SYSINFO_EHDR);
- if (p)
- HR(p, pgs);
-#endif
-#ifdef AT_BASE
- p = (char *) getauxval(AT_BASE);
- if (p)
- HD(p);
-#endif
-#endif
-
- SHA512_Final(results, &ctx);
- memcpy((char *)buf + i, results, min(sizeof(results), len - i));
- i += min(sizeof(results), len - i);
- }
- memset(results, 0, sizeof results);
- if (gotdata(buf, len) == 0) {
- errno = save_errno;
- return (0); /* satisfied */
- }
- errno = EIO;
- return (-1);
-}
-#endif /* HAVE_OPENSSL */
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 43a5032..952058f 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -44,6 +44,10 @@
// Generated android_ids array
#include "generated_android_ids.h"
+#include "grp_pwd_file.h"
+
+static PasswdFile vendor_passwd("/vendor/etc/passwd");
+static GroupFile vendor_group("/vendor/etc/group");
// POSIX seems to envisage an implementation where the <pwd.h> functions are
// implemented by brute-force searching with getpwent(3), and the <grp.h>
@@ -422,7 +426,11 @@
static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
if (!is_oem_id(uid)) {
- return NULL;
+ return nullptr;
+ }
+
+ if (vendor_passwd.FindById(uid, state)) {
+ return &state->passwd_;
}
snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid);
@@ -440,7 +448,11 @@
static group* oem_id_to_group(gid_t gid, group_state_t* state) {
if (!is_oem_id(gid)) {
- return NULL;
+ return nullptr;
+ }
+
+ if (vendor_group.FindById(gid, state)) {
+ return &state->group_;
}
snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
@@ -530,6 +542,13 @@
if (pw != NULL) {
return pw;
}
+
+ if (vendor_passwd.FindByName(login, state)) {
+ if (is_oem_id(state->passwd_.pw_uid)) {
+ return &state->passwd_;
+ }
+ }
+
// Handle OEM range.
pw = oem_id_to_passwd(oem_id_from_name(login), state);
if (pw != NULL) {
@@ -640,6 +659,13 @@
if (grp != NULL) {
return grp;
}
+
+ if (vendor_group.FindByName(name, state)) {
+ if (is_oem_id(state->group_.gr_gid)) {
+ return &state->group_;
+ }
+ }
+
// Handle OEM range.
grp = oem_id_to_group(oem_id_from_name(name), state);
if (grp != NULL) {
diff --git a/libc/bionic/grp_pwd_file.cpp b/libc/bionic/grp_pwd_file.cpp
new file mode 100644
index 0000000..37493a7
--- /dev/null
+++ b/libc/bionic/grp_pwd_file.cpp
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "grp_pwd_file.h"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "private/ErrnoRestorer.h"
+
+// This file mmap's /*/etc/passwd and /*/etc/group in order to return their contents without any
+// allocations. Note that these files and the strings contained within them are explicitly not
+// null-terminated. ':'s are used to deliminate fields and '\n's are used to deliminate lines.
+// There is a check that the file ends with '\n', such that terminating loops at '\n' ensures that
+// memory will be not ready before the mmap region.
+
+namespace {
+
+void CopyFieldToString(char* dest, const char* source, size_t max) {
+ while (*source != ':' && *source != '\n' && max > 1) {
+ *dest++ = *source++;
+ --max;
+ }
+ *dest = '\0';
+}
+
+bool FieldToUid(const char* field, uid_t* uid) {
+ if (field == nullptr) {
+ return false;
+ }
+
+ char* end = nullptr;
+ errno = 0;
+ uid_t result = strtoul(field, &end, 0);
+ if (errno != 0 || field == end || *end != ':') {
+ return false;
+ }
+ *uid = result;
+ return true;
+}
+
+// Returns a pointer to one past the end of line.
+const char* ParseLine(const char* begin, const char* end, const char** fields, size_t num_fields) {
+ size_t fields_written = 0;
+ const char* position = begin;
+ fields[fields_written++] = position;
+
+ while (position < end && fields_written < num_fields) {
+ if (*position == '\n') {
+ return position + 1;
+ }
+ if (*position == ':') {
+ fields[fields_written++] = position + 1;
+ }
+ position++;
+ }
+
+ while (position < end && *position != '\n') {
+ position++;
+ }
+
+ return position + 1;
+}
+
+struct PasswdLine {
+ const char* name() const {
+ return fields[0];
+ }
+ // Password is not supported.
+ const char* uid() const {
+ return fields[2];
+ }
+ const char* gid() const {
+ return fields[3];
+ }
+ // User Info is not supported
+ const char* dir() const {
+ return fields[5];
+ }
+ const char* shell() const {
+ return fields[6];
+ }
+
+ bool ToPasswdState(passwd_state_t* passwd_state) {
+ if (name() == nullptr || dir() == nullptr || shell() == nullptr) {
+ return false;
+ }
+
+ uid_t uid;
+ if (!FieldToUid(this->uid(), &uid)) {
+ return false;
+ }
+
+ gid_t gid;
+ if (!FieldToUid(this->gid(), &gid)) {
+ return false;
+ }
+
+ passwd_state->passwd_.pw_uid = uid;
+ passwd_state->passwd_.pw_gid = gid;
+
+ CopyFieldToString(passwd_state->name_buffer_, name(), sizeof(passwd_state->name_buffer_));
+ passwd_state->passwd_.pw_name = passwd_state->name_buffer_;
+
+ passwd_state->passwd_.pw_passwd = nullptr;
+
+#ifdef __LP64__
+ passwd_state->passwd_.pw_gecos = nullptr;
+#endif
+
+ CopyFieldToString(passwd_state->dir_buffer_, dir(), sizeof(passwd_state->dir_buffer_));
+ passwd_state->passwd_.pw_dir = passwd_state->dir_buffer_;
+
+ CopyFieldToString(passwd_state->sh_buffer_, shell(), sizeof(passwd_state->sh_buffer_));
+ passwd_state->passwd_.pw_shell = passwd_state->sh_buffer_;
+
+ return true;
+ }
+
+ static constexpr size_t kNumFields = 7;
+ const char* fields[kNumFields] = {};
+};
+
+struct GroupLine {
+ const char* name() const {
+ return fields[0];
+ }
+ // Password is not supported.
+ const char* gid() const {
+ return fields[2];
+ }
+ // User list is not supported (returns simply name)
+
+ bool ToGroupState(group_state_t* group_state) {
+ if (name() == nullptr || gid() == nullptr) {
+ return false;
+ }
+
+ gid_t gid;
+ if (!FieldToUid(this->gid(), &gid)) {
+ return false;
+ }
+
+ group_state->group_.gr_gid = gid;
+
+ CopyFieldToString(group_state->group_name_buffer_, name(),
+ sizeof(group_state->group_name_buffer_));
+ group_state->group_.gr_name = group_state->group_name_buffer_;
+
+ group_state->group_.gr_passwd = nullptr;
+
+ group_state->group_.gr_mem = group_state->group_members_;
+ group_state->group_.gr_mem[0] = group_state->group_.gr_name;
+ group_state->group_.gr_mem[1] = nullptr;
+
+ return true;
+ }
+
+ static constexpr size_t kNumFields = 4;
+ const char* fields[kNumFields] = {};
+};
+
+} // namespace
+
+MmapFile::MmapFile(const char* filename) : filename_(filename) {
+ lock_.init(false);
+}
+
+void MmapFile::Unmap() {
+ if (status_ == FileStatus::Initialized) {
+ size_t size = end_ - start_ + 1;
+ munmap(const_cast<char*>(start_), size);
+ status_ = FileStatus::Uninitialized;
+ start_ = nullptr;
+ end_ = nullptr;
+ }
+}
+
+bool MmapFile::GetFile(const char** start, const char** end) {
+ LockGuard guard(lock_);
+ if (status_ == FileStatus::Initialized) {
+ *start = start_;
+ *end = end_;
+ return true;
+ }
+ if (status_ == FileStatus::Error) {
+ return false;
+ }
+
+ if (!DoMmap()) {
+ status_ = FileStatus::Error;
+ return false;
+ }
+
+ status_ = FileStatus::Initialized;
+ *start = start_;
+ *end = end_;
+ return true;
+}
+
+bool MmapFile::DoMmap() {
+ int fd = open(filename_, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
+
+ struct stat fd_stat;
+ if (fstat(fd, &fd_stat) == -1) {
+ close(fd);
+ return false;
+ }
+
+ auto mmap_size = fd_stat.st_size;
+
+ void* map_result = mmap(nullptr, mmap_size, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+
+ if (map_result == MAP_FAILED) {
+ return false;
+ }
+
+ start_ = static_cast<const char*>(map_result);
+ end_ = start_ + mmap_size - 1;
+
+ if (*end_ != '\n') {
+ munmap(map_result, mmap_size);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename Line, typename Predicate>
+bool MmapFile::Find(Line* line, Predicate predicate) {
+ const char* start;
+ const char* end;
+ if (!GetFile(&start, &end)) {
+ return false;
+ }
+
+ const char* line_beginning = start;
+
+ while (line_beginning < end) {
+ line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields);
+ if (predicate(line)) return true;
+ }
+
+ return false;
+}
+
+template <typename Line>
+bool MmapFile::FindById(uid_t uid, Line* line) {
+ return Find(line, [uid](const auto& line) {
+ uid_t line_id;
+ if (!FieldToUid(line->fields[2], &line_id)) {
+ return false;
+ }
+
+ return line_id == uid;
+ });
+}
+
+template <typename Line>
+bool MmapFile::FindByName(const char* name, Line* line) {
+ return Find(line, [name](const auto& line) {
+ const char* line_name = line->fields[0];
+ if (line_name == nullptr) {
+ return false;
+ }
+
+ const char* match_name = name;
+ while (*line_name != '\n' && *line_name != ':' && *match_name != '\0') {
+ if (*line_name++ != *match_name++) {
+ return false;
+ }
+ }
+
+ return *line_name == ':' && *match_name == '\0';
+ });
+}
+
+PasswdFile::PasswdFile(const char* filename) : mmap_file_(filename) {
+}
+
+bool PasswdFile::FindById(uid_t id, passwd_state_t* passwd_state) {
+ ErrnoRestorer errno_restorer;
+ PasswdLine passwd_line;
+ return mmap_file_.FindById(id, &passwd_line) && passwd_line.ToPasswdState(passwd_state);
+}
+
+bool PasswdFile::FindByName(const char* name, passwd_state_t* passwd_state) {
+ ErrnoRestorer errno_restorer;
+ PasswdLine passwd_line;
+ return mmap_file_.FindByName(name, &passwd_line) && passwd_line.ToPasswdState(passwd_state);
+}
+
+GroupFile::GroupFile(const char* filename) : mmap_file_(filename) {
+}
+
+bool GroupFile::FindById(gid_t id, group_state_t* group_state) {
+ ErrnoRestorer errno_restorer;
+ GroupLine group_line;
+ return mmap_file_.FindById(id, &group_line) && group_line.ToGroupState(group_state);
+}
+
+bool GroupFile::FindByName(const char* name, group_state_t* group_state) {
+ ErrnoRestorer errno_restorer;
+ GroupLine group_line;
+ return mmap_file_.FindByName(name, &group_line) && group_line.ToGroupState(group_state);
+}
diff --git a/libc/bionic/grp_pwd_file.h b/libc/bionic/grp_pwd_file.h
new file mode 100644
index 0000000..048cd82
--- /dev/null
+++ b/libc/bionic/grp_pwd_file.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <grp.h>
+#include <pwd.h>
+
+#include "private/bionic_lock.h"
+#include "private/bionic_macros.h"
+#include "private/grp_pwd.h"
+
+class MmapFile {
+ public:
+ MmapFile(const char* filename);
+
+ template <typename Line>
+ bool FindById(uid_t uid, Line* line);
+ template <typename Line>
+ bool FindByName(const char* name, Line* line);
+ void Unmap();
+
+ DISALLOW_COPY_AND_ASSIGN(MmapFile);
+
+ private:
+ enum class FileStatus {
+ Uninitialized,
+ Initialized,
+ Error,
+ };
+
+ bool GetFile(const char** start, const char** end);
+ bool DoMmap();
+
+ template <typename Line, typename Predicate>
+ bool Find(Line* line, Predicate predicate);
+
+ FileStatus status_ = FileStatus::Uninitialized;
+ Lock lock_;
+ const char* filename_ = nullptr;
+ const char* start_ = nullptr;
+ const char* end_ = nullptr;
+};
+
+class PasswdFile {
+ public:
+ PasswdFile(const char* filename);
+
+ bool FindById(uid_t id, passwd_state_t* passwd_state);
+ bool FindByName(const char* name, passwd_state_t* passwd_state);
+ void Unmap() {
+ mmap_file_.Unmap();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(PasswdFile);
+
+ private:
+ MmapFile mmap_file_;
+};
+
+class GroupFile {
+ public:
+ GroupFile(const char* filename);
+
+ bool FindById(gid_t id, group_state_t* group_state);
+ bool FindByName(const char* name, group_state_t* group_state);
+ void Unmap() {
+ mmap_file_.Unmap();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(GroupFile);
+
+ private:
+ MmapFile mmap_file_;
+};
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index f7e8770..79a4f72 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef LIBC_BIONIC_JEMALLOC_H_
-#define LIBC_BIONIC_JEMALLOC_H_
+#pragma once
#include <jemalloc/jemalloc.h>
#include <malloc.h> // For struct mallinfo.
@@ -35,5 +34,3 @@
void* je_pvalloc(size_t);
__END_DECLS
-
-#endif // LIBC_BIONIC_DLMALLOC_H_
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 983fb32..ba59e8e 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -85,13 +85,13 @@
// to implement all four functions because the two system calls don't match any
// of the userspace functions. Unlike llseek, the pair is split lo-hi, not hi-lo.
ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) {
- return __preadv64(fd, ios, count, offset, 0);
+ return preadv64(fd, ios, count, offset);
}
ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) {
return __preadv64(fd, ios, count, offset, offset >> 32);
}
ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) {
- return __pwritev64(fd, ios, count, offset, 0);
+ return pwritev64(fd, ios, count, offset);
}
ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) {
return __pwritev64(fd, ios, count, offset, offset >> 32);
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 5066652..6ce4d10 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef LIBC_INIT_COMMON_H
-#define LIBC_INIT_COMMON_H
+
+#pragma once
#include <sys/cdefs.h>
@@ -59,5 +59,3 @@
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(KernelArgumentBlock& args);
#endif
-
-#endif
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 1f201d1..1ea4ac1 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -69,8 +69,15 @@
Malloc(malloc_disable),
Malloc(malloc_enable),
Malloc(mallopt),
+ Malloc(aligned_alloc),
};
+// Malloc hooks.
+void* (*volatile __malloc_hook)(size_t, const void*);
+void* (*volatile __realloc_hook)(void*, size_t, const void*);
+void (*volatile __free_hook)(void*, const void*);
+void* (*volatile __memalign_hook)(size_t, size_t, const void*);
+
// In a VM process, this is set to 1 after fork()ing out of zygote.
int gMallocLeakZygoteChild = 0;
@@ -142,6 +149,14 @@
return Malloc(posix_memalign)(memptr, alignment, size);
}
+extern "C" void* aligned_alloc(size_t alignment, size_t size) {
+ auto _aligned_alloc = __libc_globals->malloc_dispatch.aligned_alloc;
+ if (__predict_false(_aligned_alloc != nullptr)) {
+ return _aligned_alloc(alignment, size);
+ }
+ return Malloc(aligned_alloc)(alignment, size);
+}
+
extern "C" void* realloc(void* old_mem, size_t bytes) {
auto _realloc = __libc_globals->malloc_dispatch.realloc;
if (__predict_false(_realloc != nullptr)) {
@@ -181,17 +196,30 @@
extern "C" int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
+static const char* HOOKS_SHARED_LIB = "libc_malloc_hooks.so";
+static const char* HOOKS_PROPERTY_ENABLE = "libc.debug.hooks.enable";
+static const char* HOOKS_ENV_ENABLE = "LIBC_HOOKS_ENABLE";
+
static const char* DEBUG_SHARED_LIB = "libc_malloc_debug.so";
-static const char* DEBUG_MALLOC_PROPERTY_OPTIONS = "libc.debug.malloc.options";
-static const char* DEBUG_MALLOC_PROPERTY_PROGRAM = "libc.debug.malloc.program";
-static const char* DEBUG_MALLOC_ENV_OPTIONS = "LIBC_DEBUG_MALLOC_OPTIONS";
+static const char* DEBUG_PROPERTY_OPTIONS = "libc.debug.malloc.options";
+static const char* DEBUG_PROPERTY_PROGRAM = "libc.debug.malloc.program";
+static const char* DEBUG_ENV_OPTIONS = "LIBC_DEBUG_MALLOC_OPTIONS";
-static void* libc_malloc_impl_handle = nullptr;
+enum FunctionEnum : uint8_t {
+ FUNC_INITIALIZE,
+ FUNC_FINALIZE,
+ FUNC_GET_MALLOC_LEAK_INFO,
+ FUNC_FREE_MALLOC_LEAK_INFO,
+ FUNC_MALLOC_BACKTRACE,
+ FUNC_LAST,
+};
+static void* g_functions[FUNC_LAST];
-static void (*g_debug_finalize_func)();
-static void (*g_debug_get_malloc_leak_info_func)(uint8_t**, size_t*, size_t*, size_t*, size_t*);
-static void (*g_debug_free_malloc_leak_info_func)(uint8_t*);
-static ssize_t (*g_debug_malloc_backtrace_func)(void*, uintptr_t*, size_t);
+typedef void (*finalize_func_t)();
+typedef bool (*init_func_t)(const MallocDispatch*, int*, const char*);
+typedef void (*get_malloc_leak_info_func_t)(uint8_t**, size_t*, size_t*, size_t*, size_t*);
+typedef void (*free_malloc_leak_info_func_t)(uint8_t*);
+typedef ssize_t (*malloc_backtrace_func_t)(void*, uintptr_t*, size_t);
// =============================================================================
// Log functions
@@ -216,17 +244,20 @@
// "*backtrace_size" is set to the maximum number of entries in the back trace
extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overall_size,
size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
- if (g_debug_get_malloc_leak_info_func == nullptr) {
+ void* func = g_functions[FUNC_GET_MALLOC_LEAK_INFO];
+ if (func == nullptr) {
return;
}
- g_debug_get_malloc_leak_info_func(info, overall_size, info_size, total_memory, backtrace_size);
+ reinterpret_cast<get_malloc_leak_info_func_t>(func)(info, overall_size, info_size, total_memory,
+ backtrace_size);
}
extern "C" void free_malloc_leak_info(uint8_t* info) {
- if (g_debug_free_malloc_leak_info_func == nullptr) {
+ void* func = g_functions[FUNC_FREE_MALLOC_LEAK_INFO];
+ if (func == nullptr) {
return;
}
- g_debug_free_malloc_leak_info_func(info);
+ reinterpret_cast<free_malloc_leak_info_func_t>(func)(info);
}
// =============================================================================
@@ -243,62 +274,56 @@
return true;
}
-static bool InitMalloc(void* malloc_impl_handler, MallocDispatch* table, const char* prefix) {
- if (!InitMallocFunction<MallocCalloc>(malloc_impl_handler, &table->calloc,
- prefix, "calloc")) {
+static bool InitMallocFunctions(void* impl_handler, MallocDispatch* table, const char* prefix) {
+ if (!InitMallocFunction<MallocCalloc>(impl_handler, &table->calloc, prefix, "calloc")) {
return false;
}
- if (!InitMallocFunction<MallocFree>(malloc_impl_handler, &table->free,
- prefix, "free")) {
+ if (!InitMallocFunction<MallocFree>(impl_handler, &table->free, prefix, "free")) {
return false;
}
- if (!InitMallocFunction<MallocMallinfo>(malloc_impl_handler, &table->mallinfo,
- prefix, "mallinfo")) {
+ if (!InitMallocFunction<MallocMallinfo>(impl_handler, &table->mallinfo, prefix, "mallinfo")) {
return false;
}
- if (!InitMallocFunction<MallocMallopt>(malloc_impl_handler, &table->mallopt,
- prefix, "mallopt")) {
+ if (!InitMallocFunction<MallocMallopt>(impl_handler, &table->mallopt, prefix, "mallopt")) {
return false;
}
- if (!InitMallocFunction<MallocMalloc>(malloc_impl_handler, &table->malloc,
- prefix, "malloc")) {
+ if (!InitMallocFunction<MallocMalloc>(impl_handler, &table->malloc, prefix, "malloc")) {
return false;
}
- if (!InitMallocFunction<MallocMallocUsableSize>(
- malloc_impl_handler, &table->malloc_usable_size, prefix, "malloc_usable_size")) {
+ if (!InitMallocFunction<MallocMallocUsableSize>(impl_handler, &table->malloc_usable_size, prefix,
+ "malloc_usable_size")) {
return false;
}
- if (!InitMallocFunction<MallocMemalign>(malloc_impl_handler, &table->memalign,
- prefix, "memalign")) {
+ if (!InitMallocFunction<MallocMemalign>(impl_handler, &table->memalign, prefix, "memalign")) {
return false;
}
- if (!InitMallocFunction<MallocPosixMemalign>(malloc_impl_handler, &table->posix_memalign,
- prefix, "posix_memalign")) {
+ if (!InitMallocFunction<MallocPosixMemalign>(impl_handler, &table->posix_memalign, prefix,
+ "posix_memalign")) {
return false;
}
- if (!InitMallocFunction<MallocRealloc>(malloc_impl_handler, &table->realloc,
- prefix, "realloc")) {
+ if (!InitMallocFunction<MallocAlignedAlloc>(impl_handler, &table->aligned_alloc,
+ prefix, "aligned_alloc")) {
return false;
}
- if (!InitMallocFunction<MallocIterate>(malloc_impl_handler, &table->iterate,
- prefix, "iterate")) {
+ if (!InitMallocFunction<MallocRealloc>(impl_handler, &table->realloc, prefix, "realloc")) {
return false;
}
- if (!InitMallocFunction<MallocMallocDisable>(malloc_impl_handler, &table->malloc_disable,
- prefix, "malloc_disable")) {
+ if (!InitMallocFunction<MallocIterate>(impl_handler, &table->iterate, prefix, "iterate")) {
return false;
}
- if (!InitMallocFunction<MallocMallocEnable>(malloc_impl_handler, &table->malloc_enable,
- prefix, "malloc_enable")) {
+ if (!InitMallocFunction<MallocMallocDisable>(impl_handler, &table->malloc_disable, prefix,
+ "malloc_disable")) {
+ return false;
+ }
+ if (!InitMallocFunction<MallocMallocEnable>(impl_handler, &table->malloc_enable, prefix,
+ "malloc_enable")) {
return false;
}
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
- if (!InitMallocFunction<MallocPvalloc>(malloc_impl_handler, &table->pvalloc,
- prefix, "pvalloc")) {
+ if (!InitMallocFunction<MallocPvalloc>(impl_handler, &table->pvalloc, prefix, "pvalloc")) {
return false;
}
- if (!InitMallocFunction<MallocValloc>(malloc_impl_handler, &table->valloc,
- prefix, "valloc")) {
+ if (!InitMallocFunction<MallocValloc>(impl_handler, &table->valloc, prefix, "valloc")) {
return false;
}
#endif
@@ -315,102 +340,114 @@
fclose(stdout);
fclose(stderr);
- g_debug_finalize_func();
+ reinterpret_cast<finalize_func_t>(g_functions[FUNC_FINALIZE])();
+}
+
+static bool CheckLoadMallocHooks(char** options) {
+ char* env = getenv(HOOKS_ENV_ENABLE);
+ if ((env == nullptr || env[0] == '\0' || env[0] == '0') &&
+ (__system_property_get(HOOKS_PROPERTY_ENABLE, *options) == 0 || *options[0] == '\0' || *options[0] == '0')) {
+ return false;
+ }
+ *options = nullptr;
+ return true;
+}
+
+static bool CheckLoadMallocDebug(char** options) {
+ // If DEBUG_MALLOC_ENV_OPTIONS is set then it overrides the system properties.
+ char* env = getenv(DEBUG_ENV_OPTIONS);
+ if (env == nullptr || env[0] == '\0') {
+ if (__system_property_get(DEBUG_PROPERTY_OPTIONS, *options) == 0 || *options[0] == '\0') {
+ return false;
+ }
+
+ // Check to see if only a specific program should have debug malloc enabled.
+ char program[PROP_VALUE_MAX];
+ if (__system_property_get(DEBUG_PROPERTY_PROGRAM, program) != 0 &&
+ strstr(getprogname(), program) == nullptr) {
+ return false;
+ }
+ } else {
+ *options = env;
+ }
+ return true;
+}
+
+static void ClearGlobalFunctions() {
+ for (size_t i = 0; i < FUNC_LAST; i++) {
+ g_functions[i] = nullptr;
+ }
+}
+
+static void* LoadSharedLibrary(const char* shared_lib, const char* prefix, MallocDispatch* dispatch_table) {
+ void* impl_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
+ if (impl_handle == nullptr) {
+ error_log("%s: Unable to open shared library %s: %s", getprogname(), shared_lib, dlerror());
+ return nullptr;
+ }
+
+ static constexpr const char* names[] = {
+ "initialize",
+ "finalize",
+ "get_malloc_leak_info",
+ "free_malloc_leak_info",
+ "malloc_backtrace",
+ };
+ for (size_t i = 0; i < FUNC_LAST; i++) {
+ char symbol[128];
+ snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]);
+ g_functions[i] = dlsym(impl_handle, symbol);
+ if (g_functions[i] == nullptr) {
+ error_log("%s: %s routine not found in %s", getprogname(), symbol, shared_lib);
+ dlclose(impl_handle);
+ ClearGlobalFunctions();
+ return nullptr;
+ }
+ }
+
+ if (!InitMallocFunctions(impl_handle, dispatch_table, prefix)) {
+ dlclose(impl_handle);
+ ClearGlobalFunctions();
+ return nullptr;
+ }
+
+ return impl_handle;
}
// Initializes memory allocation framework once per process.
static void malloc_init_impl(libc_globals* globals) {
- char value[PROP_VALUE_MAX];
-
- // If DEBUG_MALLOC_ENV_OPTIONS is set then it overrides the system properties.
- const char* options = getenv(DEBUG_MALLOC_ENV_OPTIONS);
- if (options == nullptr || options[0] == '\0') {
- if (__system_property_get(DEBUG_MALLOC_PROPERTY_OPTIONS, value) == 0 || value[0] == '\0') {
- return;
- }
- options = value;
-
- // Check to see if only a specific program should have debug malloc enabled.
- char program[PROP_VALUE_MAX];
- if (__system_property_get(DEBUG_MALLOC_PROPERTY_PROGRAM, program) != 0 &&
- strstr(getprogname(), program) == nullptr) {
- return;
- }
- }
-
- // Load the debug malloc shared library.
- void* malloc_impl_handle = dlopen(DEBUG_SHARED_LIB, RTLD_NOW | RTLD_LOCAL);
- if (malloc_impl_handle == nullptr) {
- error_log("%s: Unable to open debug malloc shared library %s: %s",
- getprogname(), DEBUG_SHARED_LIB, dlerror());
+ const char* prefix;
+ const char* shared_lib;
+ char prop[PROP_VALUE_MAX];
+ char* options = prop;
+ // Prefer malloc debug since it existed first and is a more complete
+ // malloc interceptor than the hooks.
+ if (CheckLoadMallocDebug(&options)) {
+ prefix = "debug";
+ shared_lib = DEBUG_SHARED_LIB;
+ } else if (CheckLoadMallocHooks(&options)) {
+ prefix = "hooks";
+ shared_lib = HOOKS_SHARED_LIB;
+ } else {
return;
}
- // Initialize malloc debugging in the loaded module.
- auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*, const char*)>(
- dlsym(malloc_impl_handle, "debug_initialize"));
- if (init_func == nullptr) {
- error_log("%s: debug_initialize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
- dlclose(malloc_impl_handle);
+ MallocDispatch dispatch_table;
+ void* impl_handle = LoadSharedLibrary(shared_lib, prefix, &dispatch_table);
+ if (impl_handle == nullptr) {
return;
}
- // Get the syms for the external functions.
- void* finalize_sym = dlsym(malloc_impl_handle, "debug_finalize");
- if (finalize_sym == nullptr) {
- error_log("%s: debug_finalize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
- dlclose(malloc_impl_handle);
- return;
- }
-
- void* get_leak_info_sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
- if (get_leak_info_sym == nullptr) {
- error_log("%s: debug_get_malloc_leak_info routine not found in %s", getprogname(),
- DEBUG_SHARED_LIB);
- dlclose(malloc_impl_handle);
- return;
- }
-
- void* free_leak_info_sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
- if (free_leak_info_sym == nullptr) {
- error_log("%s: debug_free_malloc_leak_info routine not found in %s", getprogname(),
- DEBUG_SHARED_LIB);
- dlclose(malloc_impl_handle);
- return;
- }
-
- void* malloc_backtrace_sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
- if (malloc_backtrace_sym == nullptr) {
- error_log("%s: debug_malloc_backtrace routine not found in %s", getprogname(),
- DEBUG_SHARED_LIB);
- dlclose(malloc_impl_handle);
- return;
- }
-
+ init_func_t init_func = reinterpret_cast<init_func_t>(g_functions[FUNC_INITIALIZE]);
if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild, options)) {
- dlclose(malloc_impl_handle);
+ dlclose(impl_handle);
+ ClearGlobalFunctions();
return;
}
- MallocDispatch malloc_dispatch_table;
- if (!InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "debug")) {
- auto finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
- finalize_func();
- dlclose(malloc_impl_handle);
- return;
- }
+ globals->malloc_dispatch = dispatch_table;
- g_debug_finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
- g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(
- uint8_t**, size_t*, size_t*, size_t*, size_t*)>(get_leak_info_sym);
- g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(free_leak_info_sym);
- g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(
- void*, uintptr_t*, size_t)>(malloc_backtrace_sym);
-
- globals->malloc_dispatch = malloc_dispatch_table;
- libc_malloc_impl_handle = malloc_impl_handle;
-
- info_log("%s: malloc debug enabled", getprogname());
+ info_log("%s: malloc %s enabled", getprogname(), prefix);
// Use atexit to trigger the cleanup function. This avoids a problem
// where another atexit function is used to cleanup allocated memory,
@@ -465,10 +502,11 @@
#ifndef LIBC_STATIC
extern "C" ssize_t malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count) {
- if (g_debug_malloc_backtrace_func == nullptr) {
+ void* func = g_functions[FUNC_MALLOC_BACKTRACE];
+ if (func == nullptr) {
return 0;
}
- return g_debug_malloc_backtrace_func(pointer, frames, frame_count);
+ return reinterpret_cast<malloc_backtrace_func_t>(func)(pointer, frames, frame_count);
}
#else
extern "C" ssize_t malloc_backtrace(void*, uintptr_t*, size_t) {
diff --git a/libc/bionic/malloc_info.h b/libc/bionic/malloc_info.h
index 5fffae9..257fec1 100644
--- a/libc/bionic/malloc_info.h
+++ b/libc/bionic/malloc_info.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef LIBC_BIONIC_MALLOC_INFO_H_
-#define LIBC_BIONIC_MALLOC_INFO_H_
+#pragma once
#include <malloc.h>
#include <sys/cdefs.h>
@@ -28,5 +27,3 @@
__LIBC_HIDDEN__ struct mallinfo __mallinfo_bin_info(size_t, size_t);
__END_DECLS
-
-#endif // LIBC_BIONIC_MALLOC_INFO_H_
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index 1d72fe5..3df8b18 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -31,12 +31,13 @@
#include <sys/select.h>
#include "private/bionic_time_conversions.h"
+#include "private/sigrtmin.h"
#include "private/SigSetConverter.h"
extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t);
extern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*);
-int poll(pollfd* fds, nfds_t fd_count, int ms) __overloadable {
+int poll(pollfd* fds, nfds_t fd_count, int ms) {
timespec ts;
timespec* ts_ptr = nullptr;
if (ms >= 0) {
@@ -46,7 +47,7 @@
return __ppoll(fds, fd_count, ts_ptr, nullptr, 0);
}
-int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) __overloadable {
+int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) {
// The underlying `__ppoll` system call only takes `sigset64_t`.
SigSetConverter set;
sigset64_t* ss_ptr = nullptr;
@@ -66,7 +67,15 @@
mutable_ts = *ts;
mutable_ts_ptr = &mutable_ts;
}
- return __ppoll(fds, fd_count, mutable_ts_ptr, ss, sizeof(*ss));
+
+ sigset64_t mutable_ss;
+ sigset64_t* mutable_ss_ptr = nullptr;
+ if (ss != nullptr) {
+ mutable_ss = filter_reserved_signals(*ss);
+ mutable_ss_ptr = &mutable_ss;
+ }
+
+ return __ppoll(fds, fd_count, mutable_ts_ptr, mutable_ss_ptr, sizeof(*mutable_ss_ptr));
}
int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) {
@@ -109,6 +118,13 @@
mutable_ts_ptr = &mutable_ts;
}
+ sigset64_t mutable_ss;
+ sigset64_t* mutable_ss_ptr = nullptr;
+ if (ss != nullptr) {
+ mutable_ss = filter_reserved_signals(*ss);
+ mutable_ss_ptr = &mutable_ss;
+ }
+
// The Linux kernel only handles 6 arguments and this system call really needs 7,
// so the last argument is a void* pointing to:
struct pselect6_extra_data_t {
@@ -116,8 +132,8 @@
size_t ss_len;
};
pselect6_extra_data_t extra_data;
- extra_data.ss_addr = reinterpret_cast<uintptr_t>(ss);
- extra_data.ss_len = sizeof(*ss);
+ extra_data.ss_addr = reinterpret_cast<uintptr_t>(mutable_ss_ptr);
+ extra_data.ss_len = sizeof(*mutable_ss_ptr);
return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data);
}
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index 2edfe97..1abeb1f 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -35,6 +35,8 @@
#include <time.h>
// System calls.
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
extern "C" int __timer_create(clockid_t, sigevent*, __kernel_timer_t*);
extern "C" int __timer_delete(__kernel_timer_t);
extern "C" int __timer_getoverrun(__kernel_timer_t);
@@ -77,7 +79,7 @@
while (true) {
// Wait for a signal...
siginfo_t si = {};
- if (sigtimedwait64(&sigset, &si, nullptr) == -1) continue;
+ if (__rt_sigtimedwait(&sigset, &si, nullptr, sizeof(sigset)) == -1) continue;
if (si.si_code == SI_TIMER) {
// This signal was sent because a timer fired, so call the callback.
@@ -146,11 +148,13 @@
sigset64_t sigset = {};
sigaddset64(&sigset, TIMER_SIGNAL);
sigset64_t old_sigset;
- sigprocmask64(SIG_BLOCK, &sigset, &old_sigset);
+
+ // Use __rt_sigprocmask instead of sigprocmask64 to avoid filtering out TIMER_SIGNAL.
+ __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer);
- sigprocmask64(SIG_SETMASK, &old_sigset, nullptr);
+ __rt_sigprocmask(SIG_BLOCK, &old_sigset, nullptr, sizeof(old_sigset));
if (rc != 0) {
free(timer);
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index a4cba87..18f5aee 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _PTHREAD_INTERNAL_H_
-#define _PTHREAD_INTERNAL_H_
+
+#pragma once
#include <pthread.h>
#include <stdatomic.h>
@@ -172,5 +172,3 @@
__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent();
-
-#endif /* _PTHREAD_INTERNAL_H_ */
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index ed90639..f1f7294 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -31,6 +31,7 @@
#include <errno.h>
#include <limits.h>
#include <stdatomic.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
@@ -130,8 +131,6 @@
return 0;
}
-#if defined(__LP64__)
-
// Priority Inheritance mutex implementation
struct PIMutex {
// mutex type, can be 0 (normal), 1 (recursive), 2 (errorcheck), constant during lifetime
@@ -172,12 +171,16 @@
return EBUSY;
}
-static int PIMutexTimedLock(PIMutex& mutex, const timespec* abs_timeout) {
+// Inlining this function in pthread_mutex_lock() add the cost of stack frame instructions on
+// ARM/ARM64, which increases at most 20 percent overhead. So make it noinline.
+static int __attribute__((noinline)) PIMutexTimedLock(PIMutex& mutex,
+ const timespec* abs_timeout) {
int ret = PIMutexTryLock(mutex);
if (__predict_true(ret == 0)) {
return 0;
}
if (ret == EBUSY) {
+ ScopedTrace trace("Contending for pthread mutex");
ret = -__futex_pi_lock_ex(&mutex.owner_tid, mutex.shared, true, abs_timeout);
}
return ret;
@@ -228,7 +231,97 @@
}
return EBUSY;
}
-#endif // defined(__LP64__)
+
+#if !defined(__LP64__)
+
+namespace PIMutexAllocator {
+// pthread_mutex_t has only 4 bytes in 32-bit programs, which are not enough to hold PIMutex.
+// So we use malloc to allocate PIMutexes and use 16-bit of pthread_mutex_t as indexes to find
+// the allocated PIMutexes. This allows at most 65536 PI mutexes.
+// When calling operations like pthread_mutex_lock/unlock, the 16-bit index is mapped to the
+// corresponding PIMutex. To make the map operation fast, we use a lockless mapping method:
+// Once a PIMutex is allocated, all the data used to map index to the PIMutex isn't changed until
+// it is destroyed.
+// Below are the data structures:
+// // struct Node contains a PIMutex.
+// typedef Node NodeArray[256];
+// typedef NodeArray* NodeArrayP;
+// NodeArrayP nodes[256];
+//
+// A 16-bit index is mapped to Node as below:
+// (*nodes[index >> 8])[index & 0xff]
+//
+// Also use a free list to allow O(1) finding recycled PIMutexes.
+
+union Node {
+ PIMutex mutex;
+ int next_free_id; // If not -1, refer to the next node in the free PIMutex list.
+};
+typedef Node NodeArray[256];
+typedef NodeArray* NodeArrayP;
+
+// lock_ protects below items.
+static Lock lock;
+static NodeArrayP* nodes;
+static int next_to_alloc_id;
+static int first_free_id = -1; // If not -1, refer to the first node in the free PIMutex list.
+
+static inline __always_inline Node& IdToNode(int id) {
+ return (*nodes[id >> 8])[id & 0xff];
+}
+
+static inline __always_inline PIMutex& IdToPIMutex(int id) {
+ return IdToNode(id).mutex;
+}
+
+static int AllocIdLocked() {
+ if (first_free_id != -1) {
+ int result = first_free_id;
+ first_free_id = IdToNode(result).next_free_id;
+ return result;
+ }
+ if (next_to_alloc_id >= 0x10000) {
+ return -1;
+ }
+ int array_pos = next_to_alloc_id >> 8;
+ int node_pos = next_to_alloc_id & 0xff;
+ if (node_pos == 0) {
+ if (array_pos == 0) {
+ nodes = static_cast<NodeArray**>(calloc(256, sizeof(NodeArray*)));
+ if (nodes == nullptr) {
+ return -1;
+ }
+ }
+ nodes[array_pos] = static_cast<NodeArray*>(malloc(sizeof(NodeArray)));
+ if (nodes[array_pos] == nullptr) {
+ return -1;
+ }
+ }
+ return next_to_alloc_id++;
+}
+
+// If succeed, return an id referring to a PIMutex, otherwise return -1.
+// A valid id is in range [0, 0xffff].
+static int AllocId() {
+ lock.lock();
+ int result = AllocIdLocked();
+ lock.unlock();
+ if (result != -1) {
+ memset(&IdToPIMutex(result), 0, sizeof(PIMutex));
+ }
+ return result;
+}
+
+static void FreeId(int id) {
+ lock.lock();
+ IdToNode(id).next_free_id = first_free_id;
+ first_free_id = id;
+ lock.unlock();
+}
+
+} // namespace PIMutexAllocator
+
+#endif // !defined(__LP64__)
/* Convenience macro, creates a mask of 'bits' bits that starts from
@@ -324,7 +417,7 @@
// For a PI mutex, it includes below fields:
// Atomic(uint16_t) state;
-// PIMutex pi_mutex;
+// PIMutex pi_mutex; // uint16_t pi_mutex_id in 32-bit programs
//
// state holds the following fields:
//
@@ -332,6 +425,7 @@
// 15-14 type mutex type, should be 3
//
// pi_mutex holds the state of a PI mutex.
+// pi_mutex_id holds an integer to find the state of a PI mutex.
//
// For a Non-PI mutex, it includes below fields:
// Atomic(uint16_t) state;
@@ -351,20 +445,42 @@
// thread id.
//
// PI mutexes and Non-PI mutexes are distinguished by checking type field in state.
-struct pthread_mutex_internal_t {
- _Atomic(uint16_t) state;
#if defined(__LP64__)
- uint16_t __pad;
- union {
- atomic_int owner_tid;
- PIMutex pi_mutex;
- };
- char __reserved[28];
-#else
- _Atomic(uint16_t) owner_tid;
-#endif
+struct pthread_mutex_internal_t {
+ _Atomic(uint16_t) state;
+ uint16_t __pad;
+ union {
+ atomic_int owner_tid;
+ PIMutex pi_mutex;
+ };
+ char __reserved[28];
+
+ PIMutex& ToPIMutex() {
+ return pi_mutex;
+ }
+
+ void FreePIMutex() {
+ }
} __attribute__((aligned(4)));
+#else
+struct pthread_mutex_internal_t {
+ _Atomic(uint16_t) state;
+ union {
+ _Atomic(uint16_t) owner_tid;
+ uint16_t pi_mutex_id;
+ };
+
+ PIMutex& ToPIMutex() {
+ return PIMutexAllocator::IdToPIMutex(pi_mutex_id);
+ }
+
+ void FreePIMutex() {
+ PIMutexAllocator::FreeId(pi_mutex_id);
+ }
+} __attribute__((aligned(4)));
+#endif
+
static_assert(sizeof(pthread_mutex_t) == sizeof(pthread_mutex_internal_t),
"pthread_mutex_t should actually be pthread_mutex_internal_t in implementation.");
@@ -407,13 +523,20 @@
}
if (((*attr & MUTEXATTR_PROTOCOL_MASK) >> MUTEXATTR_PROTOCOL_SHIFT) == PTHREAD_PRIO_INHERIT) {
-#if defined(__LP64__)
- atomic_init(&mutex->state, MUTEX_TYPE_BITS_WITH_PI);
- mutex->pi_mutex.type = *attr & MUTEXATTR_TYPE_MASK;
- mutex->pi_mutex.shared = (*attr & MUTEXATTR_SHARED_MASK) != 0;
-#else
- return EINVAL;
+#if !defined(__LP64__)
+ if (state & MUTEX_SHARED_MASK) {
+ return EINVAL;
+ }
+ int id = PIMutexAllocator::AllocId();
+ if (id == -1) {
+ return ENOMEM;
+ }
+ mutex->pi_mutex_id = id;
#endif
+ atomic_init(&mutex->state, MUTEX_TYPE_BITS_WITH_PI);
+ PIMutex& pi_mutex = mutex->ToPIMutex();
+ pi_mutex.type = *attr & MUTEXATTR_TYPE_MASK;
+ pi_mutex.shared = (*attr & MUTEXATTR_SHARED_MASK) != 0;
} else {
atomic_init(&mutex->state, state);
atomic_init(&mutex->owner_tid, 0);
@@ -668,18 +791,20 @@
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
- uint16_t shared = (old_state & MUTEX_SHARED_MASK);
// Avoid slowing down fast path of normal mutex lock operation.
if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
- if (__predict_true(NonPI::NormalMutexTryLock(mutex, shared) == 0)) {
- return 0;
- }
+ uint16_t shared = (old_state & MUTEX_SHARED_MASK);
+ if (__predict_true(NonPI::NormalMutexTryLock(mutex, shared) == 0)) {
+ return 0;
+ }
+ } else if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+ PIMutex& m = mutex->ToPIMutex();
+ // Handle common case first.
+ if (__predict_true(PIMutexTryLock(m) == 0)) {
+ return 0;
+ }
+ return PIMutexTimedLock(mutex->ToPIMutex(), nullptr);
}
-#if defined(__LP64__)
- if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
- return PIMutexTimedLock(mutex->pi_mutex, nullptr);
- }
-#endif
return NonPI::MutexLockWithTimeout(mutex, false, nullptr);
}
@@ -704,11 +829,9 @@
NonPI::NormalMutexUnlock(mutex, shared);
return 0;
}
-#if defined(__LP64__)
if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
- return PIMutexUnlock(mutex->pi_mutex);
+ return PIMutexUnlock(mutex->ToPIMutex());
}
-#endif
// Do we already own this recursive or error-check mutex?
pid_t tid = __get_thread()->tid;
@@ -752,11 +875,9 @@
uint16_t shared = (old_state & MUTEX_SHARED_MASK);
return NonPI::NormalMutexTryLock(mutex, shared);
}
-#if defined(__LP64__)
if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
- return PIMutexTryLock(mutex->pi_mutex);
+ return PIMutexTryLock(mutex->ToPIMutex());
}
-#endif
// Do we already own this recursive or error-check mutex?
pid_t tid = __get_thread()->tid;
@@ -813,23 +934,28 @@
return 0;
}
}
-#if defined(__LP64__)
if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
- return PIMutexTimedLock(mutex->pi_mutex, abs_timeout);
+ return PIMutexTimedLock(mutex->ToPIMutex(), abs_timeout);
}
-#endif
return NonPI::MutexLockWithTimeout(mutex, true, abs_timeout);
}
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
-#if defined(__LP64__)
+ if (old_state == 0xffff) {
+ // The mutex has been destroyed.
+ return EBUSY;
+ }
uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
- return PIMutexDestroy(mutex->pi_mutex);
+ int result = PIMutexDestroy(mutex->ToPIMutex());
+ if (result == 0) {
+ mutex->FreePIMutex();
+ atomic_store(&mutex->state, 0xffff);
+ }
+ return result;
}
-#endif
// Store 0xffff to make the mutex unusable. Although POSIX standard says it is undefined
// behavior to destroy a locked mutex, we prefer not to change mutex->state in that situation.
if (MUTEX_STATE_BITS_IS_UNLOCKED(old_state) &&
diff --git a/libc/bionic/send.cpp b/libc/bionic/send.cpp
index 8f175d3..2e5d457 100644
--- a/libc/bionic/send.cpp
+++ b/libc/bionic/send.cpp
@@ -28,6 +28,6 @@
#include <sys/socket.h>
-ssize_t send(int socket, const void* buf, size_t len, int flags) __overloadable {
+ssize_t send(int socket, const void* buf, size_t len, int flags) {
return sendto(socket, buf, len, flags, NULL, 0);
}
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 0633748..41923cf 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -27,6 +27,9 @@
*/
#include <signal.h>
+#include <string.h>
+
+#include "private/sigrtmin.h"
extern "C" void __restore_rt(void);
extern "C" void __restore(void);
@@ -40,7 +43,7 @@
if (bionic_new_action != NULL) {
kernel_new_action.sa_flags = bionic_new_action->sa_flags;
kernel_new_action.sa_handler = bionic_new_action->sa_handler;
- kernel_new_action.sa_mask = bionic_new_action->sa_mask;
+ kernel_new_action.sa_mask = filter_reserved_signals(bionic_new_action->sa_mask);
#if defined(SA_RESTORER)
kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
#if defined(__aarch64__)
@@ -75,28 +78,57 @@
return result;
}
+__strong_alias(sigaction64, sigaction);
+
#else
-extern "C" int __sigaction(int, const struct sigaction*, struct sigaction*);
+extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t);
-int sigaction(int signal, const struct sigaction* bionic_new_action, struct sigaction* bionic_old_action) {
+int sigaction(int signal, const struct sigaction* bionic_new, struct sigaction* bionic_old) {
// The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t,
- // so we have to use sigaction(2) rather than rt_sigaction(2).
- struct sigaction kernel_new_action;
- if (bionic_new_action != NULL) {
- kernel_new_action.sa_flags = bionic_new_action->sa_flags;
- kernel_new_action.sa_handler = bionic_new_action->sa_handler;
- kernel_new_action.sa_mask = bionic_new_action->sa_mask;
+ // so we have to translate to struct sigaction64 first.
+ struct sigaction64 kernel_new;
+ if (bionic_new) {
+ kernel_new = {};
+ kernel_new.sa_flags = bionic_new->sa_flags;
+ kernel_new.sa_handler = bionic_new->sa_handler;
#if defined(SA_RESTORER)
- kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
+ kernel_new.sa_restorer = bionic_new->sa_restorer;
+#endif
+ memcpy(&kernel_new.sa_mask, &bionic_new->sa_mask, sizeof(bionic_new->sa_mask));
+ }
- if (!(kernel_new_action.sa_flags & SA_RESTORER)) {
- kernel_new_action.sa_flags |= SA_RESTORER;
- kernel_new_action.sa_restorer = (kernel_new_action.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
+ struct sigaction64 kernel_old;
+ int result = sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
+ if (bionic_old) {
+ *bionic_old = {};
+ bionic_old->sa_flags = kernel_old.sa_flags;
+ bionic_old->sa_handler = kernel_old.sa_handler;
+#if defined(SA_RESTORER)
+ bionic_old->sa_restorer = kernel_old.sa_restorer;
+#endif
+ memcpy(&bionic_old->sa_mask, &kernel_old.sa_mask, sizeof(bionic_old->sa_mask));
+ }
+ return result;
+}
+
+int sigaction64(int signal, const struct sigaction64* bionic_new, struct sigaction64* bionic_old) {
+ struct sigaction64 kernel_new;
+ if (bionic_new) {
+ kernel_new = *bionic_new;
+#if defined(SA_RESTORER)
+ if (!(kernel_new.sa_flags & SA_RESTORER)) {
+ kernel_new.sa_flags |= SA_RESTORER;
+ kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
}
#endif
+ kernel_new.sa_mask = filter_reserved_signals(kernel_new.sa_mask);
}
- return __sigaction(signal, (bionic_new_action != NULL) ? &kernel_new_action : NULL, bionic_old_action);
+
+ return __rt_sigaction(signal,
+ bionic_new ? &kernel_new : nullptr,
+ bionic_old,
+ sizeof(kernel_new.sa_mask));
}
#endif
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 099944a..175182b 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -38,9 +38,9 @@
#include "private/ErrnoRestorer.h"
#include "private/SigSetConverter.h"
+#include "private/sigrtmin.h"
extern "C" int __rt_sigpending(const sigset64_t*, size_t);
-extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
extern "C" int __rt_sigsuspend(const sigset64_t*, size_t);
extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
@@ -147,22 +147,19 @@
}
int sigignore(int sig) {
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- if (sigemptyset(&sa.sa_mask) == -1) return -1;
- sa.sa_handler = SIG_IGN;
- return sigaction(sig, &sa, nullptr);
+ struct sigaction64 sa = { .sa_handler = SIG_IGN };
+ return sigaction64(sig, &sa, nullptr);
}
int siginterrupt(int sig, int flag) {
- struct sigaction act;
- sigaction(sig, nullptr, &act);
+ struct sigaction64 act;
+ sigaction64(sig, nullptr, &act);
if (flag) {
act.sa_flags &= ~SA_RESTART;
} else {
act.sa_flags |= SA_RESTART;
}
- return sigaction(sig, &act, nullptr);
+ return sigaction64(sig, &act, nullptr);
}
template <typename SigSetT>
@@ -185,16 +182,8 @@
}
__LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) {
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = handler;
- sa.sa_flags = flags;
-
- if (sigaction(sig, &sa, &sa) == -1) {
- return SIG_ERR;
- }
-
- return sa.sa_handler;
+ struct sigaction64 sa = { .sa_handler = handler, .sa_flags = flags };
+ return (sigaction64(sig, &sa, &sa) == -1) ? SIG_ERR : sa.sa_handler;
}
sighandler_t signal(int sig, sighandler_t handler) {
@@ -219,31 +208,6 @@
return __rt_sigpending(set, sizeof(*set));
}
-int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
- SigSetConverter new_set;
- sigset64_t* new_set_ptr = nullptr;
- if (bionic_new_set != nullptr) {
- sigemptyset64(&new_set.sigset64);
- new_set.sigset = *bionic_new_set;
- new_set_ptr = &new_set.sigset64;
- }
-
- SigSetConverter old_set;
- if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
- return -1;
- }
-
- if (bionic_old_set != nullptr) {
- *bionic_old_set = old_set.sigset;
- }
-
- return 0;
-}
-
-int sigprocmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) {
- return __rt_sigprocmask(how, new_set, old_set, sizeof(*new_set));
-}
-
int sigqueue(pid_t pid, int sig, const sigval value) {
siginfo_t info;
memset(&info, 0, sizeof(siginfo_t));
@@ -262,15 +226,11 @@
}
sighandler_t sigset(int sig, sighandler_t disp) {
- struct sigaction new_sa;
- if (disp != SIG_HOLD) {
- memset(&new_sa, 0, sizeof(new_sa));
- new_sa.sa_handler = disp;
- sigemptyset(&new_sa.sa_mask);
- }
+ struct sigaction64 new_sa;
+ if (disp != SIG_HOLD) new_sa = { .sa_handler = disp };
- struct sigaction old_sa;
- if (sigaction(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
+ struct sigaction64 old_sa;
+ if (sigaction64(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
return SIG_ERR;
}
@@ -296,21 +256,33 @@
int sigsuspend(const sigset_t* bionic_set) {
SigSetConverter set = {};
set.sigset = *bionic_set;
- return __rt_sigsuspend(&set.sigset64, sizeof(set.sigset64));
+ return sigsuspend64(&set.sigset64);
}
int sigsuspend64(const sigset64_t* set) {
- return __rt_sigsuspend(set, sizeof(*set));
+ sigset64_t mutable_set;
+ sigset64_t* mutable_set_ptr = nullptr;
+ if (set) {
+ mutable_set = filter_reserved_signals(*set);
+ mutable_set_ptr = &mutable_set;
+ }
+ return __rt_sigsuspend(mutable_set_ptr, sizeof(*set));
}
int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
SigSetConverter set = {};
set.sigset = *bionic_set;
- return __rt_sigtimedwait(&set.sigset64, info, timeout, sizeof(set.sigset64));
+ return sigtimedwait64(&set.sigset64, info, timeout);
}
int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
- return __rt_sigtimedwait(set, info, timeout, sizeof(*set));
+ sigset64_t mutable_set;
+ sigset64_t* mutable_set_ptr = nullptr;
+ if (set) {
+ mutable_set = filter_reserved_signals(*set);
+ mutable_set_ptr = &mutable_set;
+ }
+ return __rt_sigtimedwait(mutable_set_ptr, info, timeout, sizeof(*set));
}
int sigwait(const sigset_t* bionic_set, int* sig) {
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
new file mode 100644
index 0000000..36866f3
--- /dev/null
+++ b/libc/bionic/sigprocmask.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <signal.h>
+
+#include "private/sigrtmin.h"
+#include "private/SigSetConverter.h"
+
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+
+//
+// These need to be kept separate from pthread_sigmask, sigblock, sigsetmask,
+// sighold, and sigset because libsigchain only intercepts sigprocmask so we
+// can't allow clang to decide to inline sigprocmask.
+//
+
+int sigprocmask(int how,
+ const sigset_t* bionic_new_set,
+ sigset_t* bionic_old_set) __attribute__((__noinline__)) {
+ SigSetConverter new_set;
+ sigset64_t* new_set_ptr = nullptr;
+ if (bionic_new_set != nullptr) {
+ sigemptyset64(&new_set.sigset64);
+ new_set.sigset = *bionic_new_set;
+ new_set_ptr = &new_set.sigset64;
+ }
+
+ SigSetConverter old_set;
+ if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
+ return -1;
+ }
+
+ if (bionic_old_set != nullptr) {
+ *bionic_old_set = old_set.sigset;
+ }
+
+ return 0;
+}
+
+int sigprocmask64(int how,
+ const sigset64_t* new_set,
+ sigset64_t* old_set) __attribute__((__noinline__)) {
+ sigset64_t mutable_new_set;
+ sigset64_t* mutable_new_set_ptr = nullptr;
+ if (new_set) {
+ mutable_new_set = filter_reserved_signals(*new_set);
+ mutable_new_set_ptr = &mutable_new_set;
+ }
+ return __rt_sigprocmask(how, mutable_new_set_ptr, old_set, sizeof(*new_set));
+}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 7422a0b..fde102c 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -98,17 +98,17 @@
// POSIX: "Signals set to be caught by the calling process shall be
// set to the default action in the child process."
bool use_sigdefault = ((flags & POSIX_SPAWN_SETSIGDEF) != 0);
- const struct sigaction default_sa = { .sa_handler = SIG_DFL };
+ const struct sigaction64 default_sa = { .sa_handler = SIG_DFL };
for (int s = 1; s < _NSIG; ++s) {
bool reset = false;
if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) {
reset = true;
} else {
- struct sigaction current;
- if (sigaction(s, nullptr, ¤t) == -1) _exit(127);
+ struct sigaction64 current;
+ if (sigaction64(s, nullptr, ¤t) == -1) _exit(127);
reset = (current.sa_handler != SIG_IGN && current.sa_handler != SIG_DFL);
}
- if (reset && sigaction(s, &default_sa, nullptr) == -1) _exit(127);
+ if (reset && sigaction64(s, &default_sa, nullptr) == -1) _exit(127);
}
if ((flags & POSIX_SPAWN_SETPGROUP) != 0 && setpgid(0, (*attr)->pgroup) == -1) _exit(127);
diff --git a/libc/bionic/system.cpp b/libc/bionic/system.cpp
new file mode 100644
index 0000000..7411ae5
--- /dev/null
+++ b/libc/bionic/system.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <spawn.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "private/ScopedSignalBlocker.h"
+#include "private/ScopedSignalHandler.h"
+
+int system(const char* command) {
+ // "The system() function shall always return non-zero when command is NULL."
+ // http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html
+ if (command == nullptr) return 1;
+
+ ScopedSignalBlocker sigchld_blocker(SIGCHLD);
+ ScopedSignalHandler sigint_ignorer(SIGINT, SIG_IGN);
+ ScopedSignalHandler sigquit_ignorer(SIGQUIT, SIG_IGN);
+
+ sigset64_t default_mask = {};
+ if (sigint_ignorer.old_action_.sa_handler != SIG_IGN) sigaddset64(&default_mask, SIGINT);
+ if (sigquit_ignorer.old_action_.sa_handler != SIG_IGN) sigaddset64(&default_mask, SIGQUIT);
+
+ static constexpr int flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+ posix_spawnattr_t attributes;
+ if ((errno = posix_spawnattr_init(&attributes))) return -1;
+ if ((errno = posix_spawnattr_setsigdefault64(&attributes, &default_mask))) return -1;
+ if ((errno = posix_spawnattr_setsigmask64(&attributes, &sigchld_blocker.old_set_))) return -1;
+ if ((errno = posix_spawnattr_setflags(&attributes, flags))) return -1;
+
+ const char* argv[] = { "sh", "-c", command, nullptr };
+ pid_t child;
+ if ((errno = posix_spawn(&child, _PATH_BSHELL, nullptr, &attributes,
+ const_cast<char**>(argv), environ)) != 0) {
+ return -1;
+ }
+
+ posix_spawnattr_destroy(&attributes);
+
+ int status;
+ pid_t pid = TEMP_FAILURE_RETRY(waitpid(child, &status, 0));
+ return (pid == -1 ? -1 : status);
+}
diff --git a/libc/bionic/system_property_api.cpp b/libc/bionic/system_property_api.cpp
index f2e1032..10d1bb3 100644
--- a/libc/bionic/system_property_api.cpp
+++ b/libc/bionic/system_property_api.cpp
@@ -35,6 +35,8 @@
#include "private/bionic_defs.h"
static SystemProperties system_properties;
+static_assert(__is_trivially_constructible(SystemProperties),
+ "System Properties must be trivially constructable");
// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
// It is set to nullptr and never modified.
diff --git a/libc/bionic/wchar_l.cpp b/libc/bionic/wchar_l.cpp
index 6c39e8d..a86961f 100644
--- a/libc/bionic/wchar_l.cpp
+++ b/libc/bionic/wchar_l.cpp
@@ -37,24 +37,42 @@
return wcsncasecmp(ws1, ws2, n);
}
-int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
+int wcscoll_l(const wchar_t* ws1, const wchar_t* ws2, locale_t) {
return wcscoll(ws1, ws2);
}
-size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, locale_t) {
- return wcsxfrm(dest, src, n);
+size_t wcsftime_l(wchar_t* buf, size_t n, const wchar_t* fmt, const struct tm* tm, locale_t) {
+ return wcsftime(buf, n, fmt, tm);
}
-long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base,
- locale_t) {
- return wcstoll(nptr, endptr, base);
+size_t wcsxfrm_l(wchar_t* dst, const wchar_t* src, size_t n, locale_t) {
+ return wcsxfrm(dst, src, n);
}
-unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr,
- int base, locale_t) {
- return wcstoull(nptr, endptr, base);
+double wcstod_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
+ return wcstod(s, end_ptr);
}
-long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t) {
- return wcstold(nptr, endptr);
+float wcstof_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
+ return wcstof(s, end_ptr);
+}
+
+long wcstol_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
+ return wcstol(s, end_ptr, base);
+}
+
+long long wcstoll_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
+ return wcstoll(s, end_ptr, base);
+}
+
+unsigned long wcstoul_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
+ return wcstoul(s, end_ptr, base);
+}
+
+unsigned long long wcstoull_l(const wchar_t* s, wchar_t** end_ptr, int base, locale_t) {
+ return wcstoull(s, end_ptr, base);
+}
+
+long double wcstold_l(const wchar_t* s, wchar_t** end_ptr, locale_t) {
+ return wcstold(s, end_ptr);
}
diff --git a/libc/dns/include/resolv_netid.h b/libc/dns/include/resolv_netid.h
index 3b2f4da..c7e2823 100644
--- a/libc/dns/include/resolv_netid.h
+++ b/libc/dns/include/resolv_netid.h
@@ -72,11 +72,15 @@
unsigned dns_netid;
unsigned dns_mark;
uid_t uid;
+ unsigned flags;
res_send_qhook qhook;
};
#define NET_CONTEXT_INVALID_UID ((uid_t)-1)
+#define NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS 0x00000001
+#define NET_CONTEXT_FLAG_USE_EDNS 0x00000002
+
struct hostent *android_gethostbyaddrfornet(const void *, socklen_t, int, unsigned, unsigned) __used_in_netd;
struct hostent *android_gethostbynamefornet(const char *, int, unsigned, unsigned) __used_in_netd;
int android_getaddrinfofornet(const char *, const char *, const struct addrinfo *, unsigned,
diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c
index c0a2fdb..47b3308 100644
--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -198,7 +198,7 @@
{ 0, 0 }
};
-#define MAXPACKET (64*1024)
+#define MAXPACKET (8*1024)
typedef union {
HEADER hdr;
diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c
index 7118a29..7589380 100644
--- a/libc/dns/net/gethnamaddr.c
+++ b/libc/dns/net/gethnamaddr.c
@@ -127,7 +127,7 @@
.uid = NET_CONTEXT_INVALID_UID
};
-#define MAXPACKET (64*1024)
+#define MAXPACKET (8*1024)
typedef union {
HEADER hdr;
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index 4896d2e..439b486 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -45,7 +45,7 @@
__END_DECLS
-#endif
+#endif /* __ANDROID_API__ < __ANDROID_API_K__ */
#if __ANDROID_API__ < __ANDROID_API_L__
@@ -83,5 +83,29 @@
__END_DECLS
-#endif
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
+
+#if __ANDROID_API__ < __ANDROID_API_O__
+
+#include <stdlib.h>
+#include <xlocale.h>
+
+__BEGIN_DECLS
+
+static __inline double strtod_l(const char* __s, char** __end_ptr, locale_t __l) {
+ return strtod(__s, __end_ptr);
+}
+
+static __inline float strtof_l(const char* __s, char** __end_ptr, locale_t __l) {
+ return strtof(__s, __end_ptr);
+}
+
+static __inline long strtol_l(const char* __s, char** __end_ptr, int __base, locale_t __l) {
+ return strtol(__s, __end_ptr, __base);
+}
+
+__END_DECLS
+
+#endif /* __ANDROID_API__ < __ANDROID_API_O__ */
+
#endif /* _ANDROID_LEGACY_STDLIB_INLINES_H_ */
diff --git a/libc/include/bits/signal_types.h b/libc/include/bits/signal_types.h
new file mode 100644
index 0000000..881ac58
--- /dev/null
+++ b/libc/include/bits/signal_types.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BITS_SIGNAL_TYPES_H_
+#define _BITS_SIGNAL_TYPES_H_
+
+#include <limits.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* For 64-bit (and mips), the kernel's struct sigaction doesn't match the
+ * POSIX one, so we need to expose our own and translate behind the scenes.
+ * For 32-bit, we're stuck with the definitions we already shipped,
+ * even though they contain a sigset_t that's too small. See sigaction64.
+ */
+#define sigaction __kernel_sigaction
+#include <linux/signal.h>
+#undef sigaction
+
+/* The arm and x86 kernel header files don't define _NSIG. */
+#ifndef _KERNEL__NSIG
+#define _KERNEL__NSIG 64
+#endif
+
+/* Userspace's NSIG is the kernel's _NSIG + 1. */
+#define _NSIG (_KERNEL__NSIG + 1)
+#define NSIG _NSIG
+
+typedef int sig_atomic_t;
+
+typedef __sighandler_t sig_t; /* BSD compatibility. */
+typedef __sighandler_t sighandler_t; /* glibc compatibility. */
+
+/* sigset_t is already large enough on LP64 and mips, but other LP32's sigset_t
+ * is just `unsigned long`.
+ */
+#if defined(__LP64__) || defined(__mips__)
+typedef sigset_t sigset64_t;
+#else
+typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t;
+#endif
+
+#if defined(__LP64__)
+
+#define __SIGACTION_BODY \
+ int sa_flags; \
+ union { \
+ sighandler_t sa_handler; \
+ void (*sa_sigaction)(int, struct siginfo*, void*); \
+ }; \
+ sigset_t sa_mask; \
+ void (*sa_restorer)(void); \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#elif defined(__mips__)
+
+#define __SIGACTION_BODY \
+ int sa_flags; \
+ union { \
+ sighandler_t sa_handler; \
+ void (*sa_sigaction)(int, struct siginfo*, void*); \
+ }; \
+ sigset_t sa_mask; \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#else
+
+#undef sa_handler
+#undef sa_sigaction
+
+struct sigaction {
+ union {
+ sighandler_t sa_handler;
+ void (*sa_sigaction)(int, struct siginfo*, void*);
+ };
+ sigset_t sa_mask;
+ int sa_flags;
+ void (*sa_restorer)(void);
+};
+
+/* This matches the kernel's internal structure. */
+struct sigaction64 {
+ union {
+ sighandler_t sa_handler;
+ void (*sa_sigaction)(int, struct siginfo*, void*);
+ };
+ int sa_flags;
+ void (*sa_restorer)(void);
+ sigset64_t sa_mask;
+};
+
+#endif
+
+#endif
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 4852f5f..1c5d64c 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -71,9 +71,9 @@
int creat(const char* __path, mode_t __mode);
int creat64(const char* __path, mode_t __mode) __INTRODUCED_IN(21);
-int openat(int __dir_fd, const char* __path, int __flags, ...) __overloadable __RENAME_CLANG(openat);
+int openat(int __dir_fd, const char* __path, int __flags, ...);
int openat64(int __dir_fd, const char* __path, int __flags, ...) __INTRODUCED_IN(21);
-int open(const char* __path, int __flags, ...) __overloadable __RENAME_CLANG(open);
+int open(const char* __path, int __flags, ...);
int open64(const char* __path, int __flags, ...) __INTRODUCED_IN(21);
ssize_t splice(int __in_fd, off64_t* __in_offset, int __out_fd, off64_t* __out_offset, size_t __length, unsigned int __flags) __INTRODUCED_IN(21);
ssize_t tee(int __in_fd, int __out_fd, size_t __length, unsigned int __flags) __INTRODUCED_IN(21);
diff --git a/libc/include/ftw.h b/libc/include/ftw.h
index 300f624..a289643 100644
--- a/libc/include/ftw.h
+++ b/libc/include/ftw.h
@@ -56,11 +56,9 @@
__BEGIN_DECLS
int ftw(const char* __dir_path, int (*__callback)(const char*, const struct stat*, int), int __max_fd_count) __INTRODUCED_IN(17);
-int nftw(const char* __dir_path, int (*__callback)(const char*, const struct stat*, int, struct FTW*), int __max_fd_count, int __flags)
- __INTRODUCED_IN(17);
-int ftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int), int __max_fd_count) __INTRODUCED_IN(21);
-int nftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int, struct FTW*), int __max_fd_count, int __flags)
- __INTRODUCED_IN(21);
+int nftw(const char* __dir_path, int (*__callback)(const char*, const struct stat*, int, struct FTW*), int __max_fd_count, int __flags) __INTRODUCED_IN(17);
+int ftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int), int __max_fd_count) __RENAME_STAT64(ftw, 17, 21);
+int nftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int, struct FTW*), int __max_fd_count, int __flags) __RENAME_STAT64(nftw, 17, 21);
__END_DECLS
#endif
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 80b08f6..3a678a9 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -81,6 +81,14 @@
#define M_DECAY_TIME -100
int mallopt(int __option, int __value) __INTRODUCED_IN(26);
+/*
+ * Memory Allocation Hooks
+ */
+extern void* (*volatile __malloc_hook)(size_t, const void*) __INTRODUCED_IN(28);
+extern void* (*volatile __realloc_hook)(void*, size_t, const void*) __INTRODUCED_IN(28);
+extern void (*volatile __free_hook)(void*, const void*) __INTRODUCED_IN(28);
+extern void* (*volatile __memalign_hook)(size_t, size_t, const void*) __INTRODUCED_IN(28);
+
__END_DECLS
#endif /* LIBC_INCLUDE_MALLOC_H_ */
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 9ca1cf8..6a8f757 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -38,8 +38,8 @@
typedef unsigned int nfds_t;
-int poll(struct pollfd* __fds, nfds_t __count, int __timeout_ms) __overloadable __RENAME_CLANG(poll);
-int ppoll(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset_t* __mask) __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
+int poll(struct pollfd* __fds, nfds_t __count, int __timeout_ms);
+int ppoll(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset_t* __mask) __INTRODUCED_IN(21);
int ppoll64(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 61bb395..00860d5 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -34,33 +34,15 @@
#include <asm/sigcontext.h>
#include <bits/pthread_types.h>
+#include <bits/signal_types.h>
#include <bits/timespec.h>
#include <limits.h>
-/* For 64-bit (and mips), the kernel's struct sigaction doesn't match the
- * POSIX one, so we need to expose our own and translate behind the scenes.
- * For 32-bit, we're stuck with the definitions we already shipped,
- * even though they contain a sigset_t that's too small. */
-#define sigaction __kernel_sigaction
-#include <linux/signal.h>
-#undef sigaction
-
#include <sys/ucontext.h>
#define __BIONIC_HAVE_UCONTEXT_T
__BEGIN_DECLS
-typedef int sig_atomic_t;
-
-/* The arm and x86 kernel header files don't define _NSIG. */
-#ifndef _KERNEL__NSIG
-#define _KERNEL__NSIG 64
-#endif
-
-/* Userspace's NSIG is the kernel's _NSIG + 1. */
-#define _NSIG (_KERNEL__NSIG + 1)
-#define NSIG _NSIG
-
/* The kernel headers define SIG_DFL (0) and SIG_IGN (1) but not SIG_HOLD, since
* SIG_HOLD is only used by the deprecated SysV signal API.
*/
@@ -75,57 +57,10 @@
extern const char* const sys_siglist[_NSIG];
extern const char* const sys_signame[_NSIG]; /* BSD compatibility. */
-typedef __sighandler_t sig_t; /* BSD compatibility. */
-typedef __sighandler_t sighandler_t; /* glibc compatibility. */
-
#define si_timerid si_tid /* glibc compatibility. */
-/* sigset_t is already large enough on LP64, but LP32's sigset_t is just `unsigned long`. */
-#if defined(__LP64__)
-typedef sigset_t sigset64_t;
-#else
-typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t;
-#endif
-
-#if defined(__LP64__)
-
-struct sigaction {
- int sa_flags;
- union {
- sighandler_t sa_handler;
- void (*sa_sigaction)(int, struct siginfo*, void*);
- };
- sigset_t sa_mask;
- void (*sa_restorer)(void);
-};
-
-#elif defined(__mips__)
-
-struct sigaction {
- int sa_flags;
- union {
- sighandler_t sa_handler;
- void (*sa_sigaction) (int, struct siginfo*, void*);
- };
- sigset_t sa_mask;
-};
-
-#else
-
-struct sigaction {
- union {
- sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo*, void*);
- } _u;
- sigset_t sa_mask;
- int sa_flags;
- void (*sa_restorer)(void);
-};
-
-#endif
-
-// TODO: sigaction contains a sigset_t that's too small on LP32.
int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action);
+int sigaction64(int __signal, const struct sigaction64* __new_action, struct sigaction64* __old_action) __INTRODUCED_IN(28);
int siginterrupt(int __signal, int __flag);
@@ -191,4 +126,4 @@
#include <android/legacy_signal_inlines.h>
-#endif /* _SIGNAL_H_ */
+#endif
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 2d9cc31..8bd690f 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -109,13 +109,13 @@
int ferror(FILE* __fp);
int fflush(FILE* __fp);
int fgetc(FILE* __fp);
-char* fgets(char* __buf, int __size, FILE* __fp) __overloadable __RENAME_CLANG(fgets);
+char* fgets(char* __buf, int __size, FILE* __fp);
int fprintf(FILE* __fp , const char* __fmt, ...) __printflike(2, 3);
int fputc(int __ch, FILE* __fp);
int fputs(const char* __s, FILE* __fp);
-size_t fread(void* __buf, size_t __size, size_t __count, FILE* __fp) __overloadable __RENAME_CLANG(fread);
+size_t fread(void* __buf, size_t __size, size_t __count, FILE* __fp);
int fscanf(FILE* __fp, const char* __fmt, ...) __scanflike(2, 3);
-size_t fwrite(const void* __buf, size_t __size, size_t __count, FILE* __fp) __overloadable __RENAME_CLANG(fwrite);
+size_t fwrite(const void* __buf, size_t __size, size_t __count, FILE* __fp);
int getc(FILE* __fp);
int getchar(void);
ssize_t getdelim(char** __line_ptr, size_t* __line_length_ptr, int __delimiter, FILE* __fp) __INTRODUCED_IN(18);
@@ -156,11 +156,9 @@
char* gets(char* __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
#endif
int sprintf(char* __s, const char* __fmt, ...)
- __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf")
- __overloadable __RENAME_CLANG(sprintf);
+ __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
int vsprintf(char* __s, const char* __fmt, va_list __args)
- __overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf)
- __warnattr_strict("vsprintf is often misused; please use vsnprintf");
+ __printflike(2, 0) __warnattr_strict("vsprintf is often misused; please use vsnprintf");
char* tmpnam(char* __s)
__warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
#define P_tmpdir "/tmp/" /* deprecated */
@@ -218,12 +216,10 @@
FILE* tmpfile(void);
FILE* tmpfile64(void) __INTRODUCED_IN(24);
-int snprintf(char* __buf, size_t __size, const char* __fmt, ...)
- __printflike(3, 4) __overloadable __RENAME_CLANG(snprintf);
+int snprintf(char* __buf, size_t __size, const char* __fmt, ...) __printflike(3, 4);
int vfscanf(FILE* __fp, const char* __fmt, va_list __args) __scanflike(2, 0);
int vscanf(const char* __fmt , va_list __args) __scanflike(1, 0);
-int vsnprintf(char* __buf, size_t __size, const char* __fmt, va_list __args)
- __printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf);
+int vsnprintf(char* __buf, size_t __size, const char* __fmt, va_list __args) __printflike(3, 0);
int vsscanf(const char* __s, const char* __fmt, va_list __args) __scanflike(2, 0);
#define L_ctermid 1024 /* size for ctermid() */
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index 2f0f438..b8aa68d 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -45,6 +45,8 @@
size_t __fpending(FILE* __fp) __INTRODUCED_IN(23);
void _flushlbf(void) __INTRODUCED_IN(23);
+void __fseterr(FILE* __fp) __INTRODUCED_IN(28);
+
#define FSETLOCKING_QUERY 0
#define FSETLOCKING_INTERNAL 1
#define FSETLOCKING_BYCALLER 2
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 944d72b..ef97538 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -79,6 +79,8 @@
int posix_memalign(void** __memptr, size_t __alignment, size_t __size) __INTRODUCED_IN(16);
+void* aligned_alloc(size_t __alignment, size_t __size) __INTRODUCED_IN(28);
+
double strtod(const char* __s, char** __end_ptr);
long double strtold(const char* __s, char** __end_ptr) __RENAME_LDBL(strtod, 3, 21);
diff --git a/libc/include/string.h b/libc/include/string.h
index 226566c..54d5e1c 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -42,24 +42,23 @@
#endif
void* memccpy(void* __dst, const void* __src, int __stop_char, size_t __n);
-void* memchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memchr);
+void* memchr(const void* __s, int __ch, size_t __n) __attribute_pure__;
#if defined(__cplusplus)
extern "C++" void* memrchr(void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
extern "C++" const void* memrchr(const void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
#else
-void* memrchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memrchr);
+void* memrchr(const void* __s, int __ch, size_t __n) __attribute_pure__;
#endif
int memcmp(const void* __lhs, const void* __rhs, size_t __n) __attribute_pure__;
-void* memcpy(void*, const void*, size_t)
- __overloadable __RENAME_CLANG(memcpy);
+void* memcpy(void*, const void*, size_t);
#if defined(__USE_GNU)
void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
#endif
-void* memmove(void* __dst, const void* __src, size_t __n) __overloadable __RENAME_CLANG(memmove);
-void* memset(void* __dst, int __ch, size_t __n) __overloadable __RENAME_CLANG(memset);
+void* memmove(void* __dst, const void* __src, size_t __n);
+void* memset(void* __dst, int __ch, size_t __n);
void* memmem(const void* __haystack, size_t __haystack_size, const void* __needle, size_t __needle_size) __attribute_pure__;
-char* strchr(const char* __s, int __ch) __attribute_pure__ __overloadable __RENAME_CLANG(strchr);
+char* strchr(const char* __s, int __ch) __attribute_pure__;
char* __strchr_chk(const char* __s, int __ch, size_t __n) __INTRODUCED_IN(18);
#if defined(__USE_GNU)
#if defined(__cplusplus)
@@ -70,16 +69,16 @@
#endif
#endif
-char* strrchr(const char* __s, int __ch) __attribute_pure__ __overloadable __RENAME_CLANG(strrchr);
+char* strrchr(const char* __s, int __ch) __attribute_pure__;
char* __strrchr_chk(const char* __s, int __ch, size_t __n) __INTRODUCED_IN(18);
-size_t strlen(const char* __s) __attribute_pure__ __overloadable __RENAME_CLANG(strlen);
+size_t strlen(const char* __s) __attribute_pure__;
size_t __strlen_chk(const char* __s, size_t __n) __INTRODUCED_IN(17);
int strcmp(const char* __lhs, const char* __rhs) __attribute_pure__;
-char* stpcpy(char* __dst, const char* __src) __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
-char* strcpy(char* __dst, const char* __src) __overloadable __RENAME_CLANG(strcpy);
-char* strcat(char* __dst, const char* __src) __overloadable __RENAME_CLANG(strcat);
+char* stpcpy(char* __dst, const char* __src) __INTRODUCED_IN(21);
+char* strcpy(char* __dst, const char* __src);
+char* strcat(char* __dst, const char* __src);
char* strdup(const char* __s);
char* strstr(const char* __haystack, const char* __needle) __attribute_pure__;
@@ -101,14 +100,14 @@
#endif
size_t strnlen(const char* __s, size_t __n) __attribute_pure__;
-char* strncat(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strncat);
+char* strncat(char* __dst, const char* __src, size_t __n);
char* strndup(const char* __s, size_t __n);
int strncmp(const char* __lhs, const char* __rhs, size_t __n) __attribute_pure__;
-char* stpncpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
-char* strncpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strncpy);
+char* stpncpy(char* __dst, const char* __src, size_t __n) __INTRODUCED_IN(21);
+char* strncpy(char* __dst, const char* __src, size_t __n);
-size_t strlcat(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strlcat);
-size_t strlcpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strlcpy);
+size_t strlcat(char* __dst, const char* __src, size_t __n);
+size_t strlcpy(char* __dst, const char* __src, size_t __n);
size_t strcspn(const char* __s, const char* __reject) __attribute_pure__;
char* strpbrk(const char* __s, const char* __accept) __attribute_pure__;
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index be07007..c270bb5 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -120,6 +120,7 @@
#define __printflike(x, y) __attribute__((__format__(printf, x, y)))
#define __scanflike(x, y) __attribute__((__format__(scanf, x, y)))
+#define __strftimelike(x) __attribute__((__format__(strftime, x, 0)))
/*
* GNU C version 2.96 added explicit branch prediction so that
@@ -245,6 +246,16 @@
#define __RENAME_LDBL(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
#endif
+/*
+ * On all architectures, `struct stat` == `struct stat64`, but LP32 didn't gain the *64 functions
+ * until API level 21.
+ */
+#if defined(__LP64__) || defined(__BIONIC_LP32_USE_STAT64)
+#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __INTRODUCED_IN(regular_api_level)
+#else
+#define __RENAME_STAT64(rewrite,rewrite_api_level,regular_api_level) __RENAME(rewrite) __INTRODUCED_IN(rewrite_api_level)
+#endif
+
/* glibc compatibility. */
#if defined(__LP64__)
#define __WORDSIZE 64
@@ -348,11 +359,8 @@
*/
#if defined(__clang__) && defined(__BIONIC_FORTIFY)
# define __overloadable __attribute__((overloadable))
-/* We don't use __RENAME directly because on gcc this could result in unnecessary renames. */
-# define __RENAME_CLANG(x) __RENAME(x)
#else
# define __overloadable
-# define __RENAME_CLANG(x)
#endif
/* Used to tag non-static symbols that are private and never exposed by the shared library. */
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 152f39d..bbde88b 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -315,12 +315,11 @@
__socketcall int socket(int __af, int __type, int __protocol);
__socketcall int socketpair(int __af, int __type, int __protocol, int __fds[2]);
-ssize_t recv(int __fd, void* __buf, size_t __n, int __flags) __overloadable __RENAME_CLANG(recv);
-ssize_t send(int __fd, const void* __buf, size_t __n, int __flags) __overloadable __RENAME_CLANG(send);
+ssize_t recv(int __fd, void* __buf, size_t __n, int __flags);
+ssize_t send(int __fd, const void* __buf, size_t __n, int __flags);
-__socketcall ssize_t sendto(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length)
- __overloadable __RENAME_CLANG(sendto);
-__socketcall ssize_t recvfrom(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length) __overloadable __RENAME_CLANG(recvfrom);
+__socketcall ssize_t sendto(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length);
+__socketcall ssize_t recvfrom(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#include <bits/fortify/socket.h>
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 14b5224..84a5015 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -156,16 +156,16 @@
int mkdir(const char* __path, mode_t __mode);
int fstat(int __fd, struct stat* __buf);
-int fstat64(int __fd, struct stat64* __buf) __INTRODUCED_IN(21);
+int fstat64(int __fd, struct stat64* __buf) __RENAME_STAT64(fstat, 3, 21);
int fstatat(int __dir_fd, const char* __path, struct stat* __buf, int __flags);
-int fstatat64(int __dir_fd, const char* __path, struct stat64* __buf, int __flags) __INTRODUCED_IN(21);
+int fstatat64(int __dir_fd, const char* __path, struct stat64* __buf, int __flags) __RENAME_STAT64(fstatat, 3, 21);
int lstat(const char* __path, struct stat* __buf);
-int lstat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21);
+int lstat64(const char* __path, struct stat64* __buf) __RENAME_STAT64(lstat, 3, 21);
int stat(const char* __path, struct stat* __buf);
-int stat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21);
+int stat64(const char* __path, struct stat64* __buf) __RENAME_STAT64(stat, 3, 21);
int mknod(const char* __path, mode_t __mode, dev_t __dev);
-mode_t umask(mode_t __mask) __overloadable __RENAME_CLANG(umask);
+mode_t umask(mode_t __mask);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#include <bits/fortify/stat.h>
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 4cc66eb..730ac69 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -87,9 +87,14 @@
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- sigset_t uc_sigmask;
- /* Android has a wrong (smaller) sigset_t on ARM. */
- uint32_t __padding_rt_sigset;
+ union {
+ struct {
+ sigset_t uc_sigmask;
+ /* Android has a wrong (smaller) sigset_t on ARM. */
+ uint32_t __padding_rt_sigset;
+ };
+ sigset64_t uc_sigmask64;
+ };
/* The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM. */
char __padding[120];
unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
@@ -109,7 +114,10 @@
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
- sigset_t uc_sigmask;
+ union {
+ sigset_t uc_sigmask;
+ sigset64_t uc_sigmask64;
+ };
/* The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64. */
char __padding[128 - sizeof(sigset_t)];
mcontext_t uc_mcontext;
@@ -194,9 +202,14 @@
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- sigset_t uc_sigmask;
- /* Android has a wrong (smaller) sigset_t on x86. */
- uint32_t __padding_rt_sigset;
+ union {
+ struct {
+ sigset_t uc_sigmask;
+ /* Android has a wrong (smaller) sigset_t on x86. */
+ uint32_t __padding_rt_sigset;
+ };
+ sigset64_t uc_sigmask64;
+ };
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
@@ -266,7 +279,10 @@
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- sigset_t uc_sigmask;
+ union {
+ sigset_t uc_sigmask;
+ sigset64_t uc_sigmask64;
+ };
} ucontext_t;
#elif defined(__x86_64__)
@@ -362,7 +378,10 @@
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- sigset_t uc_sigmask;
+ union {
+ sigset_t uc_sigmask;
+ sigset64_t uc_sigmask64;
+ };
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
diff --git a/libc/include/time.h b/libc/include/time.h
index 8e78949..17751d7 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -74,11 +74,12 @@
struct tm* gmtime(const time_t* __t);
struct tm* gmtime_r(const time_t* __t, struct tm* __tm);
-char* strptime(const char* __s, const char* __fmt, struct tm* __tm);
-size_t strftime(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm);
+char* strptime(const char* __s, const char* __fmt, struct tm* __tm) __strftimelike(2);
+char* strptime_l(const char* __s, const char* __fmt, struct tm* __tm, locale_t __l) __strftimelike(2) __INTRODUCED_IN(28);
+size_t strftime(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm) __strftimelike(3);
#if __ANDROID_API__ >= __ANDROID_API_L__
-size_t strftime_l(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm, locale_t __l) __INTRODUCED_IN(21);
+size_t strftime_l(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm, locale_t __l) __strftimelike(3) __INTRODUCED_IN(21);
#else
// Implemented as static inline before 21.
#endif
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index f191028..e0f8b43 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -140,15 +140,14 @@
int chroot(const char* __path);
int symlink(const char* __old_path, const char* __new_path);
int symlinkat(const char* __old_path, int __new_dir_fd, const char* __new_path) __INTRODUCED_IN(21);
-ssize_t readlink(const char* __path, char* __buf, size_t __buf_size)
- __overloadable __RENAME_CLANG(readlink);
+ssize_t readlink(const char* __path, char* __buf, size_t __buf_size);
ssize_t readlinkat(int __dir_fd, const char* __path, char* __buf, size_t __buf_size)
- __INTRODUCED_IN(21) __overloadable __RENAME_CLANG(readlinkat);
+ __INTRODUCED_IN(21);
int chown(const char* __path, uid_t __owner, gid_t __group);
int fchown(int __fd, uid_t __owner, gid_t __group);
int fchownat(int __dir_fd, const char* __path, uid_t __owner, gid_t __group, int __flags);
int lchown(const char* __path, uid_t __owner, gid_t __group);
-char* getcwd(char* __buf, size_t __size) __overloadable __RENAME_CLANG(getcwd);
+char* getcwd(char* __buf, size_t __size);
void sync(void);
#if defined(__USE_GNU)
@@ -157,10 +156,8 @@
int close(int __fd);
-ssize_t read(int __fd, void* __buf, size_t __count) __overloadable
- __RENAME_CLANG(read);
-ssize_t write(int __fd, const void* __buf, size_t __count) __overloadable
- __RENAME_CLANG(write);
+ssize_t read(int __fd, void* __buf, size_t __count);
+ssize_t write(int __fd, const void* __buf, size_t __count);
int dup(int __old_fd);
int dup2(int __old_fd, int __new_fd);
@@ -173,26 +170,22 @@
int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64);
ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
- __overloadable __RENAME(pread64) __INTRODUCED_IN(12);
+ __RENAME(pread64) __INTRODUCED_IN(12);
ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
- __overloadable __RENAME(pwrite64) __INTRODUCED_IN(12);
+ __RENAME(pwrite64) __INTRODUCED_IN(12);
int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64) __INTRODUCED_IN(12);
#else
int truncate(const char* __path, off_t __length);
off_t lseek(int __fd, off_t __offset, int __whence);
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
- __overloadable __RENAME_CLANG(pread);
-ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
- __overloadable __RENAME_CLANG(pwrite);
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
+ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset);
int ftruncate(int __fd, off_t __length);
#endif
int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21);
off64_t lseek64(int __fd, off64_t __offset, int __whence);
-ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset)
- __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pread64);
-ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset)
- __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pwrite64);
+ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(12);
+ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(12);
int ftruncate64(int __fd, off64_t __length) __INTRODUCED_IN(12);
int pause(void);
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 1cf498c83..f33af5f 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -81,6 +81,7 @@
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);
@@ -94,12 +95,16 @@
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);
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index 7f3abd9..1b56ecb 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -176,17 +176,32 @@
#define SCSI_ACCESS_STATE_MASK 0x0f
#define SCSI_ACCESS_STATE_PREFERRED 0x80
enum zbc_zone_reporting_options {
- ZBC_ZONE_REPORTING_OPTION_ALL = 0,
- ZBC_ZONE_REPORTING_OPTION_EMPTY,
- ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN,
- ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN,
- ZBC_ZONE_REPORTING_OPTION_CLOSED,
- ZBC_ZONE_REPORTING_OPTION_FULL,
- ZBC_ZONE_REPORTING_OPTION_READONLY,
- ZBC_ZONE_REPORTING_OPTION_OFFLINE,
+ ZBC_ZONE_REPORTING_OPTION_ALL = 0x00,
+ ZBC_ZONE_REPORTING_OPTION_EMPTY = 0x01,
+ ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN = 0x02,
+ ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN = 0x03,
+ ZBC_ZONE_REPORTING_OPTION_CLOSED = 0x04,
+ ZBC_ZONE_REPORTING_OPTION_FULL = 0x05,
+ ZBC_ZONE_REPORTING_OPTION_READONLY = 0x06,
+ ZBC_ZONE_REPORTING_OPTION_OFFLINE = 0x07,
ZBC_ZONE_REPORTING_OPTION_NEED_RESET_WP = 0x10,
- ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE,
+ ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE = 0x11,
ZBC_ZONE_REPORTING_OPTION_NON_WP = 0x3f,
};
#define ZBC_REPORT_ZONE_PARTIAL 0x80
+enum zbc_zone_type {
+ ZBC_ZONE_TYPE_CONV = 0x1,
+ ZBC_ZONE_TYPE_SEQWRITE_REQ = 0x2,
+ ZBC_ZONE_TYPE_SEQWRITE_PREF = 0x3,
+};
+enum zbc_zone_cond {
+ ZBC_ZONE_COND_NO_WP = 0x0,
+ ZBC_ZONE_COND_EMPTY = 0x1,
+ ZBC_ZONE_COND_IMP_OPEN = 0x2,
+ ZBC_ZONE_COND_EXP_OPEN = 0x3,
+ ZBC_ZONE_COND_CLOSED = 0x4,
+ ZBC_ZONE_COND_READONLY = 0xd,
+ ZBC_ZONE_COND_FULL = 0xe,
+ ZBC_ZONE_COND_OFFLINE = 0xf,
+};
#endif
diff --git a/libc/kernel/android/uapi/linux/compiler_types.h b/libc/kernel/android/uapi/linux/compiler_types.h
new file mode 100644
index 0000000..94f4fbe
--- /dev/null
+++ b/libc/kernel/android/uapi/linux/compiler_types.h
@@ -0,0 +1,5 @@
+/*
+ * The compiler.h file has been split into compiler.h and compiler_types.h.
+ * However, to compile bionic we only need the compiler.h.
+ */
+#include <linux/compiler.h>
diff --git a/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index 2332ae2..448a773 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -106,6 +106,9 @@
#define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32)
#define __ARM_CP15_REG64(op1,crm) (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
+#define KVM_REG_ARM_PTIMER_CTL ARM_CP15_REG32(0, 14, 2, 1)
+#define KVM_REG_ARM_PTIMER_CNT ARM_CP15_REG64(0, 14)
+#define KVM_REG_ARM_PTIMER_CVAL ARM_CP15_REG64(2, 14)
#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
@@ -157,6 +160,7 @@
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
+#define KVM_DEV_ARM_ITS_CTRL_RESET 4
#define KVM_ARM_IRQ_TYPE_SHIFT 24
#define KVM_ARM_IRQ_TYPE_MASK 0xff
#define KVM_ARM_IRQ_VCPU_SHIFT 16
diff --git a/libc/kernel/uapi/asm-arm/asm/ptrace.h b/libc/kernel/uapi/asm-arm/asm/ptrace.h
index dcc3826..b0291dc 100644
--- a/libc/kernel/uapi/asm-arm/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm/asm/ptrace.h
@@ -34,6 +34,9 @@
#define PTRACE_SETVFPREGS 28
#define PTRACE_GETHBPREGS 29
#define PTRACE_SETHBPREGS 30
+#define PTRACE_GETFDPIC 31
+#define PTRACE_GETFDPIC_EXEC 0
+#define PTRACE_GETFDPIC_INTERP 1
#define USR26_MODE 0x00000000
#define FIQ26_MODE 0x00000001
#define IRQ26_MODE 0x00000002
@@ -42,6 +45,7 @@
#define SVC_MODE 0x00000013
#define FIQ_MODE 0x00000011
#define IRQ_MODE 0x00000012
+#define MON_MODE 0x00000016
#define ABT_MODE 0x00000017
#define HYP_MODE 0x0000001a
#define UND_MODE 0x0000001b
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd.h b/libc/kernel/uapi/asm-arm/asm/unistd.h
index d14fd73..f4b1f3a 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd.h
@@ -29,4 +29,5 @@
#define __ARM_NR_usr26 (__ARM_NR_BASE + 3)
#define __ARM_NR_usr32 (__ARM_NR_BASE + 4)
#define __ARM_NR_set_tls (__ARM_NR_BASE + 5)
+#define __ARM_NR_get_tls (__ARM_NR_BASE + 6)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h
new file mode 100644
index 0000000..cad04bf
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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__ASM_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_BPF_PERF_EVENT_H__
+#include <asm/ptrace.h>
+typedef struct user_pt_regs bpf_user_pt_regs_t;
+#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 60b8305..4e95b95 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -35,4 +35,10 @@
#define HWCAP_FCMA (1 << 14)
#define HWCAP_LRCPC (1 << 15)
#define HWCAP_DCPOP (1 << 16)
+#define HWCAP_SHA3 (1 << 17)
+#define HWCAP_SM3 (1 << 18)
+#define HWCAP_SM4 (1 << 19)
+#define HWCAP_ASIMDDP (1 << 20)
+#define HWCAP_SHA512 (1 << 21)
+#define HWCAP_SVE (1 << 22)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index a68a8a2..c4178a1 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -117,6 +117,9 @@
#define ARM64_SYS_REG_SHIFT_MASK(x,n) (((x) << KVM_REG_ARM64_SYSREG_ ##n ##_SHIFT) & KVM_REG_ARM64_SYSREG_ ##n ##_MASK)
#define __ARM64_SYS_REG(op0,op1,crn,crm,op2) (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
+#define KVM_REG_ARM_PTIMER_CTL ARM64_SYS_REG(3, 3, 14, 2, 1)
+#define KVM_REG_ARM_PTIMER_CVAL ARM64_SYS_REG(3, 3, 14, 2, 2)
+#define KVM_REG_ARM_PTIMER_CNT ARM64_SYS_REG(3, 3, 14, 0, 1)
#define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
#define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
@@ -144,6 +147,7 @@
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
+#define KVM_DEV_ARM_ITS_CTRL_RESET 4
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
#define KVM_ARM_VCPU_PMU_V3_INIT 1
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index 0eccf79..4e6c755 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -20,6 +20,7 @@
#define _UAPI__ASM_PTRACE_H
#include <linux/types.h>
#include <asm/hwcap.h>
+#include <asm/sigcontext.h>
#define PSR_MODE_EL0t 0x00000000
#define PSR_MODE_EL1t 0x00000004
#define PSR_MODE_EL1h 0x00000005
@@ -35,7 +36,6 @@
#define PSR_D_BIT 0x00000200
#define PSR_PAN_BIT 0x00400000
#define PSR_UAO_BIT 0x00800000
-#define PSR_Q_BIT 0x08000000
#define PSR_V_BIT 0x10000000
#define PSR_C_BIT 0x20000000
#define PSR_Z_BIT 0x40000000
@@ -45,6 +45,7 @@
#define PSR_x 0x0000ff00
#define PSR_c 0x000000ff
#ifndef __ASSEMBLY__
+#include <linux/prctl.h>
struct user_pt_regs {
__u64 regs[31];
__u64 sp;
@@ -66,5 +67,39 @@
__u32 pad;
} dbg_regs[16];
};
+struct user_sve_header {
+ __u32 size;
+ __u32 max_size;
+ __u16 vl;
+ __u16 max_vl;
+ __u16 flags;
+ __u16 __reserved;
+};
+#define SVE_PT_REGS_MASK (1 << 0)
+#define SVE_PT_REGS_FPSIMD 0
+#define SVE_PT_REGS_SVE SVE_PT_REGS_MASK
+#define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16)
+#define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16)
+#define SVE_PT_REGS_OFFSET ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_FPSIMD_OFFSET SVE_PT_REGS_OFFSET
+#define SVE_PT_FPSIMD_SIZE(vq,flags) (sizeof(struct user_fpsimd_state))
+#define SVE_PT_SVE_ZREG_SIZE(vq) SVE_SIG_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq) SVE_SIG_FFR_SIZE(vq)
+#define SVE_PT_SVE_FPSR_SIZE sizeof(__u32)
+#define SVE_PT_SVE_FPCR_SIZE sizeof(__u32)
+#define __SVE_SIG_TO_PT(offset) ((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET)
+#define SVE_PT_SVE_OFFSET SVE_PT_REGS_OFFSET
+#define SVE_PT_SVE_ZREGS_OFFSET __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET)
+#define SVE_PT_SVE_ZREG_OFFSET(vq,n) __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n))
+#define SVE_PT_SVE_ZREGS_SIZE(vq) (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
+#define SVE_PT_SVE_PREGS_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_PREG_OFFSET(vq,n) __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n))
+#define SVE_PT_SVE_PREGS_SIZE(vq) (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_PT_SVE_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_FFR_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq))
+#define SVE_PT_SVE_FPSR_OFFSET(vq) ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_SVE_FPCR_OFFSET(vq) (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
+#define SVE_PT_SVE_SIZE(vq,flags) ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE - SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_SIZE(vq,flags) (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
#endif
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index be2464e..b0617de 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI__ASM_SIGCONTEXT_H
#define _UAPI__ASM_SIGCONTEXT_H
+#ifndef __ASSEMBLY__
#include <linux/types.h>
struct sigcontext {
__u64 fault_address;
@@ -50,4 +51,34 @@
__u32 size;
__u32 __reserved[3];
};
+#define SVE_MAGIC 0x53564501
+struct sve_context {
+ struct _aarch64_ctx head;
+ __u16 vl;
+ __u16 __reserved[3];
+};
+#endif
+#define SVE_VQ_BYTES 16
+#define SVE_VQ_MIN 1
+#define SVE_VQ_MAX 512
+#define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES)
+#define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES)
+#define SVE_NUM_ZREGS 32
+#define SVE_NUM_PREGS 16
+#define sve_vl_valid(vl) ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
+#define sve_vq_from_vl(vl) ((vl) / SVE_VQ_BYTES)
+#define sve_vl_from_vq(vq) ((vq) * SVE_VQ_BYTES)
+#define SVE_SIG_ZREG_SIZE(vq) ((__u32) (vq) * SVE_VQ_BYTES)
+#define SVE_SIG_PREG_SIZE(vq) ((__u32) (vq) * (SVE_VQ_BYTES / 8))
+#define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
+#define SVE_SIG_REGS_OFFSET ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET
+#define SVE_SIG_ZREG_OFFSET(vq,n) (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))
+#define SVE_SIG_ZREGS_SIZE(vq) (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)
+#define SVE_SIG_PREGS_OFFSET(vq) (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))
+#define SVE_SIG_PREG_OFFSET(vq,n) (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))
+#define SVE_SIG_PREGS_SIZE(vq) (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))
+#define SVE_SIG_FFR_OFFSET(vq) (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))
+#define SVE_SIG_REGS_SIZE(vq) (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
+#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
#endif
diff --git a/libc/kernel/uapi/asm-generic/bpf_perf_event.h b/libc/kernel/uapi/asm-generic/bpf_perf_event.h
new file mode 100644
index 0000000..794927b
--- /dev/null
+++ b/libc/kernel/uapi/asm-generic/bpf_perf_event.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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__ASM_GENERIC_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
+#include <linux/ptrace.h>
+typedef struct pt_regs bpf_user_pt_regs_t;
+#endif
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index a15624a..e752bb6 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -27,6 +27,7 @@
#define PROT_GROWSUP 0x02000000
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
+#define MAP_SHARED_VALIDATE 0x03
#define MAP_TYPE 0x0f
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
diff --git a/libc/kernel/uapi/asm-generic/mman.h b/libc/kernel/uapi/asm-generic/mman.h
index 0452237..84caab7 100644
--- a/libc/kernel/uapi/asm-generic/mman.h
+++ b/libc/kernel/uapi/asm-generic/mman.h
@@ -28,6 +28,7 @@
#define MAP_NONBLOCK 0x10000
#define MAP_STACK 0x20000
#define MAP_HUGETLB 0x40000
+#define MAP_SYNC 0x80000
#define MCL_CURRENT 1
#define MCL_FUTURE 2
#define MCL_ONFAULT 4
diff --git a/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-mips/asm/mman.h b/libc/kernel/uapi/asm-mips/asm/mman.h
index b976885..5e8e28a 100644
--- a/libc/kernel/uapi/asm-mips/asm/mman.h
+++ b/libc/kernel/uapi/asm-mips/asm/mman.h
@@ -27,6 +27,7 @@
#define PROT_GROWSUP 0x02000000
#define MAP_SHARED 0x001
#define MAP_PRIVATE 0x002
+#define MAP_SHARED_VALIDATE 0x003
#define MAP_TYPE 0x00f
#define MAP_FIXED 0x010
#define MAP_RENAME 0x020
diff --git a/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index f0f8dd2..85f9d7e 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -81,7 +81,10 @@
#define X86_CR3_PWT _BITUL(X86_CR3_PWT_BIT)
#define X86_CR3_PCD_BIT 4
#define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT)
-#define X86_CR3_PCID_MASK _AC(0x00000fff, UL)
+#define X86_CR3_PCID_BITS 12
+#define X86_CR3_PCID_MASK (_AC((1UL << X86_CR3_PCID_BITS) - 1, UL))
+#define X86_CR3_PCID_NOFLUSH_BIT 63
+#define X86_CR3_PCID_NOFLUSH _BITULL(X86_CR3_PCID_NOFLUSH_BIT)
#define X86_CR4_VME_BIT 0
#define X86_CR4_VME _BITUL(X86_CR4_VME_BIT)
#define X86_CR4_PVI_BIT 1
@@ -104,6 +107,8 @@
#define X86_CR4_OSFXSR _BITUL(X86_CR4_OSFXSR_BIT)
#define X86_CR4_OSXMMEXCPT_BIT 10
#define X86_CR4_OSXMMEXCPT _BITUL(X86_CR4_OSXMMEXCPT_BIT)
+#define X86_CR4_UMIP_BIT 11
+#define X86_CR4_UMIP _BITUL(X86_CR4_UMIP_BIT)
#define X86_CR4_LA57_BIT 12
#define X86_CR4_LA57 _BITUL(X86_CR4_LA57_BIT)
#define X86_CR4_VMXE_BIT 13
@@ -138,4 +143,5 @@
#define CX86_DIR1 0xff
#define CX86_ARR_BASE 0xc4
#define CX86_RCR_BASE 0xdc
+#define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | X86_CR0_PG)
#endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 6ae9c9c..1cdae16 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -35,6 +35,8 @@
#define DRM_AMDGPU_GEM_USERPTR 0x11
#define DRM_AMDGPU_WAIT_FENCES 0x12
#define DRM_AMDGPU_VM 0x13
+#define DRM_AMDGPU_FENCE_TO_HANDLE 0x14
+#define DRM_AMDGPU_SCHED 0x15
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
#define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
@@ -49,6 +51,8 @@
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
#define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
+#define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
+#define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
#define AMDGPU_GEM_DOMAIN_VRAM 0x4
@@ -61,6 +65,8 @@
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
#define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5)
+#define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
+#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
struct drm_amdgpu_gem_create_in {
__u64 bo_size;
__u64 alignment;
@@ -104,11 +110,17 @@
#define AMDGPU_CTX_GUILTY_RESET 1
#define AMDGPU_CTX_INNOCENT_RESET 2
#define AMDGPU_CTX_UNKNOWN_RESET 3
+#define AMDGPU_CTX_PRIORITY_UNSET - 2048
+#define AMDGPU_CTX_PRIORITY_VERY_LOW - 1023
+#define AMDGPU_CTX_PRIORITY_LOW - 512
+#define AMDGPU_CTX_PRIORITY_NORMAL 0
+#define AMDGPU_CTX_PRIORITY_HIGH 512
+#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
struct drm_amdgpu_ctx_in {
__u32 op;
__u32 flags;
__u32 ctx_id;
- __u32 _pad;
+ __s32 priority;
};
union drm_amdgpu_ctx_out {
struct {
@@ -138,6 +150,16 @@
struct drm_amdgpu_vm_in in;
struct drm_amdgpu_vm_out out;
};
+#define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1
+struct drm_amdgpu_sched_in {
+ __u32 op;
+ __u32 fd;
+ __s32 priority;
+ __u32 flags;
+};
+union drm_amdgpu_sched {
+ struct drm_amdgpu_sched_in in;
+};
#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
@@ -331,6 +353,19 @@
struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
};
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2
+union drm_amdgpu_fence_to_handle {
+ struct {
+ struct drm_amdgpu_fence fence;
+ __u32 what;
+ __u32 pad;
+ } in;
+ struct {
+ __u32 handle;
+ } out;
+};
struct drm_amdgpu_cs_chunk_data {
union {
struct drm_amdgpu_cs_chunk_ib ib_data;
@@ -381,6 +416,7 @@
#define AMDGPU_INFO_SENSOR_VDDNB 0x6
#define AMDGPU_INFO_SENSOR_VDDGFX 0x7
#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
+#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 6863dc1..ec0c1fa 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -412,6 +412,20 @@
__u32 count_handles;
__u32 pad;
};
+struct drm_crtc_get_sequence {
+ __u32 crtc_id;
+ __u32 active;
+ __u64 sequence;
+ __s64 sequence_ns;
+};
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002
+struct drm_crtc_queue_sequence {
+ __u32 crtc_id;
+ __u32 flags;
+ __u64 sequence;
+ __u64 user_data;
+};
#ifdef __cplusplus
#endif
#include "drm_mode.h"
@@ -478,6 +492,8 @@
#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
#define DRM_IOCTL_SG_FREE DRM_IOW(0x39, struct drm_scatter_gather)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
@@ -517,6 +533,10 @@
#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
struct drm_event {
@@ -525,6 +545,7 @@
};
#define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {
struct drm_event base;
__u64 user_data;
@@ -533,6 +554,12 @@
__u32 sequence;
__u32 crtc_id;
};
+struct drm_event_crtc_sequence {
+ struct drm_event base;
+ __u64 user_data;
+ __s64 time_ns;
+ __u64 sequence;
+};
typedef struct drm_clip_rect drm_clip_rect_t;
typedef struct drm_drawable_info drm_drawable_info_t;
typedef struct drm_tex_region drm_tex_region_t;
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 5e97a72..2c9defb 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -427,6 +427,26 @@
struct drm_mode_destroy_blob {
__u32 blob_id;
};
+struct drm_mode_create_lease {
+ __u64 object_ids;
+ __u32 object_count;
+ __u32 flags;
+ __u32 lessee_id;
+ __u32 fd;
+};
+struct drm_mode_list_lessees {
+ __u32 count_lessees;
+ __u32 pad;
+ __u64 lessees_ptr;
+};
+struct drm_mode_get_lease {
+ __u32 count_objects;
+ __u32 pad;
+ __u64 objects_ptr;
+};
+struct drm_mode_revoke_lease {
+ __u32 lessee_id;
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/etnaviv_drm.h b/libc/kernel/uapi/drm/etnaviv_drm.h
index 6376e25..58bd536 100644
--- a/libc/kernel/uapi/drm/etnaviv_drm.h
+++ b/libc/kernel/uapi/drm/etnaviv_drm.h
@@ -91,6 +91,17 @@
__u32 handle;
__u64 presumed;
};
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+struct drm_etnaviv_gem_submit_pmr {
+ __u32 flags;
+ __u8 domain;
+ __u8 pad;
+ __u16 signal;
+ __u32 sequence;
+ __u32 read_offset;
+ __u32 read_idx;
+};
#define ETNA_SUBMIT_NO_IMPLICIT 0x0001
#define ETNA_SUBMIT_FENCE_FD_IN 0x0002
#define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
@@ -110,6 +121,9 @@
__u64 stream;
__u32 flags;
__s32 fence_fd;
+ __u64 pmrs;
+ __u32 nr_pmrs;
+ __u32 pad;
};
#define ETNA_WAIT_NONBLOCK 0x01
struct drm_etnaviv_wait_fence {
@@ -134,6 +148,21 @@
__u32 pad;
struct drm_etnaviv_timespec timeout;
};
+struct drm_etnaviv_pm_domain {
+ __u32 pipe;
+ __u8 iter;
+ __u8 id;
+ __u16 nr_signals;
+ char name[64];
+};
+struct drm_etnaviv_pm_signal {
+ __u32 pipe;
+ __u8 domain;
+ __u8 pad;
+ __u16 iter;
+ __u16 id;
+ char name[64];
+};
#define DRM_ETNAVIV_GET_PARAM 0x00
#define DRM_ETNAVIV_GEM_NEW 0x02
#define DRM_ETNAVIV_GEM_INFO 0x03
@@ -143,7 +172,9 @@
#define DRM_ETNAVIV_WAIT_FENCE 0x07
#define DRM_ETNAVIV_GEM_USERPTR 0x08
#define DRM_ETNAVIV_GEM_WAIT 0x09
-#define DRM_ETNAVIV_NUM_IOCTLS 0x0a
+#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a
+#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b
+#define DRM_ETNAVIV_NUM_IOCTLS 0x0c
#define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
#define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
#define DRM_IOCTL_ETNAVIV_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_INFO, struct drm_etnaviv_gem_info)
@@ -153,6 +184,8 @@
#define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
#define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr)
#define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal)
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 50ea43a..34342bf 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -293,6 +293,9 @@
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
#define I915_PARAM_HAS_SCHEDULER 41
+#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
+#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1)
+#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
#define I915_PARAM_HUC_STATUS 42
#define I915_PARAM_HAS_EXEC_ASYNC 43
#define I915_PARAM_HAS_EXEC_FENCE 44
@@ -633,6 +636,7 @@
};
struct drm_i915_reg_read {
__u64 offset;
+#define I915_REG_READ_8B_WA (1ul << 0)
__u64 val;
};
struct drm_i915_reset_stats {
@@ -660,6 +664,10 @@
#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
#define I915_CONTEXT_PARAM_BANNABLE 0x5
+#define I915_CONTEXT_PARAM_PRIORITY 0x6
+#define I915_CONTEXT_MAX_USER_PRIORITY 1023
+#define I915_CONTEXT_DEFAULT_PRIORITY 0
+#define I915_CONTEXT_MIN_USER_PRIORITY - 1023
__u64 value;
};
enum drm_i915_oa_format {
@@ -709,9 +717,9 @@
__u32 n_mux_regs;
__u32 n_boolean_regs;
__u32 n_flex_regs;
- __u64 __user mux_regs_ptr;
- __u64 __user boolean_regs_ptr;
- __u64 __user flex_regs_ptr;
+ __u64 mux_regs_ptr;
+ __u64 boolean_regs_ptr;
+ __u64 flex_regs_ptr;
};
#ifdef __cplusplus
#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 4f1a423..d2f1b57 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -38,6 +38,7 @@
#define MSM_PARAM_MAX_FREQ 0x04
#define MSM_PARAM_TIMESTAMP 0x05
#define MSM_PARAM_GMEM_BASE 0x06
+#define MSM_PARAM_NR_RINGS 0x07
struct drm_msm_param {
__u32 pipe;
__u32 param;
@@ -113,11 +114,13 @@
__u64 bos;
__u64 cmds;
__s32 fence_fd;
+ __u32 queueid;
};
struct drm_msm_wait_fence {
__u32 fence;
__u32 pad;
struct drm_msm_timespec timeout;
+ __u32 queueid;
};
#define MSM_MADV_WILLNEED 0
#define MSM_MADV_DONTNEED 1
@@ -127,6 +130,12 @@
__u32 madv;
__u32 retained;
};
+#define MSM_SUBMITQUEUE_FLAGS (0)
+struct drm_msm_submitqueue {
+ __u32 flags;
+ __u32 prio;
+ __u32 id;
+};
#define DRM_MSM_GET_PARAM 0x00
#define DRM_MSM_GEM_NEW 0x02
#define DRM_MSM_GEM_INFO 0x03
@@ -135,6 +144,8 @@
#define DRM_MSM_GEM_SUBMIT 0x06
#define DRM_MSM_WAIT_FENCE 0x07
#define DRM_MSM_GEM_MADVISE 0x08
+#define DRM_MSM_SUBMITQUEUE_NEW 0x0A
+#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B
#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
#define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info)
@@ -143,6 +154,8 @@
#define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit)
#define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence)
#define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/vc4_drm.h b/libc/kernel/uapi/drm/vc4_drm.h
index d96c49d..3ca378f 100644
--- a/libc/kernel/uapi/drm/vc4_drm.h
+++ b/libc/kernel/uapi/drm/vc4_drm.h
@@ -32,6 +32,7 @@
#define DRM_VC4_SET_TILING 0x08
#define DRM_VC4_GET_TILING 0x09
#define DRM_VC4_LABEL_BO 0x0a
+#define DRM_VC4_GEM_MADVISE 0x0b
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo)
@@ -43,6 +44,7 @@
#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
+#define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise)
struct drm_vc4_submit_rcl_surface {
__u32 hindex;
__u32 offset;
@@ -142,6 +144,7 @@
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
+#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
struct drm_vc4_get_param {
__u32 param;
__u32 pad;
@@ -162,6 +165,16 @@
__u32 len;
__u64 name;
};
+#define VC4_MADV_WILLNEED 0
+#define VC4_MADV_DONTNEED 1
+#define __VC4_MADV_PURGED 2
+#define __VC4_MADV_NOTSUPP 3
+struct drm_vc4_gem_madvise {
+ __u32 handle;
+ __u32 madv;
+ __u32 retained;
+ __u32 pad;
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 3edd1d4..be48b44 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -78,6 +78,7 @@
#define AUDIT_FEATURE_CHANGE 1328
#define AUDIT_REPLACE 1329
#define AUDIT_KERN_MODULE 1330
+#define AUDIT_FANOTIFY 1331
#define AUDIT_AVC 1400
#define AUDIT_SELINUX_ERR 1401
#define AUDIT_AVC_PATH 1402
@@ -116,7 +117,8 @@
#define AUDIT_FILTER_WATCH 0x03
#define AUDIT_FILTER_EXIT 0x04
#define AUDIT_FILTER_TYPE 0x05
-#define AUDIT_NR_FILTERS 6
+#define AUDIT_FILTER_FS 0x06
+#define AUDIT_NR_FILTERS 7
#define AUDIT_FILTER_PREPEND 0x10
#define AUDIT_NEVER 0
#define AUDIT_POSSIBLE 1
@@ -190,6 +192,7 @@
#define AUDIT_OBJ_LEV_HIGH 23
#define AUDIT_LOGINUID_SET 24
#define AUDIT_SESSIONID 25
+#define AUDIT_FSTYPE 26
#define AUDIT_DEVMAJOR 100
#define AUDIT_DEVMINOR 101
#define AUDIT_INODE 102
@@ -242,7 +245,8 @@
#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008
#define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
-#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | AUDIT_FEATURE_BITMAP_LOST_RESET)
+#define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040
+#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | AUDIT_FEATURE_BITMAP_LOST_RESET | AUDIT_FEATURE_BITMAP_FILTER_FS)
#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
#define AUDIT_VERSION_BACKLOG_LIMIT AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT
#define AUDIT_VERSION_BACKLOG_WAIT_TIME AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME
diff --git a/libc/kernel/uapi/linux/bcache.h b/libc/kernel/uapi/linux/bcache.h
index 0933d51..4c7e32a 100644
--- a/libc/kernel/uapi/linux/bcache.h
+++ b/libc/kernel/uapi/linux/bcache.h
@@ -46,7 +46,7 @@
#define START_KEY(k) KEY(KEY_INODE(k), KEY_START(k), 0)
#define PTR_DEV_BITS 12
#define PTR_CHECK_DEV ((1 << PTR_DEV_BITS) - 1)
-#define PTR(gen,offset,dev) ((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
+#define MAKE_PTR(gen,offset,dev) ((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
#define bkey_copy(_dest,_src) memcpy(_dest, _src, bkey_bytes(_src))
#define BKEY_PAD 8
#define BKEY_PADDED(key) union { struct bkey key; __u64 key ##_pad[BKEY_PAD]; }
diff --git a/libc/kernel/uapi/linux/bfs_fs.h b/libc/kernel/uapi/linux/bfs_fs.h
index e828ce3..4a11e8a 100644
--- a/libc/kernel/uapi/linux/bfs_fs.h
+++ b/libc/kernel/uapi/linux/bfs_fs.h
@@ -66,5 +66,5 @@
#define BFS_NZFILESIZE(ip) ((le32_to_cpu((ip)->i_eoffset) + 1) - le32_to_cpu((ip)->i_sblock) * BFS_BSIZE)
#define BFS_FILESIZE(ip) ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
#define BFS_FILEBLOCKS(ip) ((ip)->i_sblock == 0 ? 0 : (le32_to_cpu((ip)->i_eblock) + 1) - le32_to_cpu((ip)->i_sblock))
-#define BFS_UNCLEAN(bfs_sb,sb) ((le32_to_cpu(bfs_sb->s_from) != - 1) && (le32_to_cpu(bfs_sb->s_to) != - 1) && ! (sb->s_flags & MS_RDONLY))
+#define BFS_UNCLEAN(bfs_sb,sb) ((le32_to_cpu(bfs_sb->s_from) != - 1) && (le32_to_cpu(bfs_sb->s_to) != - 1) && ! (sb->s_flags & SB_RDONLY))
#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 1dfb99f..9ac0729 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -82,6 +82,7 @@
BPF_PROG_GET_FD_BY_ID,
BPF_MAP_GET_FD_BY_ID,
BPF_OBJ_GET_INFO_BY_FD,
+ BPF_PROG_QUERY,
};
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
@@ -100,6 +101,7 @@
BPF_MAP_TYPE_HASH_OF_MAPS,
BPF_MAP_TYPE_DEVMAP,
BPF_MAP_TYPE_SOCKMAP,
+ BPF_MAP_TYPE_CPUMAP,
};
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC,
@@ -117,6 +119,7 @@
BPF_PROG_TYPE_LWT_XMIT,
BPF_PROG_TYPE_SOCK_OPS,
BPF_PROG_TYPE_SK_SKB,
+ BPF_PROG_TYPE_CGROUP_DEVICE,
};
enum bpf_attach_type {
BPF_CGROUP_INET_INGRESS,
@@ -125,10 +128,12 @@
BPF_CGROUP_SOCK_OPS,
BPF_SK_SKB_STREAM_PARSER,
BPF_SK_SKB_STREAM_VERDICT,
+ BPF_CGROUP_DEVICE,
__MAX_BPF_ATTACH_TYPE
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
#define BPF_F_ALLOW_OVERRIDE (1U << 0)
+#define BPF_F_ALLOW_MULTI (1U << 1)
#define BPF_F_STRICT_ALIGNMENT (1U << 0)
#define BPF_PSEUDO_MAP_FD 1
#define BPF_ANY 0
@@ -137,6 +142,10 @@
#define BPF_F_NO_PREALLOC (1U << 0)
#define BPF_F_NO_COMMON_LRU (1U << 1)
#define BPF_F_NUMA_NODE (1U << 2)
+#define BPF_F_QUERY_EFFECTIVE (1U << 0)
+#define BPF_OBJ_NAME_LEN 16U
+#define BPF_F_RDONLY (1U << 3)
+#define BPF_F_WRONLY (1U << 4)
union bpf_attr {
struct {
__u32 map_type;
@@ -146,6 +155,7 @@
__u32 map_flags;
__u32 inner_map_fd;
__u32 numa_node;
+ char map_name[BPF_OBJ_NAME_LEN];
};
struct {
__u32 map_fd;
@@ -166,10 +176,13 @@
__aligned_u64 log_buf;
__u32 kern_version;
__u32 prog_flags;
+ char prog_name[BPF_OBJ_NAME_LEN];
+ __u32 prog_ifindex;
};
struct {
__aligned_u64 pathname;
__u32 bpf_fd;
+ __u32 file_flags;
};
struct {
__u32 target_fd;
@@ -194,14 +207,23 @@
__u32 map_id;
};
__u32 next_id;
+ __u32 open_flags;
};
struct {
__u32 bpf_fd;
__u32 info_len;
__aligned_u64 info;
} info;
+ struct {
+ __u32 target_fd;
+ __u32 attach_type;
+ __u32 query_flags;
+ __u32 attach_flags;
+ __aligned_u64 prog_ids;
+ __u32 prog_cnt;
+ } query;
} __attribute__((aligned(8)));
-#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update),
+#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -253,6 +275,7 @@
__u32 local_ip6[4];
__u32 remote_port;
__u32 local_port;
+ __u32 data_meta;
};
struct bpf_tunnel_key {
__u32 tunnel_id;
@@ -289,6 +312,7 @@
struct xdp_md {
__u32 data;
__u32 data_end;
+ __u32 data_meta;
};
enum sk_action {
SK_DROP = 0,
@@ -303,6 +327,11 @@
__u32 xlated_prog_len;
__aligned_u64 jited_prog_insns;
__aligned_u64 xlated_prog_insns;
+ __u64 load_time;
+ __u32 created_by_uid;
+ __u32 nr_map_ids;
+ __aligned_u64 map_ids;
+ char name[BPF_OBJ_NAME_LEN];
} __attribute__((aligned(8)));
struct bpf_map_info {
__u32 type;
@@ -311,6 +340,7 @@
__u32 value_size;
__u32 max_entries;
__u32 map_flags;
+ char name[BPF_OBJ_NAME_LEN];
} __attribute__((aligned(8)));
struct bpf_sock_ops {
__u32 op;
@@ -334,7 +364,23 @@
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
BPF_SOCK_OPS_NEEDS_ECN,
+ BPF_SOCK_OPS_BASE_RTT,
};
#define TCP_BPF_IW 1001
#define TCP_BPF_SNDCWND_CLAMP 1002
+struct bpf_perf_event_value {
+ __u64 counter;
+ __u64 enabled;
+ __u64 running;
+};
+#define BPF_DEVCG_ACC_MKNOD (1ULL << 0)
+#define BPF_DEVCG_ACC_READ (1ULL << 1)
+#define BPF_DEVCG_ACC_WRITE (1ULL << 2)
+#define BPF_DEVCG_DEV_BLOCK (1ULL << 0)
+#define BPF_DEVCG_DEV_CHAR (1ULL << 1)
+struct bpf_cgroup_dev_ctx {
+ __u32 access_type;
+ __u32 major;
+ __u32 minor;
+};
#endif
diff --git a/libc/kernel/uapi/linux/bpf_perf_event.h b/libc/kernel/uapi/linux/bpf_perf_event.h
index ef7bd18..7a8d212 100644
--- a/libc/kernel/uapi/linux/bpf_perf_event.h
+++ b/libc/kernel/uapi/linux/bpf_perf_event.h
@@ -18,10 +18,9 @@
****************************************************************************/
#ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__
#define _UAPI__LINUX_BPF_PERF_EVENT_H__
-#include <linux/types.h>
-#include <linux/ptrace.h>
+#include <asm/bpf_perf_event.h>
struct bpf_perf_event_data {
- struct pt_regs regs;
+ bpf_user_pt_regs_t regs;
__u64 sample_period;
};
#endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index a23ab58..aa7c105 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -339,9 +339,11 @@
struct btrfs_ioctl_logical_ino_args {
__u64 logical;
__u64 size;
- __u64 reserved[4];
+ __u64 reserved[3];
+ __u64 flags;
__u64 inodes;
};
+#define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET (1ULL << 0)
enum btrfs_dev_stat_values {
BTRFS_DEV_STAT_WRITE_ERRS,
BTRFS_DEV_STAT_READ_ERRS,
@@ -469,4 +471,5 @@
#define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[2])
#define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[3])
#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_LOGICAL_INO_V2 _IOWR(BTRFS_IOCTL_MAGIC, 59, struct btrfs_ioctl_logical_ino_args)
#endif
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index c75732e..c2fbd40 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -320,6 +320,7 @@
#define BTRFS_FILE_EXTENT_INLINE 0
#define BTRFS_FILE_EXTENT_REG 1
#define BTRFS_FILE_EXTENT_PREALLOC 2
+#define BTRFS_FILE_EXTENT_TYPES 2
struct btrfs_file_extent_item {
__le64 generation;
__le64 ram_bytes;
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 3fcee96..98892f7 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -130,6 +130,8 @@
#define CEC_EVENT_LOST_MSGS 2
#define CEC_EVENT_PIN_CEC_LOW 3
#define CEC_EVENT_PIN_CEC_HIGH 4
+#define CEC_EVENT_PIN_HPD_LOW 5
+#define CEC_EVENT_PIN_HPD_HIGH 6
#define CEC_EVENT_FL_INITIAL_STATE (1 << 0)
#define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1)
struct cec_event_state_change {
diff --git a/libc/kernel/uapi/linux/cramfs_fs.h b/libc/kernel/uapi/linux/cramfs_fs.h
index 5d119ba..8872914 100644
--- a/libc/kernel/uapi/linux/cramfs_fs.h
+++ b/libc/kernel/uapi/linux/cramfs_fs.h
@@ -54,5 +54,10 @@
#define CRAMFS_FLAG_HOLES 0x00000100
#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200
#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400
-#define CRAMFS_SUPPORTED_FLAGS (0x000000ff | CRAMFS_FLAG_HOLES | CRAMFS_FLAG_WRONG_SIGNATURE | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET)
+#define CRAMFS_FLAG_EXT_BLOCK_POINTERS 0x00000800
+#define CRAMFS_SUPPORTED_FLAGS (0x000000ff | CRAMFS_FLAG_HOLES | CRAMFS_FLAG_WRONG_SIGNATURE | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET | CRAMFS_FLAG_EXT_BLOCK_POINTERS)
+#define CRAMFS_BLK_FLAG_UNCOMPRESSED (1 << 31)
+#define CRAMFS_BLK_FLAG_DIRECT_PTR (1 << 30)
+#define CRAMFS_BLK_FLAGS (CRAMFS_BLK_FLAG_UNCOMPRESSED | CRAMFS_BLK_FLAG_DIRECT_PTR)
+#define CRAMFS_BLK_DIRECT_PTR_SHIFT 2
#endif
diff --git a/libc/kernel/uapi/linux/dcbnl.h b/libc/kernel/uapi/linux/dcbnl.h
index 569efdd..2fe4cce 100644
--- a/libc/kernel/uapi/linux/dcbnl.h
+++ b/libc/kernel/uapi/linux/dcbnl.h
@@ -91,6 +91,7 @@
#define IEEE_8021QAZ_APP_SEL_STREAM 2
#define IEEE_8021QAZ_APP_SEL_DGRAM 3
#define IEEE_8021QAZ_APP_SEL_ANY 4
+#define IEEE_8021QAZ_APP_SEL_DSCP 5
struct dcb_app {
__u8 selector;
__u8 priority;
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 8aa1011..bf35f6c 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -347,11 +347,13 @@
#define NT_S390_VXRS_HIGH 0x30a
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
+#define NT_S390_RI_CB 0x30d
#define NT_ARM_VFP 0x400
#define NT_ARM_TLS 0x401
#define NT_ARM_HW_BREAK 0x402
#define NT_ARM_HW_WATCH 0x403
#define NT_ARM_SYSTEM_CALL 0x404
+#define NT_ARM_SVE 0x405
#define NT_METAG_CBUF 0x500
#define NT_METAG_RPIPE 0x501
#define NT_METAG_TLS 0x502
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index b10106e..73d92ca 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -38,6 +38,7 @@
#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
#define FAN_UNLIMITED_QUEUE 0x00000010
#define FAN_UNLIMITED_MARKS 0x00000020
+#define FAN_ENABLE_AUDIT 0x00000040
#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
#define FAN_MARK_ADD 0x00000001
#define FAN_MARK_REMOVE 0x00000002
@@ -67,6 +68,7 @@
};
#define FAN_ALLOW 0x01
#define FAN_DENY 0x02
+#define FAN_AUDIT 0x10
#define FAN_NOFD - 1
#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
#define FAN_EVENT_NEXT(meta,len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata *) (((char *) (meta)) + (meta)->event_len))
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index f40321e..04b6dae 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -19,6 +19,7 @@
#ifndef _UAPI_LINUX_IF_ETHER_H
#define _UAPI_LINUX_IF_ETHER_H
#include <linux/types.h>
+#include <linux/libc-compat.h>
#define ETH_ALEN 6
#define ETH_HLEN 14
#define ETH_ZLEN 60
@@ -116,9 +117,11 @@
#define ETH_P_CAIF 0x00F7
#define ETH_P_XDSA 0x00F8
#define ETH_P_MAP 0x00F9
+#if __UAPI_DEF_ETHHDR
struct ethhdr {
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
__be16 h_proto;
} __attribute__((packed));
#endif
+#endif
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index c041c82..a43eaf7 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -136,6 +136,8 @@
IFLA_PAD,
IFLA_XDP,
IFLA_EVENT,
+ IFLA_NEW_NETNSID,
+ IFLA_IF_NETNSID,
__IFLA_MAX
};
#define IFLA_MAX (__IFLA_MAX - 1)
@@ -255,6 +257,8 @@
IFLA_BRPORT_MCAST_TO_UCAST,
IFLA_BRPORT_VLAN_TUNNEL,
IFLA_BRPORT_BCAST_FLOOD,
+ IFLA_BRPORT_GROUP_FWD_MASK,
+ IFLA_BRPORT_NEIGH_SUPPRESS,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -364,6 +368,7 @@
enum {
IFLA_IPVLAN_UNSPEC,
IFLA_IPVLAN_MODE,
+ IFLA_IPVLAN_FLAGS,
__IFLA_IPVLAN_MAX
};
#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
@@ -373,6 +378,8 @@
IPVLAN_MODE_L3S,
IPVLAN_MODE_MAX
};
+#define IPVLAN_F_PRIVATE 0x01
+#define IPVLAN_F_VEPA 0x02
enum {
IFLA_VXLAN_UNSPEC,
IFLA_VXLAN_ID,
diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h
index 4912d7b..d8757a1 100644
--- a/libc/kernel/uapi/linux/if_tun.h
+++ b/libc/kernel/uapi/linux/if_tun.h
@@ -51,6 +51,8 @@
#define TUNGETVNETBE _IOR('T', 223, int)
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
#define IFF_VNET_HDR 0x4000
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index bfc6479..8edc956 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -93,6 +93,7 @@
TUNNEL_ENCAP_NONE,
TUNNEL_ENCAP_FOU,
TUNNEL_ENCAP_GUE,
+ TUNNEL_ENCAP_MPLS,
};
#define TUNNEL_ENCAP_FLAG_CSUM (1 << 0)
#define TUNNEL_ENCAP_FLAG_CSUM6 (1 << 1)
diff --git a/libc/kernel/uapi/linux/ila.h b/libc/kernel/uapi/linux/ila.h
index 38386be..a5af23a 100644
--- a/libc/kernel/uapi/linux/ila.h
+++ b/libc/kernel/uapi/linux/ila.h
@@ -29,6 +29,8 @@
ILA_ATTR_DIR,
ILA_ATTR_PAD,
ILA_ATTR_CSUM_MODE,
+ ILA_ATTR_IDENT_TYPE,
+ ILA_ATTR_HOOK_TYPE,
__ILA_ATTR_MAX,
};
#define ILA_ATTR_MAX (__ILA_ATTR_MAX - 1)
@@ -46,5 +48,21 @@
ILA_CSUM_ADJUST_TRANSPORT,
ILA_CSUM_NEUTRAL_MAP,
ILA_CSUM_NO_ACTION,
+ ILA_CSUM_NEUTRAL_MAP_AUTO,
+};
+enum {
+ ILA_ATYPE_IID = 0,
+ ILA_ATYPE_LUID,
+ ILA_ATYPE_VIRT_V4,
+ ILA_ATYPE_VIRT_UNI_V6,
+ ILA_ATYPE_VIRT_MULTI_V6,
+ ILA_ATYPE_NONLOCAL_ADDR,
+ ILA_ATYPE_RSVD_1,
+ ILA_ATYPE_RSVD_2,
+ ILA_ATYPE_USE_FORMAT = 32,
+};
+enum {
+ ILA_HOOK_ROUTE_OUTPUT,
+ ILA_HOOK_ROUTE_INPUT,
};
#endif
diff --git a/libc/kernel/uapi/linux/in6.h b/libc/kernel/uapi/linux/in6.h
index 1e3b49d..9da111c 100644
--- a/libc/kernel/uapi/linux/in6.h
+++ b/libc/kernel/uapi/linux/in6.h
@@ -175,4 +175,5 @@
#define IPV6_TRANSPARENT 75
#define IPV6_UNICAST_IF 76
#define IPV6_RECVFRAGSIZE 77
+#define IPV6_FREEBIND 78
#endif
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 346ec91..da90f1c 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -359,6 +359,7 @@
#define BTN_TOOL_MOUSE 0x146
#define BTN_TOOL_LENS 0x147
#define BTN_TOOL_QUINTTAP 0x148
+#define BTN_STYLUS3 0x149
#define BTN_TOUCH 0x14a
#define BTN_STYLUS 0x14b
#define BTN_STYLUS2 0x14c
diff --git a/libc/kernel/uapi/linux/ip6_tunnel.h b/libc/kernel/uapi/linux/ip6_tunnel.h
index b7df956..ba59235 100644
--- a/libc/kernel/uapi/linux/ip6_tunnel.h
+++ b/libc/kernel/uapi/linux/ip6_tunnel.h
@@ -29,6 +29,7 @@
#define IP6_TNL_F_MIP6_DEV 0x8
#define IP6_TNL_F_RCV_DSCP_COPY 0x10
#define IP6_TNL_F_USE_ORIG_FWMARK 0x20
+#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
struct ip6_tnl_parm {
char name[IFNAMSIZ];
int link;
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index d07fa06..ff345a6 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -140,6 +140,7 @@
DEVCONF_ADDR_GEN_MODE,
DEVCONF_DISABLE_POLICY,
DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
+ DEVCONF_NDISC_TCLASS,
DEVCONF_MAX
};
#endif
diff --git a/libc/kernel/uapi/linux/iso_fs.h b/libc/kernel/uapi/linux/iso_fs.h
index d88d646..8227031 100644
--- a/libc/kernel/uapi/linux/iso_fs.h
+++ b/libc/kernel/uapi/linux/iso_fs.h
@@ -22,34 +22,34 @@
#include <linux/magic.h>
#define ISODCL(from,to) (to - from + 1)
struct iso_volume_descriptor {
- char type[ISODCL(1, 1)];
+ __u8 type[ISODCL(1, 1)];
char id[ISODCL(2, 6)];
- char version[ISODCL(7, 7)];
- char data[ISODCL(8, 2048)];
+ __u8 version[ISODCL(7, 7)];
+ __u8 data[ISODCL(8, 2048)];
};
#define ISO_VD_PRIMARY 1
#define ISO_VD_SUPPLEMENTARY 2
#define ISO_VD_END 255
#define ISO_STANDARD_ID "CD001"
struct iso_primary_descriptor {
- char type[ISODCL(1, 1)];
+ __u8 type[ISODCL(1, 1)];
char id[ISODCL(2, 6)];
- char version[ISODCL(7, 7)];
- char unused1[ISODCL(8, 8)];
+ __u8 version[ISODCL(7, 7)];
+ __u8 unused1[ISODCL(8, 8)];
char system_id[ISODCL(9, 40)];
char volume_id[ISODCL(41, 72)];
- char unused2[ISODCL(73, 80)];
- char volume_space_size[ISODCL(81, 88)];
- char unused3[ISODCL(89, 120)];
- char volume_set_size[ISODCL(121, 124)];
- char volume_sequence_number[ISODCL(125, 128)];
- char logical_block_size[ISODCL(129, 132)];
- char path_table_size[ISODCL(133, 140)];
- char type_l_path_table[ISODCL(141, 144)];
- char opt_type_l_path_table[ISODCL(145, 148)];
- char type_m_path_table[ISODCL(149, 152)];
- char opt_type_m_path_table[ISODCL(153, 156)];
- char root_directory_record[ISODCL(157, 190)];
+ __u8 unused2[ISODCL(73, 80)];
+ __u8 volume_space_size[ISODCL(81, 88)];
+ __u8 unused3[ISODCL(89, 120)];
+ __u8 volume_set_size[ISODCL(121, 124)];
+ __u8 volume_sequence_number[ISODCL(125, 128)];
+ __u8 logical_block_size[ISODCL(129, 132)];
+ __u8 path_table_size[ISODCL(133, 140)];
+ __u8 type_l_path_table[ISODCL(141, 144)];
+ __u8 opt_type_l_path_table[ISODCL(145, 148)];
+ __u8 type_m_path_table[ISODCL(149, 152)];
+ __u8 opt_type_m_path_table[ISODCL(153, 156)];
+ __u8 root_directory_record[ISODCL(157, 190)];
char volume_set_id[ISODCL(191, 318)];
char publisher_id[ISODCL(319, 446)];
char preparer_id[ISODCL(447, 574)];
@@ -57,34 +57,34 @@
char copyright_file_id[ISODCL(703, 739)];
char abstract_file_id[ISODCL(740, 776)];
char bibliographic_file_id[ISODCL(777, 813)];
- char creation_date[ISODCL(814, 830)];
- char modification_date[ISODCL(831, 847)];
- char expiration_date[ISODCL(848, 864)];
- char effective_date[ISODCL(865, 881)];
- char file_structure_version[ISODCL(882, 882)];
- char unused4[ISODCL(883, 883)];
- char application_data[ISODCL(884, 1395)];
- char unused5[ISODCL(1396, 2048)];
+ __u8 creation_date[ISODCL(814, 830)];
+ __u8 modification_date[ISODCL(831, 847)];
+ __u8 expiration_date[ISODCL(848, 864)];
+ __u8 effective_date[ISODCL(865, 881)];
+ __u8 file_structure_version[ISODCL(882, 882)];
+ __u8 unused4[ISODCL(883, 883)];
+ __u8 application_data[ISODCL(884, 1395)];
+ __u8 unused5[ISODCL(1396, 2048)];
};
struct iso_supplementary_descriptor {
- char type[ISODCL(1, 1)];
+ __u8 type[ISODCL(1, 1)];
char id[ISODCL(2, 6)];
- char version[ISODCL(7, 7)];
- char flags[ISODCL(8, 8)];
+ __u8 version[ISODCL(7, 7)];
+ __u8 flags[ISODCL(8, 8)];
char system_id[ISODCL(9, 40)];
char volume_id[ISODCL(41, 72)];
- char unused2[ISODCL(73, 80)];
- char volume_space_size[ISODCL(81, 88)];
- char escape[ISODCL(89, 120)];
- char volume_set_size[ISODCL(121, 124)];
- char volume_sequence_number[ISODCL(125, 128)];
- char logical_block_size[ISODCL(129, 132)];
- char path_table_size[ISODCL(133, 140)];
- char type_l_path_table[ISODCL(141, 144)];
- char opt_type_l_path_table[ISODCL(145, 148)];
- char type_m_path_table[ISODCL(149, 152)];
- char opt_type_m_path_table[ISODCL(153, 156)];
- char root_directory_record[ISODCL(157, 190)];
+ __u8 unused2[ISODCL(73, 80)];
+ __u8 volume_space_size[ISODCL(81, 88)];
+ __u8 escape[ISODCL(89, 120)];
+ __u8 volume_set_size[ISODCL(121, 124)];
+ __u8 volume_sequence_number[ISODCL(125, 128)];
+ __u8 logical_block_size[ISODCL(129, 132)];
+ __u8 path_table_size[ISODCL(133, 140)];
+ __u8 type_l_path_table[ISODCL(141, 144)];
+ __u8 opt_type_l_path_table[ISODCL(145, 148)];
+ __u8 type_m_path_table[ISODCL(149, 152)];
+ __u8 opt_type_m_path_table[ISODCL(153, 156)];
+ __u8 root_directory_record[ISODCL(157, 190)];
char volume_set_id[ISODCL(191, 318)];
char publisher_id[ISODCL(319, 446)];
char preparer_id[ISODCL(447, 574)];
@@ -92,59 +92,59 @@
char copyright_file_id[ISODCL(703, 739)];
char abstract_file_id[ISODCL(740, 776)];
char bibliographic_file_id[ISODCL(777, 813)];
- char creation_date[ISODCL(814, 830)];
- char modification_date[ISODCL(831, 847)];
- char expiration_date[ISODCL(848, 864)];
- char effective_date[ISODCL(865, 881)];
- char file_structure_version[ISODCL(882, 882)];
- char unused4[ISODCL(883, 883)];
- char application_data[ISODCL(884, 1395)];
- char unused5[ISODCL(1396, 2048)];
+ __u8 creation_date[ISODCL(814, 830)];
+ __u8 modification_date[ISODCL(831, 847)];
+ __u8 expiration_date[ISODCL(848, 864)];
+ __u8 effective_date[ISODCL(865, 881)];
+ __u8 file_structure_version[ISODCL(882, 882)];
+ __u8 unused4[ISODCL(883, 883)];
+ __u8 application_data[ISODCL(884, 1395)];
+ __u8 unused5[ISODCL(1396, 2048)];
};
#define HS_STANDARD_ID "CDROM"
struct hs_volume_descriptor {
- char foo[ISODCL(1, 8)];
- char type[ISODCL(9, 9)];
+ __u8 foo[ISODCL(1, 8)];
+ __u8 type[ISODCL(9, 9)];
char id[ISODCL(10, 14)];
- char version[ISODCL(15, 15)];
- char data[ISODCL(16, 2048)];
+ __u8 version[ISODCL(15, 15)];
+ __u8 data[ISODCL(16, 2048)];
};
struct hs_primary_descriptor {
- char foo[ISODCL(1, 8)];
- char type[ISODCL(9, 9)];
- char id[ISODCL(10, 14)];
- char version[ISODCL(15, 15)];
- char unused1[ISODCL(16, 16)];
+ __u8 foo[ISODCL(1, 8)];
+ __u8 type[ISODCL(9, 9)];
+ __u8 id[ISODCL(10, 14)];
+ __u8 version[ISODCL(15, 15)];
+ __u8 unused1[ISODCL(16, 16)];
char system_id[ISODCL(17, 48)];
char volume_id[ISODCL(49, 80)];
- char unused2[ISODCL(81, 88)];
- char volume_space_size[ISODCL(89, 96)];
- char unused3[ISODCL(97, 128)];
- char volume_set_size[ISODCL(129, 132)];
- char volume_sequence_number[ISODCL(133, 136)];
- char logical_block_size[ISODCL(137, 140)];
- char path_table_size[ISODCL(141, 148)];
- char type_l_path_table[ISODCL(149, 152)];
- char unused4[ISODCL(153, 180)];
- char root_directory_record[ISODCL(181, 214)];
+ __u8 unused2[ISODCL(81, 88)];
+ __u8 volume_space_size[ISODCL(89, 96)];
+ __u8 unused3[ISODCL(97, 128)];
+ __u8 volume_set_size[ISODCL(129, 132)];
+ __u8 volume_sequence_number[ISODCL(133, 136)];
+ __u8 logical_block_size[ISODCL(137, 140)];
+ __u8 path_table_size[ISODCL(141, 148)];
+ __u8 type_l_path_table[ISODCL(149, 152)];
+ __u8 unused4[ISODCL(153, 180)];
+ __u8 root_directory_record[ISODCL(181, 214)];
};
struct iso_path_table {
- unsigned char name_len[2];
- char extent[4];
- char parent[2];
+ __u8 name_len[2];
+ __u8 extent[4];
+ __u8 parent[2];
char name[0];
} __attribute__((packed));
struct iso_directory_record {
- char length[ISODCL(1, 1)];
- char ext_attr_length[ISODCL(2, 2)];
- char extent[ISODCL(3, 10)];
- char size[ISODCL(11, 18)];
- char date[ISODCL(19, 25)];
- char flags[ISODCL(26, 26)];
- char file_unit_size[ISODCL(27, 27)];
- char interleave[ISODCL(28, 28)];
- char volume_sequence_number[ISODCL(29, 32)];
- unsigned char name_len[ISODCL(33, 33)];
+ __u8 length[ISODCL(1, 1)];
+ __u8 ext_attr_length[ISODCL(2, 2)];
+ __u8 extent[ISODCL(3, 10)];
+ __u8 size[ISODCL(11, 18)];
+ __u8 date[ISODCL(19, 25)];
+ __u8 flags[ISODCL(26, 26)];
+ __u8 file_unit_size[ISODCL(27, 27)];
+ __u8 interleave[ISODCL(28, 28)];
+ __u8 volume_sequence_number[ISODCL(29, 32)];
+ __u8 name_len[ISODCL(33, 33)];
char name[0];
} __attribute__((packed));
#define ISOFS_BLOCK_BITS 11
diff --git a/libc/kernel/uapi/linux/kcov.h b/libc/kernel/uapi/linux/kcov.h
index 9688c38..40f9912 100644
--- a/libc/kernel/uapi/linux/kcov.h
+++ b/libc/kernel/uapi/linux/kcov.h
@@ -22,4 +22,11 @@
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
#define KCOV_ENABLE _IO('c', 100)
#define KCOV_DISABLE _IO('c', 101)
+enum {
+ KCOV_TRACE_PC = 0,
+ KCOV_TRACE_CMP = 1,
+};
+#define KCOV_CMP_CONST (1 << 0)
+#define KCOV_CMP_SIZE(n) ((n) << 1)
+#define KCOV_CMP_MASK KCOV_CMP_SIZE(3)
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index f870cd6..d4582a1 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -125,7 +125,7 @@
#define KFD_IOC_WAIT_RESULT_COMPLETE 0
#define KFD_IOC_WAIT_RESULT_TIMEOUT 1
#define KFD_IOC_WAIT_RESULT_FAIL 2
-#define KFD_SIGNAL_EVENT_LIMIT 256
+#define KFD_SIGNAL_EVENT_LIMIT 4096
struct kfd_ioctl_create_event_args {
__u64 event_page_offset;
__u32 event_trigger_data;
@@ -175,19 +175,19 @@
__u32 wait_result;
};
struct kfd_ioctl_set_scratch_backing_va_args {
- uint64_t va_addr;
- uint32_t gpu_id;
- uint32_t pad;
+ __u64 va_addr;
+ __u32 gpu_id;
+ __u32 pad;
};
struct kfd_ioctl_get_tile_config_args {
- uint64_t tile_config_ptr;
- uint64_t macro_tile_config_ptr;
- uint32_t num_tile_configs;
- uint32_t num_macro_tile_configs;
- uint32_t gpu_id;
- uint32_t gb_addr_config;
- uint32_t num_banks;
- uint32_t num_ranks;
+ __u64 tile_config_ptr;
+ __u64 macro_tile_config_ptr;
+ __u32 num_tile_configs;
+ __u32 num_macro_tile_configs;
+ __u32 gpu_id;
+ __u32 gb_addr_config;
+ __u32 num_banks;
+ __u32 num_ranks;
};
#define AMDKFD_IOCTL_BASE 'K'
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 6bd4701..d04832a 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -728,6 +728,9 @@
#define KVM_CAP_PPC_SMT_POSSIBLE 147
#define KVM_CAP_HYPERV_SYNIC2 148
#define KVM_CAP_HYPERV_VP_INDEX 149
+#define KVM_CAP_S390_AIS_MIGRATION 150
+#define KVM_CAP_PPC_GET_CPU_CHAR 151
+#define KVM_CAP_S390_BPB 152
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -966,6 +969,7 @@
#define KVM_PPC_RESIZE_HPT_COMMIT _IOR(KVMIO, 0xae, struct kvm_ppc_resize_hpt)
#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
+#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
#define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
#define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index e5a2b03..c9a8b74 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -90,31 +90,86 @@
#define __UAPI_DEF_XATTR 1
#endif
#else
+#ifndef __UAPI_DEF_IF_IFCONF
#define __UAPI_DEF_IF_IFCONF 1
+#endif
+#ifndef __UAPI_DEF_IF_IFMAP
#define __UAPI_DEF_IF_IFMAP 1
+#endif
+#ifndef __UAPI_DEF_IF_IFNAMSIZ
#define __UAPI_DEF_IF_IFNAMSIZ 1
+#endif
+#ifndef __UAPI_DEF_IF_IFREQ
#define __UAPI_DEF_IF_IFREQ 1
+#endif
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS
#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+#endif
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif
+#ifndef __UAPI_DEF_IN_ADDR
#define __UAPI_DEF_IN_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN_IPPROTO
#define __UAPI_DEF_IN_IPPROTO 1
+#endif
+#ifndef __UAPI_DEF_IN_PKTINFO
#define __UAPI_DEF_IN_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP_MREQ
#define __UAPI_DEF_IP_MREQ 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN
#define __UAPI_DEF_SOCKADDR_IN 1
+#endif
+#ifndef __UAPI_DEF_IN_CLASS
#define __UAPI_DEF_IN_CLASS 1
+#endif
+#ifndef __UAPI_DEF_IN6_ADDR
#define __UAPI_DEF_IN6_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN6_ADDR_ALT
#define __UAPI_DEF_IN6_ADDR_ALT 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN6
#define __UAPI_DEF_SOCKADDR_IN6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_MREQ
#define __UAPI_DEF_IPV6_MREQ 1
+#endif
+#ifndef __UAPI_DEF_IPPROTO_V6
#define __UAPI_DEF_IPPROTO_V6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_OPTIONS
#define __UAPI_DEF_IPV6_OPTIONS 1
+#endif
+#ifndef __UAPI_DEF_IN6_PKTINFO
#define __UAPI_DEF_IN6_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP6_MTUINFO
#define __UAPI_DEF_IP6_MTUINFO 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IPX
#define __UAPI_DEF_SOCKADDR_IPX 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_CONFIG_DATA
#define __UAPI_DEF_IPX_CONFIG_DATA 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEF
#define __UAPI_DEF_IPX_ROUTE_DEF 1
+#endif
+#ifndef __UAPI_DEF_XATTR
#define __UAPI_DEF_XATTR 1
#endif
#endif
+#ifndef __UAPI_DEF_ETHHDR
+#define __UAPI_DEF_ETHHDR 1
+#endif
+#endif
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 6e0ddf7..68b4c65 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -61,6 +61,7 @@
#define OPENPROM_SUPER_MAGIC 0x9fa1
#define QNX4_SUPER_MAGIC 0x002f
#define QNX6_SUPER_MAGIC 0x68191122
+#define AFS_FS_MAGIC 0x6B414653
#define REISERFS_SUPER_MAGIC 0x52654973
#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
index 5192a54..0d35c15 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
@@ -30,7 +30,7 @@
};
#define NF_CT_STATE_INVALID_BIT (1 << 0)
#define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1))
-#define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_UNTRACKED + 1))
+#define NF_CT_STATE_UNTRACKED_BIT (1 << 6)
enum ip_conntrack_status {
IPS_EXPECTED_BIT = 0,
IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
diff --git a/libc/kernel/uapi/linux/nfc.h b/libc/kernel/uapi/linux/nfc.h
index e212b31..72e3520 100644
--- a/libc/kernel/uapi/linux/nfc.h
+++ b/libc/kernel/uapi/linux/nfc.h
@@ -54,6 +54,7 @@
NFC_CMD_SE_IO,
NFC_CMD_ACTIVATE_TARGET,
NFC_CMD_VENDOR,
+ NFC_CMD_DEACTIVATE_TARGET,
__NFC_CMD_AFTER_LAST
};
#define NFC_CMD_MAX (__NFC_CMD_AFTER_LAST - 1)
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index bb9a835..ebf9448 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -158,6 +158,8 @@
NL80211_CMD_UPDATE_CONNECT_PARAMS,
NL80211_CMD_SET_PMK,
NL80211_CMD_DEL_PMK,
+ NL80211_CMD_PORT_AUTHORIZED,
+ NL80211_CMD_RELOAD_REGDB,
__NL80211_CMD_AFTER_LAST,
NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};
@@ -904,6 +906,7 @@
enum nl80211_mfp {
NL80211_MFP_NO,
NL80211_MFP_REQUIRED,
+ NL80211_MFP_OPTIONAL,
};
enum nl80211_wpa_versions {
NL80211_WPA_VERSION_1 = 1 << 0,
@@ -1194,6 +1197,11 @@
NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
+ NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
+ NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
+ NL80211_EXT_FEATURE_MFP_OPTIONAL,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
@@ -1218,6 +1226,10 @@
NL80211_SCAN_FLAG_FLUSH = 1 << 1,
NL80211_SCAN_FLAG_AP = 1 << 2,
NL80211_SCAN_FLAG_RANDOM_ADDR = 1 << 3,
+ NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 1 << 4,
+ NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1 << 5,
+ NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1 << 6,
+ NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1 << 7,
};
enum nl80211_acl_policy {
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED,
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 7247171..bea44d0 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -123,6 +123,8 @@
OVS_VPORT_ATTR_UPCALL_PID,
OVS_VPORT_ATTR_STATS,
OVS_VPORT_ATTR_PAD,
+ OVS_VPORT_ATTR_IFINDEX,
+ OVS_VPORT_ATTR_NETNSID,
__OVS_VPORT_ATTR_MAX
};
#define OVS_VPORT_ATTR_MAX (__OVS_VPORT_ATTR_MAX - 1)
@@ -182,6 +184,7 @@
OVS_KEY_ATTR_CT_LABELS,
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
+ OVS_KEY_ATTR_NSH,
__OVS_KEY_ATTR_MAX
};
#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
@@ -298,6 +301,25 @@
__be16 dst_port;
__u8 ipv6_proto;
};
+enum ovs_nsh_key_attr {
+ OVS_NSH_KEY_ATTR_UNSPEC,
+ OVS_NSH_KEY_ATTR_BASE,
+ OVS_NSH_KEY_ATTR_MD1,
+ OVS_NSH_KEY_ATTR_MD2,
+ __OVS_NSH_KEY_ATTR_MAX
+};
+#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1)
+struct ovs_nsh_key_base {
+ __u8 flags;
+ __u8 ttl;
+ __u8 mdtype;
+ __u8 np;
+ __be32 path_hdr;
+};
+#define NSH_MD1_CONTEXT_SIZE 4
+struct ovs_nsh_key_md1 {
+ __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
enum ovs_flow_attr {
OVS_FLOW_ATTR_UNSPEC,
OVS_FLOW_ATTR_KEY,
@@ -398,7 +420,50 @@
OVS_ACTION_ATTR_TRUNC,
OVS_ACTION_ATTR_PUSH_ETH,
OVS_ACTION_ATTR_POP_ETH,
+ OVS_ACTION_ATTR_CT_CLEAR,
+ OVS_ACTION_ATTR_PUSH_NSH,
+ OVS_ACTION_ATTR_POP_NSH,
+ OVS_ACTION_ATTR_METER,
__OVS_ACTION_ATTR_MAX,
};
#define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1)
+#define OVS_METER_FAMILY "ovs_meter"
+#define OVS_METER_MCGROUP "ovs_meter"
+#define OVS_METER_VERSION 0x1
+enum ovs_meter_cmd {
+ OVS_METER_CMD_UNSPEC,
+ OVS_METER_CMD_FEATURES,
+ OVS_METER_CMD_SET,
+ OVS_METER_CMD_DEL,
+ OVS_METER_CMD_GET
+};
+enum ovs_meter_attr {
+ OVS_METER_ATTR_UNSPEC,
+ OVS_METER_ATTR_ID,
+ OVS_METER_ATTR_KBPS,
+ OVS_METER_ATTR_STATS,
+ OVS_METER_ATTR_BANDS,
+ OVS_METER_ATTR_USED,
+ OVS_METER_ATTR_CLEAR,
+ OVS_METER_ATTR_MAX_METERS,
+ OVS_METER_ATTR_MAX_BANDS,
+ OVS_METER_ATTR_PAD,
+ __OVS_METER_ATTR_MAX
+};
+#define OVS_METER_ATTR_MAX (__OVS_METER_ATTR_MAX - 1)
+enum ovs_band_attr {
+ OVS_BAND_ATTR_UNSPEC,
+ OVS_BAND_ATTR_TYPE,
+ OVS_BAND_ATTR_RATE,
+ OVS_BAND_ATTR_BURST,
+ OVS_BAND_ATTR_STATS,
+ __OVS_BAND_ATTR_MAX
+};
+#define OVS_BAND_ATTR_MAX (__OVS_BAND_ATTR_MAX - 1)
+enum ovs_meter_band_type {
+ OVS_METER_BAND_TYPE_UNSPEC,
+ OVS_METER_BAND_TYPE_DROP,
+ __OVS_METER_BAND_TYPE_MAX
+};
+#define OVS_METER_BAND_TYPE_MAX (__OVS_METER_BAND_TYPE_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index c7f8381..148f2b4 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -640,6 +640,7 @@
#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010
#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020
#define PCI_ERR_ROOT_FATAL_RCV 0x00000040
+#define PCI_ERR_ROOT_AER_IRQ 0xf8000000
#define PCI_ERR_ROOT_ERR_SRC 52
#define PCI_VC_PORT_CAP1 4
#define PCI_VC_CAP1_EVCC 0x00000007
@@ -799,9 +800,13 @@
#define PCI_SATA_REGS_INLINE 0xF
#define PCI_SATA_SIZEOF_SHORT 8
#define PCI_SATA_SIZEOF_LONG 16
+#define PCI_REBAR_CAP 4
+#define PCI_REBAR_CAP_SIZES 0x00FFFFF0
#define PCI_REBAR_CTRL 8
-#define PCI_REBAR_CTRL_NBAR_MASK (7 << 5)
+#define PCI_REBAR_CTRL_BAR_IDX 0x00000007
+#define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0
#define PCI_REBAR_CTRL_NBAR_SHIFT 5
+#define PCI_REBAR_CTRL_BAR_SIZE 0x00001F00
#define PCI_DPA_CAP 4
#define PCI_DPA_CAP_SUBSTATE_MASK 0x1F
#define PCI_DPA_BASE_SIZEOF 16
@@ -814,6 +819,7 @@
#define PCI_TPH_CAP_ST_SHIFT 16
#define PCI_TPH_BASE_SIZEOF 12
#define PCI_EXP_DPC_CAP 4
+#define PCI_EXP_DPC_IRQ 0x1f
#define PCI_EXP_DPC_CAP_RP_EXT 0x20
#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40
#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80
@@ -842,17 +848,23 @@
#define PCI_PTM_CTRL 0x08
#define PCI_PTM_CTRL_ENABLE 0x00000001
#define PCI_PTM_CTRL_ROOT 0x00000002
-#define PCI_L1SS_CAP 4
-#define PCI_L1SS_CAP_PCIPM_L1_2 1
-#define PCI_L1SS_CAP_PCIPM_L1_1 2
-#define PCI_L1SS_CAP_ASPM_L1_2 4
-#define PCI_L1SS_CAP_ASPM_L1_1 8
-#define PCI_L1SS_CAP_L1_PM_SS 16
-#define PCI_L1SS_CTL1 8
-#define PCI_L1SS_CTL1_PCIPM_L1_2 1
-#define PCI_L1SS_CTL1_PCIPM_L1_1 2
-#define PCI_L1SS_CTL1_ASPM_L1_2 4
-#define PCI_L1SS_CTL1_ASPM_L1_1 8
-#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000F
-#define PCI_L1SS_CTL2 0xC
+#define PCI_L1SS_CAP 0x04
+#define PCI_L1SS_CAP_PCIPM_L1_2 0x00000001
+#define PCI_L1SS_CAP_PCIPM_L1_1 0x00000002
+#define PCI_L1SS_CAP_ASPM_L1_2 0x00000004
+#define PCI_L1SS_CAP_ASPM_L1_1 0x00000008
+#define PCI_L1SS_CAP_L1_PM_SS 0x00000010
+#define PCI_L1SS_CAP_CM_RESTORE_TIME 0x0000ff00
+#define PCI_L1SS_CAP_P_PWR_ON_SCALE 0x00030000
+#define PCI_L1SS_CAP_P_PWR_ON_VALUE 0x00f80000
+#define PCI_L1SS_CTL1 0x08
+#define PCI_L1SS_CTL1_PCIPM_L1_2 0x00000001
+#define PCI_L1SS_CTL1_PCIPM_L1_1 0x00000002
+#define PCI_L1SS_CTL1_ASPM_L1_2 0x00000004
+#define PCI_L1SS_CTL1_ASPM_L1_1 0x00000008
+#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000f
+#define PCI_L1SS_CTL1_CM_RESTORE_TIME 0x0000ff00
+#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000
+#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000
+#define PCI_L1SS_CTL2 0x0c
#endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 326827e..97a2e99 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -329,6 +329,7 @@
#define PERF_AUX_FLAG_TRUNCATED 0x01
#define PERF_AUX_FLAG_OVERWRITE 0x02
#define PERF_AUX_FLAG_PARTIAL 0x04
+#define PERF_AUX_FLAG_COLLISION 0x08
#define PERF_FLAG_FD_NO_GROUP (1UL << 0)
#define PERF_FLAG_FD_OUTPUT (1UL << 1)
#define PERF_FLAG_PID_CGROUP (1UL << 2)
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 7d3ff96..a3f2adf 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -49,6 +49,7 @@
#define TC_H_ROOT (0xFFFFFFFFU)
#define TC_H_INGRESS (0xFFFFFFF1U)
#define TC_H_CLSACT TC_H_INGRESS
+#define TC_H_MIN_PRIORITY 0xFFE0U
#define TC_H_MIN_INGRESS 0xFFF2U
#define TC_H_MIN_EGRESS 0xFFF3U
enum tc_link_layer {
@@ -403,6 +404,9 @@
TCA_NETEM_ECN,
TCA_NETEM_RATE64,
TCA_NETEM_PAD,
+ TCA_NETEM_LATENCY64,
+ TCA_NETEM_JITTER64,
+ TCA_NETEM_SLOT,
__TCA_NETEM_MAX,
};
#define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
@@ -433,6 +437,12 @@
__u32 cell_size;
__s32 cell_overhead;
};
+struct tc_netem_slot {
+ __s64 min_delay;
+ __s64 max_delay;
+ __s32 max_packets;
+ __s32 max_bytes;
+};
enum {
NETEM_LOSS_UNSPEC,
NETEM_LOSS_GI,
@@ -472,6 +482,18 @@
__TC_MQPRIO_HW_OFFLOAD_MAX
};
#define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1)
+enum {
+ TC_MQPRIO_MODE_DCB,
+ TC_MQPRIO_MODE_CHANNEL,
+ __TC_MQPRIO_MODE_MAX
+};
+#define __TC_MQPRIO_MODE_MAX (__TC_MQPRIO_MODE_MAX - 1)
+enum {
+ TC_MQPRIO_SHAPER_DCB,
+ TC_MQPRIO_SHAPER_BW_RATE,
+ __TC_MQPRIO_SHAPER_MAX
+};
+#define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)
struct tc_mqprio_qopt {
__u8 num_tc;
__u8 prio_tc_map[TC_QOPT_BITMASK + 1];
@@ -479,6 +501,19 @@
__u16 count[TC_QOPT_MAX_QUEUE];
__u16 offset[TC_QOPT_MAX_QUEUE];
};
+#define TC_MQPRIO_F_MODE 0x1
+#define TC_MQPRIO_F_SHAPER 0x2
+#define TC_MQPRIO_F_MIN_RATE 0x4
+#define TC_MQPRIO_F_MAX_RATE 0x8
+enum {
+ TCA_MQPRIO_UNSPEC,
+ TCA_MQPRIO_MODE,
+ TCA_MQPRIO_SHAPER,
+ TCA_MQPRIO_MIN_RATE64,
+ TCA_MQPRIO_MAX_RATE64,
+ __TCA_MQPRIO_MAX,
+};
+#define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)
enum {
TCA_SFB_UNSPEC,
TCA_SFB_PARMS,
@@ -654,4 +689,18 @@
__u32 maxq;
__u32 ecn_mark;
};
+struct tc_cbs_qopt {
+ __u8 offload;
+ __u8 _pad[3];
+ __s32 hicredit;
+ __s32 locredit;
+ __s32 idleslope;
+ __s32 sendslope;
+};
+enum {
+ TCA_CBS_UNSPEC,
+ TCA_CBS_PARMS,
+ __TCA_CBS_MAX,
+};
+#define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index a30fe17..55098f5 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -129,4 +129,9 @@
#define PR_CAP_AMBIENT_RAISE 2
#define PR_CAP_AMBIENT_LOWER 3
#define PR_CAP_AMBIENT_CLEAR_ALL 4
+#define PR_SVE_SET_VL 50
+#define PR_SVE_SET_VL_ONEXEC (1 << 18)
+#define PR_SVE_GET_VL 51
+#define PR_SVE_VL_LEN_MASK 0xffff
+#define PR_SVE_VL_INHERIT (1 << 17)
#endif
diff --git a/libc/kernel/uapi/linux/qrtr.h b/libc/kernel/uapi/linux/qrtr.h
index 4040b4c..c0a4c72 100644
--- a/libc/kernel/uapi/linux/qrtr.h
+++ b/libc/kernel/uapi/linux/qrtr.h
@@ -20,9 +20,39 @@
#define _LINUX_QRTR_H
#include <linux/socket.h>
#include <linux/types.h>
+#define QRTR_NODE_BCAST 0xffffffffu
+#define QRTR_PORT_CTRL 0xfffffffeu
struct sockaddr_qrtr {
__kernel_sa_family_t sq_family;
__u32 sq_node;
__u32 sq_port;
};
+enum qrtr_pkt_type {
+ QRTR_TYPE_DATA = 1,
+ QRTR_TYPE_HELLO = 2,
+ QRTR_TYPE_BYE = 3,
+ QRTR_TYPE_NEW_SERVER = 4,
+ QRTR_TYPE_DEL_SERVER = 5,
+ QRTR_TYPE_DEL_CLIENT = 6,
+ QRTR_TYPE_RESUME_TX = 7,
+ QRTR_TYPE_EXIT = 8,
+ QRTR_TYPE_PING = 9,
+ QRTR_TYPE_NEW_LOOKUP = 10,
+ QRTR_TYPE_DEL_LOOKUP = 11,
+};
+struct qrtr_ctrl_pkt {
+ __le32 cmd;
+ union {
+ struct {
+ __le32 service;
+ __le32 instance;
+ __le32 node;
+ __le32 port;
+ } server;
+ struct {
+ __le32 node;
+ __le32 port;
+ } client;
+ };
+} __packed;
#endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index c363e34..80ba16e 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -318,6 +318,8 @@
#define RTAX_QUICKACK RTAX_QUICKACK
RTAX_CC_ALGO,
#define RTAX_CC_ALGO RTAX_CC_ALGO
+ RTAX_FASTOPEN_NO_COOKIE,
+#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE
__RTAX_MAX
};
#define RTAX_MAX (__RTAX_MAX - 1)
@@ -402,6 +404,7 @@
TCA_PAD,
TCA_DUMP_INVISIBLE,
TCA_CHAIN,
+ TCA_HW_OFFLOAD,
__TCA_MAX
};
#define TCA_MAX (__TCA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/rxrpc.h b/libc/kernel/uapi/linux/rxrpc.h
index b8b7b04..1690111 100644
--- a/libc/kernel/uapi/linux/rxrpc.h
+++ b/libc/kernel/uapi/linux/rxrpc.h
@@ -22,12 +22,12 @@
#include <linux/in.h>
#include <linux/in6.h>
struct sockaddr_rxrpc {
- sa_family_t srx_family;
- u16 srx_service;
- u16 transport_type;
- u16 transport_len;
+ __kernel_sa_family_t srx_family;
+ __u16 srx_service;
+ __u16 transport_type;
+ __u16 transport_len;
union {
- sa_family_t family;
+ __kernel_sa_family_t family;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} transport;
@@ -50,6 +50,7 @@
RXRPC_EXCLUSIVE_CALL = 10,
RXRPC_UPGRADE_SERVICE = 11,
RXRPC_TX_LENGTH = 12,
+ RXRPC_SET_CALL_TIMEOUT = 13,
RXRPC__SUPPORTED
};
#define RXRPC_SECURITY_PLAIN 0
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 9a55459..cc714ff 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -77,6 +77,8 @@
#define SCTP_RESET_ASSOC 120
#define SCTP_ADD_STREAMS 121
#define SCTP_SOCKOPT_PEELOFF_FLAGS 122
+#define SCTP_STREAM_SCHEDULER 123
+#define SCTP_STREAM_SCHEDULER_VALUE 124
#define SCTP_PR_SCTP_NONE 0x0000
#define SCTP_PR_SCTP_TTL 0x0010
#define SCTP_PR_SCTP_RTX 0x0020
@@ -443,6 +445,11 @@
sctp_assoc_t assoc_id;
uint32_t assoc_value;
};
+struct sctp_stream_value {
+ sctp_assoc_t assoc_id;
+ uint16_t stream_id;
+ uint16_t stream_value;
+};
struct sctp_paddrinfo {
sctp_assoc_t spinfo_assoc_id;
struct sockaddr_storage spinfo_address;
@@ -616,4 +623,10 @@
uint16_t sas_instrms;
uint16_t sas_outstrms;
};
+enum sctp_sched_type {
+ SCTP_SS_FCFS,
+ SCTP_SS_PRIO,
+ SCTP_SS_RR,
+ SCTP_SS_MAX = SCTP_SS_RR
+};
#endif
diff --git a/libc/kernel/uapi/linux/seg6.h b/libc/kernel/uapi/linux/seg6.h
index 6f7b8dd..f180485 100644
--- a/libc/kernel/uapi/linux/seg6.h
+++ b/libc/kernel/uapi/linux/seg6.h
@@ -27,7 +27,7 @@
__u8 segments_left;
__u8 first_segment;
__u8 flags;
- __u16 reserved;
+ __u16 tag;
struct in6_addr segments[0];
};
#define SR6_FLAG1_PROTECTED (1 << 6)
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index 95c9956..b6648f8 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -113,6 +113,7 @@
#define UART_SCR 7
#define UART_DLL 0
#define UART_DLM 1
+#define UART_DIV_MAX 0xFFFF
#define UART_EFR 2
#define UART_XR_EFR 9
#define UART_EFR_CTS 0x80
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 467a27a..b9f0c3e 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -158,7 +158,6 @@
LINUX_MIB_TCPRENORECOVERY,
LINUX_MIB_TCPSACKRECOVERY,
LINUX_MIB_TCPSACKRENEGING,
- LINUX_MIB_TCPFACKREORDER,
LINUX_MIB_TCPSACKREORDER,
LINUX_MIB_TCPRENOREORDER,
LINUX_MIB_TCPTSREORDER,
diff --git a/libc/kernel/uapi/linux/stddef.h b/libc/kernel/uapi/linux/stddef.h
index a04729b..2a5fd95 100644
--- a/libc/kernel/uapi/linux/stddef.h
+++ b/libc/kernel/uapi/linux/stddef.h
@@ -16,7 +16,7 @@
***
****************************************************************************
****************************************************************************/
-#include <linux/compiler.h>
+#include <linux/compiler_types.h>
#ifndef __always_inline
#define __always_inline inline
#endif
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 13354e6..0bf9559 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -87,6 +87,8 @@
#define TCP_FASTOPEN_CONNECT 30
#define TCP_ULP 31
#define TCP_MD5SIG_EXT 32
+#define TCP_FASTOPEN_KEY 33
+#define TCP_FASTOPEN_NO_COOKIE 34
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
diff --git a/libc/kernel/uapi/linux/tipc.h b/libc/kernel/uapi/linux/tipc.h
index cf16725..b8b4965 100644
--- a/libc/kernel/uapi/linux/tipc.h
+++ b/libc/kernel/uapi/linux/tipc.h
@@ -121,6 +121,16 @@
#define TIPC_SOCK_RECVQ_DEPTH 132
#define TIPC_MCAST_BROADCAST 133
#define TIPC_MCAST_REPLICAST 134
+#define TIPC_GROUP_JOIN 135
+#define TIPC_GROUP_LEAVE 136
+#define TIPC_GROUP_LOOPBACK 0x1
+#define TIPC_GROUP_MEMBER_EVTS 0x2
+struct tipc_group_req {
+ __u32 type;
+ __u32 instance;
+ __u32 scope;
+ __u32 flags;
+};
#define TIPC_MAX_MEDIA_NAME 16
#define TIPC_MAX_IF_NAME 16
#define TIPC_MAX_BEARER_NAME 32
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
index 73618e0..925cf80 100644
--- a/libc/kernel/uapi/linux/tls.h
+++ b/libc/kernel/uapi/linux/tls.h
@@ -19,10 +19,6 @@
#ifndef _UAPI_LINUX_TLS_H
#define _UAPI_LINUX_TLS_H
#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <linux/socket.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
#define TLS_TX 1
#define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
#define TLS_VERSION_MAJOR(ver) (((ver) >> 8) & 0xFF)
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 38e7ae7..a7cf43a 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -79,6 +79,8 @@
#define TEST_SE0_NAK 3
#define TEST_PACKET 4
#define TEST_FORCE_EN 5
+#define USB_STATUS_TYPE_STANDARD 0
+#define USB_STATUS_TYPE_PTM 1
#define USB_DEVICE_U1_ENABLE 48
#define USB_DEVICE_U2_ENABLE 49
#define USB_DEVICE_LTM_ENABLE 50
@@ -367,6 +369,7 @@
__le16 bmBandGroup;
__u8 bReserved;
} __attribute__((packed));
+#define USB_DT_USB_WIRELESS_CAP_SIZE 11
#define USB_CAP_TYPE_EXT 2
struct usb_ext_cap_descriptor {
__u8 bLength;
@@ -504,6 +507,7 @@
__u8 bDescriptorType;
__u8 bDevCapabilityType;
} __attribute__((packed));
+#define USB_DT_USB_PTM_ID_SIZE 3
#define USB_DT_USB_SSP_CAP_SIZE(ssac) (16 + ssac * 4)
struct usb_wireless_ep_comp_descriptor {
__u8 bLength;
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 7714cb7..70b6963 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 265728
+#define LINUX_VERSION_CODE 265984
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vm_sockets_diag.h b/libc/kernel/uapi/linux/vm_sockets_diag.h
new file mode 100644
index 0000000..2f9840b
--- /dev/null
+++ b/libc/kernel/uapi/linux/vm_sockets_diag.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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__VM_SOCKETS_DIAG_H__
+#define _UAPI__VM_SOCKETS_DIAG_H__
+#include <linux/types.h>
+struct vsock_diag_req {
+ __u8 sdiag_family;
+ __u8 sdiag_protocol;
+ __u16 pad;
+ __u32 vdiag_states;
+ __u32 vdiag_ino;
+ __u32 vdiag_show;
+ __u32 vdiag_cookie[2];
+};
+struct vsock_diag_msg {
+ __u8 vdiag_family;
+ __u8 vdiag_type;
+ __u8 vdiag_state;
+ __u8 vdiag_shutdown;
+ __u32 vdiag_src_cid;
+ __u32 vdiag_src_port;
+ __u32 vdiag_dst_cid;
+ __u32 vdiag_dst_port;
+ __u32 vdiag_ino;
+ __u32 vdiag_cookie[2];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/wmi.h b/libc/kernel/uapi/linux/wmi.h
new file mode 100644
index 0000000..26f54d9
--- /dev/null
+++ b/libc/kernel/uapi/linux/wmi.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_WMI_H
+#define _UAPI_LINUX_WMI_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define WMI_IOC 'W'
+struct wmi_ioctl_buffer {
+ __u64 length;
+ __u8 data[];
+};
+struct calling_interface_buffer {
+ __u16 cmd_class;
+ __u16 cmd_select;
+ volatile __u32 input[4];
+ volatile __u32 output[4];
+} __packed;
+struct dell_wmi_extensions {
+ __u32 argattrib;
+ __u32 blength;
+ __u8 data[];
+} __packed;
+struct dell_wmi_smbios_buffer {
+ __u64 length;
+ struct calling_interface_buffer std;
+ struct dell_wmi_extensions ext;
+} __packed;
+#define CLASS_TOKEN_READ 0
+#define CLASS_TOKEN_WRITE 1
+#define SELECT_TOKEN_STD 0
+#define SELECT_TOKEN_BAT 1
+#define SELECT_TOKEN_AC 2
+#define CLASS_FLASH_INTERFACE 7
+#define SELECT_FLASH_INTERFACE 3
+#define CLASS_ADMIN_PROP 10
+#define SELECT_ADMIN_PROP 3
+#define CLASS_INFO 17
+#define SELECT_RFKILL 11
+#define SELECT_APP_REGISTRATION 3
+#define SELECT_DOCK 22
+#define CAPSULE_EN_TOKEN 0x0461
+#define CAPSULE_DIS_TOKEN 0x0462
+#define WSMT_EN_TOKEN 0x04EC
+#define WSMT_DIS_TOKEN 0x04ED
+#define DELL_WMI_SMBIOS_CMD _IOWR(WMI_IOC, 0, struct dell_wmi_smbios_buffer)
+#endif
diff --git a/libc/kernel/uapi/linux/xattr.h b/libc/kernel/uapi/linux/xattr.h
index efa99e7..7c098f4 100644
--- a/libc/kernel/uapi/linux/xattr.h
+++ b/libc/kernel/uapi/linux/xattr.h
@@ -56,6 +56,8 @@
#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
+#define XATTR_APPARMOR_SUFFIX "apparmor"
+#define XATTR_NAME_APPARMOR XATTR_SECURITY_PREFIX XATTR_APPARMOR_SUFFIX
#define XATTR_CAPS_SUFFIX "capability"
#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
#define XATTR_POSIX_ACL_ACCESS "posix_acl_access"
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index ff3ebcb..03a2fcd 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -75,7 +75,8 @@
IB_USER_VERBS_EX_CMD_MODIFY_WQ,
IB_USER_VERBS_EX_CMD_DESTROY_WQ,
IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL,
- IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL
+ IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL,
+ IB_USER_VERBS_EX_CMD_MODIFY_CQ
};
struct ib_uverbs_async_event_desc {
__u64 element;
@@ -85,6 +86,11 @@
struct ib_uverbs_comp_event_desc {
__u64 cq_handle;
};
+struct ib_uverbs_cq_moderation_caps {
+ __u16 max_cq_moderation_count;
+ __u16 max_cq_moderation_period;
+ __u32 reserved;
+};
#define IB_USER_VERBS_CMD_COMMAND_MASK 0xff
#define IB_USER_VERBS_CMD_FLAGS_MASK 0xff000000u
#define IB_USER_VERBS_CMD_FLAGS_SHIFT 24
@@ -194,6 +200,7 @@
__u32 max_wq_type_rq;
__u32 raw_packet_caps;
struct ib_uverbs_tm_caps tm_caps;
+ struct ib_uverbs_cq_moderation_caps cq_moderation_caps;
};
struct ib_uverbs_query_port {
__u64 response;
@@ -952,5 +959,15 @@
__u32 comp_mask;
__u32 ind_tbl_handle;
};
+struct ib_uverbs_cq_moderation {
+ __u16 cq_count;
+ __u16 cq_period;
+};
+struct ib_uverbs_ex_modify_cq {
+ __u32 cq_handle;
+ __u32 attr_mask;
+ struct ib_uverbs_cq_moderation attr;
+ __u32 reserved;
+};
#define IB_DEVICE_NAME_MAX 64
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index b51ff4e..9347cf3 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -23,6 +23,7 @@
enum {
MLX5_QP_FLAG_SIGNATURE = 1 << 0,
MLX5_QP_FLAG_SCATTER_CQE = 1 << 1,
+ MLX5_QP_FLAG_TUNNEL_OFFLOADS = 1 << 2,
};
enum {
MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -126,6 +127,23 @@
__u32 sw_parsing_offloads;
__u32 supported_qpts;
};
+struct mlx5_ib_striding_rq_caps {
+ __u32 min_single_stride_log_num_of_bytes;
+ __u32 max_single_stride_log_num_of_bytes;
+ __u32 min_single_wqe_log_num_of_strides;
+ __u32 max_single_wqe_log_num_of_strides;
+ __u32 supported_qpts;
+ __u32 reserved;
+};
+enum mlx5_ib_query_dev_resp_flags {
+ MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0,
+ MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1,
+};
+enum mlx5_ib_tunnel_offloads {
+ MLX5_IB_TUNNELED_OFFLOADS_VXLAN = 1 << 0,
+ MLX5_IB_TUNNELED_OFFLOADS_GRE = 1 << 1,
+ MLX5_IB_TUNNELED_OFFLOADS_GENEVE = 1 << 2
+};
struct mlx5_ib_query_device_resp {
__u32 comp_mask;
__u32 response_length;
@@ -134,8 +152,14 @@
struct mlx5_ib_cqe_comp_caps cqe_comp_caps;
struct mlx5_packet_pacing_caps packet_pacing_caps;
__u32 mlx5_ib_support_multi_pkt_send_wqes;
- __u32 reserved;
+ __u32 flags;
struct mlx5_ib_sw_parsing_caps sw_parsing_caps;
+ struct mlx5_ib_striding_rq_caps striding_rq_caps;
+ __u32 tunnel_offloads_caps;
+ __u32 reserved;
+};
+enum mlx5_ib_create_cq_flags {
+ MLX5_IB_CREATE_CQ_FLAGS_CQE_128B_PAD = 1 << 0,
};
struct mlx5_ib_create_cq {
__u64 buf_addr;
@@ -143,7 +167,7 @@
__u32 cqe_size;
__u8 cqe_comp_en;
__u8 cqe_comp_res_format;
- __u16 reserved;
+ __u16 flags;
};
struct mlx5_ib_create_cq_resp {
__u32 cqn;
@@ -189,7 +213,8 @@
MLX5_RX_HASH_SRC_PORT_TCP = 1 << 4,
MLX5_RX_HASH_DST_PORT_TCP = 1 << 5,
MLX5_RX_HASH_SRC_PORT_UDP = 1 << 6,
- MLX5_RX_HASH_DST_PORT_UDP = 1 << 7
+ MLX5_RX_HASH_DST_PORT_UDP = 1 << 7,
+ MLX5_RX_HASH_INNER = 1 << 31
};
struct mlx5_ib_create_qp_rss {
__u64 rx_hash_fields_mask;
@@ -198,7 +223,7 @@
__u8 reserved[6];
__u8 rx_hash_key[128];
__u32 comp_mask;
- __u32 reserved1;
+ __u32 flags;
};
struct mlx5_ib_create_qp_resp {
__u32 bfreg_index;
@@ -209,6 +234,9 @@
__u8 reserved1;
__u16 reserved2;
};
+enum mlx5_ib_create_wq_mask {
+ MLX5_IB_CREATE_WQ_STRIDING_RQ = (1 << 0),
+};
struct mlx5_ib_create_wq {
__u64 buf_addr;
__u64 db_addr;
@@ -217,7 +245,9 @@
__u32 user_index;
__u32 flags;
__u32 comp_mask;
- __u32 reserved;
+ __u32 single_stride_log_num_of_bytes;
+ __u32 single_wqe_log_num_of_strides;
+ __u32 two_byte_shift_en;
};
struct mlx5_ib_create_ah_resp {
__u32 response_length;
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index 2062366..7c13680 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -119,6 +119,8 @@
};
struct pvrdma_create_srq {
__u64 buf_addr;
+ __u32 buf_size;
+ __u32 reserved;
};
struct pvrdma_create_srq_resp {
__u32 srqn;
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index c345ba6..19c80b7 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1321,7 +1321,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1386,6 +1392,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1398,8 +1405,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 3af0d42..cab66e6 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1241,7 +1241,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1306,6 +1312,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1318,8 +1325,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 5c54ba1..65e4802 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1346,7 +1346,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1411,6 +1417,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1423,8 +1430,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index c364608..363a55a 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1305,7 +1305,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1370,6 +1376,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1382,8 +1389,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 3af0d42..cab66e6 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1241,7 +1241,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1306,6 +1312,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1318,8 +1325,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index eec2c19..fc5e463 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1303,7 +1303,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1368,6 +1374,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1380,8 +1387,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 3af0d42..cab66e6 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1241,7 +1241,13 @@
LIBC_P { # introduced=P
global:
__freading;
+ __free_hook;
+ __fseterr;
__fwriting;
+ __malloc_hook;
+ __memalign_hook;
+ __realloc_hook;
+ aligned_alloc;
endhostent;
endnetent;
endprotoent;
@@ -1306,6 +1312,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
@@ -1318,8 +1325,14 @@
sigtimedwait64;
sigwait64;
sigwaitinfo64;
+ strptime_l;
swab;
syncfs;
+ wcsftime_l;
+ wcstod_l;
+ wcstof_l;
+ wcstol_l;
+ wcstoul_l;
} LIBC_O;
LIBC_PRIVATE {
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 06fc426..ede2431 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -13,7 +13,10 @@
stl: "libc++_static",
- whole_static_libs: ["libasync_safe", "libdemangle"],
+ whole_static_libs: [
+ "libasync_safe",
+ "libdemangle",
+ ],
include_dirs: ["bionic/libc"],
@@ -117,7 +120,10 @@
whole_static_libs: ["libc_malloc_debug"],
local_include_dirs: ["tests"],
- include_dirs: ["bionic/libc", "bionic/libc/async_safe/include"],
+ include_dirs: [
+ "bionic/libc",
+ "bionic/libc/async_safe/include",
+ ],
shared_libs: ["libbase"],
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index d597280..57d8f2a 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -59,13 +59,10 @@
bool BacktraceData::Initialize(const Config& config) {
enabled_ = config.backtrace_enabled();
if (config.backtrace_enable_on_signal()) {
- struct sigaction enable_act;
- memset(&enable_act, 0, sizeof(enable_act));
-
+ struct sigaction64 enable_act = {};
enable_act.sa_sigaction = ToggleBacktraceEnable;
enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&enable_act.sa_mask);
- if (sigaction(config.backtrace_signal(), &enable_act, nullptr) != 0) {
+ if (sigaction64(config.backtrace_signal(), &enable_act, nullptr) != 0) {
error_log("Unable to set up backtrace signal enable function: %s", strerror(errno));
return false;
}
@@ -73,13 +70,10 @@
config.backtrace_signal(), getpid());
}
- struct sigaction act;
- memset(&act, 0, sizeof(act));
-
+ struct sigaction64 act = {};
act.sa_sigaction = EnableDump;
act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&act.sa_mask);
- if (sigaction(config.backtrace_dump_signal(), &act, nullptr) != 0) {
+ if (sigaction64(config.backtrace_dump_signal(), &act, nullptr) != 0) {
error_log("Unable to set up backtrace dump signal function: %s", strerror(errno));
return false;
}
diff --git a/libc/malloc_debug/BacktraceData.h b/libc/malloc_debug/BacktraceData.h
index c8234dc..3c15348 100644
--- a/libc/malloc_debug/BacktraceData.h
+++ b/libc/malloc_debug/BacktraceData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_BACKTRACEDATA_H
-#define DEBUG_MALLOC_BACKTRACEDATA_H
+#pragma once
#include <stdint.h>
@@ -67,5 +66,3 @@
DISALLOW_COPY_AND_ASSIGN(BacktraceData);
};
-
-#endif // DEBUG_MALLOC_BACKTRACEDATA_H
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index 349ad77..a310e09 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef MALLOC_DEBUG_CONFIG_H
-#define MALLOC_DEBUG_CONFIG_H
+#pragma once
#include <stdint.h>
@@ -159,5 +158,3 @@
uint8_t front_guard_value_;
uint8_t rear_guard_value_;
};
-
-#endif // MALLOC_DEBUG_CONFIG_H
diff --git a/libc/malloc_debug/DebugData.h b/libc/malloc_debug/DebugData.h
index 7228a72..9aece0b 100644
--- a/libc/malloc_debug/DebugData.h
+++ b/libc/malloc_debug/DebugData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_DEBUGDATA_H
-#define DEBUG_MALLOC_DEBUGDATA_H
+#pragma once
#include <stdint.h>
@@ -106,5 +105,3 @@
};
extern DebugData* g_debug;
-
-#endif // MALLOC_DEBUG_DEBUGDATA_H
diff --git a/libc/malloc_debug/FreeTrackData.h b/libc/malloc_debug/FreeTrackData.h
index 0e8c177..bd3497d 100644
--- a/libc/malloc_debug/FreeTrackData.h
+++ b/libc/malloc_debug/FreeTrackData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_FREETRACKDATA_H
-#define DEBUG_MALLOC_FREETRACKDATA_H
+#pragma once
#include <stdint.h>
#include <pthread.h>
@@ -75,5 +74,3 @@
DISALLOW_COPY_AND_ASSIGN(FreeTrackData);
};
-
-#endif // DEBUG_MALLOC_FREETRACKDATA_H
diff --git a/libc/malloc_debug/GuardData.h b/libc/malloc_debug/GuardData.h
index ddf6ce1..7b21671 100644
--- a/libc/malloc_debug/GuardData.h
+++ b/libc/malloc_debug/GuardData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_GUARDDATA_H
-#define DEBUG_MALLOC_GUARDDATA_H
+#pragma once
#include <stdint.h>
#include <string.h>
@@ -93,5 +92,3 @@
DISALLOW_COPY_AND_ASSIGN(RearGuardData);
};
-
-#endif // DEBUG_MALLOC_GUARDDATA_H
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index 895f78f..a71f96d 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_MAPDATA_H
-#define DEBUG_MALLOC_MAPDATA_H
+#pragma once
#include <sys/cdefs.h>
@@ -74,5 +73,3 @@
DISALLOW_COPY_AND_ASSIGN(MapData);
};
-
-#endif // DEBUG_MALLOC_MAPDATA_H
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
index 5c2d272..3fa8e14 100644
--- a/libc/malloc_debug/OptionData.h
+++ b/libc/malloc_debug/OptionData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_OPTIONDATA_H
-#define DEBUG_MALLOC_OPTIONDATA_H
+#pragma once
// Forward Declarations
class DebugData;
@@ -42,5 +41,3 @@
DISALLOW_COPY_AND_ASSIGN(OptionData);
};
-
-#endif // MALLOC_DEBUG_OPTIONDATA_H
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index b7a12a5..69d0648 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -23,6 +23,7 @@
* `realloc`
* `posix_memalign`
* `memalign`
+* `aligned_alloc`
* `malloc_usable_size`
On 32 bit systems, these two deprecated functions are also replaced:
@@ -324,6 +325,10 @@
**THREAD\_ID**: memalign pointer alignment size
+pointer = aligned\_alloc(alignment, size)
+
+**THREAD\_ID**: memalign pointer alignment size
+
posix\_memalign(&pointer, alignment, size)
**THREAD\_ID**: memalign pointer alignment size
diff --git a/libc/malloc_debug/README_marshmallow_and_earlier.md b/libc/malloc_debug/README_marshmallow_and_earlier.md
index 3513711..c8be656 100644
--- a/libc/malloc_debug/README_marshmallow_and_earlier.md
+++ b/libc/malloc_debug/README_marshmallow_and_earlier.md
@@ -4,10 +4,10 @@
Malloc debug is a method of debugging native memory problems. It can help
detect memory corruption, memory leaks, and use after free issues.
-This documentation describes how to enable this feature on versions of
-the Android OS, Marshmallow or older. Note: malloc debug was full of bugs
-and was not fully functional until KitKat, so using it on a version older
-than that is not guaranteed to work at all.
+This documentation describes how to enable this feature on API level
+23 or older. Note: malloc debug was full of bugs and was not fully
+functional until API level 19, so using it on a version older than that
+is not guaranteed to work at all.
The documentation for malloc debug on newer versions of Android is
[here](README.md).
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 5a68deb..8e9c671 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -86,7 +86,7 @@
old_pointer_, size_);
}
-// posix_memalign, memalgin, pvalloc, valloc all recorded with this class.
+// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
MemalignEntry::MemalignEntry(void* pointer, size_t size, size_t alignment)
: MallocEntry(pointer, size), alignment_(alignment) {
}
@@ -179,13 +179,10 @@
}
bool RecordData::Initialize(const Config& config) {
- struct sigaction dump_act;
- memset(&dump_act, 0, sizeof(dump_act));
-
+ struct sigaction64 dump_act = {};
dump_act.sa_sigaction = RecordDump;
dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&dump_act.sa_mask);
- if (sigaction(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
+ if (sigaction64(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
error_log("Unable to set up record dump signal function: %s", strerror(errno));
return false;
}
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index ccabac2..021a299 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_RECORDDATA_H
-#define DEBUG_MALLOC_RECORDDATA_H
+#pragma once
#include <stdint.h>
#include <pthread.h>
@@ -129,7 +128,7 @@
DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
};
-// posix_memalign, memalign, pvalloc, valloc all recorded with this class.
+// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
class MemalignEntry : public MallocEntry {
public:
MemalignEntry(void* pointer, size_t size, size_t alignment);
@@ -173,5 +172,3 @@
DISALLOW_COPY_AND_ASSIGN(RecordData);
};
-
-#endif // DEBUG_MALLOC_RECORDDATA_H
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index 9a649b9..7201c49 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef DEBUG_MALLOC_TRACKDATA_H
-#define DEBUG_MALLOC_TRACKDATA_H
+#pragma once
#include <stdint.h>
#include <pthread.h>
@@ -75,5 +74,3 @@
DISALLOW_COPY_AND_ASSIGN(TrackData);
};
-
-#endif // DEBUG_MALLOC_TRACKDATA_H
diff --git a/libc/malloc_debug/backtrace.h b/libc/malloc_debug/backtrace.h
index f570873..92ea237 100644
--- a/libc/malloc_debug/backtrace.h
+++ b/libc/malloc_debug/backtrace.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef MALLOC_DEBUG_BACKTRACE_H
-#define MALLOC_DEBUG_BACKTRACE_H
+#pragma once
#include <stdint.h>
#include <sys/cdefs.h>
@@ -39,5 +38,3 @@
size_t backtrace_get(uintptr_t* frames, size_t frame_count);
void backtrace_log(const uintptr_t* frames, size_t frame_count);
std::string backtrace_string(const uintptr_t* frames, size_t frame_count);
-
-#endif // MALLOC_DEBUG_BACKTRACE_H
diff --git a/libc/malloc_debug/debug_disable.h b/libc/malloc_debug/debug_disable.h
index 9edb4df..0049595 100644
--- a/libc/malloc_debug/debug_disable.h
+++ b/libc/malloc_debug/debug_disable.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef MALLOC_DEBUG_DISABLE_H
-#define MALLOC_DEBUG_DISABLE_H
+#pragma once
#include <sys/cdefs.h>
@@ -60,5 +59,3 @@
DISALLOW_COPY_AND_ASSIGN(ScopedDisableDebugCalls);
};
-
-#endif // MALLOC_DEBUG_DISABLE_H
diff --git a/libc/malloc_debug/debug_log.h b/libc/malloc_debug/debug_log.h
index ed4b541..54dd221 100644
--- a/libc/malloc_debug/debug_log.h
+++ b/libc/malloc_debug/debug_log.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef MALLOC_DEBUG_LOG_H
-#define MALLOC_DEBUG_LOG_H
+#pragma once
#include <async_safe/log.h>
@@ -42,5 +41,3 @@
async_safe_write_log(ANDROID_LOG_ERROR, "malloc_debug", (str))
#define info_log(format, ...) \
async_safe_format_log(ANDROID_LOG_INFO, "malloc_debug", (format), ##__VA_ARGS__ )
-
-#endif // MALLOC_DEBUG_LOG_H
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
index e92a7cf..78a6990 100644
--- a/libc/malloc_debug/exported32.map
+++ b/libc/malloc_debug/exported32.map
@@ -1,5 +1,6 @@
LIBC_MALLOC_DEBUG {
global:
+ debug_aligned_alloc;
debug_calloc;
debug_dump_heap;
debug_finalize;
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
index 94104b0..2bfc38b 100644
--- a/libc/malloc_debug/exported64.map
+++ b/libc/malloc_debug/exported64.map
@@ -1,5 +1,6 @@
LIBC_MALLOC_DEBUG {
global:
+ debug_aligned_alloc;
debug_calloc;
debug_dump_heap;
debug_finalize;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index a2ada2f..ecfbd71 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -77,6 +77,7 @@
size_t debug_malloc_usable_size(void* pointer);
void* debug_malloc(size_t size);
void debug_free(void* pointer);
+void* debug_aligned_alloc(size_t alignment, size_t size);
void* debug_memalign(size_t alignment, size_t bytes);
void* debug_realloc(void* pointer, size_t bytes);
void* debug_calloc(size_t nmemb, size_t bytes);
@@ -669,6 +670,17 @@
return g_dispatch->mallopt(param, value);
}
+void* debug_aligned_alloc(size_t alignment, size_t size) {
+ if (DebugCallsDisabled()) {
+ return g_dispatch->aligned_alloc(alignment, size);
+ }
+ if (!powerof2(alignment)) {
+ errno = EINVAL;
+ return nullptr;
+ }
+ return debug_memalign(alignment, size);
+}
+
int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
if (DebugCallsDisabled()) {
return g_dispatch->posix_memalign(memptr, alignment, size);
diff --git a/libc/malloc_debug/malloc_debug.h b/libc/malloc_debug/malloc_debug.h
index 4a1e8da..18a6c2c 100644
--- a/libc/malloc_debug/malloc_debug.h
+++ b/libc/malloc_debug/malloc_debug.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef MALLOC_DEBUG_H
-#define MALLOC_DEBUG_H
+#pragma once
#include <stdint.h>
@@ -70,5 +69,3 @@
constexpr size_t FREE_TRACK_MEM_BUFFER_SIZE = 4096;
extern const MallocDispatch* g_dispatch;
-
-#endif // MALLOC_DEBUG_H
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 4e90668..0e4a7d8 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -54,6 +54,7 @@
void* debug_realloc(void*, size_t);
int debug_posix_memalign(void**, size_t, size_t);
void* debug_memalign(size_t, size_t);
+void* debug_aligned_alloc(size_t, size_t);
size_t debug_malloc_usable_size(void*);
void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
void debug_free_malloc_leak_info(uint8_t*);
@@ -136,6 +137,7 @@
nullptr,
nullptr,
mallopt,
+ aligned_alloc,
};
void VerifyAllocCalls(bool backtrace_enabled) {
@@ -308,6 +310,11 @@
ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
debug_free(pointer);
+ pointer = debug_aligned_alloc(128, 15);
+ ASSERT_TRUE(pointer != nullptr);
+ ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
+ debug_free(pointer);
+
pointer = debug_realloc(nullptr, 30);
ASSERT_TRUE(pointer != nullptr);
ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
@@ -1772,6 +1779,12 @@
debug_free(pointer);
expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
+ pointer = debug_aligned_alloc(32, 50);
+ ASSERT_TRUE(pointer != nullptr);
+ expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
+ debug_free(pointer);
+ expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
+
ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 50));
ASSERT_TRUE(pointer != nullptr);
expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
diff --git a/libc/malloc_hooks/Android.bp b/libc/malloc_hooks/Android.bp
new file mode 100644
index 0000000..d4b5a2a
--- /dev/null
+++ b/libc/malloc_hooks/Android.bp
@@ -0,0 +1,66 @@
+// ==============================================================
+// libc_malloc_hooks.so
+// ==============================================================
+cc_library {
+ name: "libc_malloc_hooks",
+
+ srcs: [
+ "malloc_hooks.cpp",
+ ],
+
+ static_libs: [
+ "libasync_safe",
+ ],
+
+ multilib: {
+ lib32: {
+ version_script: "exported32.map",
+ },
+ lib64: {
+ version_script: "exported64.map",
+ },
+ },
+ include_dirs: ["bionic/libc"],
+
+ sanitize: {
+ never: true,
+ },
+ native_coverage: false,
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-fno-stack-protector",
+ ],
+}
+
+// ==============================================================
+// Unit Tests
+// ==============================================================
+cc_test {
+ name: "malloc_hooks_unit_tests",
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+
+ srcs: [
+ "tests/malloc_hooks_tests.cpp",
+ ],
+
+ whole_static_libs: ["libc_malloc_hooks"],
+
+ shared_libs: ["libbase"],
+
+ local_include_dirs: ["tests"],
+ include_dirs: ["bionic/libc", "bionic"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
diff --git a/libc/malloc_hooks/README.md b/libc/malloc_hooks/README.md
new file mode 100644
index 0000000..85b2769
--- /dev/null
+++ b/libc/malloc_hooks/README.md
@@ -0,0 +1,118 @@
+Malloc Hooks
+============
+
+Malloc hooks allows a program to intercept all allocation/free calls that
+happen during execution. It is only available in Android P and newer versions
+of the OS.
+
+There are two ways to enable these hooks, set a special system
+property, or set a special environment variable and run your app/program.
+
+When malloc hooks is enabled, it works by adding a shim layer that replaces
+the normal allocation calls. The replaced calls are:
+
+* `malloc`
+* `free`
+* `calloc`
+* `realloc`
+* `posix_memalign`
+* `memalign`
+* `aligned_alloc`
+* `malloc_usable_size`
+
+On 32 bit systems, these two deprecated functions are also replaced:
+
+* `pvalloc`
+* `valloc`
+
+These four hooks are defined in malloc.h:
+
+ void* (*volatile __malloc_hook)(size_t, const void*);
+ void* (*volatile __realloc_hook)(void*, size_t, const void*);
+ void (*volatile __free_hook)(void*, const void*);
+ void* (*volatile __memalign_hook)(size_t, size_t, const void*);
+
+When malloc is called and \_\_malloc\_hook has been set, then the hook
+function is called instead.
+
+When realloc is called and \_\_realloc\_hook has been set, then the hook
+function is called instead.
+
+When free is called and \_\_free\_hook has been set, then the hook
+function is called instead.
+
+When memalign is called and \_\_memalign\_hook has been set, then the hook
+function is called instead.
+
+For posix\_memalign, if \_\_memalign\_hook has been set, then the hook is
+called, but only if alignment is a power of 2.
+
+For aligned\_alloc, if \_\_memalign\_hook has been set, then the hook is
+called, but only if alignment is a power of 2.
+
+For calloc, if \_\_malloc\_hook has been set, then the hook function is
+called, then the allocated memory is set to zero.
+
+For the two deprecated functions pvalloc and valloc, if \_\_memalign\_hook
+has been set, then the hook is called with an appropriate alignment value.
+
+There is no hook for malloc\_usable\_size as of now.
+
+These hooks can be set at any time, but there is no thread safety, so
+the caller must guarantee that it does not depend on allocations/frees
+occurring at the same time.
+
+Implementation Details
+======================
+When malloc hooks is enabled, then the hook pointers are set to
+the current default allocation functions. It is expected that if an
+app does intercept the allocation/free calls, it will eventually call
+the original hook function to do allocations. If the app does not do this,
+it runs the risk of crashing whenever a malloc\_usable\_size call is made.
+
+Example Implementation
+======================
+Below is a simple implementation intercepting only malloc/calloc calls.
+
+ void* new_malloc_hook(size_t bytes, const char* arg) {
+ return orig_malloc_hook(bytes, arg);
+ }
+
+ void orig_malloc_hook = __malloc_hook;
+ __malloc_hook = new_malloc_hook;
+
+Enabling Examples
+=================
+
+### For platform developers
+
+Enable the hooks for all processes:
+
+ adb shell stop
+ adb shell setprop libc.debug.malloc.hooks 1
+ adb shell start
+
+Enable malloc debug using an environment variable:
+
+ adb shell
+ # export LIBC_HOOK_ENABLE=1
+ # ls
+
+Any process spawned from this shell will run with malloc hooks enabled.
+
+### For app developers
+
+Enable malloc hooks for a specific program/application:
+
+ adb shell setprop wrap.<APP> '"LIBC_HOOKS_ENABLE=1"'
+
+For example, to enable malloc hooks for the google search box:
+
+ adb shell setprop wrap.com.google.android.googlequicksearchbox '"LIBC_HOOKS_ENABLE=1 logwrapper"'
+ adb shell am force-stop com.google.android.googlequicksearchbox
+
+NOTE: On pre-O versions of the Android OS, property names had a length limit
+of 32. This meant that to create a wrap property with the name of the app, it
+was necessary to truncate the name to fit. On O, property names can be
+an order of magnitude larger, so there should be no need to truncate the name
+at all.
diff --git a/libc/malloc_hooks/exported32.map b/libc/malloc_hooks/exported32.map
new file mode 100644
index 0000000..2cf5b8c
--- /dev/null
+++ b/libc/malloc_hooks/exported32.map
@@ -0,0 +1,26 @@
+LIBC_MALLOC_HOOKS {
+ global:
+ hooks_aligned_alloc;
+ hooks_calloc;
+ hooks_finalize;
+ hooks_free;
+ hooks_free_malloc_leak_info;
+ hooks_get_malloc_leak_info;
+ hooks_initialize;
+ hooks_iterate;
+ hooks_mallinfo;
+ hooks_malloc;
+ hooks_malloc_backtrace;
+ hooks_malloc_disable;
+ hooks_malloc_enable;
+ hooks_malloc_usable_size;
+ hooks_mallopt;
+ hooks_memalign;
+ hooks_posix_memalign;
+ hooks_pvalloc;
+ hooks_realloc;
+ hooks_valloc;
+
+ local:
+ *;
+};
diff --git a/libc/malloc_hooks/exported64.map b/libc/malloc_hooks/exported64.map
new file mode 100644
index 0000000..5ebcf9f
--- /dev/null
+++ b/libc/malloc_hooks/exported64.map
@@ -0,0 +1,24 @@
+LIBC_MALLOC_HOOKS {
+ global:
+ hooks_aligned_alloc;
+ hooks_calloc;
+ hooks_finalize;
+ hooks_free;
+ hooks_free_malloc_leak_info;
+ hooks_get_malloc_leak_info;
+ hooks_initialize;
+ hooks_iterate;
+ hooks_mallinfo;
+ hooks_malloc;
+ hooks_malloc_backtrace;
+ hooks_malloc_disable;
+ hooks_malloc_enable;
+ hooks_malloc_usable_size;
+ hooks_mallopt;
+ hooks_memalign;
+ hooks_posix_memalign;
+ hooks_realloc;
+
+ local:
+ *;
+};
diff --git a/libc/malloc_hooks/malloc_hooks.cpp b/libc/malloc_hooks/malloc_hooks.cpp
new file mode 100644
index 0000000..662520c
--- /dev/null
+++ b/libc/malloc_hooks/malloc_hooks.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+#include <private/bionic_malloc_dispatch.h>
+
+// ------------------------------------------------------------------------
+// Global Data
+// ------------------------------------------------------------------------
+const MallocDispatch* g_dispatch;
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+// Use C style prototypes for all exported functions. This makes it easy
+// to do dlsym lookups during libc initialization when hooks are enabled.
+// ------------------------------------------------------------------------
+__BEGIN_DECLS
+
+bool hooks_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child,
+ const char* options);
+void hooks_finalize();
+void hooks_get_malloc_leak_info(
+ uint8_t** info, size_t* overall_size, size_t* info_size, size_t* total_memory,
+ size_t* backtrace_size);
+ssize_t hooks_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count);
+void hooks_free_malloc_leak_info(uint8_t* info);
+size_t hooks_malloc_usable_size(void* pointer);
+void* hooks_malloc(size_t size);
+void hooks_free(void* pointer);
+void* hooks_memalign(size_t alignment, size_t bytes);
+void* hooks_aligned_alloc(size_t alignment, size_t bytes);
+void* hooks_realloc(void* pointer, size_t bytes);
+void* hooks_calloc(size_t nmemb, size_t bytes);
+struct mallinfo hooks_mallinfo();
+int hooks_mallopt(int param, int value);
+int hooks_posix_memalign(void** memptr, size_t alignment, size_t size);
+int hooks_iterate(uintptr_t base, size_t size,
+ void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
+void hooks_malloc_disable();
+void hooks_malloc_enable();
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* hooks_pvalloc(size_t bytes);
+void* hooks_valloc(size_t size);
+#endif
+
+static void* default_malloc_hook(size_t bytes, const void*) {
+ return g_dispatch->malloc(bytes);
+}
+
+static void* default_realloc_hook(void* pointer, size_t bytes, const void*) {
+ return g_dispatch->realloc(pointer, bytes);
+}
+
+static void default_free_hook(void* pointer, const void*) {
+ g_dispatch->free(pointer);
+}
+
+static void* default_memalign_hook(size_t alignment, size_t bytes, const void*) {
+ return g_dispatch->memalign(alignment, bytes);
+}
+
+__END_DECLS
+// ------------------------------------------------------------------------
+
+bool hooks_initialize(const MallocDispatch* malloc_dispatch, int*, const char*) {
+ g_dispatch = malloc_dispatch;
+ __malloc_hook = default_malloc_hook;
+ __realloc_hook = default_realloc_hook;
+ __free_hook = default_free_hook;
+ __memalign_hook = default_memalign_hook;
+ return true;
+}
+
+void hooks_finalize() {
+}
+
+void hooks_get_malloc_leak_info(uint8_t** info, size_t* overall_size,
+ size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+ *info = nullptr;
+ *overall_size = 0;
+ *info_size = 0;
+ *total_memory = 0;
+ *backtrace_size = 0;
+}
+
+void hooks_free_malloc_leak_info(uint8_t*) {
+}
+
+size_t hooks_malloc_usable_size(void* pointer) {
+ return g_dispatch->malloc_usable_size(pointer);
+}
+
+void* hooks_malloc(size_t size) {
+ if (__malloc_hook != nullptr && __malloc_hook != default_malloc_hook) {
+ return __malloc_hook(size, __builtin_return_address(0));
+ }
+ return g_dispatch->malloc(size);
+}
+
+void hooks_free(void* pointer) {
+ if (__free_hook != nullptr && __free_hook != default_free_hook) {
+ return __free_hook(pointer, __builtin_return_address(0));
+ }
+ return g_dispatch->free(pointer);
+}
+
+void* hooks_memalign(size_t alignment, size_t bytes) {
+ if (__memalign_hook != nullptr && __memalign_hook != default_memalign_hook) {
+ return __memalign_hook(alignment, bytes, __builtin_return_address(0));
+ }
+ return g_dispatch->memalign(alignment, bytes);
+}
+
+void* hooks_realloc(void* pointer, size_t bytes) {
+ if (__realloc_hook != nullptr && __realloc_hook != default_realloc_hook) {
+ return __realloc_hook(pointer, bytes, __builtin_return_address(0));
+ }
+ return g_dispatch->realloc(pointer, bytes);
+}
+
+void* hooks_calloc(size_t nmemb, size_t bytes) {
+ if (__malloc_hook != nullptr && __malloc_hook != default_malloc_hook) {
+ size_t size;
+ if (__builtin_mul_overflow(nmemb, bytes, &size)) {
+ return nullptr;
+ }
+ void* ptr = __malloc_hook(size, __builtin_return_address(0));
+ if (ptr != nullptr) {
+ memset(ptr, 0, size);
+ }
+ return ptr;
+ }
+ return g_dispatch->calloc(nmemb, bytes);
+}
+
+struct mallinfo hooks_mallinfo() {
+ return g_dispatch->mallinfo();
+}
+
+int hooks_mallopt(int param, int value) {
+ return g_dispatch->mallopt(param, value);
+}
+
+void* hooks_aligned_alloc(size_t alignment, size_t size) {
+ if (__memalign_hook != nullptr && __memalign_hook != default_memalign_hook) {
+ if (!powerof2(alignment)) {
+ errno = EINVAL;
+ return nullptr;
+ }
+ void* ptr = __memalign_hook(alignment, size, __builtin_return_address(0));
+ if (ptr == nullptr) {
+ errno = ENOMEM;
+ }
+ return ptr;
+ }
+ return g_dispatch->aligned_alloc(alignment, size);
+}
+
+int hooks_posix_memalign(void** memptr, size_t alignment, size_t size) {
+ if (__memalign_hook != nullptr && __memalign_hook != default_memalign_hook) {
+ if (!powerof2(alignment)) {
+ return EINVAL;
+ }
+ *memptr = __memalign_hook(alignment, size, __builtin_return_address(0));
+ if (*memptr == nullptr) {
+ return ENOMEM;
+ }
+ return 0;
+ }
+ return g_dispatch->posix_memalign(memptr, alignment, size);
+}
+
+int hooks_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*) {
+ return 0;
+}
+
+void hooks_malloc_disable() {
+}
+
+void hooks_malloc_enable() {
+}
+
+ssize_t hooks_malloc_backtrace(void*, uintptr_t*, size_t) {
+ return 0;
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* hooks_pvalloc(size_t bytes) {
+ size_t pagesize = getpagesize();
+ size_t size = __BIONIC_ALIGN(bytes, pagesize);
+ if (size < bytes) {
+ // Overflow
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return hooks_memalign(pagesize, size);
+}
+
+void* hooks_valloc(size_t size) {
+ return hooks_memalign(getpagesize(), size);
+}
+#endif
diff --git a/libc/malloc_hooks/tests/malloc_hooks_tests.cpp b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
new file mode 100644
index 0000000..0d23a6a
--- /dev/null
+++ b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include <private/bionic_malloc_dispatch.h>
+#include <tests/utils.h>
+
+__BEGIN_DECLS
+
+void get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
+void free_malloc_leak_info(uint8_t*);
+int malloc_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+void malloc_enable();
+void malloc_disable();
+ssize_t malloc_backtrace(void*, uintptr_t*, size_t);
+
+__END_DECLS
+
+class MallocHooksTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ ASSERT_EQ(0, setenv("LIBC_HOOKS_ENABLE", "1", true));
+ initialized_ = false;
+ }
+
+ void TearDown() override {
+ if (initialized_) {
+ Reset();
+ }
+ ASSERT_EQ(0, unsetenv("LIBC_HOOKS_ENABLE"));
+ }
+
+ void Init() {
+ initialized_ = true;
+ malloc_hook_called_ = false;
+ free_hook_called_ = false;
+ realloc_hook_called_ = false;
+ memalign_hook_called_ = false;
+
+ void_arg_ = nullptr;
+
+ orig_malloc_hook_ = __malloc_hook;
+ orig_free_hook_ = __free_hook;
+ orig_realloc_hook_ = __realloc_hook;
+ orig_memalign_hook_ = __memalign_hook;
+ }
+
+ void Reset() {
+ __malloc_hook = orig_malloc_hook_;
+ __free_hook = orig_free_hook_;
+ __realloc_hook = orig_realloc_hook_;
+ __memalign_hook = orig_memalign_hook_;
+ }
+
+ void Exec(std::vector<const char*> args);
+ void RunTest(std::string test_name);
+
+ public:
+ bool initialized_;
+
+ int fd_;
+ std::string raw_output_;
+ pid_t pid_;
+
+ static bool malloc_hook_called_;
+ static bool free_hook_called_;
+ static bool realloc_hook_called_;
+ static bool memalign_hook_called_;
+ static const void* void_arg_;
+
+ static void* (*orig_malloc_hook_)(size_t, const void*);
+ static void (*orig_free_hook_)(void*, const void*);
+ static void* (*orig_realloc_hook_)(void*, size_t, const void*);
+ static void* (*orig_memalign_hook_)(size_t, size_t, const void*);
+
+ static void* test_malloc_hook(size_t, const void*);
+ static void* test_realloc_hook(void* ptr, size_t, const void*);
+ static void* test_memalign_hook(size_t, size_t, const void*);
+ static void test_free_hook(void*, const void*);
+};
+
+bool MallocHooksTest::malloc_hook_called_;
+bool MallocHooksTest::free_hook_called_;
+bool MallocHooksTest::realloc_hook_called_;
+bool MallocHooksTest::memalign_hook_called_;
+const void* MallocHooksTest::void_arg_;
+
+void* (*MallocHooksTest::orig_malloc_hook_)(size_t, const void*);
+void (*MallocHooksTest::orig_free_hook_)(void*, const void*);
+void* (*MallocHooksTest::orig_realloc_hook_)(void*, size_t, const void*);
+void* (*MallocHooksTest::orig_memalign_hook_)(size_t, size_t, const void*);
+
+static void GetExe(std::string* exe_name) {
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+ ASSERT_TRUE(path_len >= 0);
+ *exe_name = std::string(path, path_len);
+}
+
+void MallocHooksTest::RunTest(std::string test_name) {
+ std::vector<const char*> args;
+ args.push_back("--gtest_also_run_disabled_tests");
+ std::string filter_arg("--gtest_filter=" + test_name);
+ args.push_back(filter_arg.c_str());
+
+ ExecTestHelper test;
+ test.Run(
+ [&]() {
+ std::string exe_name;
+ GetExe(&exe_name);
+ args.insert(args.begin(), exe_name.c_str());
+ args.push_back(nullptr);
+ execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
+ exit(1);
+ },
+ 0, nullptr);
+}
+
+void* MallocHooksTest::test_malloc_hook(size_t size, const void* arg) {
+ malloc_hook_called_ = true;
+ void_arg_ = arg;
+ return orig_malloc_hook_(size, arg);
+}
+
+void* MallocHooksTest::test_realloc_hook(void* ptr, size_t size, const void* arg) {
+ realloc_hook_called_ = true;
+ void_arg_ = arg;
+ return orig_realloc_hook_(ptr, size, arg);
+}
+
+void* MallocHooksTest::test_memalign_hook(size_t alignment, size_t size, const void* arg) {
+ memalign_hook_called_ = true;
+ void_arg_ = arg;
+ return orig_memalign_hook_(alignment, size, arg);
+}
+
+void MallocHooksTest::test_free_hook(void* ptr, const void* arg) {
+ free_hook_called_ = true;
+ void_arg_ = arg;
+ return orig_free_hook_(ptr, arg);
+}
+
+TEST_F(MallocHooksTest, other_malloc_functions) {
+ RunTest("*.DISABLED_other_malloc_functions");
+}
+
+// Call other intercepted functions to make sure there are no crashes.
+TEST_F(MallocHooksTest, DISABLED_other_malloc_functions) {
+ struct mallinfo info = mallinfo();
+ EXPECT_NE(0U, info.uordblks);
+
+ EXPECT_EQ(0, mallopt(-1000, -1000));
+
+ void* ptr = malloc(1024);
+ EXPECT_LE(1024U, malloc_usable_size(ptr));
+ free(ptr);
+}
+
+TEST_F(MallocHooksTest, extended_functions) {
+ RunTest("*.DISABLED_extended_functions");
+}
+
+TEST_F(MallocHooksTest, DISABLED_extended_functions) {
+ uint8_t* info = nullptr;
+ size_t overall_size = 100;
+ size_t info_size = 200;
+ size_t total_memory = 300;
+ size_t backtrace_size = 400;
+ get_malloc_leak_info(&info, &overall_size, &info_size, &total_memory, &backtrace_size);
+ EXPECT_EQ(nullptr, info);
+ EXPECT_EQ(0U, overall_size);
+ EXPECT_EQ(0U, info_size);
+ EXPECT_EQ(0U, total_memory);
+ EXPECT_EQ(0U, backtrace_size);
+
+ free_malloc_leak_info(info);
+
+ malloc_enable();
+ malloc_disable();
+
+ EXPECT_EQ(0, malloc_iterate(0, 0, nullptr, nullptr));
+
+ // Malloc hooks doesn't support any backtracing.
+ EXPECT_EQ(0, malloc_backtrace(nullptr, nullptr, 10));
+}
+
+TEST_F(MallocHooksTest, malloc_hook) {
+ RunTest("*.DISABLED_malloc_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_malloc_hook) {
+ Init();
+ ASSERT_TRUE(__malloc_hook != nullptr);
+ __malloc_hook = test_malloc_hook;
+
+ void* ptr = malloc(1024);
+ ASSERT_TRUE(ptr != nullptr);
+ write(0, ptr, 0);
+ free(ptr);
+
+ EXPECT_TRUE(malloc_hook_called_) << "The malloc hook was not called.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The malloc hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, free_hook) {
+ RunTest("*.DISABLED_free_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_free_hook) {
+ Init();
+ ASSERT_TRUE(__free_hook != nullptr);
+ __free_hook = test_free_hook;
+
+ void* ptr = malloc(1024);
+ ASSERT_TRUE(ptr != nullptr);
+ free(ptr);
+ write(0, ptr, 0);
+
+ EXPECT_TRUE(free_hook_called_) << "The free hook was not called.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The free hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, realloc_hook) {
+ RunTest("*.DISABLED_realloc_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_realloc_hook) {
+ Init();
+ ASSERT_TRUE(__realloc_hook != nullptr);
+ __realloc_hook = test_realloc_hook;
+
+ void* ptr = malloc(1024);
+ ASSERT_TRUE(ptr != nullptr);
+ ptr = realloc(ptr, 2048);
+ free(ptr);
+ write(0, ptr, 0);
+
+ EXPECT_TRUE(realloc_hook_called_) << "The realloc hook was not called.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The realloc hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, memalign_hook) {
+ RunTest("*.DISABLED_memalign_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_memalign_hook) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr = memalign(32, 1024);
+ ASSERT_TRUE(ptr != nullptr);
+ free(ptr);
+ write(0, ptr, 0);
+
+ EXPECT_TRUE(memalign_hook_called_) << "The memalign hook was not called.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The memalign hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, posix_memalign_hook) {
+ RunTest("*.DISABLED_posix_memalign_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_posix_memalign_hook) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr;
+ ASSERT_EQ(0, posix_memalign(&ptr, 32, 1024));
+ ASSERT_TRUE(ptr != nullptr);
+ free(ptr);
+ write(0, ptr, 0);
+
+ EXPECT_TRUE(memalign_hook_called_) << "The memalign hook was not called when running posix_memalign.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The memalign hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, posix_memalign_hook_error) {
+ RunTest("*.DISABLED_posix_memalign_hook_error");
+}
+
+TEST_F(MallocHooksTest, DISABLED_posix_memalign_hook_error) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr;
+ ASSERT_EQ(EINVAL, posix_memalign(&ptr, 11, 1024));
+ write(0, ptr, 0);
+
+ EXPECT_FALSE(memalign_hook_called_)
+ << "The memalign hook was called when running posix_memalign with an error.";
+ EXPECT_FALSE(void_arg_ != nullptr)
+ << "The memalign hook was called with a nullptr with an error.";
+}
+
+TEST_F(MallocHooksTest, aligned_alloc_hook) {
+ RunTest("*.DISABLED_aligned_alloc_hook");
+}
+
+TEST_F(MallocHooksTest, DISABLED_aligned_alloc_hook) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr = aligned_alloc(32, 1024);
+ ASSERT_TRUE(ptr != nullptr);
+ free(ptr);
+ write(0, ptr, 0);
+
+ EXPECT_TRUE(memalign_hook_called_) << "The memalign hook was not called when running aligned_alloc.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The memalign hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, aligned_alloc_hook_error) {
+ RunTest("*.DISABLED_aligned_alloc_hook_error");
+}
+
+TEST_F(MallocHooksTest, DISABLED_aligned_alloc_hook_error) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr = aligned_alloc(11, 1024);
+ ASSERT_TRUE(ptr == nullptr);
+ EXPECT_EQ(EINVAL, errno);
+ write(0, ptr, 0);
+
+ EXPECT_FALSE(memalign_hook_called_)
+ << "The memalign hook was called when running aligned_alloc with an error.";
+ EXPECT_FALSE(void_arg_ != nullptr)
+ << "The memalign hook was called with a nullptr with an error.";
+}
+
+#if !defined(__LP64__)
+TEST_F(MallocHooksTest, pvalloc_hook) {
+ RunTest("*.DISABLED_pvalloc_hook");
+}
+
+extern "C" void* pvalloc(size_t);
+
+TEST_F(MallocHooksTest, DISABLED_pvalloc_hook) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr = pvalloc(1024);
+ ASSERT_TRUE(ptr != nullptr);
+ write(0, ptr, 0);
+ free(ptr);
+
+ EXPECT_TRUE(memalign_hook_called_) << "The memalign hook was not called for pvalloc.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The memalign hook was called with a nullptr.";
+}
+
+TEST_F(MallocHooksTest, valloc_hook) {
+ RunTest("*.DISABLED_valloc_hook");
+}
+
+extern "C" void* valloc(size_t);
+
+TEST_F(MallocHooksTest, DISABLED_valloc_hook) {
+ Init();
+ ASSERT_TRUE(__memalign_hook != nullptr);
+ __memalign_hook = test_memalign_hook;
+
+ void* ptr = valloc(1024);
+ ASSERT_TRUE(ptr != nullptr);
+ write(0, ptr, 0);
+ free(ptr);
+
+ EXPECT_TRUE(memalign_hook_called_) << "The memalign hook was not called for valloc.";
+ EXPECT_TRUE(void_arg_ != nullptr) << "The memalign hook was called with a nullptr.";
+}
+#endif
diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h
index 7582068..d1cf629 100644
--- a/libc/private/ScopedSignalBlocker.h
+++ b/libc/private/ScopedSignalBlocker.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef SCOPED_SIGNAL_BLOCKER_H
-#define SCOPED_SIGNAL_BLOCKER_H
+#pragma once
#include <signal.h>
@@ -23,10 +22,18 @@
class ScopedSignalBlocker {
public:
+ // Block all signals.
explicit ScopedSignalBlocker() {
sigset64_t set;
sigfillset64(&set);
- sigprocmask64(SIG_SETMASK, &set, &old_set_);
+ sigprocmask64(SIG_BLOCK, &set, &old_set_);
+ }
+
+ // Block just the specified signal.
+ explicit ScopedSignalBlocker(int signal) {
+ sigset64_t set = {};
+ sigaddset64(&set, signal);
+ sigprocmask64(SIG_BLOCK, &set, &old_set_);
}
~ScopedSignalBlocker() {
@@ -37,10 +44,7 @@
sigprocmask64(SIG_SETMASK, &old_set_, nullptr);
}
- private:
sigset64_t old_set_;
DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
};
-
-#endif
diff --git a/libc/private/ScopedSignalHandler.h b/libc/private/ScopedSignalHandler.h
new file mode 100644
index 0000000..dd5823f
--- /dev/null
+++ b/libc/private/ScopedSignalHandler.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <signal.h>
+
+class ScopedSignalHandler {
+ public:
+ ScopedSignalHandler(int signal_number, void (*handler)(int), int sa_flags = 0)
+ : signal_number_(signal_number) {
+ action_ = { .sa_flags = sa_flags, .sa_handler = handler };
+ sigaction64(signal_number_, &action_, &old_action_);
+ }
+
+ ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*),
+ int sa_flags = SA_SIGINFO)
+ : signal_number_(signal_number) {
+ action_ = { .sa_flags = sa_flags, .sa_sigaction = action };
+ sigaction64(signal_number_, &action_, &old_action_);
+ }
+
+ ScopedSignalHandler(int signal_number) : signal_number_(signal_number) {
+ sigaction64(signal_number, nullptr, &old_action_);
+ }
+
+ ~ScopedSignalHandler() {
+ sigaction64(signal_number_, &old_action_, nullptr);
+ }
+
+ struct sigaction64 action_;
+ struct sigaction64 old_action_;
+ const int signal_number_;
+};
diff --git a/libc/private/bionic_arc4random.h b/libc/private/bionic_arc4random.h
index b51f818..0e9376e 100644
--- a/libc/private/bionic_arc4random.h
+++ b/libc/private/bionic_arc4random.h
@@ -33,18 +33,11 @@
#include "private/KernelArgumentBlock.h"
-/*
- * arc4random aborts if it's unable to fetch entropy, which is always the case
- * for init on devices without getrandom(2), since /dev/random hasn't been
- * created yet. Provide a wrapper function that falls back to AT_RANDOM if
- * we don't have getrandom and /dev/urandom is missing.
- */
+// arc4random(3) aborts if it's unable to fetch entropy, which is always
+// the case for init on devices. GCE kernels have a workaround to ensure
+// sufficient entropy during early boot, but no device kernels do. This
+// wrapper falls back to AT_RANDOM if the kernel doesn't have enough
+// entropy for getrandom(2) or /dev/urandom.
void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args);
-/*
- * Return true if libc has an unlimited entropy source (something other than
- * AT_RANDOM), and arc4random* calls will always succeed.
- */
-bool __libc_arc4random_has_unlimited_entropy();
-
#endif
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index b389247..54168d3 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -76,4 +76,19 @@
}
};
+class LockGuard {
+ public:
+ LockGuard(Lock& lock) : lock_(lock) {
+ lock_.lock();
+ }
+ ~LockGuard() {
+ lock_.unlock();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(LockGuard);
+
+ private:
+ Lock& lock_;
+};
+
#endif // _BIONIC_LOCK_H
diff --git a/libc/private/bionic_malloc_dispatch.h b/libc/private/bionic_malloc_dispatch.h
index cdae466..0dce03d 100644
--- a/libc/private/bionic_malloc_dispatch.h
+++ b/libc/private/bionic_malloc_dispatch.h
@@ -46,6 +46,7 @@
typedef void (*MallocMallocDisable)();
typedef void (*MallocMallocEnable)();
typedef int (*MallocMallopt)(int, int);
+typedef void* (*MallocAlignedAlloc)(size_t, size_t);
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
typedef void* (*MallocPvalloc)(size_t);
@@ -71,6 +72,7 @@
MallocMallocDisable malloc_disable;
MallocMallocEnable malloc_enable;
MallocMallopt mallopt;
+ MallocAlignedAlloc aligned_alloc;
} __attribute__((aligned(32)));
#endif
diff --git a/linker/arch/x86/begin.c b/libc/private/sigrtmin.h
similarity index 66%
copy from linker/arch/x86/begin.c
copy to libc/private/sigrtmin.h
index 331b79e..ea8673d 100644
--- a/linker/arch/x86/begin.c
+++ b/libc/private/sigrtmin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,28 +26,25 @@
* SUCH DAMAGE.
*/
-#include <stdint.h>
+#pragma once
+
#include <sys/cdefs.h>
-extern unsigned __linker_init(void* raw_args);
+#include <signal.h>
-__LIBC_HIDDEN__ void _start() {
- // Force unwinds to end in this function.
- asm volatile(".cfi_undefined \%eip");
+// Realtime signals reserved for internal use:
+// 32 (__SIGRTMIN + 0) POSIX timers
+// 33 (__SIGRTMIN + 1) libbacktrace
+// 34 (__SIGRTMIN + 2) libcore
+// 35 (__SIGRTMIN + 3) debuggerd -b
+//
+// If you change this, also change __ndk_legacy___libc_current_sigrtmin
+// in <android/legacy_signal_inlines.h> to match.
- void (*start)(void);
-
- void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
- start = (void(*)(void))__linker_init(raw_args);
-
- /* linker init returns (%eax) the _entry address in the main image */
- /* entry point expects sp to point to raw_args */
-
- __asm__ (
- "mov %0, %%esp\n\t"
- "jmp *%1\n\t"
- : : "r"(raw_args), "r"(start) :
- );
-
- /* Unreachable */
+#define __SIGRT_RESERVED 4
+static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigset) {
+ for (int signo = __SIGRTMIN; signo < __SIGRTMIN + __SIGRT_RESERVED; ++signo) {
+ sigdelset64(&sigset, signo);
+ }
+ return sigset;
}
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index bb91849..ae99857 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -22,7 +22,10 @@
"mips64_system_policy.cpp",
],
export_include_dirs: ["include"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
shared: {
shared_libs: ["libbase"],
},
diff --git a/libc/seccomp/arm_system_policy.cpp b/libc/seccomp/arm_system_policy.cpp
index 18df03b..8887f4d 100644
--- a/libc/seccomp/arm_system_policy.cpp
+++ b/libc/seccomp/arm_system_policy.cpp
@@ -5,128 +5,132 @@
#include "seccomp_bpfs.h"
const sock_filter arm_system_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 124),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 61, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 128),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 143, 63, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 117, 116), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 116, 115), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 114, 113), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 113, 112), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 121, 120), //restart_syscall|exit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 120, 119), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 11, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 118, 117), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 117, 116), //execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 110, 109), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 109, 108), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 107, 106), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 106, 105), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 114, 113), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 113, 112), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 111, 110), //sync|kill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 110, 109), //dup
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 102, 101), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 101, 100), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 106, 105), //times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 105, 104), //brk
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 99, 98), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 98, 97), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 103, 102), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 55, 102, 101), //ioctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 95, 94), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 94, 93), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 99, 98), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 98, 97), //umask|chroot
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 92, 91), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 91, 90), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 96, 95), //getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 95, 94), //setsid|sigaction
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 15, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 86, 85), //sethostname|setrlimit
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 85, 84), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 90, 89), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 89, 88), //getrusage|gettimeofday|settimeofday
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 83, 82), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 82, 81), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 87, 86), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 86, 85), //reboot
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 79, 78), //munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 78, 77), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 83, 82), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 82, 81), //fchmod
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 76, 75), //getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 75, 74), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 80, 79), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 79, 78), //syslog|setitimer|getitimer
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 71, 70), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 70, 69), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 75, 74), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 74, 73), //sysinfo
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 68, 67), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 67, 66), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 72, 71), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 71, 70), //adjtimex|mprotect
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 64, 63), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 63, 62), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 62, 61), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 68, 67), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 67, 66), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 65, 64), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 141, 64, 63), //setfsuid|setfsgid|_llseek
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 31, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 56, 55), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 55, 54), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 53, 52), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 52, 51), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 58, 57), //flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 57, 56), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 55, 54), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 54, 53), //getcwd|capget|capset|sigaltstack|sendfile
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 49, 48), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 48, 47), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 197, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 195, 51, 50), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 50, 49), //fstat64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 46, 45), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 45, 44), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 48, 47), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 47, 46), //setuid32|setgid32
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 41, 40), //getdents64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 40, 39), //mincore|madvise|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 38, 37), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 37, 36), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 43, 42), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 42, 41), //mincore|madvise|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 251, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 40, 39), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 39, 38), //epoll_ctl
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 34, 33), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 33, 32), //arm_fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 36, 35), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 35, 34), //arm_fadvise64_64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 31, 30), //waitid|socket|bind|connect|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 30, 29), //getsockname|getpeername|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 33, 32), //waitid|socket|bind|connect|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 32, 31), //getsockname|getpeername|socketpair
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 15, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 25, 24), //sendto
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 24, 23), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 27, 26), //sendto
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 26, 25), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 22, 21), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 21, 20), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 24, 23), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 23, 22), //openat|mkdirat|mknodat|fchownat
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 18, 17), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 17, 16), //splice|sync_file_range2|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 20, 19), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 19, 18), //splice|sync_file_range2|tee|vmsplice
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 15, 14), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 14, 13), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 17, 16), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 16, 15), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 352, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 351, 12, 11), //timerfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 11, 10), //fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 9, 8), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 7, 6), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 6, 5), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 3, 2), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 8, 7), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 5, 4), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 4, 3), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983046, 1, 0), //__ARM_NR_set_tls
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index add17b9..49280f4 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef SECCOMP_POLICY_H
-#define SECCOMP_POLICY_H
+#pragma once
#include <stddef.h>
#include <linux/filter.h>
@@ -23,5 +22,3 @@
bool set_app_seccomp_filter();
bool set_system_seccomp_filter();
bool set_global_seccomp_filter();
-
-#endif
diff --git a/libc/seccomp/mips_system_policy.cpp b/libc/seccomp/mips_system_policy.cpp
index a88a6e3..32ed567 100644
--- a/libc/seccomp/mips_system_policy.cpp
+++ b/libc/seccomp/mips_system_policy.cpp
@@ -5,108 +5,116 @@
#include "seccomp_bpfs.h"
const sock_filter mips_system_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 108),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 53, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 101, 100), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 100, 99), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 98, 97), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 97, 96), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 94, 93), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 93, 92), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 92, 91), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 116),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 57, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4064, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4006, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4003, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4002, 109, 108), //exit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4005, 108, 107), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4011, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 106, 105), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 105, 104), //execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 102, 101), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 101, 100), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 99, 98), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4038, 98, 97), //sync|kill
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 88, 87), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 87, 86), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4043, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4042, 94, 93), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 93, 92), //times
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 85, 84), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 84, 83), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 91, 90), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 90, 89), //geteuid|getegid|acct|umount2
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 81, 80), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 80, 79), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 79, 78), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4055, 87, 86), //ioctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 86, 85), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 85, 84), //umask|chroot
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 74, 73), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 73, 72), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 80, 79), //getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 79, 78), //setsid|sigaction
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 71, 70), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 70, 69), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 77, 76), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 76, 75), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4091, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4088, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 67, 66), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 66, 65), //reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 65, 64), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 73, 72), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 72, 71), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 71, 70), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 61, 60), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 60, 59), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 59, 58), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 56, 55), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 55, 54), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 54, 53), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 67, 66), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 66, 65), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 64, 63), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 63, 62), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 60, 59), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 59, 58), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 58, 57), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4249, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 15, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 48, 47), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 47, 46), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 45, 44), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 44, 43), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 52, 51), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4143, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4141, 49, 48), //setfsuid|setfsgid|_llseek
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 48, 47), //flock|msync|readv|writev|cacheflush
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 41, 40), //getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 40, 39), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 39, 38), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 35, 34), //recvfrom|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 34, 33), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 45, 44), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 44, 43), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 42, 41), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 41, 40), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4215, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 32, 31), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 31, 30), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 37, 36), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 36, 35), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 28, 27), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 27, 26), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 26, 25), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 34, 33), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4213, 33, 32), //mmap2|truncate64|ftruncate64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 30, 29), //fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 29, 28), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4285, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 21, 20), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 20, 19), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4252, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4250, 23, 22), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 22, 21), //set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4283, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 18, 17), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 17, 16), //set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 14, 13), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 13, 12), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 12, 11), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 8, 7), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 7, 6), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 20, 19), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4284, 19, 18), //set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 16, 15), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 15, 14), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 14, 13), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4320, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 10, 9), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 9, 8), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 7, 6), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 6, 5), //prlimit64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4349, 1, 0),
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index 8728c36..797dfc5 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef SECCOMP_BPFS_H
-#define SECCOMP_BPFS_H
+#pragma once
#include <stddef.h>
#include <linux/seccomp.h>
@@ -61,5 +60,3 @@
extern const size_t mips64_system_filter_size;
extern const struct sock_filter mips64_global_filter[];
extern const size_t mips64_global_filter_size;
-
-#endif
diff --git a/libc/seccomp/x86_system_policy.cpp b/libc/seccomp/x86_system_policy.cpp
index 3a34c69..af1b14f 100644
--- a/libc/seccomp/x86_system_policy.cpp
+++ b/libc/seccomp/x86_system_policy.cpp
@@ -5,112 +5,118 @@
#include "seccomp_bpfs.h"
const sock_filter x86_system_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 114),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 57, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 120),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 59, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 107, 106), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 106, 105), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 104, 103), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 103, 102), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 113, 112), //restart_syscall|exit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 112, 111), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 11, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 110, 109), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 109, 108), //execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 100, 99), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 99, 98), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 97, 96), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 96, 95), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 106, 105), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 105, 104), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 103, 102), //sync|kill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 102, 101), //dup
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 92, 91), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 91, 90), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 98, 97), //times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 97, 96), //brk
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 89, 88), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 88, 87), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 95, 94), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 55, 94, 93), //ioctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 85, 84), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 84, 83), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 83, 82), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 91, 90), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 90, 89), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 89, 88), //getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 15, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 78, 77), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 77, 76), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 84, 83), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 83, 82), //sethostname|setrlimit
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 75, 74), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 74, 73), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 81, 80), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 80, 79), //readlink
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 71, 70), //reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 70, 69), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 69, 68), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 65, 64), //getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 64, 63), //socketcall|syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 62, 61), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 61, 60), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 58, 57), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 57, 56), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 56, 55), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 50, 49), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 49, 48), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 77, 76), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 76, 75), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 74, 73), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 73, 72), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 69, 68), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 68, 67), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 66, 65), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 65, 64), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 62, 61), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 61, 60), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 60, 59), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 258, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 143, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 54, 53), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 141, 53, 52), //setfsuid|setfsgid|_llseek
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 47, 46), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 46, 45), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 43, 42), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 42, 41), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 41, 40), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 37, 36), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 36, 35), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 34, 33), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 33, 32), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 30, 29), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 29, 28), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 28, 27), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 51, 50), //flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 50, 49), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 47, 46), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 46, 45), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 197, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 195, 44, 43), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 43, 42), //fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 39, 38), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 38, 37), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 36, 35), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 35, 34), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 255, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 32, 31), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 31, 30), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 30, 29), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 15, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 23, 22), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 22, 21), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 20, 19), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 19, 18), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 25, 24), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 24, 23), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 22, 21), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 21, 20), //inotify_add_watch|inotify_rm_watch
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 16, 15), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 14, 13), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 18, 17), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 17, 16), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 10, 9), //getcpu|epoll_pwait|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 9, 8), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 324, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 10, 9), //timerfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 9, 8), //fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 7, 6), //prlimit64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 6, 5), //clock_adjtime|syncfs
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 517935b..441fcfe 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -32,19 +32,16 @@
* SUCH DAMAGE.
*/
-#ifndef __BIONIC_STDIO_LOCAL_H__
-#define __BIONIC_STDIO_LOCAL_H__
+#pragma once
#include <pthread.h>
#include <stdbool.h>
#include <wchar.h>
-#if defined(__cplusplus) // Until we fork all of stdio...
+#if defined(__cplusplus) // Until we fork all of stdio...
#include "private/bionic_fortify.h"
#endif
-#include "wcio.h"
-
/*
* Information local to this implementation of stdio,
* in particular, macros and private variables.
@@ -62,53 +59,66 @@
};
struct __sFILE {
- unsigned char *_p; /* current position in (some) buffer */
- int _r; /* read space left for getc() */
- int _w; /* write space left for putc() */
+ unsigned char* _p; /* current position in (some) buffer */
+ int _r; /* read space left for getc() */
+ int _w; /* write space left for putc() */
#if defined(__LP64__)
- int _flags; /* flags, below; this FILE is free if 0 */
- int _file; /* fileno, if Unix descriptor, else -1 */
+ int _flags; /* flags, below; this FILE is free if 0 */
+ int _file; /* fileno, if Unix descriptor, else -1 */
#else
- short _flags; /* flags, below; this FILE is free if 0 */
- short _file; /* fileno, if Unix descriptor, else -1 */
+ short _flags; /* flags, below; this FILE is free if 0 */
+ short _file; /* fileno, if Unix descriptor, else -1 */
#endif
- struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
- int _lbfsize; /* 0 or -_bf._size, for inline putc */
+ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
+ int _lbfsize; /* 0 or -_bf._size, for inline putc */
- // Function pointers used by `funopen`.
- // Note that `_seek` is ignored if `_seek64` (in __sfileext) is set.
- // TODO: NetBSD has `funopen2` which corrects the `int`s to `size_t`s.
- // TODO: glibc has `fopencookie` which passes the function pointers in a struct.
- void* _cookie; /* cookie passed to io functions */
- int (*_close)(void*);
- int (*_read)(void*, char*, int);
- fpos_t (*_seek)(void*, fpos_t, int);
- int (*_write)(void*, const char*, int);
+ // Function pointers used by `funopen`.
+ // Note that `_seek` is ignored if `_seek64` (in __sfileext) is set.
+ // TODO: NetBSD has `funopen2` which corrects the `int`s to `size_t`s.
+ // TODO: glibc has `fopencookie` which passes the function pointers in a struct.
+ void* _cookie; /* cookie passed to io functions */
+ int (*_close)(void*);
+ int (*_read)(void*, char*, int);
+ fpos_t (*_seek)(void*, fpos_t, int);
+ int (*_write)(void*, const char*, int);
- /* extension data, to avoid further ABI breakage */
- struct __sbuf _ext;
- /* data for long sequences of ungetc() */
- unsigned char *_up; /* saved _p when _p is doing ungetc data */
- int _ur; /* saved _r when _r is counting ungetc data */
+ /* extension data, to avoid further ABI breakage */
+ struct __sbuf _ext;
+ /* data for long sequences of ungetc() */
+ unsigned char* _up; /* saved _p when _p is doing ungetc data */
+ int _ur; /* saved _r when _r is counting ungetc data */
- /* tricks to meet minimum requirements even when malloc() fails */
- unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
- unsigned char _nbuf[1]; /* guarantee a getc() buffer */
+ /* tricks to meet minimum requirements even when malloc() fails */
+ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
+ unsigned char _nbuf[1]; /* guarantee a getc() buffer */
- /* separate buffer for fgetln() when line crosses buffer boundary */
- struct __sbuf _lb; /* buffer for fgetln() */
+ /* separate buffer for fgetln() when line crosses buffer boundary */
+ struct __sbuf _lb; /* buffer for fgetln() */
- /* Unix stdio files get aligned to block boundaries on fseek() */
- int _blksize; /* stat.st_blksize (may be != _bf._size) */
+ /* Unix stdio files get aligned to block boundaries on fseek() */
+ int _blksize; /* stat.st_blksize (may be != _bf._size) */
- fpos_t _unused_0; // This was the `_offset` field (see below).
+ fpos_t _unused_0; // This was the `_offset` field (see below).
- // Do not add new fields here. (Or remove or change the size of any above.)
- // Although bionic currently exports `stdin`, `stdout`, and `stderr` symbols,
- // that still hasn't made it to the NDK. All NDK-built apps index directly
- // into an array of this struct (which was in <stdio.h> historically), so if
- // you need to make any changes, they need to be in the `__sfileext` struct
- // below, and accessed via `_EXT`.
+ // Do not add new fields here. (Or remove or change the size of any above.)
+ // Although bionic currently exports `stdin`, `stdout`, and `stderr` symbols,
+ // that still hasn't made it to the NDK. All NDK-built apps index directly
+ // into an array of this struct (which was in <stdio.h> historically), so if
+ // you need to make any changes, they need to be in the `__sfileext` struct
+ // below, and accessed via `_EXT`.
+};
+
+/* minimal requirement of SUSv2 */
+#define WCIO_UNGETWC_BUFSIZE 1
+
+struct wchar_io_data {
+ mbstate_t wcio_mbstate_in;
+ mbstate_t wcio_mbstate_out;
+
+ wchar_t wcio_ungetwc_buf[WCIO_UNGETWC_BUFSIZE];
+ size_t wcio_ungetwc_inbuf;
+
+ int wcio_mode; /* orientation */
};
struct __sfileext {
@@ -134,9 +144,9 @@
#define __SNBF 0x0002 // Unbuffered.
// __SRD and __SWR are mutually exclusive because they indicate what we did last.
// If you want to know whether we were opened read-write, check __SRW instead.
-#define __SRD 0x0004 // Last operation was read.
-#define __SWR 0x0008 // Last operation was write.
-#define __SRW 0x0010 // Was opened for reading & writing.
+#define __SRD 0x0004 // Last operation was read.
+#define __SWR 0x0008 // Last operation was write.
+#define __SRW 0x0010 // Was opened for reading & writing.
#define __SEOF 0x0020 // Found EOF.
#define __SERR 0x0040 // Found error.
#define __SMBF 0x0080 // `_buf` is from malloc.
@@ -157,20 +167,19 @@
#define _EXT(fp) __BIONIC_CAST(reinterpret_cast, struct __sfileext*, (fp)->_ext._base)
#define _UB(fp) _EXT(fp)->_ub
-#define _FLOCK(fp) _EXT(fp)->_lock
+#define _FLOCK(fp) _EXT(fp)->_lock
-#define _FILEEXT_SETUP(fp, fext) \
- do { \
+#define _FILEEXT_SETUP(fp, fext) \
+ do { \
(fp)->_ext._base = __BIONIC_CAST(reinterpret_cast, unsigned char*, fext); \
- memset(_EXT(fp), 0, sizeof(struct __sfileext)); \
- _EXT(fp)->_caller_handles_locking = true; \
+ memset(_EXT(fp), 0, sizeof(struct __sfileext)); \
+ _EXT(fp)->_caller_handles_locking = true; \
} while (0)
-/*
- * Android <= KitKat had getc/putc macros in <stdio.h> that referred
- * to __srget/__swbuf, so those symbols need to be public for LP32
- * but can be hidden for LP64.
- */
+// Android <= 19 had getc/putc macros in <stdio.h> that referred
+// to __srget/__swbuf, so those symbols need to be public for LP32
+// but can be hidden for LP64. Moreover, the NDK continued to ship
+// those macros until r15 made unified headers the default.
__LIBC32_LEGACY_PUBLIC__ int __srget(FILE*);
__LIBC32_LEGACY_PUBLIC__ int __swbuf(int, FILE*);
__LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
@@ -184,49 +193,47 @@
__LIBC32_LEGACY_PUBLIC__ void __smakebuf(FILE*);
/* These are referenced by the Greed for Glory franchise. */
-__LIBC32_LEGACY_PUBLIC__ int __sflush(FILE *);
-__LIBC32_LEGACY_PUBLIC__ int __sread(void *, char *, int);
-__LIBC32_LEGACY_PUBLIC__ int __swrite(void *, const char *, int);
-__LIBC32_LEGACY_PUBLIC__ fpos_t __sseek(void *, fpos_t, int);
-__LIBC32_LEGACY_PUBLIC__ int __sclose(void *);
-__LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE *));
+__LIBC32_LEGACY_PUBLIC__ int __sflush(FILE*);
+__LIBC32_LEGACY_PUBLIC__ int __sread(void*, char*, int);
+__LIBC32_LEGACY_PUBLIC__ int __swrite(void*, const char*, int);
+__LIBC32_LEGACY_PUBLIC__ fpos_t __sseek(void*, fpos_t, int);
+__LIBC32_LEGACY_PUBLIC__ int __sclose(void*);
+__LIBC32_LEGACY_PUBLIC__ int _fwalk(int (*)(FILE*));
off64_t __sseek64(void*, off64_t, int);
-int __sflush_locked(FILE *);
-int __swhatbuf(FILE *, size_t *, int *);
-wint_t __fgetwc_unlock(FILE *);
-wint_t __ungetwc(wint_t, FILE *);
-int __vfprintf(FILE *, const char *, va_list);
-int __svfscanf(FILE *, const char *, va_list);
-int __vfwprintf(FILE *, const wchar_t *, va_list);
-int __vfwscanf(FILE *, const wchar_t *, va_list);
+int __sflush_locked(FILE*);
+int __swhatbuf(FILE*, size_t*, int*);
+wint_t __fgetwc_unlock(FILE*);
+wint_t __ungetwc(wint_t, FILE*);
+int __vfprintf(FILE*, const char*, va_list);
+int __svfscanf(FILE*, const char*, va_list);
+int __vfwprintf(FILE*, const wchar_t*, va_list);
+int __vfwscanf(FILE*, const wchar_t*, va_list);
/*
* Return true if the given FILE cannot be written now.
*/
-#define cantwrite(fp) \
- ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
- __swsetup(fp))
+#define cantwrite(fp) ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && __swsetup(fp))
/*
* Test whether the given stdio file has an active ungetc buffer;
* release such a buffer, without restoring ordinary unread data.
*/
-#define HASUB(fp) (_UB(fp)._base != NULL)
-#define FREEUB(fp) { \
- if (_UB(fp)._base != (fp)->_ubuf) \
- free(_UB(fp)._base); \
- _UB(fp)._base = NULL; \
-}
+#define HASUB(fp) (_UB(fp)._base != NULL)
+#define FREEUB(fp) \
+ { \
+ if (_UB(fp)._base != (fp)->_ubuf) free(_UB(fp)._base); \
+ _UB(fp)._base = NULL; \
+ }
-#define FLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) flockfile(fp)
-#define FUNLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) funlockfile(fp)
-
-#define NO_PRINTF_PERCENT_N
+#define FLOCKFILE(fp) \
+ if (!_EXT(fp)->_caller_handles_locking) flockfile(fp)
+#define FUNLOCKFILE(fp) \
+ if (!_EXT(fp)->_caller_handles_locking) funlockfile(fp)
/* OpenBSD exposes these in <stdio.h>, but we only want them exposed to the implementation. */
-#define __sferror(p) (((p)->_flags & __SERR) != 0)
-#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
+#define __sferror(p) (((p)->_flags & __SERR) != 0)
+#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR | __SEOF)))
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
/* OpenBSD declares these in fvwrite.h, but we share them with C++ parts of the implementation. */
@@ -243,7 +250,7 @@
wint_t __fputwc_unlock(wchar_t wc, FILE* fp);
/* Remove the if (!__sdidinit) __sinit() idiom from untouched upstream stdio code. */
-extern void __sinit(void); // Not actually implemented.
+extern void __sinit(void); // Not actually implemented.
#define __sdidinit 1
size_t parsefloat(FILE*, char*, char*);
@@ -251,7 +258,8 @@
// Sanity check a FILE* for nullptr, so we can emit a message while crashing
// instead of doing a blind null-dereference.
-#define CHECK_FP(fp) if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
+#define CHECK_FP(fp) \
+ if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
/*
* Floating point scanf/printf (input/output) definitions.
@@ -278,6 +286,21 @@
char* __hldtoa(long double, const char*, int, int*, int*, char**);
char* __ldtoa(long double*, int, int, int*, int*, char**);
-__END_DECLS
+#define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : (struct wchar_io_data*)0)
-#endif
+#define _SET_ORIENTATION(fp, mode) \
+ do { \
+ struct wchar_io_data* _wcio = WCIO_GET(fp); \
+ if (_wcio && _wcio->wcio_mode == 0) _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_ungetwc_inbuf = 0; \
+ } \
+ } while (0)
+
+__END_DECLS
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
index 050120e..85c91de 100644
--- a/libc/stdio/printf_common.h
+++ b/libc/stdio/printf_common.h
@@ -499,24 +499,8 @@
else
ADDTYPE(T_DOUBLE);
break;
-#ifndef NO_PRINTF_PERCENT_N
case 'n':
- if (flags & LLONGINT)
- ADDTYPE(TP_LLONG);
- else if (flags & LONGINT)
- ADDTYPE(TP_LONG);
- else if (flags & SHORTINT)
- ADDTYPE(TP_SHORT);
- else if (flags & PTRINT)
- ADDTYPE(TP_PTRINT);
- else if (flags & SIZEINT)
- ADDTYPE(TP_SSIZEINT);
- else if (flags & MAXINT)
- ADDTYPE(TP_MAXINT);
- else
- ADDTYPE(TP_INT);
- continue; /* no output */
-#endif /* NO_PRINTF_PERCENT_N */
+ __fortify_fatal("%%n not allowed on Android");
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index d3ac043..e066e5b 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -713,7 +713,7 @@
* Return first argument, or NULL if no characters were read.
* Do not return NULL if n == 1.
*/
-char* fgets(char* buf, int n, FILE* fp) __overloadable {
+char* fgets(char* buf, int n, FILE* fp) {
CHECK_FP(fp);
ScopedFileLock sfl(fp);
return fgets_unlocked(buf, n, fp);
@@ -1031,7 +1031,7 @@
return __sflush(fp);
}
-size_t fread(void* buf, size_t size, size_t count, FILE* fp) __overloadable {
+size_t fread(void* buf, size_t size, size_t count, FILE* fp) {
CHECK_FP(fp);
ScopedFileLock sfl(fp);
return fread_unlocked(buf, size, count, fp);
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index 8cf4f4b..e17b62a 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -72,6 +72,10 @@
fflush(NULL);
}
+void __fseterr(FILE* fp) {
+ fp->_flags |= __SERR;
+}
+
int __fsetlocking(FILE* fp, int type) {
int old_state = _EXT(fp)->_caller_handles_locking ? FSETLOCKING_BYCALLER : FSETLOCKING_INTERNAL;
if (type == FSETLOCKING_QUERY) {
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index 9182880..17e4372 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -449,26 +449,8 @@
lead = expt;
}
break;
-#ifndef NO_PRINTF_PERCENT_N
case 'n':
- if (flags & LLONGINT)
- *GETARG(long long*) = ret;
- else if (flags & LONGINT)
- *GETARG(long*) = ret;
- else if (flags & SHORTINT)
- *GETARG(short*) = ret;
- else if (flags & CHARINT)
- *GETARG(signed char*) = ret;
- else if (flags & PTRINT)
- *GETARG(ptrdiff_t*) = ret;
- else if (flags & SIZEINT)
- *GETARG(ssize_t*) = ret;
- else if (flags & MAXINT)
- *GETARG(intmax_t*) = ret;
- else
- *GETARG(int*) = ret;
- continue; /* no output */
-#endif /* NO_PRINTF_PERCENT_N */
+ __fortify_fatal("%%n not allowed on Android");
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index 7a00202..46b6233 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -434,26 +434,8 @@
lead = expt;
}
break;
-#ifndef NO_PRINTF_PERCENT_N
case 'n':
- if (flags & LLONGINT)
- *GETARG(long long*) = ret;
- else if (flags & LONGINT)
- *GETARG(long*) = ret;
- else if (flags & SHORTINT)
- *GETARG(short*) = ret;
- else if (flags & CHARINT)
- *GETARG(signed char*) = ret;
- else if (flags & PTRINT)
- *GETARG(ptrdiff_t*) = ret;
- else if (flags & SIZEINT)
- *GETARG(ssize_t*) = ret;
- else if (flags & MAXINT)
- *GETARG(intmax_t*) = ret;
- else
- *GETARG(int*) = ret;
- continue; /* no output */
-#endif /* NO_PRINTF_PERCENT_N */
+ __fortify_fatal("%%n not allowed on Android");
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
diff --git a/libc/stdio/wcio.h b/libc/stdio/wcio.h
deleted file mode 100644
index 3c4f7a4..0000000
--- a/libc/stdio/wcio.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $OpenBSD: wcio.h,v 1.2 2013/04/17 17:40:35 tedu Exp $ */
-/* $NetBSD: wcio.h,v 1.3 2003/01/18 11:30:00 thorpej Exp $ */
-
-/*-
- * Copyright (c)2001 Citrus 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:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Citrus$
- */
-
-#ifndef _WCIO_H_
-#define _WCIO_H_
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-/* minimal requirement of SUSv2 */
-#define WCIO_UNGETWC_BUFSIZE 1
-
-struct wchar_io_data {
- mbstate_t wcio_mbstate_in;
- mbstate_t wcio_mbstate_out;
-
- wchar_t wcio_ungetwc_buf[WCIO_UNGETWC_BUFSIZE];
- size_t wcio_ungetwc_inbuf;
-
- int wcio_mode; /* orientation */
-};
-
-#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);\
-} while (0)
-
-/*
- * WCIO_FREE should be called by fclose
- */
-#define WCIO_FREE(fp) \
-do {\
- struct wchar_io_data *_wcio = WCIO_GET(fp); \
- if (_wcio) { \
- _wcio->wcio_mode = 0;\
- _wcio->wcio_ungetwc_inbuf = 0;\
- } \
-} while (0)
-
-#define WCIO_FREEUB(fp) \
-do {\
- struct wchar_io_data *_wcio = WCIO_GET(fp); \
- if (_wcio) { \
- _wcio->wcio_ungetwc_inbuf = 0;\
- } \
-} while (0)
-
-__END_DECLS
-
-#endif /*_WCIO_H_*/
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
index b8afa29..92baedd 100644
--- a/libc/system_properties/contexts_split.cpp
+++ b/libc/system_properties/contexts_split.cpp
@@ -274,12 +274,22 @@
// Don't check for failure here, so we always have a sane list of properties.
// E.g. In case of recovery, the vendor partition will not have mounted and we
// still need the system / platform properties to function.
- InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
+ if (access("/vendor/etc/selinux/vendor_property_contexts", R_OK) != -1) {
+ InitializePropertiesFromFile("/vendor/etc/selinux/vendor_property_contexts");
+ } else {
+ // Fallback to nonplat_* if vendor_* doesn't exist.
+ InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
+ }
} else {
if (!InitializePropertiesFromFile("/plat_property_contexts")) {
return false;
}
- InitializePropertiesFromFile("/nonplat_property_contexts");
+ if (access("/vendor_property_contexts", R_OK) != -1) {
+ InitializePropertiesFromFile("/vendor_property_contexts");
+ } else {
+ // Fallback to nonplat_* if vendor_* doesn't exist.
+ InitializePropertiesFromFile("/nonplat_property_contexts");
+ }
}
return true;
diff --git a/libc/system_properties/include/system_properties/context_node.h b/libc/system_properties/include/system_properties/context_node.h
index 6a3bbcd..35d0e92 100644
--- a/libc/system_properties/include/system_properties/context_node.h
+++ b/libc/system_properties/include/system_properties/context_node.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_CONTEXT_NODE_H
-#define SYSTEM_PROPERTIES_CONTEXT_NODE_H
+#pragma once
#include "private/bionic_lock.h"
@@ -66,5 +65,3 @@
bool no_access_;
const char* filename_;
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/contexts.h b/libc/system_properties/include/system_properties/contexts.h
index 8f154ed..670f808 100644
--- a/libc/system_properties/include/system_properties/contexts.h
+++ b/libc/system_properties/include/system_properties/contexts.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_CONTEXTS_H
-#define SYSTEM_PROPERTIES_CONTEXTS_H
+#pragma once
#include "prop_area.h"
#include "prop_info.h"
@@ -44,5 +43,3 @@
virtual void ResetAccess() = 0;
virtual void FreeAndUnmap() = 0;
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/contexts_pre_split.h b/libc/system_properties/include/system_properties/contexts_pre_split.h
index 14b00f1..6e695e9 100644
--- a/libc/system_properties/include/system_properties/contexts_pre_split.h
+++ b/libc/system_properties/include/system_properties/contexts_pre_split.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
-#define SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
+#pragma once
#include "contexts.h"
#include "prop_area.h"
@@ -68,5 +67,3 @@
private:
prop_area* pre_split_prop_area_ = nullptr;
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/contexts_serialized.h b/libc/system_properties/include/system_properties/contexts_serialized.h
index 010730a..93d6ac1 100644
--- a/libc/system_properties/include/system_properties/contexts_serialized.h
+++ b/libc/system_properties/include/system_properties/contexts_serialized.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_CONTEXTS_SERIALIZED_H
-#define SYSTEM_PROPERTIES_CONTEXTS_SERIALIZED_H
+#pragma once
#include <property_info_parser/property_info_parser.h>
@@ -60,5 +59,3 @@
size_t context_nodes_mmap_size_ = 0;
prop_area* serial_prop_area_ = nullptr;
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/contexts_split.h b/libc/system_properties/include/system_properties/contexts_split.h
index 06c405a..acb18e3 100644
--- a/libc/system_properties/include/system_properties/contexts_split.h
+++ b/libc/system_properties/include/system_properties/contexts_split.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
-#define SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
+#pragma once
#include "contexts.h"
@@ -58,5 +57,3 @@
prop_area* serial_prop_area_ = nullptr;
const char* filename_ = nullptr;
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/prop_area.h b/libc/system_properties/include/system_properties/prop_area.h
index a7d5d22..2c25337 100644
--- a/libc/system_properties/include/system_properties/prop_area.h
+++ b/libc/system_properties/include/system_properties/prop_area.h
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#pragma once
+
#include <stdatomic.h>
#include <stdint.h>
#include <string.h>
@@ -35,9 +37,6 @@
#include "prop_info.h"
-#ifndef SYSTEM_PROPERTIES_PROP_AREA_H
-#define SYSTEM_PROPERTIES_PROP_AREA_H
-
// Properties are stored in a hybrid trie/binary tree structure.
// Each property's name is delimited at '.' characters, and the tokens are put
// into a trie structure. Siblings at each level of the trie are stored in a
@@ -161,5 +160,3 @@
DISALLOW_COPY_AND_ASSIGN(prop_area);
};
-
-#endif
diff --git a/libc/system_properties/include/system_properties/prop_info.h b/libc/system_properties/include/system_properties/prop_info.h
index 99bcaaf..a127550 100644
--- a/libc/system_properties/include/system_properties/prop_info.h
+++ b/libc/system_properties/include/system_properties/prop_info.h
@@ -26,15 +26,14 @@
* SUCH DAMAGE.
*/
+#pragma once
+
#include <stdatomic.h>
#include <stdint.h>
#include <sys/system_properties.h>
#include "private/bionic_macros.h"
-#ifndef SYSTEM_PROPERTIES_PROP_INFO_H
-#define SYSTEM_PROPERTIES_PROP_INFO_H
-
// The C11 standard doesn't allow atomic loads from const fields,
// though C++11 does. Fudge it until standards get straightened out.
static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, memory_order mo) {
@@ -88,5 +87,3 @@
};
static_assert(sizeof(prop_info) == 96, "sizeof struct prop_info must be 96 bytes");
-
-#endif
diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h
index 83ac00c..52ffcaf 100644
--- a/libc/system_properties/include/system_properties/system_properties.h
+++ b/libc/system_properties/include/system_properties/system_properties.h
@@ -26,10 +26,10 @@
* SUCH DAMAGE.
*/
-#ifndef SYSTEM_PROPERTIES_SYSTEM_PROPERTIES_H
-#define SYSTEM_PROPERTIES_SYSTEM_PROPERTIES_H
+#pragma once
#include <stdint.h>
+#include <sys/param.h>
#include <sys/system_properties.h>
#include "contexts.h"
@@ -41,12 +41,13 @@
class SystemProperties {
public:
+ friend struct LocalPropertyTestState;
+ friend class SystemPropertiesTest;
// Note that system properties are initialized before libc calls static initializers, so
// doing any initialization in this constructor is an error. Even a Constructor that zero
// initializes this class will clobber the previous property initialization.
// We rely on the static SystemProperties in libc to be placed in .bss and zero initialized.
- SystemProperties() {
- }
+ SystemProperties() = default;
// Special constructor for testing that also zero initializes the important members.
explicit SystemProperties(bool initialized) : initialized_(initialized) {
}
@@ -72,25 +73,17 @@
const prop_info* FindNth(unsigned n);
int Foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
- Contexts* contexts() {
- return reinterpret_cast<Contexts*>(&contexts_union_);
- }
-
private:
- // We don't want to use new or malloc in properties (b/31659220), and since these classes
- // are small enough and we place them in a union. See the above note about Constructors
- // for why there is a no-op constructor here.
- union ContextsUnion {
- ContextsUnion() {
- }
- ~ContextsUnion() {
- }
- ContextsSerialized contexts_serialized;
- ContextsSplit contexts_split;
- ContextsPreSplit contexts_pre_split;
- } contexts_union_;
+ // We don't want to use new or malloc in properties (b/31659220), and we don't want to waste a
+ // full page by using mmap(), so we set aside enough space to create any context of the three
+ // contexts.
+ static constexpr size_t kMaxContextsAlign =
+ MAX(alignof(ContextsSerialized), MAX(alignof(ContextsSplit), alignof(ContextsPreSplit)));
+ static constexpr size_t kMaxContextsSize =
+ MAX(sizeof(ContextsSerialized), MAX(sizeof(ContextsSplit), sizeof(ContextsPreSplit)));
+ alignas(kMaxContextsAlign) char contexts_data_[kMaxContextsSize];
+ Contexts* contexts_;
+
bool initialized_;
char property_filename_[PROP_FILENAME_MAX];
};
-
-#endif
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
index c610df2..7c48b8e 100644
--- a/libc/system_properties/system_properties.cpp
+++ b/libc/system_properties/system_properties.cpp
@@ -63,7 +63,7 @@
ErrnoRestorer errno_restorer;
if (initialized_) {
- contexts()->ResetAccess();
+ contexts_->ResetAccess();
return true;
}
@@ -74,19 +74,19 @@
if (is_dir(property_filename_)) {
if (access("/dev/__properties__/property_info", R_OK) == 0) {
- new (&contexts_union_.contexts_serialized) ContextsSerialized();
- if (!contexts_union_.contexts_serialized.Initialize(false, property_filename_, nullptr)) {
+ contexts_ = new (contexts_data_) ContextsSerialized();
+ if (!contexts_->Initialize(false, property_filename_, nullptr)) {
return false;
}
} else {
- new (&contexts_union_.contexts_split) ContextsSplit();
- if (!contexts_union_.contexts_split.Initialize(false, property_filename_, nullptr)) {
+ contexts_ = new (contexts_data_) ContextsSplit();
+ if (!contexts_->Initialize(false, property_filename_, nullptr)) {
return false;
}
}
} else {
- new (&contexts_union_.contexts_pre_split) ContextsPreSplit();
- if (!contexts_union_.contexts_pre_split.Initialize(false, property_filename_, nullptr)) {
+ contexts_ = new (contexts_data_) ContextsPreSplit();
+ if (!contexts_->Initialize(false, property_filename_, nullptr)) {
return false;
}
}
@@ -100,8 +100,8 @@
}
strcpy(property_filename_, filename);
- new (&contexts_union_.contexts_serialized) ContextsSerialized();
- if (!contexts_union_.contexts_serialized.Initialize(true, property_filename_, fsetxattr_failed)) {
+ contexts_ = new (contexts_data_) ContextsSerialized();
+ if (!contexts_->Initialize(true, property_filename_, fsetxattr_failed)) {
return false;
}
initialized_ = true;
@@ -113,7 +113,7 @@
return -1;
}
- prop_area* pa = contexts()->GetSerialPropArea();
+ prop_area* pa = contexts_->GetSerialPropArea();
if (!pa) {
return -1;
}
@@ -127,7 +127,7 @@
return nullptr;
}
- prop_area* pa = contexts()->GetPropAreaForName(name);
+ prop_area* pa = contexts_->GetPropAreaForName(name);
if (!pa) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
return nullptr;
@@ -231,7 +231,7 @@
return -1;
}
- prop_area* pa = contexts()->GetSerialPropArea();
+ prop_area* pa = contexts_->GetSerialPropArea();
if (!pa) {
return -1;
}
@@ -269,12 +269,12 @@
return -1;
}
- prop_area* serial_pa = contexts()->GetSerialPropArea();
+ prop_area* serial_pa = contexts_->GetSerialPropArea();
if (serial_pa == nullptr) {
return -1;
}
- prop_area* pa = contexts()->GetPropAreaForName(name);
+ prop_area* pa = contexts_->GetPropAreaForName(name);
if (!pa) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
return -1;
@@ -319,7 +319,7 @@
return -1;
}
- prop_area* serial_pa = contexts()->GetSerialPropArea();
+ prop_area* serial_pa = contexts_->GetSerialPropArea();
if (serial_pa == nullptr) {
return -1;
}
@@ -364,7 +364,7 @@
return -1;
}
- contexts()->ForEach(propfn, cookie);
+ contexts_->ForEach(propfn, cookie);
return 0;
}
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 0567aa4..0e9a7d3 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -38,7 +38,9 @@
//#include <sys/localedef.h>
#include <ctype.h>
+#include <errno.h>
#include <locale.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tzfile.h"
@@ -128,7 +130,7 @@
fmt++;
continue;
}
-
+
if ((c = *fmt++) != '%')
goto literal;
@@ -154,7 +156,7 @@
_LEGAL_ALT(0);
alt_format |= _ALT_O;
goto again;
-
+
/*
* "Complex" conversion rules, implemented through recursion.
*/
@@ -169,7 +171,7 @@
if (!(bp = _strptime(bp, "%m/%d/%y", tm, cr)))
return (NULL);
break;
-
+
case 'R': /* The time as "%H:%M". */
_LEGAL_ALT(0);
if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
@@ -337,6 +339,25 @@
return (NULL);
break;
+ case 's':
+ {
+ // Android addition, based on FreeBSD's implementation.
+ int saved_errno = errno;
+ errno = 0;
+ const unsigned char* old_bp = bp;
+ long n = strtol((const char*) bp, (char**) &bp, 10);
+ time_t t = n;
+ if (bp == old_bp || errno == ERANGE || ((long) t) != n) {
+ errno = saved_errno;
+ return NULL;
+ }
+ errno = saved_errno;
+
+ if (localtime_r(&t, tm) == NULL) return NULL;
+ }
+ break;
+
+
case 'U': /* The week of year, beginning on sunday. */
case 'W': /* The week of year, beginning on monday. */
_LEGAL_ALT(_ALT_O);
@@ -430,3 +451,7 @@
*dest = result;
return (1);
}
+
+char* strptime_l(const char* buf, const char* fmt, struct tm* tm, locale_t l) {
+ return strptime(buf, fmt, tm);
+}
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/system.c b/libc/upstream-openbsd/lib/libc/stdlib/system.c
deleted file mode 100644
index de32d43..0000000
--- a/libc/upstream-openbsd/lib/libc/stdlib/system.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $OpenBSD: system.c,v 1.11 2015/10/23 04:44:41 guenther Exp $ */
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <paths.h>
-
-extern char **environ;
-
-int
-system(const char *command)
-{
- pid_t pid, cpid;
- struct sigaction intsave, quitsave;
- sigset_t mask, omask;
- int pstat;
- char *argp[] = {"sh", "-c", NULL, NULL};
-
- if (!command) /* just checking... */
- return(1);
-
- argp[2] = (char *)command;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &mask, &omask);
- switch (cpid = vfork()) {
- case -1: /* error */
- sigprocmask(SIG_SETMASK, &omask, NULL);
- return(-1);
- case 0: /* child */
- sigprocmask(SIG_SETMASK, &omask, NULL);
- execve(_PATH_BSHELL, argp, environ);
- _exit(127);
- }
-
- sigaction(SIGINT, NULL, &intsave);
- sigaction(SIGQUIT, NULL, &quitsave);
- do {
- pid = waitpid(cpid, &pstat, 0);
- } while (pid == -1 && errno == EINTR);
- sigprocmask(SIG_SETMASK, &omask, NULL);
- sigaction(SIGINT, &intsave, NULL);
- sigaction(SIGQUIT, &quitsave, NULL);
- return (pid == -1 ? -1 : pstat);
-}
-DEF_STRONG(system);
diff --git a/libc/upstream-openbsd/lib/libc/string/memchr.c b/libc/upstream-openbsd/lib/libc/string/memchr.c
index 976ed21..a6a4bd6 100644
--- a/libc/upstream-openbsd/lib/libc/string/memchr.c
+++ b/libc/upstream-openbsd/lib/libc/string/memchr.c
@@ -34,7 +34,7 @@
#include <string.h>
void *
-memchr(const void *s, int c, size_t n) __overloadable
+memchr(const void *s, int c, size_t n)
{
if (n != 0) {
const unsigned char *p = s;
diff --git a/libc/upstream-openbsd/lib/libc/string/memmove.c b/libc/upstream-openbsd/lib/libc/string/memmove.c
index 6b5db47..2f1deb2 100644
--- a/libc/upstream-openbsd/lib/libc/string/memmove.c
+++ b/libc/upstream-openbsd/lib/libc/string/memmove.c
@@ -46,7 +46,7 @@
* Copy a block of memory, handling overlap.
*/
void *
-memmove(void *dst0, const void *src0, size_t length) __overloadable
+memmove(void *dst0, const void *src0, size_t length)
{
char *dst = dst0;
const char *src = src0;
diff --git a/libc/upstream-openbsd/lib/libc/string/memrchr.c b/libc/upstream-openbsd/lib/libc/string/memrchr.c
index 4b67503..26a3399 100644
--- a/libc/upstream-openbsd/lib/libc/string/memrchr.c
+++ b/libc/upstream-openbsd/lib/libc/string/memrchr.c
@@ -23,7 +23,7 @@
* Find the last occurrence of 'c' in the buffer 's' of size 'n'.
*/
void *
-memrchr(const void *s, int c, size_t n) __overloadable
+memrchr(const void *s, int c, size_t n)
{
const unsigned char *cp;
diff --git a/libc/upstream-openbsd/lib/libc/string/stpcpy.c b/libc/upstream-openbsd/lib/libc/string/stpcpy.c
index 3ed5782..d88afac 100644
--- a/libc/upstream-openbsd/lib/libc/string/stpcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/stpcpy.c
@@ -37,7 +37,7 @@
#endif
char *
-stpcpy(char *to, const char *from) __overloadable
+stpcpy(char *to, const char *from)
{
for (; (*to = *from) != '\0'; ++from, ++to);
return(to);
diff --git a/libc/upstream-openbsd/lib/libc/string/stpncpy.c b/libc/upstream-openbsd/lib/libc/string/stpncpy.c
index f30bf15..6bdee5d 100644
--- a/libc/upstream-openbsd/lib/libc/string/stpncpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/stpncpy.c
@@ -35,7 +35,7 @@
#include <string.h>
char *
-stpncpy(char *dst, const char *src, size_t n) __overloadable
+stpncpy(char *dst, const char *src, size_t n)
{
if (n != 0) {
char *d = dst;
diff --git a/libc/upstream-openbsd/lib/libc/string/strcat.c b/libc/upstream-openbsd/lib/libc/string/strcat.c
index 7872a2d..646c9c2 100644
--- a/libc/upstream-openbsd/lib/libc/string/strcat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strcat.c
@@ -37,7 +37,7 @@
#endif
char *
-strcat(char *s, const char *append) __overloadable
+strcat(char *s, const char *append)
{
char *save = s;
diff --git a/libc/upstream-openbsd/lib/libc/string/strcpy.c b/libc/upstream-openbsd/lib/libc/string/strcpy.c
index 1b1169c..5a9001e 100644
--- a/libc/upstream-openbsd/lib/libc/string/strcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strcpy.c
@@ -37,7 +37,7 @@
#endif
char *
-strcpy(char *to, const char *from) __overloadable
+strcpy(char *to, const char *from)
{
char *save = to;
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcat.c b/libc/upstream-openbsd/lib/libc/string/strlcat.c
index 8a950f5..6bf2a41 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcat.c
@@ -27,7 +27,7 @@
* If retval >= dsize, truncation occurred.
*/
size_t
-strlcat(char *dst, const char *src, size_t dsize) __overloadable
+strlcat(char *dst, const char *src, size_t dsize)
{
const char *odst = dst;
const char *osrc = src;
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcpy.c b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
index 647b18b..3677689 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
@@ -25,7 +25,7 @@
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t
-strlcpy(char *dst, const char *src, size_t dsize) __overloadable
+strlcpy(char *dst, const char *src, size_t dsize)
{
const char *osrc = src;
size_t nleft = dsize;
diff --git a/libc/upstream-openbsd/lib/libc/string/strncat.c b/libc/upstream-openbsd/lib/libc/string/strncat.c
index 5b07749..b3388ac 100644
--- a/libc/upstream-openbsd/lib/libc/string/strncat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strncat.c
@@ -38,7 +38,7 @@
* are written at dst (at most n+1 bytes being appended). Return dst.
*/
char *
-strncat(char *dst, const char *src, size_t n) __overloadable
+strncat(char *dst, const char *src, size_t n)
{
if (n != 0) {
char *d = dst;
diff --git a/libc/upstream-openbsd/lib/libc/string/strncpy.c b/libc/upstream-openbsd/lib/libc/string/strncpy.c
index ad9dc84..d6d8647 100644
--- a/libc/upstream-openbsd/lib/libc/string/strncpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strncpy.c
@@ -39,7 +39,7 @@
* Return dst.
*/
char *
-strncpy(char *dst, const char *src, size_t n) __overloadable
+strncpy(char *dst, const char *src, size_t n)
{
if (n != 0) {
char *d = dst;
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 0603d06..082cdea 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -4,7 +4,10 @@
cc_library_static {
name: "libdl_static",
- srcs: ["libdl.cpp", "libdl_cfi.cpp"],
+ srcs: [
+ "libdl.cpp",
+ "libdl_cfi.cpp",
+ ],
cflags: [
"-Wall",
@@ -71,7 +74,7 @@
whole_static_libs: ["libdl_static"],
},
static: {
- srcs: [ "libdl_static.c" ],
+ srcs: ["libdl_static.c"],
},
cflags: [
"-Wall",
@@ -91,7 +94,7 @@
// This is placeholder library the actual implementation is (currently)
// provided by the linker.
- shared_libs: [ "ld-android" ],
+ shared_libs: ["ld-android"],
sanitize: {
never: true,
diff --git a/libm/fpmath.h b/libm/fpmath.h
index 80420e5..854ba11 100644
--- a/libm/fpmath.h
+++ b/libm/fpmath.h
@@ -33,8 +33,7 @@
// - android uses 128 bits long doubles for LP64, so the structure and macros
// were reworked for the quad precision ieee representation.
-#ifndef _FPMATH_
-#define _FPMATH_
+#pragma once
#include <endian.h>
@@ -92,5 +91,3 @@
} while(0)
#endif // __LP64__
-
-#endif // _FPMATH_
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index ee41e45..0bcc40d 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _BIONIC_LIBM_FREEBSD_COMPAT_H_included
-#define _BIONIC_LIBM_FREEBSD_COMPAT_H_included
+#pragma once
#include <float.h>
@@ -38,5 +37,3 @@
// Similarly rename _scan_nan.
#define _scan_nan __libm_scan_nan
-
-#endif
diff --git a/linker/Android.bp b/linker/Android.bp
index 8d7fae5..2fcf369 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -6,7 +6,10 @@
"linker_allocator.cpp",
"linker_memory.cpp",
],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
@@ -26,9 +29,15 @@
host_supported: true,
device_supported: false,
target: {
- linux_bionic: { enabled: true },
- linux_glibc: { enabled: false },
- darwin: { enabled: false },
+ linux_bionic: {
+ enabled: true,
+ },
+ linux_glibc: {
+ enabled: false,
+ },
+ darwin: {
+ enabled: false,
+ },
},
cflags: [
@@ -95,9 +104,7 @@
version_script: "linker.generic.map",
},
x86: {
- srcs: ["arch/x86/begin.c"],
-
- cflags: ["-D__work_around_b_24465209__"],
+ srcs: ["arch/x86/begin.S"],
version_script: "linker.generic.map",
},
x86_64: {
@@ -187,7 +194,7 @@
// Important: The liblinker_malloc should be the last library in the list
// to overwrite any other malloc implementations by other static libraries.
- "liblinker_malloc"
+ "liblinker_malloc",
],
static_executable: true,
@@ -202,12 +209,6 @@
android: {
static_libs: ["libdebuggerd_handler_fallback"],
},
- android64: {
- cflags: ["-DTARGET_IS_64_BIT"],
- },
- linux_bionic: {
- cflags: ["-DTARGET_IS_64_BIT"],
- },
},
compile_multilib: "both",
diff --git a/linker/arch/x86/begin.c b/linker/arch/x86/begin.S
similarity index 72%
rename from linker/arch/x86/begin.c
rename to linker/arch/x86/begin.S
index 331b79e..3812646 100644
--- a/linker/arch/x86/begin.c
+++ b/linker/arch/x86/begin.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,28 +26,18 @@
* SUCH DAMAGE.
*/
-#include <stdint.h>
-#include <sys/cdefs.h>
+#include <private/bionic_asm.h>
-extern unsigned __linker_init(void* raw_args);
-
-__LIBC_HIDDEN__ void _start() {
+ENTRY(_start)
// Force unwinds to end in this function.
- asm volatile(".cfi_undefined \%eip");
+ .cfi_undefined %eip
- void (*start)(void);
-
- void* raw_args = (void*) ((uintptr_t) __builtin_frame_address(0) + sizeof(void*));
- start = (void(*)(void))__linker_init(raw_args);
+ movl %esp, %eax // %esp is aligned to 16 here.
+ subl $12, %esp
+ pushl %eax
+ call __linker_init // %esp is aligned to 16 before the call.
+ addl $16, %esp
/* linker init returns (%eax) the _entry address in the main image */
- /* entry point expects sp to point to raw_args */
-
- __asm__ (
- "mov %0, %%esp\n\t"
- "jmp *%1\n\t"
- : : "r"(raw_args), "r"(start) :
- );
-
- /* Unreachable */
-}
+ jmp *%eax
+END(_start)
diff --git a/linker/linked_list.h b/linker/linked_list.h
index ed2b150..048ea4d 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKED_LIST_H
-#define __LINKED_LIST_H
+#pragma once
#include "private/bionic_macros.h"
@@ -259,5 +258,3 @@
LinkedListEntry<T>* tail_;
DISALLOW_COPY_AND_ASSIGN(LinkedList);
};
-
-#endif // __LINKED_LIST_H
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3f898ba..dd700fe 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -863,11 +863,8 @@
}
}
- // If not found - use dlsym_handle_lookup for caller's
- // local_group unless it is part of the global group in which
- // case we already did it.
- if (s == nullptr && caller != nullptr &&
- (caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
+ // If not found - use dlsym_handle_lookup for caller's local_group
+ if (s == nullptr && caller != nullptr) {
soinfo* local_group_root = caller->get_local_group_root();
return dlsym_handle_lookup(local_group_root->get_primary_namespace(),
@@ -1108,10 +1105,14 @@
const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
#if !defined(__LP64__)
// Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
- if (get_application_target_sdk_version() < __ANDROID_API_M__) {
+ int app_target_api_level = get_application_target_sdk_version();
+ if (app_target_api_level < __ANDROID_API_M__) {
const char* bname = basename(dt_needed);
if (bname != dt_needed) {
- DL_WARN("library \"%s\" has invalid DT_NEEDED entry \"%s\"", sopath, dt_needed);
+ DL_WARN_documented_change(__ANDROID_API_M__,
+ "invalid-dt_needed-entries-enforced-for-api-level-23",
+ "library \"%s\" has invalid DT_NEEDED entry \"%s\"",
+ sopath, dt_needed, app_target_api_level);
add_dlwarning(sopath, "invalid DT_NEEDED entry", dt_needed);
}
@@ -1249,10 +1250,11 @@
const soinfo* needed_or_dlopened_by = task->get_needed_by();
const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
needed_or_dlopened_by->get_realpath();
- DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the namespace \"%s\""
- " - the access is temporarily granted as a workaround for http://b/26394120, note that the access"
- " will be removed in future releases of Android.",
- name, realpath.c_str(), sopath, ns->get_name());
+ DL_WARN_documented_change(__ANDROID_API_N__,
+ "private-api-enforced-for-api-level-24",
+ "library \"%s\" (\"%s\") needed or dlopened by \"%s\" "
+ "is not accessible by namespace \"%s\"",
+ name, realpath.c_str(), sopath, ns->get_name());
add_dlwarning(sopath, "unauthorized access to", name);
}
} else {
@@ -3366,7 +3368,9 @@
set_dt_flags_1(d->d_un.d_val);
if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
- DL_WARN("\"%s\" has unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
+ DL_WARN("Warning: \"%s\" has unsupported flags DT_FLAGS_1=%p "
+ "(ignoring unsupported flags)",
+ get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
}
break;
#if defined(__mips__)
@@ -3445,7 +3449,7 @@
} else {
tag_name = "unknown";
}
- DL_WARN("\"%s\" unused DT entry: %s (type %p arg %p)",
+ DL_WARN("Warning: \"%s\" unused DT entry: %s (type %p arg %p) (ignoring)",
get_realpath(),
tag_name,
reinterpret_cast<void*>(d->d_tag),
@@ -3498,16 +3502,20 @@
// Before M release linker was using basename in place of soname.
// In the case when dt_soname is absent some apps stop working
// because they can't find dt_needed library by soname.
- // This workaround should keep them working. (applies only
- // for apps targeting sdk version < M). Make an exception for
- // the main executable and linker; they do not need to have dt_soname
+ // This workaround should keep them working. (Applies only
+ // for apps targeting sdk version < M.) Make an exception for
+ // the main executable and linker; they do not need to have dt_soname.
+ // TODO: >= O the linker doesn't need this workaround.
if (soname_ == nullptr &&
this != solist_get_somain() &&
(flags_ & FLAG_LINKER) == 0 &&
get_application_target_sdk_version() < __ANDROID_API_M__) {
soname_ = basename(realpath_.c_str());
- DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
- get_realpath(), soname_);
+ DL_WARN_documented_change(__ANDROID_API_M__,
+ "missing-soname-enforced-for-api-level-23",
+ "\"%s\" has no DT_SONAME (will use %s instead)",
+ get_realpath(), soname_);
+
// Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
}
return true;
@@ -3538,7 +3546,8 @@
#if !defined(__LP64__)
if (has_text_relocations) {
// Fail if app is targeting M or above.
- if (get_application_target_sdk_version() >= __ANDROID_API_M__) {
+ int app_target_api_level = get_application_target_sdk_version();
+ if (app_target_api_level >= __ANDROID_API_M__) {
DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/"
"bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-"
"Enforced-for-API-level-23)", get_realpath());
@@ -3546,13 +3555,13 @@
}
// Make segments writable to allow text relocations to work properly. We will later call
// phdr_table_protect_segments() after all of them are applied.
- DL_WARN("\"%s\" has text relocations (https://android.googlesource.com/platform/"
- "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-Enforced-"
- "for-API-level-23)", get_realpath());
+ DL_WARN_documented_change(__ANDROID_API_M__,
+ "Text-Relocations-Enforced-for-API-level-23",
+ "\"%s\" has text relocations",
+ get_realpath());
add_dlwarning(get_realpath(), "text relocations");
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
- DL_ERR("can't unprotect loadable segments for \"%s\": %s",
- get_realpath(), strerror(errno));
+ DL_ERR("can't unprotect loadable segments for \"%s\": %s", get_realpath(), strerror(errno));
return false;
}
}
@@ -3742,7 +3751,7 @@
&config,
&error_msg)) {
if (!error_msg.empty()) {
- DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
+ DL_WARN("Warning: couldn't read \"%s\" for \"%s\" (using default configuration instead): %s",
config_file,
executable_path,
error_msg.c_str());
diff --git a/linker/linker.h b/linker/linker.h
index 29d40fa..260c89d 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_H_
-#define _LINKER_H_
+#pragma once
#include <dlfcn.h>
#include <android/dlext.h>
@@ -187,5 +186,3 @@
void increment_dso_handle_reference_counter(void* dso_handle);
void decrement_dso_handle_reference_counter(void* dso_handle);
-
-#endif
diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h
index 7fc6cbf..82e4ef4 100644
--- a/linker/linker_allocator.h
+++ b/linker/linker_allocator.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_ALLOCATOR_H
-#define __LINKER_ALLOCATOR_H
+#pragma once
#include <errno.h>
#include <stdlib.h>
@@ -152,6 +151,3 @@
LinkerSmallObjectAllocator* allocators_;
uint8_t allocators_buf_[sizeof(LinkerSmallObjectAllocator)*kSmallObjectAllocatorsCount];
};
-
-
-#endif /* __LINKER_ALLOCATOR_H */
diff --git a/linker/linker_block_allocator.h b/linker/linker_block_allocator.h
index eba1db2..b501659 100644
--- a/linker/linker_block_allocator.h
+++ b/linker/linker_block_allocator.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_BLOCK_ALLOCATOR_H
-#define __LINKER_BLOCK_ALLOCATOR_H
+#pragma once
#include <stdlib.h>
#include <limits.h>
@@ -89,5 +88,3 @@
LinkerBlockAllocator block_allocator_;
DISALLOW_COPY_AND_ASSIGN(LinkerTypeAllocator);
};
-
-#endif // __LINKER_BLOCK_ALLOCATOR_H
diff --git a/linker/linker_cfi.h b/linker/linker_cfi.h
index e54554f..f3300d6 100644
--- a/linker/linker_cfi.h
+++ b/linker/linker_cfi.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_CFI_H_
-#define _LINKER_CFI_H_
+#pragma once
#include "linker.h"
#include "linker_debug.h"
@@ -103,5 +102,3 @@
};
CFIShadowWriter* get_cfi_shadow();
-
-#endif // _LINKER_CFI_H_
diff --git a/linker/linker_common_types.h b/linker/linker_common_types.h
index 6afd950..ffa4066 100644
--- a/linker/linker_common_types.h
+++ b/linker/linker_common_types.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_COMMON_TYPES_H
-#define __LINKER_COMMON_TYPES_H
+#pragma once
#include <android/dlext.h>
#include "linked_list.h"
@@ -65,5 +64,3 @@
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
-
-#endif /* __LINKER_COMMON_TYPES_H */
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 83c2f36..c00b734 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -194,14 +194,14 @@
std::string section_name;
- while(true) {
+ while (true) {
std::string name;
std::string value;
std::string error;
int result = cp.next_token(&name, &value, &error);
if (result == ConfigParser::kError) {
- DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ DL_WARN("%s:%zd: warning: couldn't parse %s (ignoring this line)",
ld_config_file_path,
cp.lineno(),
error.c_str());
@@ -214,7 +214,7 @@
if (result == ConfigParser::kPropertyAssign) {
if (!android::base::StartsWith(name, "dir.")) {
- DL_WARN("error parsing %s:%zd: unexpected property name \"%s\", "
+ DL_WARN("%s:%zd: warning: unexpected property name \"%s\", "
"expected format dir.<section_name> (ignoring this line)",
ld_config_file_path,
cp.lineno(),
@@ -228,7 +228,7 @@
}
if (value.empty()) {
- DL_WARN("error parsing %s:%zd: property value is empty (ignoring this line)",
+ DL_WARN("%s:%zd: warning: property value is empty (ignoring this line)",
ld_config_file_path,
cp.lineno());
continue;
@@ -275,7 +275,7 @@
if (result == ConfigParser::kPropertyAssign) {
if (properties->find(name) != properties->end()) {
- DL_WARN("%s:%zd: warning: property \"%s\" redefinition",
+ DL_WARN("%s:%zd: warning: redefining property \"%s\" (overriding previous value)",
ld_config_file_path,
cp.lineno(),
name.c_str());
@@ -284,7 +284,7 @@
(*properties)[name] = PropertyValue(std::move(value), cp.lineno());
} else if (result == ConfigParser::kPropertyAppend) {
if (properties->find(name) == properties->end()) {
- DL_WARN("%s:%zd: warning: appending to property \"%s\" which isn't defined",
+ DL_WARN("%s:%zd: warning: appending to undefined property \"%s\" (treating as assignment)",
ld_config_file_path,
cp.lineno(),
name.c_str());
@@ -299,7 +299,7 @@
value = ":" + value;
(*properties)[name].append_value(std::move(value));
} else {
- DL_WARN("%s:%zd: warning: += isn't allowed to property \"%s\". Ignoring.",
+ DL_WARN("%s:%zd: warning: += isn't allowed for property \"%s\" (ignoring)",
ld_config_file_path,
cp.lineno(),
name.c_str());
@@ -308,7 +308,7 @@
}
if (result == ConfigParser::kError) {
- DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ DL_WARN("%s:%zd: warning: couldn't parse %s (ignoring this line)",
ld_config_file_path,
cp.lineno(),
error.c_str());
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 0c50d57..e117aea 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_CONFIG_H_
-#define _LINKER_CONFIG_H_
+#pragma once
#include <android/api-level.h>
@@ -171,5 +170,3 @@
DISALLOW_COPY_AND_ASSIGN(Config);
};
-
-#endif /* _LINKER_CONFIG_H_ */
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 7ceab08..862ea12 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_DEBUG_H_
-#define _LINKER_DEBUG_H_
+#pragma once
// You can increase the verbosity of debug traces by defining the LD_DEBUG
// environment variable to a numeric value from 0 to 2 (corresponding to
@@ -102,5 +101,3 @@
#define MARK(x) do {} while (0)
#endif
-
-#endif /* _LINKER_DEBUG_H_ */
diff --git a/linker/linker_dlwarning.h b/linker/linker_dlwarning.h
index 68827f7..af26824 100644
--- a/linker/linker_dlwarning.h
+++ b/linker/linker_dlwarning.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_DLWARNING_H
-#define __LINKER_DLWARNING_H
+#pragma once
void add_dlwarning(const char* sopath, const char* message, const char* value = nullptr);
@@ -36,5 +35,3 @@
// is used to avoid forcing user into saving the message
// to a global variable.
void get_dlwarning(void* user_data, void (*f)(void*, const char*));
-
-#endif /* __LINKER_DLWARNING_H */
diff --git a/linker/linker_gdb_support.h b/linker/linker_gdb_support.h
index 6709da1..4ae18ee 100644
--- a/linker/linker_gdb_support.h
+++ b/linker/linker_gdb_support.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef __LINKER_GDB_SUPPORT_H
-#define __LINKER_GDB_SUPPORT_H
+
+#pragma once
#include <link.h>
#include <sys/cdefs.h>
@@ -42,5 +42,3 @@
extern struct r_debug _r_debug;
__END_DECLS
-
-#endif
diff --git a/linker/linker_globals.cpp b/linker/linker_globals.cpp
index 155ebf4..bcc2a1e 100644
--- a/linker/linker_globals.cpp
+++ b/linker/linker_globals.cpp
@@ -26,10 +26,12 @@
* SUCH DAMAGE.
*/
-
+#include "linker.h"
#include "linker_globals.h"
#include "linker_namespaces.h"
+#include "android-base/stringprintf.h"
+
int g_argc = 0;
char** g_argv = nullptr;
char** g_envp = nullptr;
@@ -48,3 +50,18 @@
return sizeof(__linker_dl_err_buf);
}
+void DL_WARN_documented_change(int api_level, const char* doc_link, const char* fmt, ...) {
+ std::string result{"Warning: "};
+
+ va_list ap;
+ va_start(ap, fmt);
+ android::base::StringAppendV(&result, fmt, ap);
+ va_end(ap);
+
+ android::base::StringAppendF(&result,
+ " and will not work when the app moves to API level %d or later "
+ "(https://android.googlesource.com/platform/bionic/+/master/%s) "
+ "(allowing for now because this app's target API level is still %d)",
+ api_level, doc_link, get_application_target_sdk_version());
+ DL_WARN("%s", result.c_str());
+}
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index 11ccbd5..32aa09d 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_GLOBALS_H
-#define __LINKER_GLOBALS_H
+#pragma once
#include <link.h>
#include <stddef.h>
@@ -50,6 +49,8 @@
async_safe_format_fd(2, "\n"); \
} while (false)
+void DL_WARN_documented_change(int api_level, const char* doc_link, const char* fmt, ...);
+
#define DL_ERR_AND_LOG(fmt, x...) \
do { \
DL_ERR(fmt, x); \
@@ -86,5 +87,3 @@
private:
std::string saved_error_msg_;
};
-
-#endif /* __LINKER_GLOBALS_H */
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index 3e53f74..9ce438e 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_LOGGER_H_
-#define _LINKER_LOGGER_H_
+#pragma once
#include <stdlib.h>
#include <limits.h>
@@ -61,5 +60,3 @@
// If the system property debug.ld.greylist_disabled is true, we'll not use the greylist
// regardless of API level.
extern bool g_greylist_disabled;
-
-#endif /* _LINKER_LOGGER_H_ */
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 5641696..8d486e8 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_MAIN_H
-#define __LINKER_MAIN_H
+#pragma once
#include <android/dlext.h>
@@ -71,5 +70,3 @@
bool solist_remove_soinfo(soinfo* si);
soinfo* solist_get_head();
soinfo* solist_get_somain();
-
-#endif
diff --git a/linker/linker_mapped_file_fragment.h b/linker/linker_mapped_file_fragment.h
index 0bfc7a3..f7872bd 100644
--- a/linker/linker_mapped_file_fragment.h
+++ b/linker/linker_mapped_file_fragment.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef LINKER_MAPPED_FILE_FRAGMENT_H
-#define LINKER_MAPPED_FILE_FRAGMENT_H
+
+#pragma once
#include <unistd.h>
@@ -49,5 +49,3 @@
DISALLOW_COPY_AND_ASSIGN(MappedFileFragment);
};
-
-#endif /* LINKER_MAPPED_FILE_FRAGMENT_H */
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index 472c4e8..6a54c13 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -32,27 +32,28 @@
#include <sys/cdefs.h>
#include <unistd.h>
+#include <atomic>
+
#include <async_safe/log.h>
static LinkerMemoryAllocator g_linker_allocator;
-static pid_t fallback_tid = 0;
+static std::atomic<pid_t> fallback_tid(0);
// Used by libdebuggerd_handler to switch allocators during a crash dump, in
// case the linker heap is corrupted. Do not use this function.
-extern "C" void __linker_enable_fallback_allocator() {
- if (fallback_tid != 0) {
- async_safe_fatal("attempted to use currently-in-use fallback allocator");
- }
-
- fallback_tid = gettid();
+extern "C" bool __linker_enable_fallback_allocator() {
+ pid_t expected = 0;
+ return fallback_tid.compare_exchange_strong(expected, gettid());
}
extern "C" void __linker_disable_fallback_allocator() {
- if (fallback_tid == 0) {
+ pid_t previous = fallback_tid.exchange(0);
+ if (previous == 0) {
async_safe_fatal("attempted to disable unused fallback allocator");
+ } else if (previous != gettid()) {
+ async_safe_fatal("attempted to disable fallback allocator in use by another thread (%d)",
+ previous);
}
-
- fallback_tid = 0;
}
static LinkerMemoryAllocator& get_fallback_allocator() {
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index 9fdf0b5..fd72cdc 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -64,7 +64,8 @@
// This is workaround for apps hacking into soinfo list.
// and inserting their own entries into it. (http://b/37191433)
if (!si->has_min_version(3)) {
- DL_WARN("invalid soinfo version for \"%s\"", si->get_soname());
+ DL_WARN("Warning: invalid soinfo version for \"%s\" (assuming inaccessible)",
+ si->get_soname());
return false;
}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index a7fe0d5..03520d7 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_NAMESPACES_H
-#define __LINKER_NAMESPACES_H
+#pragma once
#include "linker_common_types.h"
@@ -164,5 +163,3 @@
DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
};
-
-#endif /* __LINKER_NAMESPACES_H */
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index a9873c4..a5eab44 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -268,8 +268,10 @@
name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
return false;
}
- DL_WARN("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
- name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
+ DL_WARN_documented_change(__ANDROID_API_O__,
+ "invalid-elf-header_section-headers-enforced-for-api-level-26",
+ "\"%s\" has unsupported e_shentsize 0x%x (expected 0x%zx)",
+ name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
add_dlwarning(name_.c_str(), "has invalid ELF header");
}
@@ -280,7 +282,9 @@
return false;
}
- DL_WARN("\"%s\" has invalid e_shstrndx", name_.c_str());
+ DL_WARN_documented_change(__ANDROID_API_O__,
+ "invalid-elf-header_section-headers-enforced-for-api-level-26",
+ "\"%s\" has invalid e_shstrndx", name_.c_str());
add_dlwarning(name_.c_str(), "has invalid ELF header");
}
@@ -395,11 +399,13 @@
pt_dynamic_offset);
return false;
}
- DL_WARN("\"%s\" .dynamic section has invalid offset: 0x%zx, "
- "expected to match PT_DYNAMIC offset: 0x%zx",
- name_.c_str(),
- static_cast<size_t>(dynamic_shdr->sh_offset),
- pt_dynamic_offset);
+ DL_WARN_documented_change(__ANDROID_API_O__,
+ "invalid-elf-header_section-headers-enforced-for-api-level-26",
+ "\"%s\" .dynamic section has invalid offset: 0x%zx "
+ "(expected to match PT_DYNAMIC offset 0x%zx)",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_offset),
+ pt_dynamic_offset);
add_dlwarning(name_.c_str(), "invalid .dynamic section");
}
@@ -412,11 +418,13 @@
pt_dynamic_filesz);
return false;
}
- DL_WARN("\"%s\" .dynamic section has invalid size: 0x%zx, "
- "expected to match PT_DYNAMIC filesz: 0x%zx",
- name_.c_str(),
- static_cast<size_t>(dynamic_shdr->sh_size),
- pt_dynamic_filesz);
+ DL_WARN_documented_change(__ANDROID_API_O__,
+ "invalid-elf-header_section-headers-enforced-for-api-level-26",
+ "\"%s\" .dynamic section has invalid size: 0x%zx "
+ "(expected to match PT_DYNAMIC filesz 0x%zx)",
+ name_.c_str(),
+ static_cast<size_t>(dynamic_shdr->sh_size),
+ pt_dynamic_filesz);
add_dlwarning(name_.c_str(), "invalid .dynamic section");
}
@@ -651,10 +659,13 @@
if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
// W + E PT_LOAD segments are not allowed in O.
if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
- DL_ERR_AND_LOG("\"%s\": W + E load segments are not allowed", name_.c_str());
+ DL_ERR_AND_LOG("\"%s\": W+E load segments are not allowed", name_.c_str());
return false;
}
- DL_WARN("\"%s\": W + E load segments are not allowed", name_.c_str());
+ DL_WARN_documented_change(__ANDROID_API_O__,
+ "writable-and-executable-segments-enforced-for-api-level-26",
+ "\"%s\" has load segments that are both writable and executable",
+ name_.c_str());
add_dlwarning(name_.c_str(), "W+E load segments");
}
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index d6276ed..9b9ce94 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef LINKER_PHDR_H
-#define LINKER_PHDR_H
+
+#pragma once
/* Declarations related to the ELF program header table and segments.
*
@@ -134,5 +134,3 @@
const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
ElfW(Addr) load_bias);
-
-#endif /* LINKER_PHDR_H */
diff --git a/linker/linker_reloc_iterators.h b/linker/linker_reloc_iterators.h
index 6340924..b162684 100644
--- a/linker/linker_reloc_iterators.h
+++ b/linker/linker_reloc_iterators.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_RELOC_ITERATORS_H
-#define __LINKER_RELOC_ITERATORS_H
+#pragma once
#include "linker.h"
@@ -173,5 +172,3 @@
size_t relocation_group_index_;
rel_t reloc_;
};
-
-#endif // __LINKER_RELOC_ITERATORS_H
diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h
index ed00594..4bab0e0 100644
--- a/linker/linker_relocs.h
+++ b/linker/linker_relocs.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_RELOCS_H
-#define __LINKER_RELOCS_H
+#pragma once
#include <elf.h>
@@ -62,5 +61,3 @@
#define R_GENERIC_IRELATIVE R_X86_64_IRELATIVE
#endif
-
-#endif // __LINKER_RELOCS_H
diff --git a/linker/linker_sleb128.h b/linker/linker_sleb128.h
index 01e127d..6bb3199 100644
--- a/linker/linker_sleb128.h
+++ b/linker/linker_sleb128.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _LINKER_SLEB128_H
-#define _LINKER_SLEB128_H
+#pragma once
#include <stdint.h>
@@ -70,5 +69,3 @@
const uint8_t* current_;
const uint8_t* const end_;
};
-
-#endif // __LINKER_SLEB128_H
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 54bfcf0..731e8f5 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -152,7 +152,7 @@
ELF_ST_BIND(s->st_info) == STB_WEAK) {
return s->st_shndx != SHN_UNDEF;
} else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
- DL_WARN("unexpected ST_BIND value: %d for \"%s\" in \"%s\"",
+ DL_WARN("Warning: unexpected ST_BIND value: %d for \"%s\" in \"%s\" (ignoring)",
ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
}
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 447c7c3..6e1f005 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_SOINFO_H
-#define __LINKER_SOINFO_H
+#pragma once
#include <link.h>
@@ -386,5 +385,3 @@
}
}
}
-
-#endif /* __LINKER_SOINFO_H */
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 5bf88e7..661e7cb 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -209,31 +209,28 @@
const char* original_path = path.c_str();
if (realpath(original_path, resolved_path) != nullptr) {
struct stat s;
- if (stat(resolved_path, &s) == 0) {
- if (S_ISDIR(s.st_mode)) {
- resolved_paths->push_back(resolved_path);
- } else {
- DL_WARN("Warning: \"%s\" is not a directory (excluding from path)", resolved_path);
- continue;
- }
- } else {
- DL_WARN("Warning: cannot stat file \"%s\": %s", resolved_path, strerror(errno));
+ if (stat(resolved_path, &s) == -1) {
+ DL_WARN("Warning: cannot stat file \"%s\": %s (ignoring)", resolved_path, strerror(errno));
continue;
}
+ if (!S_ISDIR(s.st_mode)) {
+ DL_WARN("Warning: \"%s\" is not a directory (ignoring)", resolved_path);
+ continue;
+ }
+ resolved_paths->push_back(resolved_path);
} else {
+ std::string normalized_path;
+ if (!normalize_path(original_path, &normalized_path)) {
+ DL_WARN("Warning: unable to normalize \"%s\" (ignoring)", original_path);
+ continue;
+ }
+
std::string zip_path;
std::string entry_path;
-
- std::string normalized_path;
-
- if (!normalize_path(original_path, &normalized_path)) {
- DL_WARN("Warning: unable to normalize \"%s\"", original_path);
- continue;
- }
-
if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
- DL_WARN("Warning: unable to resolve \"%s\": %s", zip_path.c_str(), strerror(errno));
+ DL_WARN("Warning: unable to resolve \"%s\": %s (ignoring)",
+ zip_path.c_str(), strerror(errno));
continue;
}
@@ -242,4 +239,3 @@
}
}
}
-
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index e104a25..214646c 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef __LINKER_UTILS_H
-#define __LINKER_UTILS_H
+#pragma once
#include <string>
#include <vector>
@@ -56,5 +55,3 @@
off64_t page_start(off64_t offset);
size_t page_offset(off64_t offset);
bool safe_add(off64_t* out, off64_t a, size_t b);
-
-#endif
diff --git a/tests/Android.bp b/tests/Android.bp
index 443fe8e..ec90296 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -17,6 +17,7 @@
cc_defaults {
name: "bionic_tests_defaults",
host_supported: true,
+ cpp_std: "experimental",
target: {
darwin: {
enabled: false,
@@ -75,6 +76,7 @@
"getcwd_test.cpp",
"glob_test.cpp",
"grp_pwd_test.cpp",
+ "grp_pwd_file_test.cpp",
"iconv_test.cpp",
"ifaddrs_test.cpp",
"inttypes_test.cpp",
@@ -245,10 +247,13 @@
cc_test_library {
name: "libfortify1-tests-clang",
- defaults: ["bionic_fortify_tests_defaults", "bionic_tests_defaults"],
+ defaults: [
+ "bionic_fortify_tests_defaults",
+ "bionic_tests_defaults",
+ ],
cflags: [
"-D_FORTIFY_SOURCE=1",
- "-DTEST_NAME=Fortify1_clang"
+ "-DTEST_NAME=Fortify1_clang",
],
shared: {
enabled: false,
@@ -257,10 +262,13 @@
cc_test_library {
name: "libfortify2-tests-clang",
- defaults: ["bionic_fortify_tests_defaults", "bionic_tests_defaults"],
+ defaults: [
+ "bionic_fortify_tests_defaults",
+ "bionic_tests_defaults",
+ ],
cflags: [
"-D_FORTIFY_SOURCE=2",
- "-DTEST_NAME=Fortify2_clang"
+ "-DTEST_NAME=Fortify2_clang",
],
shared: {
enabled: false,
@@ -312,7 +320,10 @@
cc_test_library {
name: "libBionicLoaderTests",
- defaults: ["bionic_tests_defaults", "llvm-defaults"],
+ defaults: [
+ "bionic_tests_defaults",
+ "llvm-defaults",
+ ],
srcs: [
"atexit_test.cpp",
"dl_test.cpp",
@@ -347,7 +358,7 @@
"libLLVMCore",
"libLLVMSupport",
],
- }
+ },
},
}
@@ -439,12 +450,15 @@
"-Wl,--enable-new-dtags",
],
},
- }
+ },
}
cc_test {
name: "bionic-unit-tests",
- defaults: ["bionic_unit_tests_defaults", "bionic_tests_defaults"],
+ defaults: [
+ "bionic_unit_tests_defaults",
+ "bionic_tests_defaults",
+ ],
target: {
android: {
diff --git a/tests/BionicDeathTest.h b/tests/BionicDeathTest.h
index 3e8d7b2..6826ab7 100644
--- a/tests/BionicDeathTest.h
+++ b/tests/BionicDeathTest.h
@@ -21,25 +21,28 @@
#include <gtest/gtest.h>
+#if !defined(__BIONIC__)
+#define sigaction64 sigaction
+#endif
+
class BionicDeathTest : public testing::Test {
protected:
virtual void SetUp() {
// Suppress debuggerd stack traces. Too slow.
for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
- struct sigaction action = {};
- action.sa_handler = SIG_DFL;
- sigaction(signo, &action, &previous_);
+ struct sigaction64 action = { .sa_handler = SIG_DFL };
+ sigaction64(signo, &action, &previous_);
}
}
virtual void TearDown() {
for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
- sigaction(signo, &previous_, nullptr);
+ sigaction64(signo, &previous_, nullptr);
}
}
private:
- struct sigaction previous_;
+ struct sigaction64 previous_;
};
#endif // BIONIC_TESTS_BIONIC_DEATH_TEST_H_
diff --git a/tests/ScopedSignalHandler.h b/tests/ScopedSignalHandler.h
deleted file mode 100644
index 85c41a8..0000000
--- a/tests/ScopedSignalHandler.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _BIONIC_TESTS_SCOPED_SIGNAL_HANDLER_H
-#define _BIONIC_TESTS_SCOPED_SIGNAL_HANDLER_H
-
-#include <signal.h>
-#include <string.h>
-
-#if defined(__GLIBC__)
-#define posix_spawnattr_getsigdefault64 posix_spawnattr_getsigdefault
-#define posix_spawnattr_getsigmask64 posix_spawnattr_getsigmask
-#define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
-#define posix_spawnattr_setsigmask64 posix_spawnattr_setsigmask
-#define pthread_sigmask64 pthread_sigmask
-#define sigaddset64 sigaddset
-#define sigdelset64 sigdelset
-#define sigemptyset64 sigemptyset
-#define sigfillset64 sigfillset
-#define sigismember64 sigismember
-#define sigpending64 sigpending
-#define sigprocmask64 sigprocmask
-#define sigset64_t sigset_t
-#define sigsuspend64 sigsuspend
-#define sigtimedwait64 sigtimedwait
-#define sigwait64 sigwait
-#define sigwaitinfo64 sigwaitinfo
-#endif
-
-class ScopedSignalHandler {
- public:
- ScopedSignalHandler(int signal_number, void (*handler)(int), int sa_flags = 0)
- : signal_number_(signal_number) {
- memset(&action_, 0, sizeof(action_));
- action_.sa_flags = sa_flags;
- action_.sa_handler = handler;
- sigaction(signal_number_, &action_, &old_action_);
- }
-
- ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*),
- int sa_flags = SA_SIGINFO)
- : signal_number_(signal_number) {
- memset(&action_, 0, sizeof(action_));
- action_.sa_flags = sa_flags;
- action_.sa_sigaction = action;
- sigaction(signal_number_, &action_, &old_action_);
- }
-
- ScopedSignalHandler(int signal_number) : signal_number_(signal_number) {
- sigaction(signal_number, nullptr, &old_action_);
- }
-
- ~ScopedSignalHandler() {
- sigaction(signal_number_, &old_action_, NULL);
- }
-
- private:
- struct sigaction action_;
- struct sigaction old_action_;
- const int signal_number_;
-};
-
-class SignalMaskRestorer {
- public:
- SignalMaskRestorer() {
- sigprocmask64(SIG_SETMASK, nullptr, &old_mask_);
- }
-
- ~SignalMaskRestorer() {
- sigprocmask64(SIG_SETMASK, &old_mask_, nullptr);
- }
-
- private:
- sigset64_t old_mask_;
-};
-
-#endif // _BIONIC_TESTS_SCOPED_SIGNAL_HANDLER_H
diff --git a/tests/SignalUtils.h b/tests/SignalUtils.h
new file mode 100644
index 0000000..ece28ba
--- /dev/null
+++ b/tests/SignalUtils.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <signal.h>
+#include <string.h>
+
+#if defined(__GLIBC__)
+#define posix_spawnattr_getsigdefault64 posix_spawnattr_getsigdefault
+#define posix_spawnattr_getsigmask64 posix_spawnattr_getsigmask
+#define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
+#define posix_spawnattr_setsigmask64 posix_spawnattr_setsigmask
+#define pthread_sigmask64 pthread_sigmask
+#define sigaction64 sigaction
+#define sigaddset64 sigaddset
+#define sigdelset64 sigdelset
+#define sigemptyset64 sigemptyset
+#define sigfillset64 sigfillset
+#define sigismember64 sigismember
+#define sigpending64 sigpending
+#define sigprocmask64 sigprocmask
+#define sigset64_t sigset_t
+#define sigsuspend64 sigsuspend
+#define sigtimedwait64 sigtimedwait
+#define sigwait64 sigwait
+#define sigwaitinfo64 sigwaitinfo
+#endif
+
+#include "private/ScopedSignalHandler.h"
+
+class SignalMaskRestorer {
+ public:
+ SignalMaskRestorer() {
+ sigprocmask64(SIG_SETMASK, nullptr, &old_mask_);
+ }
+
+ ~SignalMaskRestorer() {
+ sigprocmask64(SIG_SETMASK, &old_mask_, nullptr);
+ }
+
+ private:
+ sigset64_t old_mask_;
+};
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 000d1f7..46f5097 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -256,7 +256,12 @@
return;
}
#endif
- void* handle = dlopen("linux-vdso.so.1", RTLD_NOW);
+
+ const char* vdso_name = "linux-vdso.so.1";
+#if defined(__i386__)
+ vdso_name = "linux-gate.so.1";
+#endif
+ void* handle = dlopen(vdso_name, RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
dlclose(handle);
}
@@ -1118,7 +1123,7 @@
// Check that RTLD_NEXT of a libc symbol works in dlopened library
TEST(dlfcn, rtld_next_from_library) {
- void* library_with_fclose = dlopen("libtest_check_rtld_next_from_library.so", RTLD_NOW);
+ void* library_with_fclose = dlopen("libtest_check_rtld_next_from_library.so", RTLD_NOW | RTLD_GLOBAL);
ASSERT_TRUE(library_with_fclose != nullptr) << dlerror();
void* expected_addr = dlsym(RTLD_DEFAULT, "fclose");
ASSERT_TRUE(expected_addr != nullptr) << dlerror();
@@ -1498,7 +1503,7 @@
"/libtest_invalid-rw_load_segment.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
- std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W + E load segments are not allowed";
+ std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W+E load segments are not allowed";
ASSERT_STREQ(expected_dlerror.c_str(), dlerror());
}
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index 9fc7d96..d27808f 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -16,7 +16,6 @@
#include <gtest/gtest.h>
-#include "ScopedSignalHandler.h"
#include "utils.h"
#include <fenv.h>
diff --git a/tests/grp_pwd_file_test.cpp b/tests/grp_pwd_file_test.cpp
new file mode 100644
index 0000000..d6f3c9f
--- /dev/null
+++ b/tests/grp_pwd_file_test.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+#include "TemporaryFile.h"
+
+#if defined(__BIONIC__)
+#include "../libc/bionic/grp_pwd_file.cpp"
+
+template <typename T>
+class FileUnmapper {
+ public:
+ FileUnmapper(T& file) : file_(file) {
+ }
+ ~FileUnmapper() {
+ file_.Unmap();
+ }
+
+ private:
+ T& file_;
+};
+
+void FindAndCheckPasswdEntry(PasswdFile* file, const char* name, uid_t uid, gid_t gid,
+ const char* dir, const char* shell) {
+ passwd_state_t name_passwd_state;
+ ASSERT_TRUE(file->FindByName(name, &name_passwd_state)) << name;
+
+ passwd& name_passwd = name_passwd_state.passwd_;
+ EXPECT_STREQ(name, name_passwd.pw_name);
+ EXPECT_EQ(nullptr, name_passwd.pw_passwd);
+ EXPECT_EQ(uid, name_passwd.pw_uid);
+ EXPECT_EQ(gid, name_passwd.pw_gid);
+ EXPECT_EQ(nullptr, name_passwd.pw_gecos);
+ EXPECT_STREQ(dir, name_passwd.pw_dir);
+ EXPECT_STREQ(shell, name_passwd.pw_shell);
+
+ passwd_state_t id_passwd_state;
+ ASSERT_TRUE(file->FindById(uid, &id_passwd_state)) << uid;
+
+ passwd& id_passwd = id_passwd_state.passwd_;
+ EXPECT_STREQ(name, id_passwd.pw_name);
+ EXPECT_EQ(nullptr, id_passwd.pw_passwd);
+ EXPECT_EQ(uid, id_passwd.pw_uid);
+ EXPECT_EQ(gid, id_passwd.pw_gid);
+ EXPECT_EQ(nullptr, id_passwd.pw_gecos);
+ EXPECT_STREQ(dir, id_passwd.pw_dir);
+ EXPECT_STREQ(shell, id_passwd.pw_shell);
+}
+
+void FindAndCheckGroupEntry(GroupFile* file, const char* name, gid_t gid) {
+ group_state_t name_group_state;
+ ASSERT_TRUE(file->FindByName(name, &name_group_state)) << name;
+
+ group& name_group = name_group_state.group_;
+ EXPECT_STREQ(name, name_group.gr_name);
+ EXPECT_EQ(nullptr, name_group.gr_passwd);
+ EXPECT_EQ(gid, name_group.gr_gid);
+ EXPECT_EQ(name_group.gr_name, name_group.gr_mem[0]);
+ EXPECT_EQ(nullptr, name_group.gr_mem[1]);
+
+ group_state_t id_group_state;
+ ASSERT_TRUE(file->FindById(gid, &id_group_state)) << gid;
+
+ group& id_group = id_group_state.group_;
+ EXPECT_STREQ(name, id_group.gr_name);
+ EXPECT_EQ(nullptr, id_group.gr_passwd);
+ EXPECT_EQ(gid, id_group.gr_gid);
+ EXPECT_EQ(id_group.gr_name, id_group.gr_mem[0]);
+ EXPECT_EQ(nullptr, id_group.gr_mem[1]);
+}
+
+#endif // __BIONIC__
+
+TEST(grp_pwd_file, passwd_file_one_entry) {
+#if defined(__BIONIC__)
+ TemporaryFile file;
+ ASSERT_NE(-1, file.fd);
+ static const char test_string[] = "name:password:1:2:user_info:dir:shell\n";
+ write(file.fd, test_string, sizeof(test_string) - 1);
+
+ PasswdFile passwd_file(file.filename);
+ FileUnmapper unmapper(passwd_file);
+
+ FindAndCheckPasswdEntry(&passwd_file, "name", 1, 2, "dir", "shell");
+
+ EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
+ EXPECT_FALSE(passwd_file.FindById(3, nullptr));
+
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+
+TEST(grp_pwd_file, group_file_one_entry) {
+#if defined(__BIONIC__)
+ TemporaryFile file;
+ ASSERT_NE(-1, file.fd);
+ static const char test_string[] = "name:password:1:one,two,three\n";
+ write(file.fd, test_string, sizeof(test_string) - 1);
+
+ GroupFile group_file(file.filename);
+ FileUnmapper unmapper(group_file);
+
+ FindAndCheckGroupEntry(&group_file, "name", 1);
+
+ EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
+ EXPECT_FALSE(group_file.FindById(3, nullptr));
+
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+
+TEST(grp_pwd_file, passwd_file_many_entries) {
+#if defined(__BIONIC__)
+ TemporaryFile file;
+ ASSERT_NE(-1, file.fd);
+ static const char test_string[] =
+ "first:x:1:2::dir:shell\n"
+ "abc1::3:4::def:abc\n"
+ "abc2::5:4:abc::abc\n"
+ "abc3::7:4:abc:def:\n"
+ "abc4::9:4:::abc\n"
+ "abc5::11:4:abc:def:abc\n"
+ "middle-ish::13:4::/:/system/bin/sh\n"
+ "abc7::15:4:abc::\n"
+ "abc8::17:4:::\n"
+ "abc9::19:4:abc:def:abc\n"
+ "abc10::21:4:abc:def:abc\n"
+ "abc11::23:4:abc:def:abc\n"
+ "abc12::25:4:abc:def:abc\n"
+ "abc13::27:4:abc:def:abc\n"
+ "last::29:4::last_user_dir:last_user_shell\n";
+
+ write(file.fd, test_string, sizeof(test_string) - 1);
+
+ PasswdFile passwd_file(file.filename);
+ FileUnmapper unmapper(passwd_file);
+
+ FindAndCheckPasswdEntry(&passwd_file, "first", 1, 2, "dir", "shell");
+ FindAndCheckPasswdEntry(&passwd_file, "middle-ish", 13, 4, "/", "/system/bin/sh");
+ FindAndCheckPasswdEntry(&passwd_file, "last", 29, 4, "last_user_dir", "last_user_shell");
+
+ EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
+ EXPECT_FALSE(passwd_file.FindById(50, nullptr));
+
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+
+TEST(grp_pwd_file, group_file_many_entries) {
+#if defined(__BIONIC__)
+ TemporaryFile file;
+ ASSERT_NE(-1, file.fd);
+ static const char test_string[] =
+ "first:password:1:one,two,three\n"
+ "abc:def:2:group1,group2,group3\n"
+ "abc:def:3:\n"
+ "abc:def:4:\n"
+ "abc:def:5:\n"
+ "middle-ish:def_a_password_that_is_over_32_characters_long:6:\n"
+ "abc:def:7:\n"
+ "abc:def:8:\n"
+ "abc:def:20:\n"
+ "abc:def:25:\n"
+ "abc:def:27:\n"
+ "abc:def:52:\n"
+ "last::800:\n";
+
+ write(file.fd, test_string, sizeof(test_string) - 1);
+
+ GroupFile group_file(file.filename);
+ FileUnmapper unmapper(group_file);
+
+ FindAndCheckGroupEntry(&group_file, "first", 1);
+ FindAndCheckGroupEntry(&group_file, "middle-ish", 6);
+ FindAndCheckGroupEntry(&group_file, "last", 800);
+
+ EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
+ EXPECT_FALSE(group_file.FindById(799, nullptr));
+
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 61748c8..12d4b7f 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -115,10 +115,14 @@
#else // !defined(__BIONIC__)
-static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
+static void print_no_getpwnam_test_info() {
GTEST_LOG_(INFO) << "This test is about uid/username translation for Android, which does nothing on libc other than bionic.\n";
}
+static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
+ print_no_getpwnam_test_info();
+}
+
#endif
TEST(pwd, getpwnam_system_id_root) {
@@ -238,6 +242,7 @@
}
TEST(pwd, getpwent_iterate) {
+#if defined(__BIONIC__)
passwd* pwd;
std::set<uid_t> uids;
@@ -257,19 +262,15 @@
EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
}
- // TODO(b/27999086): fix this check with the OEM range
- // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
- // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
- // yet, so therefore we do not check for uid's in the OEM range.
- if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
- !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
- EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
- }
+ EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
uids.emplace(pwd->pw_uid);
}
endpwent();
expect_ids(uids);
+#else
+ print_no_getpwnam_test_info();
+#endif
}
static void check_group(const group* grp, const char* group_name, gid_t gid) {
@@ -484,6 +485,7 @@
}
TEST(grp, getgrent_iterate) {
+#if defined(__BIONIC__)
group* grp;
std::set<gid_t> gids;
@@ -494,17 +496,13 @@
EXPECT_STREQ(grp->gr_name, grp->gr_mem[0]) << "grp->gr_gid: " << grp->gr_gid;
EXPECT_TRUE(grp->gr_mem[1] == NULL) << "grp->gr_gid: " << grp->gr_gid;
- // TODO(b/27999086): fix this check with the OEM range
- // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
- // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
- // yet, so therefore we do not check for gid's in the OEM range.
- if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
- !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
- EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
- }
+ EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
gids.emplace(grp->gr_gid);
}
endgrent();
expect_ids(gids);
+#else
+ print_no_getgrnam_test_info();
+#endif
}
diff --git a/tests/headers/posix/Android.bp b/tests/headers/posix/Android.bp
index 682627f..8f3a2f2 100644
--- a/tests/headers/posix/Android.bp
+++ b/tests/headers/posix/Android.bp
@@ -18,11 +18,11 @@
name: "libbionic_tests_headers_posix",
srcs: ["*.c"],
cflags: [
- "-Wno-absolute-value", // broken clang diagnostic that doesn't understand <tgmath.h>
- "-Wno-deprecated",
- "-Werror",
- "-D_POSIX_C_SOURCE=200809L",
- "-D_XOPEN_SOURCE=700",
+ "-Wno-absolute-value", // broken clang diagnostic that doesn't understand <tgmath.h>
+ "-Wno-deprecated",
+ "-Werror",
+ "-D_POSIX_C_SOURCE=200809L",
+ "-D_XOPEN_SOURCE=700",
],
host_supported: true,
target: {
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index cae30b5..3afda67 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -80,7 +80,7 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["dlext_test_library.cpp"],
ldflags: ["-Wl,-z,norelro"],
- shared_libs = ["libtest_simple"],
+ shared_libs: ["libtest_simple"],
}
// -----------------------------------------------------------------------------
@@ -123,7 +123,6 @@
relative_install_path: "bionic-loader-test-libs/public_namespace_libs",
}
-
// -----------------------------------------------------------------------------
// Library used by dlext indirect unload on the namespace boundary tests
//
@@ -407,7 +406,6 @@
// +-> libtest_relo_check_dt_needed_order_2.so
// -----------------------------------------------------------------------------
-
cc_test_library {
name: "libtest_relo_check_dt_needed_order",
defaults: ["bionic_testlib_defaults"],
@@ -457,7 +455,7 @@
name: "libtest_ifunc_variable",
defaults: ["bionic_testlib_defaults"],
srcs: ["dlopen_testlib_ifunc_variable.cpp"],
- shared_libs: [ "libtest_ifunc_variable_impl" ],
+ shared_libs: ["libtest_ifunc_variable_impl"],
arch: {
mips: {
@@ -560,7 +558,6 @@
},
}
-
// -----------------------------------------------------------------------------
// Library with weak function
// -----------------------------------------------------------------------------
@@ -696,7 +693,6 @@
srcs: ["thread_local_dtor.cpp"],
}
-
// -----------------------------------------------------------------------------
// Tool to use to align the shared libraries in a zip file.
// -----------------------------------------------------------------------------
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index d029311..1e7e58d 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -225,7 +225,9 @@
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isfinite(double);
extern "C" int __isfinitef(float);
+extern "C" int isfinitef(float);
extern "C" int __isfinitel(long double);
+extern "C" int isfinitel(long double);
TEST(MATH_TEST, __isfinite) {
#if defined(__GLIBC__)
@@ -243,6 +245,14 @@
ASSERT_FALSE(__isfinitef(HUGE_VALF));
}
+TEST(MATH_TEST, isfinitef) {
+#if defined(__GLIBC__)
+#define isfinitef __finitef
+#endif
+ ASSERT_TRUE(isfinitef(123.0f));
+ ASSERT_FALSE(isfinitef(HUGE_VALF));
+}
+
TEST(MATH_TEST, __isfinitel) {
#if defined(__GLIBC__)
#define __isfinitel __finitel
@@ -251,6 +261,14 @@
ASSERT_FALSE(__isfinitel(HUGE_VALL));
}
+TEST(MATH_TEST, isfinitel) {
+#if defined(__GLIBC__)
+#define isfinitel __finitel
+#endif
+ ASSERT_TRUE(isfinitel(123.0L));
+ ASSERT_FALSE(isfinitel(HUGE_VALL));
+}
+
TEST(MATH_TEST, finite) {
ASSERT_TRUE(finite(123.0));
ASSERT_FALSE(finite(HUGE_VAL));
@@ -265,7 +283,9 @@
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isinf(double);
extern "C" int __isinff(float);
+extern "C" int isinff(float);
extern "C" int __isinfl(long double);
+extern "C" int isinfl(long double);
TEST(MATH_TEST, __isinf) {
ASSERT_FALSE(__isinf(123.0));
@@ -277,11 +297,21 @@
ASSERT_TRUE(__isinff(HUGE_VALF));
}
+TEST(MATH_TEST, isinff) {
+ ASSERT_FALSE(isinff(123.0f));
+ ASSERT_TRUE(isinff(HUGE_VALF));
+}
+
TEST(MATH_TEST, __isinfl) {
ASSERT_FALSE(__isinfl(123.0L));
ASSERT_TRUE(__isinfl(HUGE_VALL));
}
+TEST(MATH_TEST, isinfl) {
+ ASSERT_FALSE(isinfl(123.0L));
+ ASSERT_TRUE(isinfl(HUGE_VALL));
+}
+
TEST(MATH_TEST, isnan_function) {
// The isnan macro deals with all three types; the isnan function is for doubles.
ASSERT_FALSE((isnan)(123.0));
@@ -291,7 +321,9 @@
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isnan(double);
extern "C" int __isnanf(float);
+extern "C" int isnanf(float);
extern "C" int __isnanl(long double);
+extern "C" int isnanl(long double);
TEST(MATH_TEST, __isnan) {
ASSERT_FALSE(__isnan(123.0));
@@ -303,20 +335,27 @@
ASSERT_TRUE(__isnanf(nanf("")));
}
-TEST(MATH_TEST, __isnanl) {
- ASSERT_FALSE(__isnanl(123.0L));
- ASSERT_TRUE(__isnanl(nanl("")));
-}
-
TEST(MATH_TEST, isnanf) {
ASSERT_FALSE(isnanf(123.0f));
ASSERT_TRUE(isnanf(nanf("")));
}
+TEST(MATH_TEST, __isnanl) {
+ ASSERT_FALSE(__isnanl(123.0L));
+ ASSERT_TRUE(__isnanl(nanl("")));
+}
+
+TEST(MATH_TEST, isnanl) {
+ ASSERT_FALSE(isnanl(123.0L));
+ ASSERT_TRUE(isnanl(nanl("")));
+}
+
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __isnormal(double);
extern "C" int __isnormalf(float);
+extern "C" int isnormalf(float);
extern "C" int __isnormall(long double);
+extern "C" int isnormall(long double);
TEST(MATH_TEST, __isnormal) {
#if defined(__BIONIC__)
@@ -336,6 +375,15 @@
#endif // __BIONIC__
}
+TEST(MATH_TEST, isnormalf) {
+#if defined(__BIONIC__)
+ ASSERT_TRUE(isnormalf(123.0f));
+ ASSERT_FALSE(isnormalf(float_subnormal()));
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "glibc doesn't have isnormalf.\n";
+#endif // __BIONIC__
+}
+
TEST(MATH_TEST, __isnormall) {
#if defined(__BIONIC__)
ASSERT_TRUE(__isnormall(123.0L));
@@ -345,6 +393,15 @@
#endif // __BIONIC__
}
+TEST(MATH_TEST, isnormall) {
+#if defined(__BIONIC__)
+ ASSERT_TRUE(isnormall(123.0L));
+ ASSERT_FALSE(isnormall(ldouble_subnormal()));
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "glibc doesn't have isnormall.\n";
+#endif // __BIONIC__
+}
+
// Historical BSD cruft that isn't exposed in <math.h> any more.
extern "C" int __signbit(double);
extern "C" int __signbitf(float);
@@ -957,7 +1014,7 @@
TEST(MATH_TEST, logbf) {
ASSERT_EQ(-HUGE_VALF, logbf(0.0f));
ASSERT_TRUE(isnanf(logbf(nanf(""))));
- ASSERT_TRUE(__isinff(logbf(HUGE_VALF)));
+ ASSERT_TRUE(isinff(logbf(HUGE_VALF)));
ASSERT_EQ(0.0f, logbf(1.0f));
ASSERT_EQ(3.0f, logbf(10.0f));
}
@@ -980,7 +1037,7 @@
TEST(MATH_TEST, log1pf) {
ASSERT_EQ(-HUGE_VALF, log1pf(-1.0f));
ASSERT_TRUE(isnanf(log1pf(nanf(""))));
- ASSERT_TRUE(__isinff(log1pf(HUGE_VALF)));
+ ASSERT_TRUE(isinff(log1pf(HUGE_VALF)));
ASSERT_FLOAT_EQ(1.0f, log1pf(static_cast<float>(M_E) - 1.0f));
}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index f288612..523ed63 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -40,7 +40,7 @@
#include "private/bionic_constants.h"
#include "private/bionic_macros.h"
#include "BionicDeathTest.h"
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
#include "utils.h"
TEST(pthread, pthread_key_create) {
@@ -914,7 +914,7 @@
ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
wakeup_arg.tid = 0;
- wakeup_arg.trylock_function = pthread_rwlock_trywrlock;
+ wakeup_arg.trylock_function = &pthread_rwlock_trywrlock;
wakeup_arg.lock_function = lock_function;
pthread_t thread;
@@ -950,7 +950,7 @@
ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
wakeup_arg.tid = 0;
- wakeup_arg.trylock_function = pthread_rwlock_tryrdlock;
+ wakeup_arg.trylock_function = &pthread_rwlock_tryrdlock;
wakeup_arg.lock_function = lock_function;
pthread_t thread;
@@ -1010,8 +1010,8 @@
ASSERT_EQ(0, pthread_rwlock_wrlock(&wakeup_arg.lock));
wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
wakeup_arg.tid = 0;
- wakeup_arg.trylock_function = pthread_rwlock_tryrdlock;
- wakeup_arg.timed_lock_function = pthread_rwlock_timedrdlock;
+ wakeup_arg.trylock_function = &pthread_rwlock_tryrdlock;
+ wakeup_arg.timed_lock_function = &pthread_rwlock_timedrdlock;
pthread_t thread;
ASSERT_EQ(0, pthread_create(&thread, nullptr,
@@ -1031,8 +1031,8 @@
ASSERT_EQ(0, pthread_rwlock_rdlock(&wakeup_arg.lock));
wakeup_arg.progress = RwlockWakeupHelperArg::LOCK_INITIALIZED;
wakeup_arg.tid = 0;
- wakeup_arg.trylock_function = pthread_rwlock_trywrlock;
- wakeup_arg.timed_lock_function = pthread_rwlock_timedwrlock;
+ wakeup_arg.trylock_function = &pthread_rwlock_trywrlock;
+ wakeup_arg.timed_lock_function = &pthread_rwlock_timedwrlock;
pthread_t thread;
ASSERT_EQ(0, pthread_create(&thread, nullptr,
@@ -1718,6 +1718,7 @@
void destroy() {
ASSERT_EQ(0, pthread_mutex_destroy(&lock));
+ ASSERT_EQ(EBUSY, pthread_mutex_destroy(&lock));
}
DISALLOW_COPY_AND_ASSIGN(PthreadMutex);
@@ -1776,15 +1777,42 @@
}
TEST(pthread, pthread_mutex_lock_pi) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
TestPthreadMutexLockNormal(PTHREAD_PRIO_INHERIT);
TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_INHERIT);
TestPthreadMutexLockRecursive(PTHREAD_PRIO_INHERIT);
}
+TEST(pthread, pthread_mutex_pi_count_limit) {
+#if defined(__BIONIC__) && !defined(__LP64__)
+ // Bionic only supports 65536 pi mutexes in 32-bit programs.
+ pthread_mutexattr_t attr;
+ ASSERT_EQ(0, pthread_mutexattr_init(&attr));
+ ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT));
+ std::vector<pthread_mutex_t> mutexes(65536);
+ // Test if we can use 65536 pi mutexes at the same time.
+ // Run 2 times to check if freed pi mutexes can be recycled.
+ for (int repeat = 0; repeat < 2; ++repeat) {
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_init(&m, &attr));
+ }
+ pthread_mutex_t m;
+ ASSERT_EQ(ENOMEM, pthread_mutex_init(&m, &attr));
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_lock(&m));
+ }
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_unlock(&m));
+ }
+ for (auto& m : mutexes) {
+ ASSERT_EQ(0, pthread_mutex_destroy(&m));
+ }
+ }
+ ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing as pi mutex count isn't limited.\n";
+#endif
+}
+
TEST(pthread, pthread_mutex_init_same_as_static_initializers) {
pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER;
PthreadMutex m1(PTHREAD_MUTEX_NORMAL);
@@ -1801,6 +1829,7 @@
ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
}
+
class MutexWakeupHelper {
private:
PthreadMutex m;
@@ -1949,10 +1978,6 @@
};
TEST(pthread, pthread_mutex_pi_wakeup) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
for (int type : {PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK}) {
for (int protocol : {PTHREAD_PRIO_INHERIT}) {
PIMutexWakeupHelper helper(type, protocol);
@@ -2005,10 +2030,6 @@
}
TEST(pthread, pthread_mutex_timedlock_pi) {
-#if defined(__BIONIC__) && !defined(__LP64__)
- GTEST_LOG_(INFO) << "PTHREAD_PRIO_INHERIT isn't supported in 32bit programs, skipping test";
- return;
-#endif
PthreadMutex m(PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_INHERIT);
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index 24a2dbe..b216ec9 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -24,7 +24,7 @@
#include <unistd.h>
#include "private/bionic_constants.h"
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
TEST(semaphore, sem_init) {
sem_t s;
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 4f5e60c..a49e910 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -19,7 +19,7 @@
#include <setjmp.h>
#include <stdlib.h>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
TEST(setjmp, setjmp_smoke) {
int value;
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index ebc079e..53c91a2 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -24,7 +24,7 @@
#include <gtest/gtest.h>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
static int SIGNAL_MIN() {
return 1; // Signals start at 1 (SIGHUP), not 0.
@@ -269,55 +269,280 @@
ASSERT_EQ(1, g_sigsuspend64_signal_handler_call_count);
}
-static void EmptySignalHandler(int) {}
-static void EmptySignalAction(int, siginfo_t*, void*) {}
-
-TEST(signal, sigaction) {
+template <typename SigActionT, typename SigSetT>
+static void TestSigAction(int (sigaction_fn)(int, const SigActionT*, SigActionT*),
+ int (sigaddset_fn)(SigSetT*, int),
+ int sig) {
// Both bionic and glibc set SA_RESTORER when talking to the kernel on arm,
// arm64, x86, and x86-64. The version of glibc we're using also doesn't
// define SA_RESTORER, but luckily it's the same value everywhere, and mips
// doesn't use the bit for anything.
static const unsigned sa_restorer = 0x4000000;
- // See what's currently set for SIGALRM.
- struct sigaction original_sa;
- memset(&original_sa, 0, sizeof(original_sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa));
+ // See what's currently set for this signal.
+ SigActionT original_sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &original_sa));
ASSERT_TRUE(original_sa.sa_handler == NULL);
ASSERT_TRUE(original_sa.sa_sigaction == NULL);
ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer);
+#ifdef SA_RESTORER
+ ASSERT_EQ(bool(original_sa.sa_flags & sa_restorer), bool(original_sa.sa_restorer));
+#endif
// Set a traditional sa_handler signal handler.
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sigaddset(&sa.sa_mask, SIGALRM);
+ auto no_op_signal_handler = [](int) {};
+ SigActionT sa = {};
+ sigaddset_fn(&sa.sa_mask, sig);
sa.sa_flags = SA_ONSTACK;
- sa.sa_handler = EmptySignalHandler;
- ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+ sa.sa_handler = no_op_signal_handler;
+ ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
// Check that we can read it back.
- memset(&sa, 0, sizeof(sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
- ASSERT_TRUE(sa.sa_handler == EmptySignalHandler);
+ sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+ ASSERT_TRUE(sa.sa_handler == no_op_signal_handler);
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer);
+#ifdef SA_RESTORER
+ ASSERT_EQ(bool(sa.sa_flags & sa_restorer), bool(sa.sa_restorer));
+#endif
// Set a new-style sa_sigaction signal handler.
- memset(&sa, 0, sizeof(sa));
- sigaddset(&sa.sa_mask, SIGALRM);
+ auto no_op_sigaction = [](int, siginfo_t*, void*) {};
+ sa = {};
+ sigaddset_fn(&sa.sa_mask, sig);
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
- sa.sa_sigaction = EmptySignalAction;
- ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+ sa.sa_sigaction = no_op_sigaction;
+ ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
// Check that we can read it back.
- memset(&sa, 0, sizeof(sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
- ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction);
+ sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+ ASSERT_TRUE(sa.sa_sigaction == no_op_sigaction);
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer);
+#ifdef SA_RESTORER
+ ASSERT_EQ(bool(sa.sa_flags & sa_restorer), bool(sa.sa_restorer));
+#endif
// Put everything back how it was.
- ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL));
+ ASSERT_EQ(0, sigaction_fn(sig, &original_sa, NULL));
+}
+
+TEST(signal, sigaction) {
+ TestSigAction(sigaction, sigaddset, SIGALRM);
+}
+
+TEST(signal, sigaction64_SIGRTMIN) {
+ TestSigAction(sigaction64, sigaddset64, SIGRTMIN);
+}
+
+static void ClearSignalMask() {
+ uint64_t sigset = 0;
+ if (syscall(__NR_rt_sigprocmask, SIG_SETMASK, &sigset, nullptr, sizeof(sigset)) != 0) {
+ abort();
+ }
+}
+
+static uint64_t GetSignalMask() {
+ uint64_t sigset;
+ if (syscall(__NR_rt_sigprocmask, SIG_SETMASK, nullptr, &sigset, sizeof(sigset)) != 0) {
+ abort();
+ }
+ return sigset;
+}
+
+enum class SignalMaskFunctionType {
+ RtAware,
+ RtNonaware,
+};
+
+#if defined(__LP64__) || !defined(__BIONIC__)
+constexpr SignalMaskFunctionType sigset_type = SignalMaskFunctionType::RtAware;
+#else
+constexpr SignalMaskFunctionType sigset_type = SignalMaskFunctionType::RtNonaware;
+#endif
+
+static void TestSignalMaskFiltered(uint64_t sigset, SignalMaskFunctionType type) {
+ for (int signo = 1; signo <= 64; ++signo) {
+ bool signal_blocked = sigset & (1ULL << (signo - 1));
+ if (signo == SIGKILL || signo == SIGSTOP) {
+ // SIGKILL and SIGSTOP shouldn't be blocked.
+ EXPECT_EQ(false, signal_blocked) << "signal " << signo;
+ } else if (signo < __SIGRTMIN) {
+ // Everything else should be blocked.
+ EXPECT_EQ(true, signal_blocked) << "signal " << signo;
+ } else if (signo >= __SIGRTMIN && signo < SIGRTMIN) {
+ // Reserved signals must not be blocked.
+ EXPECT_EQ(false, signal_blocked) << "signal " << signo;
+ } else if (type == SignalMaskFunctionType::RtAware) {
+ // Realtime signals should be blocked, unless we blocked using a non-rt aware function.
+ EXPECT_EQ(true, signal_blocked) << "signal " << signo;
+ }
+ }
+}
+
+static void TestSignalMaskFunction(std::function<void()> fn, SignalMaskFunctionType fn_type) {
+ ClearSignalMask();
+ fn();
+ TestSignalMaskFiltered(GetSignalMask(), fn_type);
+}
+
+TEST(signal, sigaction_filter) {
+ ClearSignalMask();
+ static uint64_t sigset;
+ struct sigaction sa = {};
+ sa.sa_handler = [](int) { sigset = GetSignalMask(); };
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGUSR1, &sa, nullptr);
+ raise(SIGUSR1);
+ ASSERT_NE(0ULL, sigset);
+ TestSignalMaskFiltered(sigset, sigset_type);
+}
+
+TEST(signal, sigaction64_filter) {
+ ClearSignalMask();
+ static uint64_t sigset;
+ struct sigaction64 sa = {};
+ sa.sa_handler = [](int) { sigset = GetSignalMask(); };
+ sigfillset64(&sa.sa_mask);
+ sigaction64(SIGUSR1, &sa, nullptr);
+ raise(SIGUSR1);
+ ASSERT_NE(0ULL, sigset);
+ TestSignalMaskFiltered(sigset, SignalMaskFunctionType::RtAware);
+}
+
+TEST(signal, sigprocmask_setmask_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset_t sigset_libc;
+ sigfillset(&sigset_libc);
+ ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &sigset_libc, nullptr));
+ },
+ sigset_type);
+}
+
+TEST(signal, sigprocmask64_setmask_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset64_t sigset_libc;
+ sigfillset64(&sigset_libc);
+ ASSERT_EQ(0, sigprocmask64(SIG_SETMASK, &sigset_libc, nullptr));
+ },
+ SignalMaskFunctionType::RtAware);
+}
+
+TEST(signal, pthread_sigmask_setmask_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset_t sigset_libc;
+ sigfillset(&sigset_libc);
+ ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &sigset_libc, nullptr));
+ },
+ sigset_type);
+}
+
+TEST(signal, pthread_sigmask64_setmask_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset64_t sigset_libc;
+ sigfillset64(&sigset_libc);
+ ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &sigset_libc, nullptr));
+ },
+ SignalMaskFunctionType::RtAware);
+}
+
+TEST(signal, sigprocmask_block_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset_t sigset_libc;
+ sigfillset(&sigset_libc);
+ ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigset_libc, nullptr));
+ },
+ sigset_type);
+}
+
+TEST(signal, sigprocmask64_block_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset64_t sigset_libc;
+ sigfillset64(&sigset_libc);
+ ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &sigset_libc, nullptr));
+ },
+ SignalMaskFunctionType::RtAware);
+}
+
+TEST(signal, pthread_sigmask_block_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset_t sigset_libc;
+ sigfillset(&sigset_libc);
+ ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &sigset_libc, nullptr));
+ },
+ sigset_type);
+}
+
+TEST(signal, pthread_sigmask64_block_filter) {
+ TestSignalMaskFunction(
+ []() {
+ sigset64_t sigset_libc;
+ sigfillset64(&sigset_libc);
+ ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &sigset_libc, nullptr));
+ },
+ SignalMaskFunctionType::RtAware);
+}
+
+// glibc filters out signals via sigfillset, not the actual underlying functions.
+TEST(signal, sigset_filter) {
+#if defined(__BIONIC__)
+ TestSignalMaskFunction(
+ []() {
+ for (int i = 1; i <= 64; ++i) {
+ sigset(i, SIG_HOLD);
+ }
+ },
+ SignalMaskFunctionType::RtAware);
+#endif
+}
+
+TEST(signal, sighold_filter) {
+#if defined(__BIONIC__)
+ TestSignalMaskFunction(
+ []() {
+ for (int i = 1; i <= 64; ++i) {
+ sighold(i);
+ }
+ },
+ SignalMaskFunctionType::RtAware);
+#endif
+}
+
+#if defined(__BIONIC__)
+// Not exposed via headers, but the symbols are available if you declare them yourself.
+extern "C" int sigblock(int);
+extern "C" int sigsetmask(int);
+#endif
+
+TEST(signal, sigblock_filter) {
+#if defined(__BIONIC__)
+ TestSignalMaskFunction(
+ []() {
+ int mask = ~0U;
+ ASSERT_EQ(0, sigblock(mask));
+ },
+ SignalMaskFunctionType::RtNonaware);
+#endif
+}
+
+TEST(signal, sigsetmask_filter) {
+#if defined(__BIONIC__)
+ TestSignalMaskFunction(
+ []() {
+ int mask = ~0U;
+ ASSERT_EQ(0, sigsetmask(mask));
+ },
+ SignalMaskFunctionType::RtNonaware);
+#endif
}
TEST(signal, sys_signame) {
@@ -495,8 +720,7 @@
"* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
static siginfo received;
- struct sigaction handler;
- memset(&handler, 0, sizeof(handler));
+ struct sigaction handler = {};
handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
handler.sa_flags = SA_SIGINFO;
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index 84df16d..86175f9 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -20,7 +20,7 @@
#include <fcntl.h>
#include <gtest/gtest.h>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
#include "utils.h"
#include <android-base/file.h>
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index bb58ae4..0ff6f30 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -29,7 +29,7 @@
#include <unistd.h>
#include <unwind.h>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
#define noinline __attribute__((__noinline__))
#define __unused __attribute__((__unused__))
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index 128e255..849bf0b 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -190,6 +190,22 @@
}
}
+TEST(stdio_ext, __fseterr) {
+#if defined(__GLIBC__)
+ GTEST_LOG_(INFO) << "glibc doesn't have __fseterr, but gnulib will use it";
+#else
+ FILE* fp = fopen("/dev/null", "w");
+
+ ASSERT_FALSE(ferror(fp));
+ __fseterr(fp);
+ ASSERT_TRUE(ferror(fp));
+ clearerr(fp);
+ ASSERT_FALSE(ferror(fp));
+
+ fclose(fp);
+#endif
+}
+
TEST(stdio_ext, __fsetlocking) {
FILE* fp = fopen("/proc/version", "r");
ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index c1a51a8..33514d4 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -335,12 +335,10 @@
TEST(STDIO_TEST, snprintf_n) {
#if defined(__BIONIC__)
- // http://b/14492135
+ // http://b/14492135 and http://b/31832608.
char buf[32];
int i = 1234;
- EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i));
- EXPECT_EQ(1234, i);
- EXPECT_STREQ("a n b", buf);
+ EXPECT_DEATH(snprintf(buf, sizeof(buf), "a %n b", &i), "%n not allowed on Android");
#else
GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
#endif
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index caa7a85..2fbd937 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -35,6 +35,14 @@
#include <limits>
#include <string>
+#if defined(__BIONIC__)
+ #define ALIGNED_ALLOC_AVAILABLE 1
+#elif defined(__GLIBC_PREREQ)
+ #if __GLIBC_PREREQ(2, 16)
+ #define ALIGNED_ALLOC_AVAILABLE 1
+ #endif
+#endif
+
// The random number generator tests all set the seed, get four values, reset the seed and check
// that they get the first two values repeated, and then reset the seed and check two more values
// to rule out the possibility that we're just going round a cycle of four values.
@@ -226,6 +234,50 @@
ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
}
+TEST(stdlib, aligned_alloc_sweep) {
+#if defined(ALIGNED_ALLOC_AVAILABLE)
+ // Verify powers of 2 up to 2048 allocate, and verify that all other
+ // alignment values between the powers of 2 fail.
+ size_t last_align = 1;
+ for (size_t align = 1; align <= 2048; align <<= 1) {
+ // Try all of the non power of 2 values from the last until this value.
+ for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
+ ASSERT_TRUE(aligned_alloc(fail_align, 256) == nullptr)
+ << "Unexpected success at align " << fail_align;
+ ASSERT_EQ(EINVAL, errno) << "Unexpected errno at align " << fail_align;
+ }
+ void* ptr = aligned_alloc(align, 256);
+ ASSERT_TRUE(ptr != nullptr) << "Unexpected failure at align " << align;
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
+ << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
+ free(ptr);
+ last_align = align;
+ }
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
+#endif
+}
+
+TEST(stdlib, aligned_alloc_overflow) {
+#if defined(ALIGNED_ALLOC_AVAILABLE)
+ ASSERT_TRUE(aligned_alloc(16, SIZE_MAX) == nullptr);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
+#endif
+}
+
+TEST(stdlib, aligned_alloc_size_not_multiple_of_alignment) {
+#if defined(ALIGNED_ALLOC_AVAILABLE)
+ for (size_t size = 1; size <= 2048; size++) {
+ void* ptr = aligned_alloc(2048, size);
+ ASSERT_TRUE(ptr != nullptr) << "Failed at size " << std::to_string(size);
+ free(ptr);
+ }
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
+#endif
+}
+
TEST(stdlib, realpath__NULL_filename) {
errno = 0;
// Work around the compile-time error generated by FORTIFY here.
diff --git a/tests/sys_signalfd_test.cpp b/tests/sys_signalfd_test.cpp
index 67a72e0..179fcf9 100644
--- a/tests/sys_signalfd_test.cpp
+++ b/tests/sys_signalfd_test.cpp
@@ -36,7 +36,7 @@
#include <thread>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
static void TestSignalFd(int fd, int signal) {
ASSERT_NE(-1, fd) << strerror(errno);
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index f2151e1..949019f 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -42,7 +42,7 @@
}
~SystemPropertiesTest() {
if (valid_) {
- contexts()->FreeAndUnmap();
+ contexts_->FreeAndUnmap();
}
}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index fccff67..3196f34 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -26,7 +26,7 @@
#include <unistd.h>
#include <atomic>
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
#include "utils.h"
#include "private/bionic_constants.h"
@@ -279,6 +279,23 @@
EXPECT_STREQ("09:41:53", buf);
}
+TEST(time, strptime_l) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm t;
+ char buf[64];
+
+ memset(&t, 0, sizeof(t));
+ strptime_l("11:14", "%R", &t, LC_GLOBAL_LOCALE);
+ strftime_l(buf, sizeof(buf), "%H:%M", &t, LC_GLOBAL_LOCALE);
+ EXPECT_STREQ("11:14", buf);
+
+ memset(&t, 0, sizeof(t));
+ strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
+ strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
+ EXPECT_STREQ("09:41:53", buf);
+}
+
void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
itimerspec ts;
ts.it_value.tv_sec = value_s;
@@ -854,3 +871,54 @@
ASSERT_EQ(buf, ctime_r(&t, buf));
ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", buf);
}
+
+// https://issuetracker.google.com/37128336
+TEST(time, strftime_strptime_s) {
+ char buf[32];
+ const struct tm tm0 = { .tm_year = 1982-1900, .tm_mon = 0, .tm_mday = 1 };
+
+ setenv("TZ", "America/Los_Angeles", 1);
+ strftime(buf, sizeof(buf), "<%s>", &tm0);
+ EXPECT_STREQ("<378720000>", buf);
+
+ setenv("TZ", "UTC", 1);
+ strftime(buf, sizeof(buf), "<%s>", &tm0);
+ EXPECT_STREQ("<378691200>", buf);
+
+ struct tm tm;
+
+ setenv("TZ", "America/Los_Angeles", 1);
+ tzset();
+ memset(&tm, 0xff, sizeof(tm));
+ char* p = strptime("378720000x", "%s", &tm);
+ ASSERT_EQ('x', *p);
+ EXPECT_EQ(0, tm.tm_sec);
+ EXPECT_EQ(0, tm.tm_min);
+ EXPECT_EQ(0, tm.tm_hour);
+ EXPECT_EQ(1, tm.tm_mday);
+ EXPECT_EQ(0, tm.tm_mon);
+ EXPECT_EQ(82, tm.tm_year);
+ EXPECT_EQ(5, tm.tm_wday);
+ EXPECT_EQ(0, tm.tm_yday);
+ EXPECT_EQ(0, tm.tm_isdst);
+
+ setenv("TZ", "UTC", 1);
+ tzset();
+ memset(&tm, 0xff, sizeof(tm));
+ p = strptime("378691200x", "%s", &tm);
+ ASSERT_EQ('x', *p);
+ EXPECT_EQ(0, tm.tm_sec);
+ EXPECT_EQ(0, tm.tm_min);
+ EXPECT_EQ(0, tm.tm_hour);
+ EXPECT_EQ(1, tm.tm_mday);
+ EXPECT_EQ(0, tm.tm_mon);
+ EXPECT_EQ(82, tm.tm_year);
+ EXPECT_EQ(5, tm.tm_wday);
+ EXPECT_EQ(0, tm.tm_yday);
+ EXPECT_EQ(0, tm.tm_isdst);
+}
+
+TEST(time, strptime_s_nothing) {
+ struct tm tm;
+ ASSERT_EQ(nullptr, strptime("x", "%s", &tm));
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 912ea0c..db4859b 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -17,7 +17,7 @@
#include <gtest/gtest.h>
#include "BionicDeathTest.h"
-#include "ScopedSignalHandler.h"
+#include "SignalUtils.h"
#include "TemporaryFile.h"
#include "utils.h"
diff --git a/tests/utils.h b/tests/utils.h
index 3f4218e..f07bd58 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -140,15 +140,20 @@
}
}
-static inline void AssertChildExited(int pid, int expected_exit_status) {
+static inline void AssertChildExited(int pid, int expected_exit_status,
+ const std::string* error_msg = nullptr) {
int status;
- ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)));
+ std::string error;
+ if (error_msg == nullptr) {
+ error_msg = &error;
+ }
+ ASSERT_EQ(pid, TEMP_FAILURE_RETRY(waitpid(pid, &status, 0))) << *error_msg;
if (expected_exit_status >= 0) {
- ASSERT_TRUE(WIFEXITED(status));
- ASSERT_EQ(expected_exit_status, WEXITSTATUS(status));
+ ASSERT_TRUE(WIFEXITED(status)) << *error_msg;
+ ASSERT_EQ(expected_exit_status, WEXITSTATUS(status)) << *error_msg;
} else {
- ASSERT_TRUE(WIFSIGNALED(status));
- ASSERT_EQ(-expected_exit_status, WTERMSIG(status));
+ ASSERT_TRUE(WIFSIGNALED(status)) << *error_msg;
+ ASSERT_EQ(-expected_exit_status, WTERMSIG(status)) << *error_msg;
}
}
@@ -215,7 +220,8 @@
}
close(fds[0]);
- AssertChildExited(pid, expected_exit_status);
+ std::string error_msg("Test output:\n" + output);
+ AssertChildExited(pid, expected_exit_status, &error_msg);
if (expected_output != nullptr) {
ASSERT_EQ(expected_output, output);
}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 6f90c6c..b42e13c 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -539,7 +539,7 @@
ASSERT_EQ(EILSEQ, errno);
}
-TEST(wchar, wcsftime) {
+TEST(wchar, wcsftime__wcsftime_l) {
setenv("TZ", "UTC", 1);
struct tm t;
@@ -552,6 +552,8 @@
EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));
EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
+ EXPECT_EQ(24U, wcsftime_l(buf, sizeof(buf), L"%c", &t, LC_GLOBAL_LOCALE));
+ EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
}
TEST(wchar, wmemmove_smoke) {
@@ -878,6 +880,34 @@
TestWcsToFloatInfNan(wcstold);
}
+TEST(wchar, wcstod_l) {
+ EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstof_l) {
+ EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstol_l) {
+ EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstold_l) {
+ EXPECT_EQ(1.23L, wcstold_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstoll_l) {
+ EXPECT_EQ(123LL, wcstoll_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstoul_l) {
+ EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+}
+
+TEST(wchar, wcstoull_l) {
+ EXPECT_EQ(123ULL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+}
+
static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) {
for (wchar_t i = begin; i < end; ++i) {
EXPECT_EQ(expected, wcwidth(i)) << static_cast<int>(i);