Merge "Workaround potential access to unmapped stack"
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 72ab6c0..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-bionic_mountpoint {
- name: "libc.mountpoint",
- stem: "libc.so",
- src: "dummy_mountpoint",
- library: true,
- symlinks: ["libc.so"],
- mountsource: "libc",
-}
-
-bionic_mountpoint {
- name: "libdl.mountpoint",
- stem: "libdl.so",
- src: "dummy_mountpoint",
- library: true,
- symlinks: ["libdl.so"],
- mountsource: "libdl",
-}
-
-bionic_mountpoint {
- name: "libm.mountpoint",
- stem: "libm.so",
- src: "dummy_mountpoint",
- library: true,
- symlinks: ["libm.so"],
- mountsource: "libm",
-}
-
-bionic_mountpoint {
- name: "linker.mountpoint",
- stem: "linker",
- multilib: {
- lib64: {
- suffix: "64",
- },
- },
- src: "dummy_mountpoint",
- binary: true,
- symlinks: ["linker", "linker_asan"],
- mountsource: "linker",
-}
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 9421e26..8865723 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -53,6 +53,10 @@
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/libGLES*)
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/libGLES*)
+# /bionic is removed
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/bionic)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/bionic)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 1630db8..4c13bec 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -417,3 +417,17 @@
| No workaround | Works for static STL | Broken | Works |
| `-Wl,-z,nodelete` | Works for static STL | Works | Works |
| No `dlclose` | Works | Works | Works |
+
+## Use of IFUNC in libc (True for all API levels on devices running Q)
+
+Starting with Android Q (API level 29), libc uses
+[IFUNC](https://sourceware.org/glibc/wiki/GNU_IFUNC) functionality in
+the dynamic linker to choose optimized assembler routines at run time
+rather than at build time. This lets us use the same `libc.so` on all
+devices, and is similar to what other OSes already did. Because the zygote
+uses the C library, this decision is made long before we know what API
+level an app targets, so all code sees the new IFUNC-using C library.
+Most apps should be unaffected by this change, but apps that hook or try to
+detect hooking of C library functions might need to fix their code to cope
+with IFUNC relocations. The affected functions are from `<string.h>`, but
+may expand to include more functions (and more libraries) in future.
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index ba89137..cf51489 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -80,7 +80,7 @@
class SemaphoreFixture : public benchmark::Fixture {
public:
- void SetUp(const benchmark::State&) {
+ void SetUp(const benchmark::State&) override {
sem_init(&semaphore, 0, 0);
pthread_attr_t attr;
@@ -100,7 +100,7 @@
setup = true;
}
- ~SemaphoreFixture() {
+ ~SemaphoreFixture() override {
if (setup) {
// Only do this if the test was actually run.
sched_setscheduler(0, SCHED_OTHER, ¶m);
diff --git a/build/Android.bp b/build/Android.bp
deleted file mode 100644
index acd0ee2..0000000
--- a/build/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-
-bootstrap_go_package {
- name: "soong-bionic",
- pkgPath: "android/soong/bionic",
- deps: [
- "blueprint",
- "blueprint-pathtools",
- "blueprint-proptools",
- "soong",
- "soong-android",
- "soong-cc",
- ],
- srcs: [
- "bionic.go",
- ],
- pluginFor: ["soong_build"],
-}
diff --git a/build/bionic.go b/build/bionic.go
deleted file mode 100644
index 54ad10b..0000000
--- a/build/bionic.go
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (C) 2019 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.
-
-package bionic
-
-import (
- "fmt"
- "io"
- "strings"
-
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
-
- "android/soong/android"
- "android/soong/cc"
-)
-
-// bionic_mountpoint is a module type that is specialized to create
-// mount points for Bionic files (libc, libdl, libm, and linker).
-//
-// With following description,
-//
-// bionic_mountpoint {
-// name: "libc.mountpoint",
-// stem: "libc.so",
-// src: "dummy_mountpoint",
-// library: true,
-// symlinks: ["libc.so"],
-// }
-//
-// , the build system does following jobs:
-//
-// A mount point /bionic/lib[64]/libc.so is created. Its content
-// is from the file 'dummy_mountpoint'.
-//
-// Then a symlink is created at /system/lib[64]/libc.so which points to
-// the created mountpoint.
-//
-// At runtime, on the mount point, either bootstrap Bionic or default Bionic
-// (which is from the runtime APEX) is mounted by the init process. The
-// symlink exists to provide consistent legacy path for compatibility
-// reason.
-func init() {
- android.RegisterModuleType("bionic_mountpoint", bionicMountpointFactory)
-}
-
-type bionicMountpoint struct {
- android.ModuleBase
- properties bionicMountpointProperties
-
- outputFile android.Path
- pathInPartition string
- stem string
- unstrippedOutputFile android.Path
-}
-
-type bionicMountpointProperties struct {
- // The file that is installed as the mount point
- Src *string
-
- // TODO(jiyong) remove these two properties (probably Stem and Suffix
- // as well, as they can be inteffered from Mountsource
-
- // True if the mount point is for a Bionic library such libc.so
- Library *bool
- // True if the mount point is for a Bionic binary such as linker
- Binary *bool
-
- // The module that this module is a mount point for
- Mountsource *string
-
- // Base name of the mount point
- Stem *string `android:"arch_variant"`
-
- // Append to the name of the output
- Suffix *string `android:"arch_variant"`
-
- // Symlinks to the mountpoints from the system and recovery partitions
- // Symlinks names will have the same suffix as the mount point
- Symlinks []string
-
- // List of sanitizer names that this APEX is enabled for
- SanitizerNames []string `blueprint:"mutated"`
-}
-
-type dependencyTag struct {
- blueprint.BaseDependencyTag
- name string
-}
-
-var mountsourceTag = dependencyTag{name: "mountsource"}
-
-
-func (m *bionicMountpoint) EnableSanitizer(sanitizerName string) {
- if !android.InList(sanitizerName, m.properties.SanitizerNames) {
- m.properties.SanitizerNames = append(m.properties.SanitizerNames, sanitizerName)
- }
-}
-
-func (m *bionicMountpoint) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
- if android.InList(sanitizerName, m.properties.SanitizerNames) {
- return true
- }
-
- // Then follow the global setting
- globalSanitizerNames := []string{}
- if m.Host() {
- globalSanitizerNames = ctx.Config().SanitizeHost()
- } else {
- arches := ctx.Config().SanitizeDeviceArch()
- if len(arches) == 0 || android.InList(m.Arch().ArchType.Name, arches) {
- globalSanitizerNames = ctx.Config().SanitizeDevice()
- }
- }
- return android.InList(sanitizerName, globalSanitizerNames)
-}
-
-func (m *bionicMountpoint) DepsMutator(ctx android.BottomUpMutatorContext) {
- if Bool(m.properties.Library) == Bool(m.properties.Binary) {
- ctx.ModuleErrorf("either binary or library must be set to true")
- return
- }
- if m.properties.Stem == nil {
- ctx.PropertyErrorf("stem", "stem must be set")
- return
- }
- if m.properties.Src == nil {
- ctx.PropertyErrorf("src", "src must be set")
- }
- android.ExtractSourceDeps(ctx, m.properties.Src)
-
- if m.properties.Mountsource == nil {
- ctx.PropertyErrorf("mountsource", "mountsource must be set")
- return
- }
-
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "arch", Variation: ctx.Target().String()},
- {Mutator: "image", Variation: "core"},
- {Mutator: "link", Variation: "shared"},
- }, mountsourceTag, String(m.properties.Mountsource))
-}
-
-func (m *bionicMountpoint) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if Bool(m.properties.Library) {
- m.pathInPartition = "lib"
- if m.Arch().ArchType.Multilib == "lib64" {
- m.pathInPartition = "lib64"
- }
- } else if Bool(m.properties.Binary) {
- m.pathInPartition = "bin"
- }
-
- m.stem = String(m.properties.Stem) + String(m.properties.Suffix)
-
- m.outputFile = ctx.ExpandSource(String(m.properties.Src), "src")
-
- ctx.VisitDirectDepsWithTag(mountsourceTag, func(module android.Module) {
- if cc, ok := module.(*cc.Module); ok {
- m.unstrippedOutputFile = cc.UnstrippedOutputFile()
- }
- })
-}
-
-func (m *bionicMountpoint) AndroidMk() android.AndroidMkData {
- return android.AndroidMkData {
- Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
- if !m.Arch().Native {
- return
- }
- fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
- fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
- fmt.Fprintln(w, "LOCAL_MODULE :=", name)
- fmt.Fprintln(w, "LOCAL_USE_CLANG_LLD := false")
- fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
- if Bool(m.properties.Library) {
- fmt.Fprintln(w, "LOCAL_MODULE_CLASS := SHARED_LIBRARIES")
- } else if Bool(m.properties.Binary) {
- fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES")
- }
- fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
- fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", m.outputFile.String())
- fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", m.Arch().ArchType.String())
- fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(TARGET_ROOT_OUT)/bionic/" + m.pathInPartition)
- fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem)
-
- if len(m.properties.Symlinks) > 0 {
- symlink_dir_in_system := "$(TARGET_OUT)/" + m.pathInPartition + "/"
- symlink_dir_in_recovery := "$(TARGET_RECOVERY_ROOT_OUT)/system/" + m.pathInPartition + "/"
- symlink_target := "/bionic/" + m.pathInPartition + "/" + m.stem
- cmds := []string{}
- cmds = append(cmds, "$(hide) mkdir -p " + symlink_dir_in_system)
- cmds = append(cmds, "mkdir -p " + symlink_dir_in_recovery)
- for _, s := range m.properties.Symlinks {
- symlink := s + String(m.properties.Suffix)
- cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_system + symlink)
- cmds = append(cmds, "ln -sf " + symlink_target + " " + symlink_dir_in_recovery + symlink)
- }
- fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := " + strings.Join(cmds, " && "))
- }
- if m.unstrippedOutputFile != nil {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", m.unstrippedOutputFile.String())
- }
- fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
- },
- }
-}
-
-func bionicMountpointFactory() android.Module {
- m := &bionicMountpoint{}
- m.AddProperties(&m.properties)
- android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
- return m
-}
-
-var Bool = proptools.Bool
-var String = proptools.String
diff --git a/docs/status.md b/docs/status.md
index 54385a4..d6a2f4c 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -45,11 +45,21 @@
* `getloadavg` (BSD/GNU extension in <stdlib.h>)
New libc behavior in Q (API level 29):
- * Whole printf family now supports the GNU `%m` extension, rather than a special-case hack in `syslog`
- * `popen` now always uses `O_CLOEXEC`, not just with the `e` extension
- * Bug fixes to handling of UTF-8 U+fffe/U+ffff and code points above U+10ffff
+ * Whole printf family now supports the GNU `%m` extension, rather than a
+ special-case hack in `syslog`.
+ * `popen` now always uses `O_CLOEXEC`, not just with the `e` extension.
+ * Bug fixes to handling of UTF-8 U+fffe/U+ffff and code points above U+10ffff.
+ * `aligned_alloc` correctly verifies that `size` is a multiple of `alignment`.
+ * Using `%n` with the printf family is now reported as a FORTIFY failure.
+ Previous versions of Android would ignore the `%n` but not consume the
+ corresponding pointer argument, leading to obscure errors. The scanf family
+ is unchanged.
+ * Support in strptime for `%F`, `%G`, `%g`, `%P`, `%u`, `%V`, and `%v`.
+ (strftime already supported them all.)
+ * [fdsan](fdsan.md) detects common file descriptor errors at runtime.
New libc functions in P (API level 28):
+ * `aligned_alloc`
* `__freading`/`__fwriting` (completing <stdio_ext.h>)
* `endhostent`/`endnetent`/`endprotoent`/`getnetent`/`getprotoent`/`sethostent`/`setnetent`/`setprotoent` (completing <netdb.h>)
* `fexecve`
@@ -67,9 +77,13 @@
* `syncfs`
New libc behavior in P (API level 28):
- * `%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)
+ * `%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).
+ * Using a `pthread_mutex_t` after it's been destroyed will be detected at
+ runtime and reported as a FORTIFY failure.
+ * Passing a null `FILE*` or `DIR*` to libc is now detected at runtime and
+ reported as a FORTIFY failure.
New libc functions in O (API level 26):
* `sendto` FORTIFY support
@@ -94,6 +108,11 @@
* `strtod_l`/`strtof_l`/`strtol_l`/`strtoul_l`
* <wctype.h> `towctrans`/`towctrans_l`/`wctrans`/`wctrans_l`
+New libc behavior in O (API level 26):
+ * Passing an invalid `pthread_t` to libc is now detected at runtime and
+ reported as a FORTIFY failure. Most commonly this is a result of confusing
+ `pthread_t` and `pid_t`.
+
New libc functions in N (API level 24):
* more FORTIFY support functions (`fread`/`fwrite`/`getcwd`/`pwrite`/`write`)
* all remaining `_FILE_OFFSET_BITS=64` functions, completing `_FILE_OFFSET_BITS=64` support in bionic (8)
@@ -106,6 +125,9 @@
* GNU extensions `fileno_unlocked`/`strchrnul`
* 32-bit `prlimit`
+New libc behavior in N (API level 24):
+ * `sem_wait` now returns EINTR when interrupted by a signal.
+
New libc functions in M (API level 23):
* <dirent.h> `telldir`, `seekdir`.
* <malloc.h> `malloc_info`.
diff --git a/dummy_mountpoint b/dummy_mountpoint
deleted file mode 100644
index 2d13c55..0000000
--- a/dummy_mountpoint
+++ /dev/null
@@ -1 +0,0 @@
-This file serves as a mount point for bionic files either from /system partition or from /apex/com.android.runtime. This file is never meant to be accessed directly.
diff --git a/libc/Android.bp b/libc/Android.bp
index 489918b..0950662 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -77,16 +77,9 @@
native_coverage: false,
recovery_available: true,
- arch: {
- x86: {
- no_libcrt: true,
- },
- x86_64: {
- no_libcrt: true,
- },
- },
- // TODO(ivanlozano): Remove after b/118321713
- xom: false,
+ // lld complains about duplicate symbols in libcrt and libgcc. Suppress the
+ // warning since this is intended right now.
+ ldflags: ["-Wl,-z,muldefs"],
}
// ========================================================
@@ -1088,7 +1081,6 @@
"bionic/locale.cpp",
"bionic/lockf.cpp",
"bionic/lstat.cpp",
- "bionic/malloc_info.cpp",
"bionic/mblen.cpp",
"bionic/mbrtoc16.cpp",
"bionic/mbrtoc32.cpp",
@@ -1310,6 +1302,7 @@
defaults: ["libc_defaults"],
srcs: libc_common_src_files + [
"bionic/malloc_common.cpp",
+ "bionic/malloc_limit.cpp",
],
multilib: {
lib32: {
@@ -1505,6 +1498,7 @@
"bionic/malloc_common.cpp",
"bionic/malloc_common_dynamic.cpp",
"bionic/malloc_heapprofd.cpp",
+ "bionic/malloc_limit.cpp",
"bionic/NetdClient.cpp",
"arch-common/bionic/crtend_so.S",
],
@@ -1515,6 +1509,7 @@
srcs: [
"bionic/dl_iterate_phdr_static.cpp",
"bionic/malloc_common.cpp",
+ "bionic/malloc_limit.cpp",
],
}
@@ -1560,7 +1555,7 @@
],
},
- required: ["tzdata", "libc.mountpoint"],
+ required: ["tzdata"],
// Leave the symbols in the shared library so that stack unwinders can produce
// meaningful name resolution.
@@ -2430,3 +2425,54 @@
static_libs: ["libbase"],
},
}
+
+// This is a temporary library that will use scudo as the native memory
+// allocator. To use it, add it as the first shared library.
+cc_library_shared {
+ name: "libc_scudo",
+ vendor_available: true,
+ srcs: [
+ "bionic/malloc_common.cpp",
+ "bionic/malloc_common_dynamic.cpp",
+ "bionic/malloc_heapprofd.cpp",
+ "bionic/malloc_limit.cpp",
+ "bionic/scudo_wrapper.cpp",
+ "bionic/__set_errno.cpp",
+ ],
+ cflags: ["-DUSE_SCUDO"],
+ stl: "none",
+ system_shared_libs: [],
+
+ header_libs: ["libc_headers"],
+
+ static_libs: ["libasync_safe"],
+
+ allow_undefined_symbols: true,
+ shared_libs: ["libscudo_wrapper"],
+
+ arch: {
+ arm: {
+ srcs: ["arch-arm/syscalls/__rt_sigprocmask.S"],
+ },
+ arm64: {
+ srcs: ["arch-arm64/syscalls/__rt_sigprocmask.S"],
+ },
+ x86: {
+ srcs: [
+ "arch-x86/bionic/__libc_init_sysinfo.cpp",
+ "arch-x86/syscalls/__rt_sigprocmask.S",
+ ],
+ },
+ x86_64: {
+ srcs: ["arch-x86_64/syscalls/__rt_sigprocmask.S"],
+ },
+ },
+
+ // Mark this library as global so it overrides all the allocation
+ // definitions properly.
+ ldflags: ["-Wl,-z,global"],
+}
+
+subdirs = [
+ "bionic/scudo",
+]
diff --git a/libc/arch-arm/bionic/libcrt_compat.c b/libc/arch-arm/bionic/libcrt_compat.c
index 22a3387..ce77a5d 100644
--- a/libc/arch-arm/bionic/libcrt_compat.c
+++ b/libc/arch-arm/bionic/libcrt_compat.c
@@ -31,8 +31,12 @@
extern char __aeabi_cdcmpeq;
extern char __aeabi_cdcmple;
extern char __aeabi_cdrcmple;
+extern char __aeabi_cfcmpeq;
+extern char __aeabi_cfcmple;
+extern char __aeabi_cfrcmple;
extern char __aeabi_d2f;
extern char __aeabi_d2iz;
+extern char __aeabi_d2uiz;
extern char __aeabi_dadd;
extern char __aeabi_dcmpeq;
extern char __aeabi_dcmpge;
@@ -48,6 +52,11 @@
extern char __aeabi_f2iz;
extern char __aeabi_f2uiz;
extern char __aeabi_fadd;
+extern char __aeabi_fcmpeq;
+extern char __aeabi_fcmpge;
+extern char __aeabi_fcmpgt;
+extern char __aeabi_fcmple;
+extern char __aeabi_fcmplt;
extern char __aeabi_fcmpun;
extern char __aeabi_fdiv;
extern char __aeabi_fmul;
@@ -74,12 +83,15 @@
extern char __aeabi_unwind_cpp_pr0;
extern char __aeabi_unwind_cpp_pr1;
extern char __cmpdf2;
+extern char __cmpsf2;
extern char __divdf3;
extern char __divsf3;
extern char __eqdf2;
+extern char __eqsf2;
extern char __extendsfdf2;
extern char __fixdfsi;
extern char __fixsfsi;
+extern char __fixunsdfsi;
extern char __floatdidf;
extern char __floatdisf;
extern char __floatsidf;
@@ -89,15 +101,20 @@
extern char __floatunsidf;
extern char __floatunsisf;
extern char __gedf2;
+extern char __gesf2;
extern char __gtdf2;
+extern char __gtsf2;
extern char __gnu_ldivmod_helper;
extern char __gnu_uldivmod_helper;
extern char __ledf2;
+extern char __lesf2;
extern char __ltdf2;
+extern char __ltsf2;
extern char __muldf3;
extern char __muldi3;
extern char __mulsf3;
extern char __nedf2;
+extern char __nesf2;
extern char __popcount_tab;
extern char __popcountsi2;
extern char __subdf3;
@@ -113,8 +130,12 @@
&__aeabi_cdcmpeq,
&__aeabi_cdcmple,
&__aeabi_cdrcmple,
+ &__aeabi_cfcmpeq,
+ &__aeabi_cfcmple,
+ &__aeabi_cfrcmple,
&__aeabi_d2f,
&__aeabi_d2iz,
+ &__aeabi_d2uiz,
&__aeabi_dadd,
&__aeabi_dcmpeq,
&__aeabi_dcmpge,
@@ -130,6 +151,11 @@
&__aeabi_f2iz,
&__aeabi_f2uiz,
&__aeabi_fadd,
+ &__aeabi_fcmpeq,
+ &__aeabi_fcmpge,
+ &__aeabi_fcmpgt,
+ &__aeabi_fcmple,
+ &__aeabi_fcmplt,
&__aeabi_fcmpun,
&__aeabi_fdiv,
&__aeabi_fmul,
@@ -156,12 +182,15 @@
&__aeabi_unwind_cpp_pr0,
&__aeabi_unwind_cpp_pr1,
&__cmpdf2,
+ &__cmpsf2,
&__divdf3,
&__divsf3,
&__eqdf2,
+ &__eqsf2,
&__extendsfdf2,
&__fixdfsi,
&__fixsfsi,
+ &__fixunsdfsi,
&__floatdidf,
&__floatdisf,
&__floatsidf,
@@ -171,15 +200,20 @@
&__floatunsidf,
&__floatunsisf,
&__gedf2,
+ &__gesf2,
&__gtdf2,
+ &__gtsf2,
&__gnu_ldivmod_helper,
&__gnu_uldivmod_helper,
&__ledf2,
+ &__lesf2,
&__ltdf2,
+ &__ltsf2,
&__muldf3,
&__muldi3,
&__mulsf3,
&__nedf2,
+ &__nesf2,
&__popcount_tab,
&__popcountsi2,
&__subdf3,
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 6acd64b..6c01572 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -51,5 +51,26 @@
cneg x0, x0, hi
b.hi __set_errno_internal
+#if __has_feature(hwaddress_sanitizer)
+ cbz x0, .L_exit
+
+ // Clean up stack shadow in the parent process.
+ // https://github.com/google/sanitizers/issues/925
+ stp x0, x30, [sp, #-16]!
+ .cfi_adjust_cfa_offset 16
+ .cfi_rel_offset x0, 0
+ .cfi_rel_offset x30, 8
+
+ add x0, sp, #16
+ bl __hwasan_handle_vfork
+
+ ldp x0, x30, [sp], #16
+ .cfi_adjust_cfa_offset -16
+ .cfi_restore x0
+ .cfi_restore x30
+
+#endif
+
+.L_exit:
ret
END(vfork)
diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index 6624385..70f4b3e 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -30,33 +30,6 @@
extern "C" {
-struct __processor_model {
- unsigned int __cpu_vendor;
- unsigned int __cpu_type;
- unsigned int __cpu_subtype;
- unsigned int __cpu_features[1];
-};
-
-__attribute__((visibility("hidden")))
-extern struct __processor_model __cpu_model;
-
-// These definitions have to match the values in
-// llvm/include/llvm/Support/X86TargetParser.def
-static constexpr int SSSE3 = 6;
-static constexpr int SSE4_1 = 7;
-static constexpr int ATOM = 1;
-
-// __builtin_cpu_supports and __builtin_cpu_is can not be used here. They
-// don't access __cpu_model directly but use GOT.
-// See https://reviews.llvm.org/D53850
-static bool cpu_supports(unsigned int feature) {
- return (__cpu_model.__cpu_features[0] & (1U << feature)) != 0;
-}
-
-static bool cpu_is(unsigned int type) {
- return (__cpu_model.__cpu_type == type);
-}
-
#define DEFINE_IFUNC_FOR(name) \
name##_func name __attribute__((ifunc(#name "_resolver"))); \
__attribute__((visibility("hidden"))) \
@@ -74,29 +47,29 @@
typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n);
DEFINE_IFUNC_FOR(memcmp) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memcmp_func, memcmp_atom);
- if (cpu_supports(SSE4_1)) RETURN_FUNC(memcmp_func, memcmp_sse4);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memcmp_func, memcmp_atom);
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(memcmp_func, memcmp_sse4);
RETURN_FUNC(memcmp_func, memcmp_generic);
}
typedef void* memset_func(void* __dst, int __ch, size_t __n);
DEFINE_IFUNC_FOR(memset) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memset_func, memset_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memset_func, memset_atom);
RETURN_FUNC(memset_func, memset_generic);
}
typedef void* __memset_chk_func(void *s, int c, size_t n, size_t n2);
DEFINE_IFUNC_FOR(__memset_chk) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(__memset_chk_func, __memset_chk_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(__memset_chk_func, __memset_chk_atom);
RETURN_FUNC(__memset_chk_func, __memset_chk_generic);
}
typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
DEFINE_IFUNC_FOR(memmove) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(memmove_func, memmove_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(memmove_func, memmove_atom);
RETURN_FUNC(memmove_func, memmove_generic);
}
@@ -108,85 +81,85 @@
typedef char* strcpy_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcpy) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strcpy_func, strcpy_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strcpy_func, strcpy_atom);
RETURN_FUNC(strcpy_func, strcpy_generic);
}
typedef char* strncpy_func(char* __dst, const char* __src, size_t __n);
DEFINE_IFUNC_FOR(strncpy) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strncpy_func, strncpy_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strncpy_func, strncpy_atom);
RETURN_FUNC(strncpy_func, strncpy_generic);
}
typedef size_t strlen_func(const char* __s);
DEFINE_IFUNC_FOR(strlen) {
__builtin_cpu_init();
- if (cpu_is(ATOM)) RETURN_FUNC(strlen_func, strlen_atom);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(strlen_func, strlen_atom);
RETURN_FUNC(strlen_func, strlen_generic);
}
typedef int wmemcmp_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
DEFINE_IFUNC_FOR(wmemcmp) {
__builtin_cpu_init();
- if (cpu_supports(SSE4_1)) RETURN_FUNC(wmemcmp_func, wmemcmp_sse4);
- if (cpu_is(ATOM)) RETURN_FUNC(wmemcmp_func, wmemcmp_atom);
+ if (__builtin_cpu_supports("sse4.1")) RETURN_FUNC(wmemcmp_func, wmemcmp_sse4);
+ if (__builtin_cpu_is("atom")) RETURN_FUNC(wmemcmp_func, wmemcmp_atom);
RETURN_FUNC(wmemcmp_func, wmemcmp_freebsd);
}
typedef int strcmp_func(const char* __lhs, const char* __rhs);
DEFINE_IFUNC_FOR(strcmp) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strcmp_func, strcmp_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcmp_func, strcmp_ssse3);
RETURN_FUNC(strcmp_func, strcmp_generic);
}
typedef int strncmp_func(const char* __lhs, const char* __rhs, size_t __n);
DEFINE_IFUNC_FOR(strncmp) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strncmp_func, strncmp_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncmp_func, strncmp_ssse3);
RETURN_FUNC(strncmp_func, strncmp_generic);
}
typedef char* strcat_func(char* __dst, const char* __src);
DEFINE_IFUNC_FOR(strcat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strcat_func, strcat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strcat_func, strcat_ssse3);
RETURN_FUNC(strcat_func, strcat_generic);
}
typedef char* strncat_func(char* __dst, const char* __src, size_t __n);
DEFINE_IFUNC_FOR(strncat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strncat_func, strncat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strncat_func, strncat_ssse3);
RETURN_FUNC(strncat_func, strncat_openbsd);
}
typedef size_t strlcat_func(char *dst, const char *src, size_t dsize);
DEFINE_IFUNC_FOR(strlcat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strlcat_func, strlcat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcat_func, strlcat_ssse3);
RETURN_FUNC(strlcat_func, strlcat_openbsd);
}
typedef size_t strlcpy_func(char *dst, const char *src, size_t dsize);
DEFINE_IFUNC_FOR(strlcpy) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(strlcpy_func, strlcpy_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(strlcpy_func, strlcpy_ssse3);
RETURN_FUNC(strlcpy_func, strlcpy_openbsd);
}
typedef wchar_t* wcscat_func(wchar_t *s1, const wchar_t *s2);
DEFINE_IFUNC_FOR(wcscat) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(wcscat_func, wcscat_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscat_func, wcscat_ssse3);
RETURN_FUNC(wcscat_func, wcscat_freebsd);
}
typedef wchar_t* wcscpy_func(wchar_t *s1, const wchar_t *s2);
DEFINE_IFUNC_FOR(wcscpy) {
__builtin_cpu_init();
- if (cpu_supports(SSSE3)) RETURN_FUNC(wcscpy_func, wcscpy_ssse3);
+ if (__builtin_cpu_supports("ssse3")) RETURN_FUNC(wcscpy_func, wcscpy_ssse3);
RETURN_FUNC(wcscpy_func, wcscpy_freebsd);
}
diff --git a/libc/bionic/__bionic_get_shell_path.cpp b/libc/bionic/__bionic_get_shell_path.cpp
index 1352815..7aeed18 100644
--- a/libc/bionic/__bionic_get_shell_path.cpp
+++ b/libc/bionic/__bionic_get_shell_path.cpp
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include "private/__bionic_get_shell_path.h"
+
#include <errno.h>
#include <string.h>
#include <sys/cdefs.h>
@@ -51,7 +53,7 @@
return "/system/bin/sh";
}
-__LIBC_HIDDEN__ extern "C" const char* __bionic_get_shell_path() {
+const char* __bionic_get_shell_path() {
static const char* sh_path = init_sh_path();
return sh_path;
}
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 56e6771..2ea12ee 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -33,6 +33,7 @@
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/prctl.h>
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
@@ -82,6 +83,10 @@
return;
}
+ // Name the abort message mapping to make it easier for tools to find the
+ // mapping.
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map, size, "abort message");
+
magic_abort_msg_t* new_magic_abort_message = reinterpret_cast<magic_abort_msg_t*>(map);
fill_abort_message_magic(new_magic_abort_message);
new_magic_abort_message->msg.size = size;
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 1cf3a58..3309585 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -39,6 +39,7 @@
#include <string.h>
#include <unistd.h>
+#include "private/__bionic_get_shell_path.h"
#include "private/FdPath.h"
extern "C" char** environ;
@@ -111,7 +112,7 @@
script_argv[0] = "sh";
script_argv[1] = buf;
memcpy(script_argv + 2, argv + 1, arg_count * sizeof(char*));
- return execve(_PATH_BSHELL, const_cast<char**>(script_argv), envp);
+ return execve(__bionic_get_shell_path(), const_cast<char**>(script_argv), envp);
}
int execvpe(const char* name, char* const* argv, char* const* envp) {
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index 79a4f72..b9a4e99 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -22,14 +22,20 @@
// Need to wrap memalign since je_memalign fails on non-power of 2 alignments.
#define je_memalign je_memalign_round_up_boundary
+// Need to wrap aligned_alloc since je_aligned_alloc does not enforce
+// that size is a multiple of alignment.
+#define je_aligned_alloc je_aligned_alloc_wrapper
+
__BEGIN_DECLS
-struct mallinfo je_mallinfo();
-int je_mallopt(int, int);
+void* je_aligned_alloc_wrapper(size_t, size_t);
int je_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+struct mallinfo je_mallinfo();
void je_malloc_disable();
void je_malloc_enable();
-int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+int je_malloc_info(int options, FILE* fp);
+int je_mallopt(int, int);
void* je_memalign_round_up_boundary(size_t, size_t);
void* je_pvalloc(size_t);
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index ef0d384..bc3a9dc 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -14,12 +14,14 @@
* limitations under the License.
*/
+#include <errno.h>
#include <malloc.h>
#include <sys/param.h>
#include <unistd.h>
+#include <private/MallocXmlElem.h>
+
#include "jemalloc.h"
-#include "private/bionic_macros.h"
void* je_pvalloc(size_t bytes) {
size_t pagesize = getpagesize();
@@ -48,6 +50,20 @@
return je_memalign(boundary, size);
}
+#ifdef je_aligned_alloc
+#undef je_aligned_alloc
+#endif
+
+// The aligned_alloc function requires that size is a multiple of alignment.
+// jemalloc doesn't enforce this, so add enforcement here.
+void* je_aligned_alloc_wrapper(size_t alignment, size_t size) {
+ if ((size % alignment) != 0) {
+ errno = EINVAL;
+ return nullptr;
+ }
+ return je_aligned_alloc(alignment, size);
+}
+
int je_mallopt(int param, int value) {
// The only parameter we currently understand is M_DECAY_TIME.
if (param == M_DECAY_TIME) {
@@ -101,3 +117,49 @@
}
return 0;
}
+
+__BEGIN_DECLS
+
+size_t __mallinfo_narenas();
+size_t __mallinfo_nbins();
+struct mallinfo __mallinfo_arena_info(size_t);
+struct mallinfo __mallinfo_bin_info(size_t, size_t);
+
+__END_DECLS
+
+int je_malloc_info(int options, FILE* fp) {
+ if (options != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ MallocXmlElem root(fp, "malloc", "version=\"jemalloc-1\"");
+
+ // Dump all of the large allocations in the arenas.
+ for (size_t i = 0; i < __mallinfo_narenas(); i++) {
+ struct mallinfo mi = __mallinfo_arena_info(i);
+ if (mi.hblkhd != 0) {
+ MallocXmlElem arena_elem(fp, "heap", "nr=\"%d\"", i);
+ {
+ MallocXmlElem(fp, "allocated-large").Contents("%zu", mi.ordblks);
+ MallocXmlElem(fp, "allocated-huge").Contents("%zu", mi.uordblks);
+ MallocXmlElem(fp, "allocated-bins").Contents("%zu", mi.fsmblks);
+
+ size_t total = 0;
+ for (size_t j = 0; j < __mallinfo_nbins(); j++) {
+ struct mallinfo mi = __mallinfo_bin_info(i, j);
+ if (mi.ordblks != 0) {
+ MallocXmlElem bin_elem(fp, "bin", "nr=\"%d\"", j);
+ MallocXmlElem(fp, "allocated").Contents("%zu", mi.ordblks);
+ MallocXmlElem(fp, "nmalloc").Contents("%zu", mi.uordblks);
+ MallocXmlElem(fp, "ndalloc").Contents("%zu", mi.fordblks);
+ total += mi.ordblks;
+ }
+ }
+ MallocXmlElem(fp, "bins-total").Contents("%zu", total);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index f1fbfa9..b229cda 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -298,11 +298,26 @@
unsigned long is_AT_SECURE = getauxval(AT_SECURE);
if (errno != 0) __early_abort(__LINE__);
- if (is_AT_SECURE) {
- // If this is a setuid/setgid program, close the security hole described in
- // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
+ // Always ensure that STDIN/STDOUT/STDERR exist. This prevents file
+ // descriptor confusion bugs where a parent process closes
+ // STD*, the exec()d process calls open() for an unrelated reason,
+ // the newly created file descriptor is assigned
+ // 0<=FD<=2, and unrelated code attempts to read / write to the STD*
+ // FDs.
+ // In particular, this can be a security bug for setuid/setgid programs.
+ // For example:
+ // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
+ // However, for robustness reasons, we don't limit these protections to
+ // just security critical executables.
+ //
+ // Init is excluded from these protections unless AT_SECURE is set, as
+ // /dev/null and/or /sys/fs/selinux/null will not be available at
+ // early boot.
+ if ((getpid() != 1) || is_AT_SECURE) {
__nullify_closed_stdio();
+ }
+ if (is_AT_SECURE) {
__sanitize_environment_variables(env);
}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3219239..b4bddce 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -67,9 +67,20 @@
}
#if defined(__aarch64__) || defined(__x86_64__)
-extern __LIBC_HIDDEN__ ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
+extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
static void call_ifunc_resolvers() {
+ if (__rela_iplt_start == nullptr || __rela_iplt_end == nullptr) {
+ // These symbols are not emitted by gold. Gold has code to do so, but for
+ // whatever reason it is not being run. In these cases ifuncs cannot be
+ // resolved, so we do not support using ifuncs in static executables linked
+ // with gold.
+ //
+ // Since they are weak, they will be non-null when linked with bfd/lld and
+ // null when linked with gold.
+ return;
+ }
+
typedef ElfW(Addr) (*ifunc_resolver_t)(void);
for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
@@ -78,9 +89,20 @@
}
}
#else
-extern __LIBC_HIDDEN__ ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
+extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
static void call_ifunc_resolvers() {
+ if (__rel_iplt_start == nullptr || __rel_iplt_end == nullptr) {
+ // These symbols are not emitted by gold. Gold has code to do so, but for
+ // whatever reason it is not being run. In these cases ifuncs cannot be
+ // resolved, so we do not support using ifuncs in static executables linked
+ // with gold.
+ //
+ // Since they are weak, they will be non-null when linked with bfd/lld and
+ // null when linked with gold.
+ return;
+ }
+
typedef ElfW(Addr) (*ifunc_resolver_t)(void);
for (ElfW(Rel) *r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
@@ -180,7 +202,7 @@
exit(slingshot(args.argc, args.argv, args.envp));
}
-extern "C" void __hwasan_init();
+extern "C" void __hwasan_init_static();
__attribute__((no_sanitize("hwaddress")))
__noreturn void __libc_init(void* raw_args,
@@ -192,8 +214,9 @@
// Install main thread TLS early. It will be initialized later in __libc_init_main_thread. For now
// all we need is access to TLS_SLOT_SANITIZER.
__set_tls(&temp_tcb.tls_slot(0));
- // Initialize HWASan. This sets up TLS_SLOT_SANITIZER, among other things.
- __hwasan_init();
+ // Initialize HWASan enough to run instrumented code. This sets up TLS_SLOT_SANITIZER, among other
+ // things.
+ __hwasan_init_static();
// We are ready to run HWASan-instrumented code, proceed with libc initialization...
#endif
__real_libc_init(raw_args, onexit, slingshot, structors, &temp_tcb);
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 80e82f7..f817281 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -41,11 +41,15 @@
// get_malloc_leak_info.
// write_malloc_leak_info: Writes the leak info data to a file.
+#include <errno.h>
#include <stdint.h>
+#include <stdio.h>
#include <private/bionic_config.h>
+#include <private/bionic_malloc.h>
#include "malloc_common.h"
+#include "malloc_limit.h"
// =============================================================================
// Global variables instantations.
@@ -69,7 +73,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->calloc(n_elements, elem_size);
}
- return Malloc(calloc)(n_elements, elem_size);
+ void* result = Malloc(calloc)(n_elements, elem_size);
+ if (__predict_false(result == nullptr)) {
+ warning_log("calloc(%zu, %zu) failed: returning null pointer", n_elements, elem_size);
+ }
+ return result;
}
extern "C" void free(void* mem) {
@@ -89,6 +97,14 @@
return Malloc(mallinfo)();
}
+extern "C" int malloc_info(int options, FILE* fp) {
+ auto dispatch_table = GetDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->malloc_info(options, fp);
+ }
+ return Malloc(malloc_info)(options, fp);
+}
+
extern "C" int mallopt(int param, int value) {
auto dispatch_table = GetDispatchTable();
if (__predict_false(dispatch_table != nullptr)) {
@@ -102,7 +118,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->malloc(bytes);
}
- return Malloc(malloc)(bytes);
+ void* result = Malloc(malloc)(bytes);
+ if (__predict_false(result == nullptr)) {
+ warning_log("malloc(%zu) failed: returning null pointer", bytes);
+ }
+ return result;
}
extern "C" size_t malloc_usable_size(const void* mem) {
@@ -118,7 +138,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->memalign(alignment, bytes);
}
- return Malloc(memalign)(alignment, bytes);
+ void* result = Malloc(memalign)(alignment, bytes);
+ if (__predict_false(result == nullptr)) {
+ warning_log("memalign(%zu, %zu) failed: returning null pointer", alignment, bytes);
+ }
+ return result;
}
extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size) {
@@ -134,7 +158,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->aligned_alloc(alignment, size);
}
- return Malloc(aligned_alloc)(alignment, size);
+ void* result = Malloc(aligned_alloc)(alignment, size);
+ if (__predict_false(result == nullptr)) {
+ warning_log("aligned_alloc(%zu, %zu) failed: returning null pointer", alignment, size);
+ }
+ return result;
}
extern "C" void* realloc(void* old_mem, size_t bytes) {
@@ -142,12 +170,18 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->realloc(old_mem, bytes);
}
- return Malloc(realloc)(old_mem, bytes);
+ void* result = Malloc(realloc)(old_mem, bytes);
+ if (__predict_false(result == nullptr && bytes != 0)) {
+ warning_log("realloc(%p, %zu) failed: returning null pointer", old_mem, bytes);
+ }
+ return result;
}
extern "C" void* reallocarray(void* old_mem, size_t item_count, size_t item_size) {
size_t new_size;
if (__builtin_mul_overflow(item_count, item_size, &new_size)) {
+ warning_log("reallocaray(%p, %zu, %zu) failed: returning null pointer",
+ old_mem, item_count, item_size);
errno = ENOMEM;
return nullptr;
}
@@ -160,7 +194,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->pvalloc(bytes);
}
- return Malloc(pvalloc)(bytes);
+ void* result = Malloc(pvalloc)(bytes);
+ if (__predict_false(result == nullptr)) {
+ warning_log("pvalloc(%zu) failed: returning null pointer", bytes);
+ }
+ return result;
}
extern "C" void* valloc(size_t bytes) {
@@ -168,7 +206,11 @@
if (__predict_false(dispatch_table != nullptr)) {
return dispatch_table->valloc(bytes);
}
- return Malloc(valloc)(bytes);
+ void* result = Malloc(valloc)(bytes);
+ if (__predict_false(result == nullptr)) {
+ warning_log("valloc(%zu) failed: returning null pointer", bytes);
+ }
+ return result;
}
#endif
// =============================================================================
@@ -226,6 +268,11 @@
extern "C" void __sanitizer_malloc_enable() {
}
+
+extern "C" int __sanitizer_malloc_info(int, FILE*) {
+ errno = ENOTSUP;
+ return -1;
+}
#endif
// =============================================================================
@@ -233,8 +280,10 @@
// Platform-internal mallopt variant.
// =============================================================================
#if defined(LIBC_STATIC)
-extern "C" bool android_mallopt(int, void*, size_t) {
- // There are no options supported on static executables.
+extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
+ if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
+ return LimitEnable(arg, arg_size);
+ }
errno = ENOTSUP;
return false;
}
diff --git a/libc/bionic/malloc_common.h b/libc/bionic/malloc_common.h
index a2f338a..7f3b711 100644
--- a/libc/bionic/malloc_common.h
+++ b/libc/bionic/malloc_common.h
@@ -29,6 +29,7 @@
#pragma once
#include <stdatomic.h>
+#include <stdio.h>
#include <async_safe/log.h>
#include <private/bionic_globals.h>
@@ -46,6 +47,7 @@
void* arg);
void __sanitizer_malloc_disable();
void __sanitizer_malloc_enable();
+int __sanitizer_malloc_info(int options, FILE* fp);
__END_DECLS
@@ -53,17 +55,30 @@
#else // __has_feature(hwaddress_sanitizer)
+#if defined(USE_SCUDO)
+
+#include "scudo.h"
+#define Malloc(function) scudo_ ## function
+
+#else
+
#include "jemalloc.h"
#define Malloc(function) je_ ## function
#endif
+#endif
+
extern int gMallocLeakZygoteChild;
static inline const MallocDispatch* GetDispatchTable() {
return atomic_load_explicit(&__libc_globals->current_dispatch_table, memory_order_acquire);
}
+static inline const MallocDispatch* GetDefaultDispatchTable() {
+ return atomic_load_explicit(&__libc_globals->default_dispatch_table, memory_order_acquire);
+}
+
// =============================================================================
// Log functions
// =============================================================================
@@ -71,4 +86,6 @@
async_safe_format_log(ANDROID_LOG_ERROR, "libc", (format), ##__VA_ARGS__ )
#define info_log(format, ...) \
async_safe_format_log(ANDROID_LOG_INFO, "libc", (format), ##__VA_ARGS__ )
+#define warning_log(format, ...) \
+ async_safe_format_log(ANDROID_LOG_WARN, "libc", (format), ##__VA_ARGS__ )
// =============================================================================
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index ce3e761..3ccaed6 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -57,12 +57,22 @@
#include <private/bionic_config.h>
#include <private/bionic_defs.h>
#include <private/bionic_malloc_dispatch.h>
+#include <private/bionic_malloc.h>
#include <sys/system_properties.h>
#include "malloc_common.h"
#include "malloc_common_dynamic.h"
#include "malloc_heapprofd.h"
+#include "malloc_limit.h"
+
+// =============================================================================
+// Global variables instantations.
+// =============================================================================
+pthread_mutex_t gGlobalsMutateLock = PTHREAD_MUTEX_INITIALIZER;
+
+_Atomic bool gGlobalsMutating = false;
+// =============================================================================
static constexpr MallocDispatch __libc_malloc_default_dispatch
__attribute__((unused)) = {
@@ -85,6 +95,7 @@
Malloc(malloc_enable),
Malloc(mallopt),
Malloc(aligned_alloc),
+ Malloc(malloc_info),
};
static constexpr char kHooksSharedLib[] = "libc_malloc_hooks.so";
@@ -146,6 +157,10 @@
if (!InitMallocFunction<MallocMalloc>(impl_handler, &table->malloc, prefix, "malloc")) {
return false;
}
+ if (!InitMallocFunction<MallocMallocInfo>(impl_handler, &table->malloc_info, prefix,
+ "malloc_info")) {
+ return false;
+ }
if (!InitMallocFunction<MallocMallocUsableSize>(impl_handler, &table->malloc_usable_size, prefix,
"malloc_usable_size")) {
return false;
@@ -287,9 +302,10 @@
// Do a pointer swap so that all of the functions become valid at once to
// avoid any initialization order problems.
- atomic_store(&globals->current_dispatch_table, &globals->malloc_dispatch_table);
-
- info_log("%s: malloc %s enabled", getprogname(), prefix);
+ atomic_store(&globals->default_dispatch_table, &globals->malloc_dispatch_table);
+ if (GetDispatchTable() == nullptr) {
+ atomic_store(&globals->current_dispatch_table, &globals->malloc_dispatch_table);
+ }
// Use atexit to trigger the cleanup function. This avoids a problem
// where another atexit function is used to cleanup allocated memory,
@@ -298,7 +314,7 @@
int ret_value = __cxa_atexit(MallocFiniImpl, nullptr, nullptr);
if (ret_value != 0) {
// We don't consider this a fatal error.
- info_log("failed to set atexit cleanup function: %d", ret_value);
+ warning_log("failed to set atexit cleanup function: %d", ret_value);
}
return true;
}
@@ -310,13 +326,6 @@
return false;
}
- init_func_t init_func = reinterpret_cast<init_func_t>(gFunctions[FUNC_INITIALIZE]);
- if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild, options)) {
- error_log("%s: failed to enable malloc %s", getprogname(), prefix);
- ClearGlobalFunctions();
- return false;
- }
-
if (!FinishInstallHooks(globals, options, prefix)) {
dlclose(impl_handle);
return false;
@@ -426,6 +435,9 @@
// Platform-internal mallopt variant.
// =============================================================================
extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
+ if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
+ return LimitEnable(arg, arg_size);
+ }
return HeapprofdMallopt(opcode, arg, arg_size);
}
// =============================================================================
diff --git a/libc/bionic/malloc_common_dynamic.h b/libc/bionic/malloc_common_dynamic.h
index 8794ed0..755af8f 100644
--- a/libc/bionic/malloc_common_dynamic.h
+++ b/libc/bionic/malloc_common_dynamic.h
@@ -28,7 +28,8 @@
#pragma once
-#include <stdbool.h>
+#include <pthread.h>
+#include <stdatomic.h>
#include <private/bionic_globals.h>
#include <private/bionic_malloc_dispatch.h>
@@ -40,3 +41,7 @@
void* LoadSharedLibrary(const char* shared_lib, const char* prefix, MallocDispatch* dispatch_table);
bool FinishInstallHooks(libc_globals* globals, const char* options, const char* prefix);
+
+// Lock for globals, to guarantee that only one thread is doing a mutate.
+extern pthread_mutex_t gGlobalsMutateLock;
+extern _Atomic bool gGlobalsMutating;
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index c492bac..eda54ce 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -32,6 +32,7 @@
#include <dlfcn.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -108,6 +109,7 @@
Malloc(malloc_enable),
Malloc(mallopt),
Malloc(aligned_alloc),
+ Malloc(malloc_info),
};
static void MaybeInstallInitHeapprofdHook(int) {
@@ -117,10 +119,27 @@
return;
}
- if (!atomic_exchange(&gHeapprofdInitInProgress, true)) {
- __libc_globals.mutate([](libc_globals* globals) {
- atomic_store(&globals->current_dispatch_table, &__heapprofd_init_dispatch);
- });
+ // Checking this variable is only necessary when this could conflict with
+ // the change to enable the allocation limit. All other places will
+ // not ever have a conflict modifying the globals.
+ if (!atomic_exchange(&gGlobalsMutating, true)) {
+ if (!atomic_exchange(&gHeapprofdInitInProgress, true)) {
+ __libc_globals.mutate([](libc_globals* globals) {
+ atomic_store(&globals->default_dispatch_table, &__heapprofd_init_dispatch);
+ auto dispatch_table = GetDispatchTable();
+ if (dispatch_table == nullptr || dispatch_table == &globals->malloc_dispatch_table) {
+ atomic_store(&globals->current_dispatch_table, &__heapprofd_init_dispatch);
+ }
+ });
+ }
+ atomic_store(&gGlobalsMutating, false);
+ } else {
+ // The only way you can get to this point is if the signal has been
+ // blocked by a call to HeapprofdMaskSignal. The raise below will
+ // do nothing until a call to HeapprofdUnmaskSignal, which will cause
+ // the signal to be resent. Using this avoids the need for a busy loop
+ // waiting for gGlobalsMutating to change back to false.
+ raise(kHeapprofdSignal);
}
}
@@ -202,7 +221,7 @@
if (__system_property_get(program_property, property_value) == 0) {
return false;
}
- return program_property[0] != '\0';
+ return property_value[0] != '\0';
}
void HeapprofdInstallSignalHandler() {
@@ -211,6 +230,24 @@
sigaction(kHeapprofdSignal, &action, nullptr);
}
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+
+void HeapprofdMaskSignal() {
+ sigset64_t mask_set;
+ // Need to use this function instead because sigprocmask64 filters
+ // out this signal.
+ __rt_sigprocmask(SIG_SETMASK, nullptr, &mask_set, sizeof(mask_set));
+ sigaddset64(&mask_set, kHeapprofdSignal);
+ __rt_sigprocmask(SIG_SETMASK, &mask_set, nullptr, sizeof(mask_set));
+}
+
+void HeapprofdUnmaskSignal() {
+ sigset64_t mask_set;
+ __rt_sigprocmask(SIG_SETMASK, nullptr, &mask_set, sizeof(mask_set));
+ sigdelset64(&mask_set, kHeapprofdSignal);
+ __rt_sigprocmask(SIG_SETMASK, &mask_set, nullptr, sizeof(mask_set));
+}
+
static void DisplayError(int) {
error_log("Cannot install heapprofd while malloc debug/malloc hooks are enabled.");
}
@@ -250,9 +287,11 @@
}
static void* InitHeapprofd(void*) {
+ pthread_mutex_lock(&gGlobalsMutateLock);
__libc_globals.mutate([](libc_globals* globals) {
CommonInstallHooks(globals);
});
+ pthread_mutex_unlock(&gGlobalsMutateLock);
// Allow to install hook again to re-initialize heap profiling after the
// current session finished.
@@ -262,9 +301,15 @@
extern "C" void* MallocInitHeapprofdHook(size_t bytes) {
if (!atomic_exchange(&gHeapprofdInitHookInstalled, true)) {
+ pthread_mutex_lock(&gGlobalsMutateLock);
__libc_globals.mutate([](libc_globals* globals) {
- atomic_store(&globals->current_dispatch_table, nullptr);
+ auto old_dispatch = GetDefaultDispatchTable();
+ atomic_store(&globals->default_dispatch_table, nullptr);
+ if (GetDispatchTable() == old_dispatch) {
+ atomic_store(&globals->current_dispatch_table, nullptr);
+ }
});
+ pthread_mutex_unlock(&gGlobalsMutateLock);
pthread_t thread_id;
if (pthread_create(&thread_id, nullptr, InitHeapprofd, nullptr) != 0) {
@@ -294,9 +339,15 @@
static bool DispatchReset() {
if (!atomic_exchange(&gHeapprofdInitInProgress, true)) {
+ pthread_mutex_lock(&gGlobalsMutateLock);
__libc_globals.mutate([](libc_globals* globals) {
- atomic_store(&globals->current_dispatch_table, nullptr);
+ auto old_dispatch = GetDefaultDispatchTable();
+ atomic_store(&globals->default_dispatch_table, nullptr);
+ if (GetDispatchTable() == old_dispatch) {
+ atomic_store(&globals->current_dispatch_table, nullptr);
+ }
});
+ pthread_mutex_unlock(&gGlobalsMutateLock);
atomic_store(&gHeapprofdInitInProgress, false);
return true;
}
diff --git a/libc/bionic/malloc_heapprofd.h b/libc/bionic/malloc_heapprofd.h
index 5a766fc..9e846b6 100644
--- a/libc/bionic/malloc_heapprofd.h
+++ b/libc/bionic/malloc_heapprofd.h
@@ -40,4 +40,8 @@
void HeapprofdInstallErrorSignalHandler();
+void HeapprofdMaskSignal();
+
+void HeapprofdUnmaskSignal();
+
bool HeapprofdMallopt(int optcode, void* arg, size_t arg_size);
diff --git a/libc/bionic/malloc_info.cpp b/libc/bionic/malloc_info.cpp
deleted file mode 100644
index 9c8a4bf..0000000
--- a/libc/bionic/malloc_info.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "malloc_info.h"
-
-#include <errno.h>
-#include "private/bionic_macros.h"
-
-class __LIBC_HIDDEN__ Elem {
-public:
- // name must be valid throughout lifetime of the object.
- explicit Elem(FILE* fp, const char* name,
- const char* attr_fmt = nullptr, ...) {
- this->fp = fp;
- this->name = name;
-
- fprintf(fp, "<%s", name);
- if (attr_fmt != nullptr) {
- va_list args;
- va_start(args, attr_fmt);
- fputc(' ', fp);
- vfprintf(fp, attr_fmt, args);
- va_end(args);
- }
- fputc('>', fp);
- }
-
- ~Elem() noexcept {
- fprintf(fp, "</%s>", name);
- }
-
- void contents(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vfprintf(fp, fmt, args);
- va_end(args);
- }
-
-private:
- FILE* fp;
- const char* name;
-
- BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(Elem);
-};
-
-int malloc_info(int options, FILE* fp) {
- if (options != 0) {
- errno = EINVAL;
- return -1;
- }
-
- Elem root(fp, "malloc", "version=\"jemalloc-1\"");
-
- // Dump all of the large allocations in the arenas.
- for (size_t i = 0; i < __mallinfo_narenas(); i++) {
- struct mallinfo mi = __mallinfo_arena_info(i);
- if (mi.hblkhd != 0) {
- Elem arena_elem(fp, "heap", "nr=\"%d\"", i);
- {
- Elem(fp, "allocated-large").contents("%zu", mi.ordblks);
- Elem(fp, "allocated-huge").contents("%zu", mi.uordblks);
- Elem(fp, "allocated-bins").contents("%zu", mi.fsmblks);
-
- size_t total = 0;
- for (size_t j = 0; j < __mallinfo_nbins(); j++) {
- struct mallinfo mi = __mallinfo_bin_info(i, j);
- if (mi.ordblks != 0) {
- Elem bin_elem(fp, "bin", "nr=\"%d\"", j);
- Elem(fp, "allocated").contents("%zu", mi.ordblks);
- Elem(fp, "nmalloc").contents("%zu", mi.uordblks);
- Elem(fp, "ndalloc").contents("%zu", mi.fordblks);
- total += mi.ordblks;
- }
- }
- Elem(fp, "bins-total").contents("%zu", total);
- }
- }
- }
-
- return 0;
-}
diff --git a/libc/bionic/malloc_info.h b/libc/bionic/malloc_info.h
deleted file mode 100644
index 257fec1..0000000
--- a/libc/bionic/malloc_info.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <malloc.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-__LIBC_HIDDEN__ size_t __mallinfo_narenas();
-__LIBC_HIDDEN__ size_t __mallinfo_nbins();
-__LIBC_HIDDEN__ struct mallinfo __mallinfo_arena_info(size_t);
-__LIBC_HIDDEN__ struct mallinfo __mallinfo_bin_info(size_t, size_t);
-
-__END_DECLS
diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp
new file mode 100644
index 0000000..b42865b
--- /dev/null
+++ b/libc/bionic/malloc_limit.cpp
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdatomic.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <private/bionic_malloc_dispatch.h>
+
+#if __has_feature(hwaddress_sanitizer)
+#include <sanitizer/allocator_interface.h>
+#endif
+
+#include "malloc_common.h"
+#include "malloc_common_dynamic.h"
+#include "malloc_heapprofd.h"
+#include "malloc_limit.h"
+
+__BEGIN_DECLS
+static void* LimitCalloc(size_t n_elements, size_t elem_size);
+static void LimitFree(void* mem);
+static void* LimitMalloc(size_t bytes);
+static void* LimitMemalign(size_t alignment, size_t bytes);
+static int LimitPosixMemalign(void** memptr, size_t alignment, size_t size);
+static void* LimitRealloc(void* old_mem, size_t bytes);
+static void* LimitAlignedAlloc(size_t alignment, size_t size);
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+static void* LimitPvalloc(size_t bytes);
+static void* LimitValloc(size_t bytes);
+#endif
+
+// Pass through functions.
+static size_t LimitUsableSize(const void* mem);
+static struct mallinfo LimitMallinfo();
+static int LimitIterate(uintptr_t base, size_t size, void (*callback)(uintptr_t, size_t, void*), void* arg);
+static void LimitMallocDisable();
+static void LimitMallocEnable();
+static int LimitMallocInfo(int options, FILE* fp);
+static int LimitMallopt(int param, int value);
+__END_DECLS
+
+static constexpr MallocDispatch __limit_dispatch
+ __attribute__((unused)) = {
+ LimitCalloc,
+ LimitFree,
+ LimitMallinfo,
+ LimitMalloc,
+ LimitUsableSize,
+ LimitMemalign,
+ LimitPosixMemalign,
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ LimitPvalloc,
+#endif
+ LimitRealloc,
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ LimitValloc,
+#endif
+ LimitIterate,
+ LimitMallocDisable,
+ LimitMallocEnable,
+ LimitMallopt,
+ LimitAlignedAlloc,
+ LimitMallocInfo,
+ };
+
+static _Atomic uint64_t gAllocated;
+static uint64_t gAllocLimit;
+
+static inline bool CheckLimit(size_t bytes) {
+ uint64_t total;
+ if (__predict_false(__builtin_add_overflow(
+ atomic_load_explicit(&gAllocated, memory_order_relaxed), bytes, &total) ||
+ total > gAllocLimit)) {
+ return false;
+ }
+ return true;
+}
+
+static inline void* IncrementLimit(void* mem) {
+ if (__predict_false(mem == nullptr)) {
+ return nullptr;
+ }
+ atomic_fetch_add(&gAllocated, LimitUsableSize(mem));
+ return mem;
+}
+
+void* LimitCalloc(size_t n_elements, size_t elem_size) {
+ size_t total;
+ if (__builtin_add_overflow(n_elements, elem_size, &total) || !CheckLimit(total)) {
+ warning_log("malloc_limit: calloc(%zu, %zu) exceeds limit %" PRId64, n_elements, elem_size,
+ gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->calloc(n_elements, elem_size));
+ }
+ return IncrementLimit(Malloc(calloc)(n_elements, elem_size));
+}
+
+void LimitFree(void* mem) {
+ atomic_fetch_sub(&gAllocated, LimitUsableSize(mem));
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->free(mem);
+ }
+ return Malloc(free)(mem);
+}
+
+void* LimitMalloc(size_t bytes) {
+ if (!CheckLimit(bytes)) {
+ warning_log("malloc_limit: malloc(%zu) exceeds limit %" PRId64, bytes, gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->malloc(bytes));
+ }
+ return IncrementLimit(Malloc(malloc)(bytes));
+}
+
+static void* LimitMemalign(size_t alignment, size_t bytes) {
+ if (!CheckLimit(bytes)) {
+ warning_log("malloc_limit: memalign(%zu, %zu) exceeds limit %" PRId64, alignment, bytes,
+ gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->memalign(alignment, bytes));
+ }
+ return IncrementLimit(Malloc(memalign)(alignment, bytes));
+}
+
+static int LimitPosixMemalign(void** memptr, size_t alignment, size_t size) {
+ if (!CheckLimit(size)) {
+ warning_log("malloc_limit: posix_memalign(%zu, %zu) exceeds limit %" PRId64, alignment, size,
+ gAllocLimit);
+ return ENOMEM;
+ }
+ int retval;
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ retval = dispatch_table->posix_memalign(memptr, alignment, size);
+ } else {
+ retval = Malloc(posix_memalign)(memptr, alignment, size);
+ }
+ if (__predict_false(retval != 0)) {
+ return retval;
+ }
+ IncrementLimit(*memptr);
+ return 0;
+}
+
+static void* LimitAlignedAlloc(size_t alignment, size_t size) {
+ if (!CheckLimit(size)) {
+ warning_log("malloc_limit: aligned_alloc(%zu, %zu) exceeds limit %" PRId64, alignment, size,
+ gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->aligned_alloc(alignment, size));
+ }
+ return IncrementLimit(Malloc(aligned_alloc)(alignment, size));
+}
+
+static void* LimitRealloc(void* old_mem, size_t bytes) {
+ size_t old_usable_size = LimitUsableSize(old_mem);
+ void* new_ptr;
+ // Need to check the size only if the allocation will increase in size.
+ if (bytes > old_usable_size && !CheckLimit(bytes - old_usable_size)) {
+ warning_log("malloc_limit: realloc(%p, %zu) exceeds limit %" PRId64, old_mem, bytes,
+ gAllocLimit);
+ // Free the old pointer.
+ LimitFree(old_mem);
+ return nullptr;
+ }
+
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ new_ptr = dispatch_table->realloc(old_mem, bytes);
+ } else {
+ new_ptr = Malloc(realloc)(old_mem, bytes);
+ }
+
+ if (__predict_false(new_ptr == nullptr)) {
+ // This acts as if the pointer was freed.
+ atomic_fetch_sub(&gAllocated, old_usable_size);
+ return nullptr;
+ }
+
+ size_t new_usable_size = LimitUsableSize(new_ptr);
+ // Assumes that most allocations increase in size, rather than shrink.
+ if (__predict_false(old_usable_size > new_usable_size)) {
+ atomic_fetch_sub(&gAllocated, old_usable_size - new_usable_size);
+ } else {
+ atomic_fetch_add(&gAllocated, new_usable_size - old_usable_size);
+ }
+ return new_ptr;
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+static void* LimitPvalloc(size_t bytes) {
+ if (!CheckLimit(bytes)) {
+ warning_log("malloc_limit: pvalloc(%zu) exceeds limit %" PRId64, bytes, gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->pvalloc(bytes));
+ }
+ return IncrementLimit(Malloc(pvalloc)(bytes));
+}
+
+static void* LimitValloc(size_t bytes) {
+ if (!CheckLimit(bytes)) {
+ warning_log("malloc_limit: valloc(%zu) exceeds limit %" PRId64, bytes, gAllocLimit);
+ return nullptr;
+ }
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return IncrementLimit(dispatch_table->valloc(bytes));
+ }
+ return IncrementLimit(Malloc(valloc)(bytes));
+}
+#endif
+
+#if defined(LIBC_STATIC)
+static bool EnableLimitDispatchTable() {
+ // This is the only valid way to modify the dispatch tables for a
+ // static executable so no locks are necessary.
+ __libc_globals.mutate([](libc_globals* globals) {
+ atomic_store(&globals->current_dispatch_table, &__limit_dispatch);
+ });
+ return true;
+}
+#else
+static bool EnableLimitDispatchTable() {
+ HeapprofdMaskSignal();
+ pthread_mutex_lock(&gGlobalsMutateLock);
+ // All other code that calls mutate will grab the gGlobalsMutateLock.
+ // However, there is one case where the lock cannot be acquired, in the
+ // signal handler that enables heapprofd. In order to avoid having two
+ // threads calling mutate at the same time, use an atomic variable to
+ // verify that only this function or the signal handler are calling mutate.
+ // If this function is called at the same time as the signal handler is
+ // being called, allow up to five ms for the signal handler to complete
+ // before failing.
+ bool enabled = false;
+ size_t num_tries = 20;
+ while (true) {
+ if (!atomic_exchange(&gGlobalsMutating, true)) {
+ __libc_globals.mutate([](libc_globals* globals) {
+ atomic_store(&globals->current_dispatch_table, &__limit_dispatch);
+ });
+ atomic_store(&gGlobalsMutating, false);
+ enabled = true;
+ break;
+ }
+ if (--num_tries == 0) {
+ break;
+ }
+ usleep(1000);
+ }
+ pthread_mutex_unlock(&gGlobalsMutateLock);
+ HeapprofdUnmaskSignal();
+ if (enabled) {
+ info_log("malloc_limit: Allocation limit enabled, max size %" PRId64 " bytes\n", gAllocLimit);
+ } else {
+ error_log("malloc_limit: Failed to enable allocation limit.");
+ }
+ return enabled;
+}
+#endif
+
+bool LimitEnable(void* arg, size_t arg_size) {
+ if (arg == nullptr || arg_size != sizeof(size_t)) {
+ errno = EINVAL;
+ return false;
+ }
+
+ static _Atomic bool limit_enabled;
+ if (atomic_exchange(&limit_enabled, true)) {
+ // The limit can only be enabled once.
+ error_log("malloc_limit: The allocation limit has already been set, it can only be set once.");
+ return false;
+ }
+
+ gAllocLimit = *reinterpret_cast<size_t*>(arg);
+#if __has_feature(hwaddress_sanitizer)
+ size_t current_allocated = __sanitizer_get_current_allocated_bytes();
+#else
+ size_t current_allocated;
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ current_allocated = dispatch_table->mallinfo().uordblks;
+ } else {
+ current_allocated = Malloc(mallinfo)().uordblks;
+ }
+#endif
+ atomic_store(&gAllocated, current_allocated);
+
+ return EnableLimitDispatchTable();
+}
+
+static size_t LimitUsableSize(const void* mem) {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->malloc_usable_size(mem);
+ }
+ return Malloc(malloc_usable_size)(mem);
+}
+
+static struct mallinfo LimitMallinfo() {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->mallinfo();
+ }
+ return Malloc(mallinfo)();
+}
+
+static int LimitIterate(uintptr_t base, size_t size, void (*callback)(uintptr_t, size_t, void*), void* arg) {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->iterate(base, size, callback, arg);
+ }
+ return Malloc(iterate)(base, size, callback, arg);
+}
+
+static void LimitMallocDisable() {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ dispatch_table->malloc_disable();
+ } else {
+ Malloc(malloc_disable)();
+ }
+}
+
+static void LimitMallocEnable() {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ dispatch_table->malloc_enable();
+ } else {
+ Malloc(malloc_enable)();
+ }
+}
+
+static int LimitMallocInfo(int options, FILE* fp) {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->malloc_info(options, fp);
+ }
+ return Malloc(malloc_info)(options, fp);
+}
+
+static int LimitMallopt(int param, int value) {
+ auto dispatch_table = GetDefaultDispatchTable();
+ if (__predict_false(dispatch_table != nullptr)) {
+ return dispatch_table->mallopt(param, value);
+ }
+ return Malloc(mallopt)(param, value);
+}
diff --git a/libc/bionic/malloc_limit.h b/libc/bionic/malloc_limit.h
new file mode 100644
index 0000000..282598f
--- /dev/null
+++ b/libc/bionic/malloc_limit.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+// Function prototypes.
+bool LimitEnable(void* arg, size_t arg_size);
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index b8784b8..4cf14ad 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -127,18 +127,25 @@
static void __init_shadow_call_stack(pthread_internal_t* thread __unused) {
#ifdef __aarch64__
- // Allocate the stack and store its address in register x18. The address is aligned to SCS_SIZE so
- // that we only need to store the lower log2(SCS_SIZE) bits in jmp_buf.
- // TODO(pcc): We ought to allocate a larger guard region here and then allocate the SCS at a
- // random location within it. This will provide greater security since it would mean that an
- // attacker who can read the pthread_internal_t won't be able to discover the address of the SCS.
- // However, doing so is blocked on a solution to b/118642754.
+ // Allocate the stack and the guard region.
char* scs_guard_region = reinterpret_cast<char*>(
mmap(nullptr, SCS_GUARD_REGION_SIZE, 0, MAP_PRIVATE | MAP_ANON, -1, 0));
thread->shadow_call_stack_guard_region = scs_guard_region;
- char* scs =
+ // The address is aligned to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
+ // in jmp_buf.
+ char* scs_aligned_guard_region =
reinterpret_cast<char*>(align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
+
+ // We need to ensure that [scs_offset,scs_offset+SCS_SIZE) is in the guard region and that there
+ // is at least one unmapped page after the shadow call stack (to catch stack overflows). We can't
+ // use arc4random_uniform in init because /dev/urandom might not have been created yet.
+ size_t scs_offset =
+ (getpid() == 1) ? 0 : (arc4random_uniform(SCS_GUARD_REGION_SIZE / SCS_SIZE - 1) * SCS_SIZE);
+
+ // Make the stack readable and writable and store its address in register x18. This is
+ // deliberately the only place where the address is stored.
+ char *scs = scs_aligned_guard_region + scs_offset;
mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
__asm__ __volatile__("mov x18, %0" ::"r"(scs));
#endif
diff --git a/libc/bionic/scudo.h b/libc/bionic/scudo.h
new file mode 100644
index 0000000..d9933c4
--- /dev/null
+++ b/libc/bionic/scudo.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdio.h>
+#include <malloc.h>
+
+#include <private/bionic_config.h>
+
+__BEGIN_DECLS
+
+void* scudo_aligned_alloc(size_t, size_t);
+void* scudo_calloc(size_t, size_t);
+void scudo_free(void*);
+struct mallinfo scudo_mallinfo();
+void* scudo_malloc(size_t);
+int scudo_malloc_info(int, FILE*);
+size_t scudo_malloc_usable_size(const void*);
+int scudo_mallopt(int, int);
+void* scudo_memalign(size_t, size_t);
+void* scudo_realloc(void*, size_t);
+int scudo_posix_memalign(void**, size_t, size_t);
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+void* scudo_pvalloc(size_t);
+void* scudo_valloc(size_t);
+#endif
+
+int scudo_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
+void scudo_malloc_disable();
+void scudo_malloc_enable();
+
+__END_DECLS
diff --git a/libc/bionic/scudo/Android.bp b/libc/bionic/scudo/Android.bp
new file mode 100644
index 0000000..8b518bb
--- /dev/null
+++ b/libc/bionic/scudo/Android.bp
@@ -0,0 +1,60 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_library_shared {
+ name: "libscudo_wrapper",
+ vendor_available: true,
+ srcs: ["scudo.cpp"],
+
+ stl: "none",
+ system_shared_libs: [],
+ host_supported: false,
+
+ header_libs: ["libc_headers"],
+ include_dirs: [
+ "bionic/libc",
+ "bionic/libc/bionic",
+ ],
+
+ whole_static_libs: ["libasync_safe"],
+
+ arch: {
+ arm: {
+ whole_static_libs: ["libclang_rt.scudo_minimal-arm-android.static"],
+ },
+ arm64: {
+ whole_static_libs: ["libclang_rt.scudo_minimal-aarch64-android.static"],
+ },
+ x86: {
+ whole_static_libs: ["libclang_rt.scudo_minimal-i686-android.static"],
+ },
+ x86_64: {
+ whole_static_libs: ["libclang_rt.scudo_minimal-x86_64-android.static"],
+ },
+ },
+
+ // Will be referencing other libc code that won't be defined here.
+ allow_undefined_symbols: true,
+
+ multilib: {
+ lib32: {
+ version_script: "exported32.map",
+ },
+ lib64: {
+ version_script: "exported64.map",
+ },
+ },
+}
diff --git a/libc/bionic/scudo/exported32.map b/libc/bionic/scudo/exported32.map
new file mode 100644
index 0000000..4b6791d
--- /dev/null
+++ b/libc/bionic/scudo/exported32.map
@@ -0,0 +1,16 @@
+LIBC_SCUDO {
+ global:
+ scudo_aligned_alloc;
+ scudo_calloc;
+ scudo_free;
+ scudo_mallinfo;
+ scudo_malloc;
+ scudo_malloc_usable_size;
+ scudo_memalign;
+ scudo_posix_memalign;
+ scudo_pvalloc;
+ scudo_realloc;
+ scudo_valloc;
+ local:
+ *;
+};
diff --git a/libc/bionic/scudo/exported64.map b/libc/bionic/scudo/exported64.map
new file mode 100644
index 0000000..1346b4b
--- /dev/null
+++ b/libc/bionic/scudo/exported64.map
@@ -0,0 +1,14 @@
+LIBC_SCUDO {
+ global:
+ scudo_aligned_alloc;
+ scudo_calloc;
+ scudo_free;
+ scudo_mallinfo;
+ scudo_malloc;
+ scudo_malloc_usable_size;
+ scudo_memalign;
+ scudo_posix_memalign;
+ scudo_realloc;
+ local:
+ *;
+};
diff --git a/libc/bionic/scudo/scudo.cpp b/libc/bionic/scudo/scudo.cpp
new file mode 100644
index 0000000..fb09b92
--- /dev/null
+++ b/libc/bionic/scudo/scudo.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/prctl.h>
+
+#include "private/bionic_macros.h"
+
+#include "scudo.h"
+
+// Disable Scudo's mismatch allocation check, as it is being triggered
+// by some third party code.
+extern "C" const char *__scudo_default_options() {
+ return "DeallocationTypeMismatch=false";
+}
+
+static inline bool AllocTooBig(size_t bytes) {
+#if defined(__LP64__)
+ if (__predict_false(bytes > 0x10000000000ULL)) {
+#else
+ if (__predict_false(bytes > 0x80000000ULL)) {
+#endif
+ return true;
+ }
+ return false;
+}
+
+void* scudo_aligned_alloc(size_t alignment, size_t size) {
+ if (alignment == 0 || !powerof2(alignment) || (size % alignment) != 0) {
+ errno = EINVAL;
+ return nullptr;
+ }
+ if (AllocTooBig(size)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ return aligned_alloc(alignment, size);
+}
+
+void* scudo_calloc(size_t item_count, size_t item_size) {
+ size_t total;
+ if (__builtin_mul_overflow(item_count, item_size, &total) || AllocTooBig(total)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return calloc(item_count, item_size);
+}
+
+void scudo_free(void* ptr) {
+ free(ptr);
+}
+
+extern "C" size_t __sanitizer_get_current_allocated_bytes();
+extern "C" size_t __sanitizer_get_heap_size();
+
+struct mallinfo scudo_mallinfo() {
+ struct mallinfo info {};
+ info.uordblks = __sanitizer_get_current_allocated_bytes();
+ info.hblkhd = __sanitizer_get_heap_size();
+ info.usmblks = info.hblkhd;
+ return info;
+}
+
+void* scudo_malloc(size_t byte_count) {
+ if (AllocTooBig(byte_count)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return malloc(byte_count);
+}
+
+size_t scudo_malloc_usable_size(const void* ptr) {
+ return malloc_usable_size(ptr);
+}
+
+void* scudo_memalign(size_t alignment, size_t byte_count) {
+ if (AllocTooBig(byte_count)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ if (alignment != 0) {
+ if (!powerof2(alignment)) {
+ alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
+ }
+ } else {
+ alignment = 1;
+ }
+ return memalign(alignment, byte_count);
+}
+
+void* scudo_realloc(void* ptr, size_t byte_count) {
+ if (AllocTooBig(byte_count)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return realloc(ptr, byte_count);
+}
+
+int scudo_posix_memalign(void** memptr, size_t alignment, size_t size) {
+ if (alignment < sizeof(void*) || !powerof2(alignment)) {
+ return EINVAL;
+ }
+ if (AllocTooBig(size)) {
+ return ENOMEM;
+ }
+ return posix_memalign(memptr, alignment, size);
+}
+
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+extern "C" void* pvalloc(size_t);
+
+void* scudo_pvalloc(size_t size) {
+ if (AllocTooBig(size)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return pvalloc(size);
+}
+
+extern "C" void* valloc(size_t);
+
+void* scudo_valloc(size_t size) {
+ if (AllocTooBig(size)) {
+ errno = ENOMEM;
+ return nullptr;
+ }
+ return valloc(size);
+}
+#endif
+
+// Do not try and name the scudo maps by overriding __sanitizer::internal_mmap.
+// There is already a function called MmapNamed that names the maps.
+// Unfortunately, there is no easy way to override MmapNamed because
+// too much of the code is not compiled into functions available in the
+// library, and the code is complicated.
diff --git a/libc/bionic/scudo_wrapper.cpp b/libc/bionic/scudo_wrapper.cpp
new file mode 100644
index 0000000..e17f20b
--- /dev/null
+++ b/libc/bionic/scudo_wrapper.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "scudo.h"
+#include "private/bionic_globals.h"
+#include "private/WriteProtected.h"
+
+__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
+
+#if defined(__i386__)
+__LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
+#endif
+
+int scudo_mallopt(int /*param*/, int /*value*/) {
+ return 0;
+}
+
+int scudo_malloc_info(int /*options*/, FILE* /*fp*/) {
+ errno = ENOTSUP;
+ return -1;
+}
+
+int scudo_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*) {
+ return 0;
+}
+
+void scudo_malloc_disable() {
+}
+
+void scudo_malloc_enable() {
+}
diff --git a/libc/bionic/strsignal.cpp b/libc/bionic/strsignal.cpp
index 5637431..05d3498 100644
--- a/libc/bionic/strsignal.cpp
+++ b/libc/bionic/strsignal.cpp
@@ -37,7 +37,7 @@
};
const char* const sys_signame[NSIG] = {
-#define __BIONIC_SIGDEF(signal_number, unused) [ signal_number ] = #signal_number + 3,
+#define __BIONIC_SIGDEF(signal_number, unused) [ signal_number ] = &(#signal_number)[3],
#include "private/bionic_sigdefs.h"
};
diff --git a/libc/bionic/system.cpp b/libc/bionic/system.cpp
index 7411ae5..950f05c 100644
--- a/libc/bionic/system.cpp
+++ b/libc/bionic/system.cpp
@@ -27,12 +27,12 @@
*/
#include <errno.h>
-#include <paths.h>
#include <stdlib.h>
#include <spawn.h>
#include <sys/wait.h>
#include <unistd.h>
+#include "private/__bionic_get_shell_path.h"
#include "private/ScopedSignalBlocker.h"
#include "private/ScopedSignalHandler.h"
@@ -58,7 +58,7 @@
const char* argv[] = { "sh", "-c", command, nullptr };
pid_t child;
- if ((errno = posix_spawn(&child, _PATH_BSHELL, nullptr, &attributes,
+ if ((errno = posix_spawn(&child, __bionic_get_shell_path(), nullptr, &attributes,
const_cast<char**>(argv), environ)) != 0) {
return -1;
}
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index e78be39..f0b731c 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -114,6 +114,29 @@
*/
ANDROID_DLEXT_USE_NAMESPACE = 0x200,
+ /**
+ * Instructs dlopen to apply `ANDROID_DLEXT_RESERVED_ADDRESS`,
+ * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`, `ANDROID_DLEXT_WRITE_RELRO` and
+ * `ANDROID_DLEXT_USE_RELRO` to any libraries loaded as dependencies of the
+ * main library as well.
+ *
+ * This means that if the main library depends on one or more not-already-loaded libraries, they
+ * will be loaded consecutively into the region starting at `reserved_addr`, and `reserved_size`
+ * must be large enough to contain all of the libraries. The libraries will be loaded in the
+ * deterministic order constructed from the DT_NEEDED entries, rather than the more secure random
+ * order used by default.
+ *
+ * Each library's GNU RELRO sections will be written out to `relro_fd` in the same order they were
+ * loaded. This will mean that the resulting file is dependent on which of the libraries were
+ * already loaded, as only the newly loaded libraries will be included, not any already-loaded
+ * dependencies. The caller should ensure that the set of libraries newly loaded is consistent
+ * for this to be effective.
+ *
+ * This is mainly useful for the system WebView implementation.
+ */
+ ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE = 0x400,
+
+
/** Mask of valid bits. */
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
@@ -122,7 +145,8 @@
ANDROID_DLEXT_USE_LIBRARY_FD |
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
ANDROID_DLEXT_FORCE_LOAD |
- ANDROID_DLEXT_USE_NAMESPACE,
+ ANDROID_DLEXT_USE_NAMESPACE |
+ ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE,
};
struct android_namespace_t;
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index ea7689c..1169ed0 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -128,40 +128,40 @@
/*
* Create an owner tag with the specified type and least significant 56 bits of tag.
*/
-uint64_t android_fdsan_create_owner_tag(enum android_fdsan_owner_type type, uint64_t tag) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+uint64_t android_fdsan_create_owner_tag(enum android_fdsan_owner_type type, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__));
/*
* Exchange a file descriptor's tag.
*
* Logs and aborts if the fd's tag does not match expected_tag.
*/
-void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) __INTRODUCED_IN(29) __attribute__((__weak__));
/*
* Close a file descriptor with a tag, and resets the tag to 0.
*
* Logs and aborts if the tag is incorrect.
*/
-int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN(29) __attribute__((__weak__));
/*
* Get a file descriptor's current owner tag.
*
* Returns 0 for untagged and invalid file descriptors.
*/
-uint64_t android_fdsan_get_owner_tag(int fd);
+uint64_t android_fdsan_get_owner_tag(int fd) __INTRODUCED_IN(29);
/*
* Get an owner tag's string representation.
*
* The return value points to memory with static lifetime, do not attempt to modify it.
*/
-const char* android_fdsan_get_tag_type(uint64_t tag);
+const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
/*
* Get an owner tag's value, with the type masked off.
*/
-uint64_t android_fdsan_get_tag_value(uint64_t tag);
+uint64_t android_fdsan_get_tag_value(uint64_t tag) __INTRODUCED_IN(29);
enum android_fdsan_error_level {
// No errors.
@@ -180,7 +180,7 @@
/*
* Get the error level.
*/
-enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(29) __attribute__((__weak__));
/*
* Set the error level and return the previous state.
@@ -195,6 +195,6 @@
* value, and so should probably only be called in single-threaded contexts
* (e.g. postfork).
*/
-enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__));
__END_DECLS
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 8219759..5ca9813 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -52,7 +52,7 @@
static __inline int __ndk_legacy___libc_current_sigrtmin() {
if (__libc_current_sigrtmin) return __libc_current_sigrtmin();
- return __SIGRTMIN + 5; /* Should match __libc_current_sigrtmin. */
+ return __SIGRTMIN + 6; /* Should match __libc_current_sigrtmin. */
}
#undef SIGRTMAX
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 01fa348..d60957f 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -17,7 +17,6 @@
#pragma once
#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
-#define __INTRODUCED_IN_FUTURE __attribute__((annotate("introduced_in_future")))
#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index 9c6e243..d14eb2c 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -28,11 +28,9 @@
#pragma once
-#include <sys/cdefs.h>
+#if defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#if !defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static inline /* for versioner */
-#endif
+#include <sys/cdefs.h>
__BEGIN_DECLS
@@ -48,3 +46,5 @@
}
__END_DECLS
+
+#endif // __BIONIC_GET_DEVICE_API_LEVEL_INLINE
diff --git a/libc/include/paths.h b/libc/include/paths.h
index b5b8610..0cf2789 100644
--- a/libc/include/paths.h
+++ b/libc/include/paths.h
@@ -47,7 +47,7 @@
#define _PATH_CONSOLE "/dev/console"
/** Default shell search path. */
-#define _PATH_DEFPATH "/sbin:/system/sbin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
+#define _PATH_DEFPATH "/sbin:/system/sbin:/product/bin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
/** Path to the directory containing device files. */
#define _PATH_DEV "/dev/"
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 3089adc..724e5b7 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -137,7 +137,21 @@
const struct timespec* __timeout) __INTRODUCED_IN_64(28);
int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+#if defined(__clang__)
+/*
+ * Disable -Wbuiltin-requires-header because clang confuses this declaration with the one defined in
+ * "llvm/tools/clang/include/clang/Basic/Builtins.def", which did not define any formal arguments.
+ * It seems to be an upstream bug and the fix (https://reviews.llvm.org/D58531) is still under
+ * review. Thus, let's disable the warning for this function declaration.
+ */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
+#endif
int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
int pthread_detach(pthread_t __pthread);
void pthread_exit(void* __return_value) __noreturn;
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 1518475..6318d00 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -60,7 +60,7 @@
int res_search(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
#define res_randomid __res_randomid
-u_int __res_randomid(void) __INTRODUCED_IN_FUTURE;
+u_int __res_randomid(void) __INTRODUCED_IN(29);
__END_DECLS
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 96a77a7..d5b8619 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -154,7 +154,7 @@
*
* Returns the number of samples written to `__averages` (at most 3), and returns -1 on failure.
*/
-int getloadavg(double __averages[], int __n) __INTRODUCED_IN_FUTURE;
+int getloadavg(double __averages[], int __n) __INTRODUCED_IN(29);
/* BSD compatibility. */
const char* getprogname(void) __INTRODUCED_IN(21);
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index 5cde4b7..79ae067 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -51,8 +51,19 @@
#endif
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-/** Returns true if the argument is a power of two. */
-#define powerof2(x) ((((x)-1)&(x))==0)
+/**
+ * Returns true if the binary representation of the argument is all zeros
+ * or has exactly one bit set. Contrary to the macro name, this macro
+ * DOES NOT determine if the provided value is a power of 2. In particular,
+ * this function falsely returns true for powerof2(0) and some negative
+ * numbers.
+ */
+#define powerof2(x) \
+ ({ \
+ __typeof__(x) _x = (x); \
+ __typeof__(x) _x2; \
+ __builtin_add_overflow(_x, -1, &_x2) ? 1 : ((_x2 & _x) == 0); \
+ })
/** Returns the lesser of its two arguments. */
#define MIN(a,b) (((a)<(b))?(a):(b))
diff --git a/libc/include/time.h b/libc/include/time.h
index ea41fda..48c5efc 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -109,7 +109,7 @@
time_t timegm(struct tm* __tm) __INTRODUCED_IN(12);
#define TIME_UTC 1
-int timespec_get(struct timespec* __ts, int __base) __INTRODUCED_IN_FUTURE;
+int timespec_get(struct timespec* __ts, int __base) __INTRODUCED_IN(29);
__END_DECLS
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index 7c802c2..b79c9b6 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -172,7 +172,12 @@
dst_file = os.path.join(dst_dir, path)
src_file = os.path.join(src_dir, path)
new_data = cleanupFile(dst_file, src_file, path)
- print new_data
+ # Use sys.stdout.write instead of a simple print statement to avoid
+ # sending an extra new line character to stdout. Running this
+ # program in non-update mode and redirecting stdout to a file should
+ # yield the same result as using update mode, where new_data is
+ # written directly to a file.
+ sys.stdout.write(new_data)
sys.exit(0)
@@ -187,8 +192,8 @@
if not new_data:
continue
- b.readFile(path)
- r = b.editFile(path, new_data)
+ b.readFile(dst_file)
+ r = b.editFile(dst_file, new_data)
if r == 0:
r = "unchanged"
elif r == 1:
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 8f50b1d..44853a4 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -47,4 +47,7 @@
#define HWCAP_ILRCPC (1 << 26)
#define HWCAP_FLAGM (1 << 27)
#define HWCAP_SSBS (1 << 28)
+#define HWCAP_SB (1 << 29)
+#define HWCAP_PACA (1 << 30)
+#define HWCAP_PACG (1UL << 31)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index e1cfb48..15fde29 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -20,7 +20,7 @@
#define _UAPI__ASM_PTRACE_H
#include <linux/types.h>
#include <asm/hwcap.h>
-#include <asm/sigcontext.h>
+#include <asm/sve_context.h>
#define PSR_MODE_EL0t 0x00000000
#define PSR_MODE_EL1t 0x00000004
#define PSR_MODE_EL1h 0x00000005
@@ -81,26 +81,29 @@
#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_REGS_OFFSET ((sizeof(struct user_sve_header) + (__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_ZREG_SIZE(vq) __SVE_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq) __SVE_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq) __SVE_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_ZREGS_OFFSET (SVE_PT_REGS_OFFSET + __SVE_ZREGS_OFFSET)
+#define SVE_PT_SVE_ZREG_OFFSET(vq,n) (SVE_PT_REGS_OFFSET + __SVE_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_PT_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_PREG_OFFSET(vq,n) (SVE_PT_REGS_OFFSET + __SVE_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_PT_REGS_OFFSET + __SVE_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_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))
+struct user_pac_mask {
+ __u64 data_mask;
+ __u64 insn_mask;
+};
#endif
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index b0617de..518079d 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -58,27 +58,28 @@
__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)
+#include <asm/sve_context.h>
+#define SVE_VQ_BYTES __SVE_VQ_BYTES
+#define SVE_VQ_MIN __SVE_VQ_MIN
+#define SVE_VQ_MAX __SVE_VQ_MAX
+#define SVE_VL_MIN __SVE_VL_MIN
+#define SVE_VL_MAX __SVE_VL_MAX
+#define SVE_NUM_ZREGS __SVE_NUM_ZREGS
+#define SVE_NUM_PREGS __SVE_NUM_PREGS
+#define sve_vl_valid(vl) __sve_vl_valid(vl)
+#define sve_vq_from_vl(vl) __sve_vq_from_vl(vl)
+#define sve_vl_from_vq(vq) __sve_vl_from_vq(vq)
+#define SVE_SIG_ZREG_SIZE(vq) __SVE_ZREG_SIZE(vq)
+#define SVE_SIG_PREG_SIZE(vq) __SVE_PREG_SIZE(vq)
+#define SVE_SIG_FFR_SIZE(vq) __SVE_FFR_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 + __SVE_ZREGS_OFFSET)
+#define SVE_SIG_ZREG_OFFSET(vq,n) (SVE_SIG_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
+#define SVE_SIG_ZREGS_SIZE(vq) __SVE_ZREGS_SIZE(vq)
+#define SVE_SIG_PREGS_OFFSET(vq) (SVE_SIG_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
+#define SVE_SIG_PREG_OFFSET(vq,n) (SVE_SIG_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
+#define SVE_SIG_PREGS_SIZE(vq) __SVE_PREGS_SIZE(vq)
+#define SVE_SIG_FFR_OFFSET(vq) (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
+#define SVE_SIG_REGS_SIZE(vq) (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sve_context.h b/libc/kernel/uapi/asm-arm64/asm/sve_context.h
new file mode 100644
index 0000000..ff0063e
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm64/asm/sve_context.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_SVE_CONTEXT_H
+#define _UAPI__ASM_SVE_CONTEXT_H
+#include <linux/types.h>
+#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_ZREG_SIZE(vq) ((__u32) (vq) * __SVE_VQ_BYTES)
+#define __SVE_PREG_SIZE(vq) ((__u32) (vq) * (__SVE_VQ_BYTES / 8))
+#define __SVE_FFR_SIZE(vq) __SVE_PREG_SIZE(vq)
+#define __SVE_ZREGS_OFFSET 0
+#define __SVE_ZREG_OFFSET(vq,n) (__SVE_ZREGS_OFFSET + __SVE_ZREG_SIZE(vq) * (n))
+#define __SVE_ZREGS_SIZE(vq) (__SVE_ZREG_OFFSET(vq, __SVE_NUM_ZREGS) - __SVE_ZREGS_OFFSET)
+#define __SVE_PREGS_OFFSET(vq) (__SVE_ZREGS_OFFSET + __SVE_ZREGS_SIZE(vq))
+#define __SVE_PREG_OFFSET(vq,n) (__SVE_PREGS_OFFSET(vq) + __SVE_PREG_SIZE(vq) * (n))
+#define __SVE_PREGS_SIZE(vq) (__SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - __SVE_PREGS_OFFSET(vq))
+#define __SVE_FFR_OFFSET(vq) (__SVE_PREGS_OFFSET(vq) + __SVE_PREGS_SIZE(vq))
+#endif
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index fddf1d0..4113881 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -321,8 +321,9 @@
#define __NR_statx 291
#define __NR_io_pgetevents 292
#define __NR_rseq 293
+#define __NR_kexec_file_load 294
#undef __NR_syscalls
-#define __NR_syscalls 294
+#define __NR_syscalls 295
#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
#define __NR_fcntl __NR3264_fcntl
#define __NR_statfs __NR3264_statfs
diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h
index 61fa3d6..090a40b 100644
--- a/libc/kernel/uapi/asm-mips/asm/inst.h
+++ b/libc/kernel/uapi/asm-mips/asm/inst.h
@@ -549,8 +549,9 @@
mm_ext_op = 0x02c,
mm_pool32axf_op = 0x03c,
mm_srl32_op = 0x040,
+ mm_srlv32_op = 0x050,
mm_sra_op = 0x080,
- mm_srlv32_op = 0x090,
+ mm_srav_op = 0x090,
mm_rotr_op = 0x0c0,
mm_lwxs_op = 0x118,
mm_addu32_op = 0x150,
diff --git a/libc/kernel/uapi/asm-mips/asm/sgidefs.h b/libc/kernel/uapi/asm-mips/asm/sgidefs.h
index 040459b..92750de 100644
--- a/libc/kernel/uapi/asm-mips/asm/sgidefs.h
+++ b/libc/kernel/uapi/asm-mips/asm/sgidefs.h
@@ -18,9 +18,6 @@
****************************************************************************/
#ifndef __ASM_SGIDEFS_H
#define __ASM_SGIDEFS_H
-#ifndef __linux__
-#error Use a Linux compiler or give up .
-#endif
#define _MIPS_ISA_MIPS1 1
#define _MIPS_ISA_MIPS2 2
#define _MIPS_ISA_MIPS3 3
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd.h b/libc/kernel/uapi/asm-mips/asm/unistd.h
index e4dee2b..65f3614 100644
--- a/libc/kernel/uapi/asm-mips/asm/unistd.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd.h
@@ -21,1048 +21,14 @@
#include <asm/sgidefs.h>
#if _MIPS_SIM == _MIPS_SIM_ABI32
#define __NR_Linux 4000
-#define __NR_syscall (__NR_Linux + 0)
-#define __NR_exit (__NR_Linux + 1)
-#define __NR_fork (__NR_Linux + 2)
-#define __NR_read (__NR_Linux + 3)
-#define __NR_write (__NR_Linux + 4)
-#define __NR_open (__NR_Linux + 5)
-#define __NR_close (__NR_Linux + 6)
-#define __NR_waitpid (__NR_Linux + 7)
-#define __NR_creat (__NR_Linux + 8)
-#define __NR_link (__NR_Linux + 9)
-#define __NR_unlink (__NR_Linux + 10)
-#define __NR_execve (__NR_Linux + 11)
-#define __NR_chdir (__NR_Linux + 12)
-#define __NR_time (__NR_Linux + 13)
-#define __NR_mknod (__NR_Linux + 14)
-#define __NR_chmod (__NR_Linux + 15)
-#define __NR_lchown (__NR_Linux + 16)
-#define __NR_break (__NR_Linux + 17)
-#define __NR_unused18 (__NR_Linux + 18)
-#define __NR_lseek (__NR_Linux + 19)
-#define __NR_getpid (__NR_Linux + 20)
-#define __NR_mount (__NR_Linux + 21)
-#define __NR_umount (__NR_Linux + 22)
-#define __NR_setuid (__NR_Linux + 23)
-#define __NR_getuid (__NR_Linux + 24)
-#define __NR_stime (__NR_Linux + 25)
-#define __NR_ptrace (__NR_Linux + 26)
-#define __NR_alarm (__NR_Linux + 27)
-#define __NR_unused28 (__NR_Linux + 28)
-#define __NR_pause (__NR_Linux + 29)
-#define __NR_utime (__NR_Linux + 30)
-#define __NR_stty (__NR_Linux + 31)
-#define __NR_gtty (__NR_Linux + 32)
-#define __NR_access (__NR_Linux + 33)
-#define __NR_nice (__NR_Linux + 34)
-#define __NR_ftime (__NR_Linux + 35)
-#define __NR_sync (__NR_Linux + 36)
-#define __NR_kill (__NR_Linux + 37)
-#define __NR_rename (__NR_Linux + 38)
-#define __NR_mkdir (__NR_Linux + 39)
-#define __NR_rmdir (__NR_Linux + 40)
-#define __NR_dup (__NR_Linux + 41)
-#define __NR_pipe (__NR_Linux + 42)
-#define __NR_times (__NR_Linux + 43)
-#define __NR_prof (__NR_Linux + 44)
-#define __NR_brk (__NR_Linux + 45)
-#define __NR_setgid (__NR_Linux + 46)
-#define __NR_getgid (__NR_Linux + 47)
-#define __NR_signal (__NR_Linux + 48)
-#define __NR_geteuid (__NR_Linux + 49)
-#define __NR_getegid (__NR_Linux + 50)
-#define __NR_acct (__NR_Linux + 51)
-#define __NR_umount2 (__NR_Linux + 52)
-#define __NR_lock (__NR_Linux + 53)
-#define __NR_ioctl (__NR_Linux + 54)
-#define __NR_fcntl (__NR_Linux + 55)
-#define __NR_mpx (__NR_Linux + 56)
-#define __NR_setpgid (__NR_Linux + 57)
-#define __NR_ulimit (__NR_Linux + 58)
-#define __NR_unused59 (__NR_Linux + 59)
-#define __NR_umask (__NR_Linux + 60)
-#define __NR_chroot (__NR_Linux + 61)
-#define __NR_ustat (__NR_Linux + 62)
-#define __NR_dup2 (__NR_Linux + 63)
-#define __NR_getppid (__NR_Linux + 64)
-#define __NR_getpgrp (__NR_Linux + 65)
-#define __NR_setsid (__NR_Linux + 66)
-#define __NR_sigaction (__NR_Linux + 67)
-#define __NR_sgetmask (__NR_Linux + 68)
-#define __NR_ssetmask (__NR_Linux + 69)
-#define __NR_setreuid (__NR_Linux + 70)
-#define __NR_setregid (__NR_Linux + 71)
-#define __NR_sigsuspend (__NR_Linux + 72)
-#define __NR_sigpending (__NR_Linux + 73)
-#define __NR_sethostname (__NR_Linux + 74)
-#define __NR_setrlimit (__NR_Linux + 75)
-#define __NR_getrlimit (__NR_Linux + 76)
-#define __NR_getrusage (__NR_Linux + 77)
-#define __NR_gettimeofday (__NR_Linux + 78)
-#define __NR_settimeofday (__NR_Linux + 79)
-#define __NR_getgroups (__NR_Linux + 80)
-#define __NR_setgroups (__NR_Linux + 81)
-#define __NR_reserved82 (__NR_Linux + 82)
-#define __NR_symlink (__NR_Linux + 83)
-#define __NR_unused84 (__NR_Linux + 84)
-#define __NR_readlink (__NR_Linux + 85)
-#define __NR_uselib (__NR_Linux + 86)
-#define __NR_swapon (__NR_Linux + 87)
-#define __NR_reboot (__NR_Linux + 88)
-#define __NR_readdir (__NR_Linux + 89)
-#define __NR_mmap (__NR_Linux + 90)
-#define __NR_munmap (__NR_Linux + 91)
-#define __NR_truncate (__NR_Linux + 92)
-#define __NR_ftruncate (__NR_Linux + 93)
-#define __NR_fchmod (__NR_Linux + 94)
-#define __NR_fchown (__NR_Linux + 95)
-#define __NR_getpriority (__NR_Linux + 96)
-#define __NR_setpriority (__NR_Linux + 97)
-#define __NR_profil (__NR_Linux + 98)
-#define __NR_statfs (__NR_Linux + 99)
-#define __NR_fstatfs (__NR_Linux + 100)
-#define __NR_ioperm (__NR_Linux + 101)
-#define __NR_socketcall (__NR_Linux + 102)
-#define __NR_syslog (__NR_Linux + 103)
-#define __NR_setitimer (__NR_Linux + 104)
-#define __NR_getitimer (__NR_Linux + 105)
-#define __NR_stat (__NR_Linux + 106)
-#define __NR_lstat (__NR_Linux + 107)
-#define __NR_fstat (__NR_Linux + 108)
-#define __NR_unused109 (__NR_Linux + 109)
-#define __NR_iopl (__NR_Linux + 110)
-#define __NR_vhangup (__NR_Linux + 111)
-#define __NR_idle (__NR_Linux + 112)
-#define __NR_vm86 (__NR_Linux + 113)
-#define __NR_wait4 (__NR_Linux + 114)
-#define __NR_swapoff (__NR_Linux + 115)
-#define __NR_sysinfo (__NR_Linux + 116)
-#define __NR_ipc (__NR_Linux + 117)
-#define __NR_fsync (__NR_Linux + 118)
-#define __NR_sigreturn (__NR_Linux + 119)
-#define __NR_clone (__NR_Linux + 120)
-#define __NR_setdomainname (__NR_Linux + 121)
-#define __NR_uname (__NR_Linux + 122)
-#define __NR_modify_ldt (__NR_Linux + 123)
-#define __NR_adjtimex (__NR_Linux + 124)
-#define __NR_mprotect (__NR_Linux + 125)
-#define __NR_sigprocmask (__NR_Linux + 126)
-#define __NR_create_module (__NR_Linux + 127)
-#define __NR_init_module (__NR_Linux + 128)
-#define __NR_delete_module (__NR_Linux + 129)
-#define __NR_get_kernel_syms (__NR_Linux + 130)
-#define __NR_quotactl (__NR_Linux + 131)
-#define __NR_getpgid (__NR_Linux + 132)
-#define __NR_fchdir (__NR_Linux + 133)
-#define __NR_bdflush (__NR_Linux + 134)
-#define __NR_sysfs (__NR_Linux + 135)
-#define __NR_personality (__NR_Linux + 136)
-#define __NR_afs_syscall (__NR_Linux + 137)
-#define __NR_setfsuid (__NR_Linux + 138)
-#define __NR_setfsgid (__NR_Linux + 139)
-#define __NR__llseek (__NR_Linux + 140)
-#define __NR_getdents (__NR_Linux + 141)
-#define __NR__newselect (__NR_Linux + 142)
-#define __NR_flock (__NR_Linux + 143)
-#define __NR_msync (__NR_Linux + 144)
-#define __NR_readv (__NR_Linux + 145)
-#define __NR_writev (__NR_Linux + 146)
-#define __NR_cacheflush (__NR_Linux + 147)
-#define __NR_cachectl (__NR_Linux + 148)
-#define __NR_sysmips (__NR_Linux + 149)
-#define __NR_unused150 (__NR_Linux + 150)
-#define __NR_getsid (__NR_Linux + 151)
-#define __NR_fdatasync (__NR_Linux + 152)
-#define __NR__sysctl (__NR_Linux + 153)
-#define __NR_mlock (__NR_Linux + 154)
-#define __NR_munlock (__NR_Linux + 155)
-#define __NR_mlockall (__NR_Linux + 156)
-#define __NR_munlockall (__NR_Linux + 157)
-#define __NR_sched_setparam (__NR_Linux + 158)
-#define __NR_sched_getparam (__NR_Linux + 159)
-#define __NR_sched_setscheduler (__NR_Linux + 160)
-#define __NR_sched_getscheduler (__NR_Linux + 161)
-#define __NR_sched_yield (__NR_Linux + 162)
-#define __NR_sched_get_priority_max (__NR_Linux + 163)
-#define __NR_sched_get_priority_min (__NR_Linux + 164)
-#define __NR_sched_rr_get_interval (__NR_Linux + 165)
-#define __NR_nanosleep (__NR_Linux + 166)
-#define __NR_mremap (__NR_Linux + 167)
-#define __NR_accept (__NR_Linux + 168)
-#define __NR_bind (__NR_Linux + 169)
-#define __NR_connect (__NR_Linux + 170)
-#define __NR_getpeername (__NR_Linux + 171)
-#define __NR_getsockname (__NR_Linux + 172)
-#define __NR_getsockopt (__NR_Linux + 173)
-#define __NR_listen (__NR_Linux + 174)
-#define __NR_recv (__NR_Linux + 175)
-#define __NR_recvfrom (__NR_Linux + 176)
-#define __NR_recvmsg (__NR_Linux + 177)
-#define __NR_send (__NR_Linux + 178)
-#define __NR_sendmsg (__NR_Linux + 179)
-#define __NR_sendto (__NR_Linux + 180)
-#define __NR_setsockopt (__NR_Linux + 181)
-#define __NR_shutdown (__NR_Linux + 182)
-#define __NR_socket (__NR_Linux + 183)
-#define __NR_socketpair (__NR_Linux + 184)
-#define __NR_setresuid (__NR_Linux + 185)
-#define __NR_getresuid (__NR_Linux + 186)
-#define __NR_query_module (__NR_Linux + 187)
-#define __NR_poll (__NR_Linux + 188)
-#define __NR_nfsservctl (__NR_Linux + 189)
-#define __NR_setresgid (__NR_Linux + 190)
-#define __NR_getresgid (__NR_Linux + 191)
-#define __NR_prctl (__NR_Linux + 192)
-#define __NR_rt_sigreturn (__NR_Linux + 193)
-#define __NR_rt_sigaction (__NR_Linux + 194)
-#define __NR_rt_sigprocmask (__NR_Linux + 195)
-#define __NR_rt_sigpending (__NR_Linux + 196)
-#define __NR_rt_sigtimedwait (__NR_Linux + 197)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
-#define __NR_rt_sigsuspend (__NR_Linux + 199)
-#define __NR_pread64 (__NR_Linux + 200)
-#define __NR_pwrite64 (__NR_Linux + 201)
-#define __NR_chown (__NR_Linux + 202)
-#define __NR_getcwd (__NR_Linux + 203)
-#define __NR_capget (__NR_Linux + 204)
-#define __NR_capset (__NR_Linux + 205)
-#define __NR_sigaltstack (__NR_Linux + 206)
-#define __NR_sendfile (__NR_Linux + 207)
-#define __NR_getpmsg (__NR_Linux + 208)
-#define __NR_putpmsg (__NR_Linux + 209)
-#define __NR_mmap2 (__NR_Linux + 210)
-#define __NR_truncate64 (__NR_Linux + 211)
-#define __NR_ftruncate64 (__NR_Linux + 212)
-#define __NR_stat64 (__NR_Linux + 213)
-#define __NR_lstat64 (__NR_Linux + 214)
-#define __NR_fstat64 (__NR_Linux + 215)
-#define __NR_pivot_root (__NR_Linux + 216)
-#define __NR_mincore (__NR_Linux + 217)
-#define __NR_madvise (__NR_Linux + 218)
-#define __NR_getdents64 (__NR_Linux + 219)
-#define __NR_fcntl64 (__NR_Linux + 220)
-#define __NR_reserved221 (__NR_Linux + 221)
-#define __NR_gettid (__NR_Linux + 222)
-#define __NR_readahead (__NR_Linux + 223)
-#define __NR_setxattr (__NR_Linux + 224)
-#define __NR_lsetxattr (__NR_Linux + 225)
-#define __NR_fsetxattr (__NR_Linux + 226)
-#define __NR_getxattr (__NR_Linux + 227)
-#define __NR_lgetxattr (__NR_Linux + 228)
-#define __NR_fgetxattr (__NR_Linux + 229)
-#define __NR_listxattr (__NR_Linux + 230)
-#define __NR_llistxattr (__NR_Linux + 231)
-#define __NR_flistxattr (__NR_Linux + 232)
-#define __NR_removexattr (__NR_Linux + 233)
-#define __NR_lremovexattr (__NR_Linux + 234)
-#define __NR_fremovexattr (__NR_Linux + 235)
-#define __NR_tkill (__NR_Linux + 236)
-#define __NR_sendfile64 (__NR_Linux + 237)
-#define __NR_futex (__NR_Linux + 238)
-#define __NR_sched_setaffinity (__NR_Linux + 239)
-#define __NR_sched_getaffinity (__NR_Linux + 240)
-#define __NR_io_setup (__NR_Linux + 241)
-#define __NR_io_destroy (__NR_Linux + 242)
-#define __NR_io_getevents (__NR_Linux + 243)
-#define __NR_io_submit (__NR_Linux + 244)
-#define __NR_io_cancel (__NR_Linux + 245)
-#define __NR_exit_group (__NR_Linux + 246)
-#define __NR_lookup_dcookie (__NR_Linux + 247)
-#define __NR_epoll_create (__NR_Linux + 248)
-#define __NR_epoll_ctl (__NR_Linux + 249)
-#define __NR_epoll_wait (__NR_Linux + 250)
-#define __NR_remap_file_pages (__NR_Linux + 251)
-#define __NR_set_tid_address (__NR_Linux + 252)
-#define __NR_restart_syscall (__NR_Linux + 253)
-#define __NR_fadvise64 (__NR_Linux + 254)
-#define __NR_statfs64 (__NR_Linux + 255)
-#define __NR_fstatfs64 (__NR_Linux + 256)
-#define __NR_timer_create (__NR_Linux + 257)
-#define __NR_timer_settime (__NR_Linux + 258)
-#define __NR_timer_gettime (__NR_Linux + 259)
-#define __NR_timer_getoverrun (__NR_Linux + 260)
-#define __NR_timer_delete (__NR_Linux + 261)
-#define __NR_clock_settime (__NR_Linux + 262)
-#define __NR_clock_gettime (__NR_Linux + 263)
-#define __NR_clock_getres (__NR_Linux + 264)
-#define __NR_clock_nanosleep (__NR_Linux + 265)
-#define __NR_tgkill (__NR_Linux + 266)
-#define __NR_utimes (__NR_Linux + 267)
-#define __NR_mbind (__NR_Linux + 268)
-#define __NR_get_mempolicy (__NR_Linux + 269)
-#define __NR_set_mempolicy (__NR_Linux + 270)
-#define __NR_mq_open (__NR_Linux + 271)
-#define __NR_mq_unlink (__NR_Linux + 272)
-#define __NR_mq_timedsend (__NR_Linux + 273)
-#define __NR_mq_timedreceive (__NR_Linux + 274)
-#define __NR_mq_notify (__NR_Linux + 275)
-#define __NR_mq_getsetattr (__NR_Linux + 276)
-#define __NR_vserver (__NR_Linux + 277)
-#define __NR_waitid (__NR_Linux + 278)
-#define __NR_add_key (__NR_Linux + 280)
-#define __NR_request_key (__NR_Linux + 281)
-#define __NR_keyctl (__NR_Linux + 282)
-#define __NR_set_thread_area (__NR_Linux + 283)
-#define __NR_inotify_init (__NR_Linux + 284)
-#define __NR_inotify_add_watch (__NR_Linux + 285)
-#define __NR_inotify_rm_watch (__NR_Linux + 286)
-#define __NR_migrate_pages (__NR_Linux + 287)
-#define __NR_openat (__NR_Linux + 288)
-#define __NR_mkdirat (__NR_Linux + 289)
-#define __NR_mknodat (__NR_Linux + 290)
-#define __NR_fchownat (__NR_Linux + 291)
-#define __NR_futimesat (__NR_Linux + 292)
-#define __NR_fstatat64 (__NR_Linux + 293)
-#define __NR_unlinkat (__NR_Linux + 294)
-#define __NR_renameat (__NR_Linux + 295)
-#define __NR_linkat (__NR_Linux + 296)
-#define __NR_symlinkat (__NR_Linux + 297)
-#define __NR_readlinkat (__NR_Linux + 298)
-#define __NR_fchmodat (__NR_Linux + 299)
-#define __NR_faccessat (__NR_Linux + 300)
-#define __NR_pselect6 (__NR_Linux + 301)
-#define __NR_ppoll (__NR_Linux + 302)
-#define __NR_unshare (__NR_Linux + 303)
-#define __NR_splice (__NR_Linux + 304)
-#define __NR_sync_file_range (__NR_Linux + 305)
-#define __NR_tee (__NR_Linux + 306)
-#define __NR_vmsplice (__NR_Linux + 307)
-#define __NR_move_pages (__NR_Linux + 308)
-#define __NR_set_robust_list (__NR_Linux + 309)
-#define __NR_get_robust_list (__NR_Linux + 310)
-#define __NR_kexec_load (__NR_Linux + 311)
-#define __NR_getcpu (__NR_Linux + 312)
-#define __NR_epoll_pwait (__NR_Linux + 313)
-#define __NR_ioprio_set (__NR_Linux + 314)
-#define __NR_ioprio_get (__NR_Linux + 315)
-#define __NR_utimensat (__NR_Linux + 316)
-#define __NR_signalfd (__NR_Linux + 317)
-#define __NR_timerfd (__NR_Linux + 318)
-#define __NR_eventfd (__NR_Linux + 319)
-#define __NR_fallocate (__NR_Linux + 320)
-#define __NR_timerfd_create (__NR_Linux + 321)
-#define __NR_timerfd_gettime (__NR_Linux + 322)
-#define __NR_timerfd_settime (__NR_Linux + 323)
-#define __NR_signalfd4 (__NR_Linux + 324)
-#define __NR_eventfd2 (__NR_Linux + 325)
-#define __NR_epoll_create1 (__NR_Linux + 326)
-#define __NR_dup3 (__NR_Linux + 327)
-#define __NR_pipe2 (__NR_Linux + 328)
-#define __NR_inotify_init1 (__NR_Linux + 329)
-#define __NR_preadv (__NR_Linux + 330)
-#define __NR_pwritev (__NR_Linux + 331)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
-#define __NR_perf_event_open (__NR_Linux + 333)
-#define __NR_accept4 (__NR_Linux + 334)
-#define __NR_recvmmsg (__NR_Linux + 335)
-#define __NR_fanotify_init (__NR_Linux + 336)
-#define __NR_fanotify_mark (__NR_Linux + 337)
-#define __NR_prlimit64 (__NR_Linux + 338)
-#define __NR_name_to_handle_at (__NR_Linux + 339)
-#define __NR_open_by_handle_at (__NR_Linux + 340)
-#define __NR_clock_adjtime (__NR_Linux + 341)
-#define __NR_syncfs (__NR_Linux + 342)
-#define __NR_sendmmsg (__NR_Linux + 343)
-#define __NR_setns (__NR_Linux + 344)
-#define __NR_process_vm_readv (__NR_Linux + 345)
-#define __NR_process_vm_writev (__NR_Linux + 346)
-#define __NR_kcmp (__NR_Linux + 347)
-#define __NR_finit_module (__NR_Linux + 348)
-#define __NR_sched_setattr (__NR_Linux + 349)
-#define __NR_sched_getattr (__NR_Linux + 350)
-#define __NR_renameat2 (__NR_Linux + 351)
-#define __NR_seccomp (__NR_Linux + 352)
-#define __NR_getrandom (__NR_Linux + 353)
-#define __NR_memfd_create (__NR_Linux + 354)
-#define __NR_bpf (__NR_Linux + 355)
-#define __NR_execveat (__NR_Linux + 356)
-#define __NR_userfaultfd (__NR_Linux + 357)
-#define __NR_membarrier (__NR_Linux + 358)
-#define __NR_mlock2 (__NR_Linux + 359)
-#define __NR_copy_file_range (__NR_Linux + 360)
-#define __NR_preadv2 (__NR_Linux + 361)
-#define __NR_pwritev2 (__NR_Linux + 362)
-#define __NR_pkey_mprotect (__NR_Linux + 363)
-#define __NR_pkey_alloc (__NR_Linux + 364)
-#define __NR_pkey_free (__NR_Linux + 365)
-#define __NR_statx (__NR_Linux + 366)
-#define __NR_rseq (__NR_Linux + 367)
-#define __NR_io_pgetevents (__NR_Linux + 368)
-#define __NR_Linux_syscalls 368
+#include <asm/unistd_o32.h>
#endif
-#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 368
#if _MIPS_SIM == _MIPS_SIM_ABI64
#define __NR_Linux 5000
-#define __NR_read (__NR_Linux + 0)
-#define __NR_write (__NR_Linux + 1)
-#define __NR_open (__NR_Linux + 2)
-#define __NR_close (__NR_Linux + 3)
-#define __NR_stat (__NR_Linux + 4)
-#define __NR_fstat (__NR_Linux + 5)
-#define __NR_lstat (__NR_Linux + 6)
-#define __NR_poll (__NR_Linux + 7)
-#define __NR_lseek (__NR_Linux + 8)
-#define __NR_mmap (__NR_Linux + 9)
-#define __NR_mprotect (__NR_Linux + 10)
-#define __NR_munmap (__NR_Linux + 11)
-#define __NR_brk (__NR_Linux + 12)
-#define __NR_rt_sigaction (__NR_Linux + 13)
-#define __NR_rt_sigprocmask (__NR_Linux + 14)
-#define __NR_ioctl (__NR_Linux + 15)
-#define __NR_pread64 (__NR_Linux + 16)
-#define __NR_pwrite64 (__NR_Linux + 17)
-#define __NR_readv (__NR_Linux + 18)
-#define __NR_writev (__NR_Linux + 19)
-#define __NR_access (__NR_Linux + 20)
-#define __NR_pipe (__NR_Linux + 21)
-#define __NR__newselect (__NR_Linux + 22)
-#define __NR_sched_yield (__NR_Linux + 23)
-#define __NR_mremap (__NR_Linux + 24)
-#define __NR_msync (__NR_Linux + 25)
-#define __NR_mincore (__NR_Linux + 26)
-#define __NR_madvise (__NR_Linux + 27)
-#define __NR_shmget (__NR_Linux + 28)
-#define __NR_shmat (__NR_Linux + 29)
-#define __NR_shmctl (__NR_Linux + 30)
-#define __NR_dup (__NR_Linux + 31)
-#define __NR_dup2 (__NR_Linux + 32)
-#define __NR_pause (__NR_Linux + 33)
-#define __NR_nanosleep (__NR_Linux + 34)
-#define __NR_getitimer (__NR_Linux + 35)
-#define __NR_setitimer (__NR_Linux + 36)
-#define __NR_alarm (__NR_Linux + 37)
-#define __NR_getpid (__NR_Linux + 38)
-#define __NR_sendfile (__NR_Linux + 39)
-#define __NR_socket (__NR_Linux + 40)
-#define __NR_connect (__NR_Linux + 41)
-#define __NR_accept (__NR_Linux + 42)
-#define __NR_sendto (__NR_Linux + 43)
-#define __NR_recvfrom (__NR_Linux + 44)
-#define __NR_sendmsg (__NR_Linux + 45)
-#define __NR_recvmsg (__NR_Linux + 46)
-#define __NR_shutdown (__NR_Linux + 47)
-#define __NR_bind (__NR_Linux + 48)
-#define __NR_listen (__NR_Linux + 49)
-#define __NR_getsockname (__NR_Linux + 50)
-#define __NR_getpeername (__NR_Linux + 51)
-#define __NR_socketpair (__NR_Linux + 52)
-#define __NR_setsockopt (__NR_Linux + 53)
-#define __NR_getsockopt (__NR_Linux + 54)
-#define __NR_clone (__NR_Linux + 55)
-#define __NR_fork (__NR_Linux + 56)
-#define __NR_execve (__NR_Linux + 57)
-#define __NR_exit (__NR_Linux + 58)
-#define __NR_wait4 (__NR_Linux + 59)
-#define __NR_kill (__NR_Linux + 60)
-#define __NR_uname (__NR_Linux + 61)
-#define __NR_semget (__NR_Linux + 62)
-#define __NR_semop (__NR_Linux + 63)
-#define __NR_semctl (__NR_Linux + 64)
-#define __NR_shmdt (__NR_Linux + 65)
-#define __NR_msgget (__NR_Linux + 66)
-#define __NR_msgsnd (__NR_Linux + 67)
-#define __NR_msgrcv (__NR_Linux + 68)
-#define __NR_msgctl (__NR_Linux + 69)
-#define __NR_fcntl (__NR_Linux + 70)
-#define __NR_flock (__NR_Linux + 71)
-#define __NR_fsync (__NR_Linux + 72)
-#define __NR_fdatasync (__NR_Linux + 73)
-#define __NR_truncate (__NR_Linux + 74)
-#define __NR_ftruncate (__NR_Linux + 75)
-#define __NR_getdents (__NR_Linux + 76)
-#define __NR_getcwd (__NR_Linux + 77)
-#define __NR_chdir (__NR_Linux + 78)
-#define __NR_fchdir (__NR_Linux + 79)
-#define __NR_rename (__NR_Linux + 80)
-#define __NR_mkdir (__NR_Linux + 81)
-#define __NR_rmdir (__NR_Linux + 82)
-#define __NR_creat (__NR_Linux + 83)
-#define __NR_link (__NR_Linux + 84)
-#define __NR_unlink (__NR_Linux + 85)
-#define __NR_symlink (__NR_Linux + 86)
-#define __NR_readlink (__NR_Linux + 87)
-#define __NR_chmod (__NR_Linux + 88)
-#define __NR_fchmod (__NR_Linux + 89)
-#define __NR_chown (__NR_Linux + 90)
-#define __NR_fchown (__NR_Linux + 91)
-#define __NR_lchown (__NR_Linux + 92)
-#define __NR_umask (__NR_Linux + 93)
-#define __NR_gettimeofday (__NR_Linux + 94)
-#define __NR_getrlimit (__NR_Linux + 95)
-#define __NR_getrusage (__NR_Linux + 96)
-#define __NR_sysinfo (__NR_Linux + 97)
-#define __NR_times (__NR_Linux + 98)
-#define __NR_ptrace (__NR_Linux + 99)
-#define __NR_getuid (__NR_Linux + 100)
-#define __NR_syslog (__NR_Linux + 101)
-#define __NR_getgid (__NR_Linux + 102)
-#define __NR_setuid (__NR_Linux + 103)
-#define __NR_setgid (__NR_Linux + 104)
-#define __NR_geteuid (__NR_Linux + 105)
-#define __NR_getegid (__NR_Linux + 106)
-#define __NR_setpgid (__NR_Linux + 107)
-#define __NR_getppid (__NR_Linux + 108)
-#define __NR_getpgrp (__NR_Linux + 109)
-#define __NR_setsid (__NR_Linux + 110)
-#define __NR_setreuid (__NR_Linux + 111)
-#define __NR_setregid (__NR_Linux + 112)
-#define __NR_getgroups (__NR_Linux + 113)
-#define __NR_setgroups (__NR_Linux + 114)
-#define __NR_setresuid (__NR_Linux + 115)
-#define __NR_getresuid (__NR_Linux + 116)
-#define __NR_setresgid (__NR_Linux + 117)
-#define __NR_getresgid (__NR_Linux + 118)
-#define __NR_getpgid (__NR_Linux + 119)
-#define __NR_setfsuid (__NR_Linux + 120)
-#define __NR_setfsgid (__NR_Linux + 121)
-#define __NR_getsid (__NR_Linux + 122)
-#define __NR_capget (__NR_Linux + 123)
-#define __NR_capset (__NR_Linux + 124)
-#define __NR_rt_sigpending (__NR_Linux + 125)
-#define __NR_rt_sigtimedwait (__NR_Linux + 126)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
-#define __NR_rt_sigsuspend (__NR_Linux + 128)
-#define __NR_sigaltstack (__NR_Linux + 129)
-#define __NR_utime (__NR_Linux + 130)
-#define __NR_mknod (__NR_Linux + 131)
-#define __NR_personality (__NR_Linux + 132)
-#define __NR_ustat (__NR_Linux + 133)
-#define __NR_statfs (__NR_Linux + 134)
-#define __NR_fstatfs (__NR_Linux + 135)
-#define __NR_sysfs (__NR_Linux + 136)
-#define __NR_getpriority (__NR_Linux + 137)
-#define __NR_setpriority (__NR_Linux + 138)
-#define __NR_sched_setparam (__NR_Linux + 139)
-#define __NR_sched_getparam (__NR_Linux + 140)
-#define __NR_sched_setscheduler (__NR_Linux + 141)
-#define __NR_sched_getscheduler (__NR_Linux + 142)
-#define __NR_sched_get_priority_max (__NR_Linux + 143)
-#define __NR_sched_get_priority_min (__NR_Linux + 144)
-#define __NR_sched_rr_get_interval (__NR_Linux + 145)
-#define __NR_mlock (__NR_Linux + 146)
-#define __NR_munlock (__NR_Linux + 147)
-#define __NR_mlockall (__NR_Linux + 148)
-#define __NR_munlockall (__NR_Linux + 149)
-#define __NR_vhangup (__NR_Linux + 150)
-#define __NR_pivot_root (__NR_Linux + 151)
-#define __NR__sysctl (__NR_Linux + 152)
-#define __NR_prctl (__NR_Linux + 153)
-#define __NR_adjtimex (__NR_Linux + 154)
-#define __NR_setrlimit (__NR_Linux + 155)
-#define __NR_chroot (__NR_Linux + 156)
-#define __NR_sync (__NR_Linux + 157)
-#define __NR_acct (__NR_Linux + 158)
-#define __NR_settimeofday (__NR_Linux + 159)
-#define __NR_mount (__NR_Linux + 160)
-#define __NR_umount2 (__NR_Linux + 161)
-#define __NR_swapon (__NR_Linux + 162)
-#define __NR_swapoff (__NR_Linux + 163)
-#define __NR_reboot (__NR_Linux + 164)
-#define __NR_sethostname (__NR_Linux + 165)
-#define __NR_setdomainname (__NR_Linux + 166)
-#define __NR_create_module (__NR_Linux + 167)
-#define __NR_init_module (__NR_Linux + 168)
-#define __NR_delete_module (__NR_Linux + 169)
-#define __NR_get_kernel_syms (__NR_Linux + 170)
-#define __NR_query_module (__NR_Linux + 171)
-#define __NR_quotactl (__NR_Linux + 172)
-#define __NR_nfsservctl (__NR_Linux + 173)
-#define __NR_getpmsg (__NR_Linux + 174)
-#define __NR_putpmsg (__NR_Linux + 175)
-#define __NR_afs_syscall (__NR_Linux + 176)
-#define __NR_reserved177 (__NR_Linux + 177)
-#define __NR_gettid (__NR_Linux + 178)
-#define __NR_readahead (__NR_Linux + 179)
-#define __NR_setxattr (__NR_Linux + 180)
-#define __NR_lsetxattr (__NR_Linux + 181)
-#define __NR_fsetxattr (__NR_Linux + 182)
-#define __NR_getxattr (__NR_Linux + 183)
-#define __NR_lgetxattr (__NR_Linux + 184)
-#define __NR_fgetxattr (__NR_Linux + 185)
-#define __NR_listxattr (__NR_Linux + 186)
-#define __NR_llistxattr (__NR_Linux + 187)
-#define __NR_flistxattr (__NR_Linux + 188)
-#define __NR_removexattr (__NR_Linux + 189)
-#define __NR_lremovexattr (__NR_Linux + 190)
-#define __NR_fremovexattr (__NR_Linux + 191)
-#define __NR_tkill (__NR_Linux + 192)
-#define __NR_reserved193 (__NR_Linux + 193)
-#define __NR_futex (__NR_Linux + 194)
-#define __NR_sched_setaffinity (__NR_Linux + 195)
-#define __NR_sched_getaffinity (__NR_Linux + 196)
-#define __NR_cacheflush (__NR_Linux + 197)
-#define __NR_cachectl (__NR_Linux + 198)
-#define __NR_sysmips (__NR_Linux + 199)
-#define __NR_io_setup (__NR_Linux + 200)
-#define __NR_io_destroy (__NR_Linux + 201)
-#define __NR_io_getevents (__NR_Linux + 202)
-#define __NR_io_submit (__NR_Linux + 203)
-#define __NR_io_cancel (__NR_Linux + 204)
-#define __NR_exit_group (__NR_Linux + 205)
-#define __NR_lookup_dcookie (__NR_Linux + 206)
-#define __NR_epoll_create (__NR_Linux + 207)
-#define __NR_epoll_ctl (__NR_Linux + 208)
-#define __NR_epoll_wait (__NR_Linux + 209)
-#define __NR_remap_file_pages (__NR_Linux + 210)
-#define __NR_rt_sigreturn (__NR_Linux + 211)
-#define __NR_set_tid_address (__NR_Linux + 212)
-#define __NR_restart_syscall (__NR_Linux + 213)
-#define __NR_semtimedop (__NR_Linux + 214)
-#define __NR_fadvise64 (__NR_Linux + 215)
-#define __NR_timer_create (__NR_Linux + 216)
-#define __NR_timer_settime (__NR_Linux + 217)
-#define __NR_timer_gettime (__NR_Linux + 218)
-#define __NR_timer_getoverrun (__NR_Linux + 219)
-#define __NR_timer_delete (__NR_Linux + 220)
-#define __NR_clock_settime (__NR_Linux + 221)
-#define __NR_clock_gettime (__NR_Linux + 222)
-#define __NR_clock_getres (__NR_Linux + 223)
-#define __NR_clock_nanosleep (__NR_Linux + 224)
-#define __NR_tgkill (__NR_Linux + 225)
-#define __NR_utimes (__NR_Linux + 226)
-#define __NR_mbind (__NR_Linux + 227)
-#define __NR_get_mempolicy (__NR_Linux + 228)
-#define __NR_set_mempolicy (__NR_Linux + 229)
-#define __NR_mq_open (__NR_Linux + 230)
-#define __NR_mq_unlink (__NR_Linux + 231)
-#define __NR_mq_timedsend (__NR_Linux + 232)
-#define __NR_mq_timedreceive (__NR_Linux + 233)
-#define __NR_mq_notify (__NR_Linux + 234)
-#define __NR_mq_getsetattr (__NR_Linux + 235)
-#define __NR_vserver (__NR_Linux + 236)
-#define __NR_waitid (__NR_Linux + 237)
-#define __NR_add_key (__NR_Linux + 239)
-#define __NR_request_key (__NR_Linux + 240)
-#define __NR_keyctl (__NR_Linux + 241)
-#define __NR_set_thread_area (__NR_Linux + 242)
-#define __NR_inotify_init (__NR_Linux + 243)
-#define __NR_inotify_add_watch (__NR_Linux + 244)
-#define __NR_inotify_rm_watch (__NR_Linux + 245)
-#define __NR_migrate_pages (__NR_Linux + 246)
-#define __NR_openat (__NR_Linux + 247)
-#define __NR_mkdirat (__NR_Linux + 248)
-#define __NR_mknodat (__NR_Linux + 249)
-#define __NR_fchownat (__NR_Linux + 250)
-#define __NR_futimesat (__NR_Linux + 251)
-#define __NR_newfstatat (__NR_Linux + 252)
-#define __NR_unlinkat (__NR_Linux + 253)
-#define __NR_renameat (__NR_Linux + 254)
-#define __NR_linkat (__NR_Linux + 255)
-#define __NR_symlinkat (__NR_Linux + 256)
-#define __NR_readlinkat (__NR_Linux + 257)
-#define __NR_fchmodat (__NR_Linux + 258)
-#define __NR_faccessat (__NR_Linux + 259)
-#define __NR_pselect6 (__NR_Linux + 260)
-#define __NR_ppoll (__NR_Linux + 261)
-#define __NR_unshare (__NR_Linux + 262)
-#define __NR_splice (__NR_Linux + 263)
-#define __NR_sync_file_range (__NR_Linux + 264)
-#define __NR_tee (__NR_Linux + 265)
-#define __NR_vmsplice (__NR_Linux + 266)
-#define __NR_move_pages (__NR_Linux + 267)
-#define __NR_set_robust_list (__NR_Linux + 268)
-#define __NR_get_robust_list (__NR_Linux + 269)
-#define __NR_kexec_load (__NR_Linux + 270)
-#define __NR_getcpu (__NR_Linux + 271)
-#define __NR_epoll_pwait (__NR_Linux + 272)
-#define __NR_ioprio_set (__NR_Linux + 273)
-#define __NR_ioprio_get (__NR_Linux + 274)
-#define __NR_utimensat (__NR_Linux + 275)
-#define __NR_signalfd (__NR_Linux + 276)
-#define __NR_timerfd (__NR_Linux + 277)
-#define __NR_eventfd (__NR_Linux + 278)
-#define __NR_fallocate (__NR_Linux + 279)
-#define __NR_timerfd_create (__NR_Linux + 280)
-#define __NR_timerfd_gettime (__NR_Linux + 281)
-#define __NR_timerfd_settime (__NR_Linux + 282)
-#define __NR_signalfd4 (__NR_Linux + 283)
-#define __NR_eventfd2 (__NR_Linux + 284)
-#define __NR_epoll_create1 (__NR_Linux + 285)
-#define __NR_dup3 (__NR_Linux + 286)
-#define __NR_pipe2 (__NR_Linux + 287)
-#define __NR_inotify_init1 (__NR_Linux + 288)
-#define __NR_preadv (__NR_Linux + 289)
-#define __NR_pwritev (__NR_Linux + 290)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
-#define __NR_perf_event_open (__NR_Linux + 292)
-#define __NR_accept4 (__NR_Linux + 293)
-#define __NR_recvmmsg (__NR_Linux + 294)
-#define __NR_fanotify_init (__NR_Linux + 295)
-#define __NR_fanotify_mark (__NR_Linux + 296)
-#define __NR_prlimit64 (__NR_Linux + 297)
-#define __NR_name_to_handle_at (__NR_Linux + 298)
-#define __NR_open_by_handle_at (__NR_Linux + 299)
-#define __NR_clock_adjtime (__NR_Linux + 300)
-#define __NR_syncfs (__NR_Linux + 301)
-#define __NR_sendmmsg (__NR_Linux + 302)
-#define __NR_setns (__NR_Linux + 303)
-#define __NR_process_vm_readv (__NR_Linux + 304)
-#define __NR_process_vm_writev (__NR_Linux + 305)
-#define __NR_kcmp (__NR_Linux + 306)
-#define __NR_finit_module (__NR_Linux + 307)
-#define __NR_getdents64 (__NR_Linux + 308)
-#define __NR_sched_setattr (__NR_Linux + 309)
-#define __NR_sched_getattr (__NR_Linux + 310)
-#define __NR_renameat2 (__NR_Linux + 311)
-#define __NR_seccomp (__NR_Linux + 312)
-#define __NR_getrandom (__NR_Linux + 313)
-#define __NR_memfd_create (__NR_Linux + 314)
-#define __NR_bpf (__NR_Linux + 315)
-#define __NR_execveat (__NR_Linux + 316)
-#define __NR_userfaultfd (__NR_Linux + 317)
-#define __NR_membarrier (__NR_Linux + 318)
-#define __NR_mlock2 (__NR_Linux + 319)
-#define __NR_copy_file_range (__NR_Linux + 320)
-#define __NR_preadv2 (__NR_Linux + 321)
-#define __NR_pwritev2 (__NR_Linux + 322)
-#define __NR_pkey_mprotect (__NR_Linux + 323)
-#define __NR_pkey_alloc (__NR_Linux + 324)
-#define __NR_pkey_free (__NR_Linux + 325)
-#define __NR_statx (__NR_Linux + 326)
-#define __NR_rseq (__NR_Linux + 327)
-#define __NR_io_pgetevents (__NR_Linux + 328)
-#define __NR_Linux_syscalls 328
+#include <asm/unistd_n64.h>
#endif
-#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 328
#if _MIPS_SIM == _MIPS_SIM_NABI32
#define __NR_Linux 6000
-#define __NR_read (__NR_Linux + 0)
-#define __NR_write (__NR_Linux + 1)
-#define __NR_open (__NR_Linux + 2)
-#define __NR_close (__NR_Linux + 3)
-#define __NR_stat (__NR_Linux + 4)
-#define __NR_fstat (__NR_Linux + 5)
-#define __NR_lstat (__NR_Linux + 6)
-#define __NR_poll (__NR_Linux + 7)
-#define __NR_lseek (__NR_Linux + 8)
-#define __NR_mmap (__NR_Linux + 9)
-#define __NR_mprotect (__NR_Linux + 10)
-#define __NR_munmap (__NR_Linux + 11)
-#define __NR_brk (__NR_Linux + 12)
-#define __NR_rt_sigaction (__NR_Linux + 13)
-#define __NR_rt_sigprocmask (__NR_Linux + 14)
-#define __NR_ioctl (__NR_Linux + 15)
-#define __NR_pread64 (__NR_Linux + 16)
-#define __NR_pwrite64 (__NR_Linux + 17)
-#define __NR_readv (__NR_Linux + 18)
-#define __NR_writev (__NR_Linux + 19)
-#define __NR_access (__NR_Linux + 20)
-#define __NR_pipe (__NR_Linux + 21)
-#define __NR__newselect (__NR_Linux + 22)
-#define __NR_sched_yield (__NR_Linux + 23)
-#define __NR_mremap (__NR_Linux + 24)
-#define __NR_msync (__NR_Linux + 25)
-#define __NR_mincore (__NR_Linux + 26)
-#define __NR_madvise (__NR_Linux + 27)
-#define __NR_shmget (__NR_Linux + 28)
-#define __NR_shmat (__NR_Linux + 29)
-#define __NR_shmctl (__NR_Linux + 30)
-#define __NR_dup (__NR_Linux + 31)
-#define __NR_dup2 (__NR_Linux + 32)
-#define __NR_pause (__NR_Linux + 33)
-#define __NR_nanosleep (__NR_Linux + 34)
-#define __NR_getitimer (__NR_Linux + 35)
-#define __NR_setitimer (__NR_Linux + 36)
-#define __NR_alarm (__NR_Linux + 37)
-#define __NR_getpid (__NR_Linux + 38)
-#define __NR_sendfile (__NR_Linux + 39)
-#define __NR_socket (__NR_Linux + 40)
-#define __NR_connect (__NR_Linux + 41)
-#define __NR_accept (__NR_Linux + 42)
-#define __NR_sendto (__NR_Linux + 43)
-#define __NR_recvfrom (__NR_Linux + 44)
-#define __NR_sendmsg (__NR_Linux + 45)
-#define __NR_recvmsg (__NR_Linux + 46)
-#define __NR_shutdown (__NR_Linux + 47)
-#define __NR_bind (__NR_Linux + 48)
-#define __NR_listen (__NR_Linux + 49)
-#define __NR_getsockname (__NR_Linux + 50)
-#define __NR_getpeername (__NR_Linux + 51)
-#define __NR_socketpair (__NR_Linux + 52)
-#define __NR_setsockopt (__NR_Linux + 53)
-#define __NR_getsockopt (__NR_Linux + 54)
-#define __NR_clone (__NR_Linux + 55)
-#define __NR_fork (__NR_Linux + 56)
-#define __NR_execve (__NR_Linux + 57)
-#define __NR_exit (__NR_Linux + 58)
-#define __NR_wait4 (__NR_Linux + 59)
-#define __NR_kill (__NR_Linux + 60)
-#define __NR_uname (__NR_Linux + 61)
-#define __NR_semget (__NR_Linux + 62)
-#define __NR_semop (__NR_Linux + 63)
-#define __NR_semctl (__NR_Linux + 64)
-#define __NR_shmdt (__NR_Linux + 65)
-#define __NR_msgget (__NR_Linux + 66)
-#define __NR_msgsnd (__NR_Linux + 67)
-#define __NR_msgrcv (__NR_Linux + 68)
-#define __NR_msgctl (__NR_Linux + 69)
-#define __NR_fcntl (__NR_Linux + 70)
-#define __NR_flock (__NR_Linux + 71)
-#define __NR_fsync (__NR_Linux + 72)
-#define __NR_fdatasync (__NR_Linux + 73)
-#define __NR_truncate (__NR_Linux + 74)
-#define __NR_ftruncate (__NR_Linux + 75)
-#define __NR_getdents (__NR_Linux + 76)
-#define __NR_getcwd (__NR_Linux + 77)
-#define __NR_chdir (__NR_Linux + 78)
-#define __NR_fchdir (__NR_Linux + 79)
-#define __NR_rename (__NR_Linux + 80)
-#define __NR_mkdir (__NR_Linux + 81)
-#define __NR_rmdir (__NR_Linux + 82)
-#define __NR_creat (__NR_Linux + 83)
-#define __NR_link (__NR_Linux + 84)
-#define __NR_unlink (__NR_Linux + 85)
-#define __NR_symlink (__NR_Linux + 86)
-#define __NR_readlink (__NR_Linux + 87)
-#define __NR_chmod (__NR_Linux + 88)
-#define __NR_fchmod (__NR_Linux + 89)
-#define __NR_chown (__NR_Linux + 90)
-#define __NR_fchown (__NR_Linux + 91)
-#define __NR_lchown (__NR_Linux + 92)
-#define __NR_umask (__NR_Linux + 93)
-#define __NR_gettimeofday (__NR_Linux + 94)
-#define __NR_getrlimit (__NR_Linux + 95)
-#define __NR_getrusage (__NR_Linux + 96)
-#define __NR_sysinfo (__NR_Linux + 97)
-#define __NR_times (__NR_Linux + 98)
-#define __NR_ptrace (__NR_Linux + 99)
-#define __NR_getuid (__NR_Linux + 100)
-#define __NR_syslog (__NR_Linux + 101)
-#define __NR_getgid (__NR_Linux + 102)
-#define __NR_setuid (__NR_Linux + 103)
-#define __NR_setgid (__NR_Linux + 104)
-#define __NR_geteuid (__NR_Linux + 105)
-#define __NR_getegid (__NR_Linux + 106)
-#define __NR_setpgid (__NR_Linux + 107)
-#define __NR_getppid (__NR_Linux + 108)
-#define __NR_getpgrp (__NR_Linux + 109)
-#define __NR_setsid (__NR_Linux + 110)
-#define __NR_setreuid (__NR_Linux + 111)
-#define __NR_setregid (__NR_Linux + 112)
-#define __NR_getgroups (__NR_Linux + 113)
-#define __NR_setgroups (__NR_Linux + 114)
-#define __NR_setresuid (__NR_Linux + 115)
-#define __NR_getresuid (__NR_Linux + 116)
-#define __NR_setresgid (__NR_Linux + 117)
-#define __NR_getresgid (__NR_Linux + 118)
-#define __NR_getpgid (__NR_Linux + 119)
-#define __NR_setfsuid (__NR_Linux + 120)
-#define __NR_setfsgid (__NR_Linux + 121)
-#define __NR_getsid (__NR_Linux + 122)
-#define __NR_capget (__NR_Linux + 123)
-#define __NR_capset (__NR_Linux + 124)
-#define __NR_rt_sigpending (__NR_Linux + 125)
-#define __NR_rt_sigtimedwait (__NR_Linux + 126)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
-#define __NR_rt_sigsuspend (__NR_Linux + 128)
-#define __NR_sigaltstack (__NR_Linux + 129)
-#define __NR_utime (__NR_Linux + 130)
-#define __NR_mknod (__NR_Linux + 131)
-#define __NR_personality (__NR_Linux + 132)
-#define __NR_ustat (__NR_Linux + 133)
-#define __NR_statfs (__NR_Linux + 134)
-#define __NR_fstatfs (__NR_Linux + 135)
-#define __NR_sysfs (__NR_Linux + 136)
-#define __NR_getpriority (__NR_Linux + 137)
-#define __NR_setpriority (__NR_Linux + 138)
-#define __NR_sched_setparam (__NR_Linux + 139)
-#define __NR_sched_getparam (__NR_Linux + 140)
-#define __NR_sched_setscheduler (__NR_Linux + 141)
-#define __NR_sched_getscheduler (__NR_Linux + 142)
-#define __NR_sched_get_priority_max (__NR_Linux + 143)
-#define __NR_sched_get_priority_min (__NR_Linux + 144)
-#define __NR_sched_rr_get_interval (__NR_Linux + 145)
-#define __NR_mlock (__NR_Linux + 146)
-#define __NR_munlock (__NR_Linux + 147)
-#define __NR_mlockall (__NR_Linux + 148)
-#define __NR_munlockall (__NR_Linux + 149)
-#define __NR_vhangup (__NR_Linux + 150)
-#define __NR_pivot_root (__NR_Linux + 151)
-#define __NR__sysctl (__NR_Linux + 152)
-#define __NR_prctl (__NR_Linux + 153)
-#define __NR_adjtimex (__NR_Linux + 154)
-#define __NR_setrlimit (__NR_Linux + 155)
-#define __NR_chroot (__NR_Linux + 156)
-#define __NR_sync (__NR_Linux + 157)
-#define __NR_acct (__NR_Linux + 158)
-#define __NR_settimeofday (__NR_Linux + 159)
-#define __NR_mount (__NR_Linux + 160)
-#define __NR_umount2 (__NR_Linux + 161)
-#define __NR_swapon (__NR_Linux + 162)
-#define __NR_swapoff (__NR_Linux + 163)
-#define __NR_reboot (__NR_Linux + 164)
-#define __NR_sethostname (__NR_Linux + 165)
-#define __NR_setdomainname (__NR_Linux + 166)
-#define __NR_create_module (__NR_Linux + 167)
-#define __NR_init_module (__NR_Linux + 168)
-#define __NR_delete_module (__NR_Linux + 169)
-#define __NR_get_kernel_syms (__NR_Linux + 170)
-#define __NR_query_module (__NR_Linux + 171)
-#define __NR_quotactl (__NR_Linux + 172)
-#define __NR_nfsservctl (__NR_Linux + 173)
-#define __NR_getpmsg (__NR_Linux + 174)
-#define __NR_putpmsg (__NR_Linux + 175)
-#define __NR_afs_syscall (__NR_Linux + 176)
-#define __NR_reserved177 (__NR_Linux + 177)
-#define __NR_gettid (__NR_Linux + 178)
-#define __NR_readahead (__NR_Linux + 179)
-#define __NR_setxattr (__NR_Linux + 180)
-#define __NR_lsetxattr (__NR_Linux + 181)
-#define __NR_fsetxattr (__NR_Linux + 182)
-#define __NR_getxattr (__NR_Linux + 183)
-#define __NR_lgetxattr (__NR_Linux + 184)
-#define __NR_fgetxattr (__NR_Linux + 185)
-#define __NR_listxattr (__NR_Linux + 186)
-#define __NR_llistxattr (__NR_Linux + 187)
-#define __NR_flistxattr (__NR_Linux + 188)
-#define __NR_removexattr (__NR_Linux + 189)
-#define __NR_lremovexattr (__NR_Linux + 190)
-#define __NR_fremovexattr (__NR_Linux + 191)
-#define __NR_tkill (__NR_Linux + 192)
-#define __NR_reserved193 (__NR_Linux + 193)
-#define __NR_futex (__NR_Linux + 194)
-#define __NR_sched_setaffinity (__NR_Linux + 195)
-#define __NR_sched_getaffinity (__NR_Linux + 196)
-#define __NR_cacheflush (__NR_Linux + 197)
-#define __NR_cachectl (__NR_Linux + 198)
-#define __NR_sysmips (__NR_Linux + 199)
-#define __NR_io_setup (__NR_Linux + 200)
-#define __NR_io_destroy (__NR_Linux + 201)
-#define __NR_io_getevents (__NR_Linux + 202)
-#define __NR_io_submit (__NR_Linux + 203)
-#define __NR_io_cancel (__NR_Linux + 204)
-#define __NR_exit_group (__NR_Linux + 205)
-#define __NR_lookup_dcookie (__NR_Linux + 206)
-#define __NR_epoll_create (__NR_Linux + 207)
-#define __NR_epoll_ctl (__NR_Linux + 208)
-#define __NR_epoll_wait (__NR_Linux + 209)
-#define __NR_remap_file_pages (__NR_Linux + 210)
-#define __NR_rt_sigreturn (__NR_Linux + 211)
-#define __NR_fcntl64 (__NR_Linux + 212)
-#define __NR_set_tid_address (__NR_Linux + 213)
-#define __NR_restart_syscall (__NR_Linux + 214)
-#define __NR_semtimedop (__NR_Linux + 215)
-#define __NR_fadvise64 (__NR_Linux + 216)
-#define __NR_statfs64 (__NR_Linux + 217)
-#define __NR_fstatfs64 (__NR_Linux + 218)
-#define __NR_sendfile64 (__NR_Linux + 219)
-#define __NR_timer_create (__NR_Linux + 220)
-#define __NR_timer_settime (__NR_Linux + 221)
-#define __NR_timer_gettime (__NR_Linux + 222)
-#define __NR_timer_getoverrun (__NR_Linux + 223)
-#define __NR_timer_delete (__NR_Linux + 224)
-#define __NR_clock_settime (__NR_Linux + 225)
-#define __NR_clock_gettime (__NR_Linux + 226)
-#define __NR_clock_getres (__NR_Linux + 227)
-#define __NR_clock_nanosleep (__NR_Linux + 228)
-#define __NR_tgkill (__NR_Linux + 229)
-#define __NR_utimes (__NR_Linux + 230)
-#define __NR_mbind (__NR_Linux + 231)
-#define __NR_get_mempolicy (__NR_Linux + 232)
-#define __NR_set_mempolicy (__NR_Linux + 233)
-#define __NR_mq_open (__NR_Linux + 234)
-#define __NR_mq_unlink (__NR_Linux + 235)
-#define __NR_mq_timedsend (__NR_Linux + 236)
-#define __NR_mq_timedreceive (__NR_Linux + 237)
-#define __NR_mq_notify (__NR_Linux + 238)
-#define __NR_mq_getsetattr (__NR_Linux + 239)
-#define __NR_vserver (__NR_Linux + 240)
-#define __NR_waitid (__NR_Linux + 241)
-#define __NR_add_key (__NR_Linux + 243)
-#define __NR_request_key (__NR_Linux + 244)
-#define __NR_keyctl (__NR_Linux + 245)
-#define __NR_set_thread_area (__NR_Linux + 246)
-#define __NR_inotify_init (__NR_Linux + 247)
-#define __NR_inotify_add_watch (__NR_Linux + 248)
-#define __NR_inotify_rm_watch (__NR_Linux + 249)
-#define __NR_migrate_pages (__NR_Linux + 250)
-#define __NR_openat (__NR_Linux + 251)
-#define __NR_mkdirat (__NR_Linux + 252)
-#define __NR_mknodat (__NR_Linux + 253)
-#define __NR_fchownat (__NR_Linux + 254)
-#define __NR_futimesat (__NR_Linux + 255)
-#define __NR_newfstatat (__NR_Linux + 256)
-#define __NR_unlinkat (__NR_Linux + 257)
-#define __NR_renameat (__NR_Linux + 258)
-#define __NR_linkat (__NR_Linux + 259)
-#define __NR_symlinkat (__NR_Linux + 260)
-#define __NR_readlinkat (__NR_Linux + 261)
-#define __NR_fchmodat (__NR_Linux + 262)
-#define __NR_faccessat (__NR_Linux + 263)
-#define __NR_pselect6 (__NR_Linux + 264)
-#define __NR_ppoll (__NR_Linux + 265)
-#define __NR_unshare (__NR_Linux + 266)
-#define __NR_splice (__NR_Linux + 267)
-#define __NR_sync_file_range (__NR_Linux + 268)
-#define __NR_tee (__NR_Linux + 269)
-#define __NR_vmsplice (__NR_Linux + 270)
-#define __NR_move_pages (__NR_Linux + 271)
-#define __NR_set_robust_list (__NR_Linux + 272)
-#define __NR_get_robust_list (__NR_Linux + 273)
-#define __NR_kexec_load (__NR_Linux + 274)
-#define __NR_getcpu (__NR_Linux + 275)
-#define __NR_epoll_pwait (__NR_Linux + 276)
-#define __NR_ioprio_set (__NR_Linux + 277)
-#define __NR_ioprio_get (__NR_Linux + 278)
-#define __NR_utimensat (__NR_Linux + 279)
-#define __NR_signalfd (__NR_Linux + 280)
-#define __NR_timerfd (__NR_Linux + 281)
-#define __NR_eventfd (__NR_Linux + 282)
-#define __NR_fallocate (__NR_Linux + 283)
-#define __NR_timerfd_create (__NR_Linux + 284)
-#define __NR_timerfd_gettime (__NR_Linux + 285)
-#define __NR_timerfd_settime (__NR_Linux + 286)
-#define __NR_signalfd4 (__NR_Linux + 287)
-#define __NR_eventfd2 (__NR_Linux + 288)
-#define __NR_epoll_create1 (__NR_Linux + 289)
-#define __NR_dup3 (__NR_Linux + 290)
-#define __NR_pipe2 (__NR_Linux + 291)
-#define __NR_inotify_init1 (__NR_Linux + 292)
-#define __NR_preadv (__NR_Linux + 293)
-#define __NR_pwritev (__NR_Linux + 294)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
-#define __NR_perf_event_open (__NR_Linux + 296)
-#define __NR_accept4 (__NR_Linux + 297)
-#define __NR_recvmmsg (__NR_Linux + 298)
-#define __NR_getdents64 (__NR_Linux + 299)
-#define __NR_fanotify_init (__NR_Linux + 300)
-#define __NR_fanotify_mark (__NR_Linux + 301)
-#define __NR_prlimit64 (__NR_Linux + 302)
-#define __NR_name_to_handle_at (__NR_Linux + 303)
-#define __NR_open_by_handle_at (__NR_Linux + 304)
-#define __NR_clock_adjtime (__NR_Linux + 305)
-#define __NR_syncfs (__NR_Linux + 306)
-#define __NR_sendmmsg (__NR_Linux + 307)
-#define __NR_setns (__NR_Linux + 308)
-#define __NR_process_vm_readv (__NR_Linux + 309)
-#define __NR_process_vm_writev (__NR_Linux + 310)
-#define __NR_kcmp (__NR_Linux + 311)
-#define __NR_finit_module (__NR_Linux + 312)
-#define __NR_sched_setattr (__NR_Linux + 313)
-#define __NR_sched_getattr (__NR_Linux + 314)
-#define __NR_renameat2 (__NR_Linux + 315)
-#define __NR_seccomp (__NR_Linux + 316)
-#define __NR_getrandom (__NR_Linux + 317)
-#define __NR_memfd_create (__NR_Linux + 318)
-#define __NR_bpf (__NR_Linux + 319)
-#define __NR_execveat (__NR_Linux + 320)
-#define __NR_userfaultfd (__NR_Linux + 321)
-#define __NR_membarrier (__NR_Linux + 322)
-#define __NR_mlock2 (__NR_Linux + 323)
-#define __NR_copy_file_range (__NR_Linux + 324)
-#define __NR_preadv2 (__NR_Linux + 325)
-#define __NR_pwritev2 (__NR_Linux + 326)
-#define __NR_pkey_mprotect (__NR_Linux + 327)
-#define __NR_pkey_alloc (__NR_Linux + 328)
-#define __NR_pkey_free (__NR_Linux + 329)
-#define __NR_statx (__NR_Linux + 330)
-#define __NR_rseq (__NR_Linux + 331)
-#define __NR_io_pgetevents (__NR_Linux + 332)
-#define __NR_Linux_syscalls 332
+#include <asm/unistd_n32.h>
#endif
-#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 332
#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_n32.h b/libc/kernel/uapi/asm-mips/asm/unistd_n32.h
new file mode 100644
index 0000000..a72d9d2
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_n32.h
@@ -0,0 +1,353 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_MIPS_UNISTD_N32_H
+#define _UAPI_ASM_MIPS_UNISTD_N32_H
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_fcntl64 (__NR_Linux + 212)
+#define __NR_set_tid_address (__NR_Linux + 213)
+#define __NR_restart_syscall (__NR_Linux + 214)
+#define __NR_semtimedop (__NR_Linux + 215)
+#define __NR_fadvise64 (__NR_Linux + 216)
+#define __NR_statfs64 (__NR_Linux + 217)
+#define __NR_fstatfs64 (__NR_Linux + 218)
+#define __NR_sendfile64 (__NR_Linux + 219)
+#define __NR_timer_create (__NR_Linux + 220)
+#define __NR_timer_settime (__NR_Linux + 221)
+#define __NR_timer_gettime (__NR_Linux + 222)
+#define __NR_timer_getoverrun (__NR_Linux + 223)
+#define __NR_timer_delete (__NR_Linux + 224)
+#define __NR_clock_settime (__NR_Linux + 225)
+#define __NR_clock_gettime (__NR_Linux + 226)
+#define __NR_clock_getres (__NR_Linux + 227)
+#define __NR_clock_nanosleep (__NR_Linux + 228)
+#define __NR_tgkill (__NR_Linux + 229)
+#define __NR_utimes (__NR_Linux + 230)
+#define __NR_mbind (__NR_Linux + 231)
+#define __NR_get_mempolicy (__NR_Linux + 232)
+#define __NR_set_mempolicy (__NR_Linux + 233)
+#define __NR_mq_open (__NR_Linux + 234)
+#define __NR_mq_unlink (__NR_Linux + 235)
+#define __NR_mq_timedsend (__NR_Linux + 236)
+#define __NR_mq_timedreceive (__NR_Linux + 237)
+#define __NR_mq_notify (__NR_Linux + 238)
+#define __NR_mq_getsetattr (__NR_Linux + 239)
+#define __NR_vserver (__NR_Linux + 240)
+#define __NR_waitid (__NR_Linux + 241)
+#define __NR_add_key (__NR_Linux + 243)
+#define __NR_request_key (__NR_Linux + 244)
+#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
+#define __NR_migrate_pages (__NR_Linux + 250)
+#define __NR_openat (__NR_Linux + 251)
+#define __NR_mkdirat (__NR_Linux + 252)
+#define __NR_mknodat (__NR_Linux + 253)
+#define __NR_fchownat (__NR_Linux + 254)
+#define __NR_futimesat (__NR_Linux + 255)
+#define __NR_newfstatat (__NR_Linux + 256)
+#define __NR_unlinkat (__NR_Linux + 257)
+#define __NR_renameat (__NR_Linux + 258)
+#define __NR_linkat (__NR_Linux + 259)
+#define __NR_symlinkat (__NR_Linux + 260)
+#define __NR_readlinkat (__NR_Linux + 261)
+#define __NR_fchmodat (__NR_Linux + 262)
+#define __NR_faccessat (__NR_Linux + 263)
+#define __NR_pselect6 (__NR_Linux + 264)
+#define __NR_ppoll (__NR_Linux + 265)
+#define __NR_unshare (__NR_Linux + 266)
+#define __NR_splice (__NR_Linux + 267)
+#define __NR_sync_file_range (__NR_Linux + 268)
+#define __NR_tee (__NR_Linux + 269)
+#define __NR_vmsplice (__NR_Linux + 270)
+#define __NR_move_pages (__NR_Linux + 271)
+#define __NR_set_robust_list (__NR_Linux + 272)
+#define __NR_get_robust_list (__NR_Linux + 273)
+#define __NR_kexec_load (__NR_Linux + 274)
+#define __NR_getcpu (__NR_Linux + 275)
+#define __NR_epoll_pwait (__NR_Linux + 276)
+#define __NR_ioprio_set (__NR_Linux + 277)
+#define __NR_ioprio_get (__NR_Linux + 278)
+#define __NR_utimensat (__NR_Linux + 279)
+#define __NR_signalfd (__NR_Linux + 280)
+#define __NR_timerfd (__NR_Linux + 281)
+#define __NR_eventfd (__NR_Linux + 282)
+#define __NR_fallocate (__NR_Linux + 283)
+#define __NR_timerfd_create (__NR_Linux + 284)
+#define __NR_timerfd_gettime (__NR_Linux + 285)
+#define __NR_timerfd_settime (__NR_Linux + 286)
+#define __NR_signalfd4 (__NR_Linux + 287)
+#define __NR_eventfd2 (__NR_Linux + 288)
+#define __NR_epoll_create1 (__NR_Linux + 289)
+#define __NR_dup3 (__NR_Linux + 290)
+#define __NR_pipe2 (__NR_Linux + 291)
+#define __NR_inotify_init1 (__NR_Linux + 292)
+#define __NR_preadv (__NR_Linux + 293)
+#define __NR_pwritev (__NR_Linux + 294)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
+#define __NR_perf_event_open (__NR_Linux + 296)
+#define __NR_accept4 (__NR_Linux + 297)
+#define __NR_recvmmsg (__NR_Linux + 298)
+#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
+#define __NR_name_to_handle_at (__NR_Linux + 303)
+#define __NR_open_by_handle_at (__NR_Linux + 304)
+#define __NR_clock_adjtime (__NR_Linux + 305)
+#define __NR_syncfs (__NR_Linux + 306)
+#define __NR_sendmmsg (__NR_Linux + 307)
+#define __NR_setns (__NR_Linux + 308)
+#define __NR_process_vm_readv (__NR_Linux + 309)
+#define __NR_process_vm_writev (__NR_Linux + 310)
+#define __NR_kcmp (__NR_Linux + 311)
+#define __NR_finit_module (__NR_Linux + 312)
+#define __NR_sched_setattr (__NR_Linux + 313)
+#define __NR_sched_getattr (__NR_Linux + 314)
+#define __NR_renameat2 (__NR_Linux + 315)
+#define __NR_seccomp (__NR_Linux + 316)
+#define __NR_getrandom (__NR_Linux + 317)
+#define __NR_memfd_create (__NR_Linux + 318)
+#define __NR_bpf (__NR_Linux + 319)
+#define __NR_execveat (__NR_Linux + 320)
+#define __NR_userfaultfd (__NR_Linux + 321)
+#define __NR_membarrier (__NR_Linux + 322)
+#define __NR_mlock2 (__NR_Linux + 323)
+#define __NR_copy_file_range (__NR_Linux + 324)
+#define __NR_preadv2 (__NR_Linux + 325)
+#define __NR_pwritev2 (__NR_Linux + 326)
+#define __NR_pkey_mprotect (__NR_Linux + 327)
+#define __NR_pkey_alloc (__NR_Linux + 328)
+#define __NR_pkey_free (__NR_Linux + 329)
+#define __NR_statx (__NR_Linux + 330)
+#define __NR_rseq (__NR_Linux + 331)
+#define __NR_io_pgetevents (__NR_Linux + 332)
+#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_n64.h b/libc/kernel/uapi/asm-mips/asm/unistd_n64.h
new file mode 100644
index 0000000..5ea908a
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_n64.h
@@ -0,0 +1,349 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_MIPS_UNISTD_N64_H
+#define _UAPI_ASM_MIPS_UNISTD_N64_H
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_set_tid_address (__NR_Linux + 212)
+#define __NR_restart_syscall (__NR_Linux + 213)
+#define __NR_semtimedop (__NR_Linux + 214)
+#define __NR_fadvise64 (__NR_Linux + 215)
+#define __NR_timer_create (__NR_Linux + 216)
+#define __NR_timer_settime (__NR_Linux + 217)
+#define __NR_timer_gettime (__NR_Linux + 218)
+#define __NR_timer_getoverrun (__NR_Linux + 219)
+#define __NR_timer_delete (__NR_Linux + 220)
+#define __NR_clock_settime (__NR_Linux + 221)
+#define __NR_clock_gettime (__NR_Linux + 222)
+#define __NR_clock_getres (__NR_Linux + 223)
+#define __NR_clock_nanosleep (__NR_Linux + 224)
+#define __NR_tgkill (__NR_Linux + 225)
+#define __NR_utimes (__NR_Linux + 226)
+#define __NR_mbind (__NR_Linux + 227)
+#define __NR_get_mempolicy (__NR_Linux + 228)
+#define __NR_set_mempolicy (__NR_Linux + 229)
+#define __NR_mq_open (__NR_Linux + 230)
+#define __NR_mq_unlink (__NR_Linux + 231)
+#define __NR_mq_timedsend (__NR_Linux + 232)
+#define __NR_mq_timedreceive (__NR_Linux + 233)
+#define __NR_mq_notify (__NR_Linux + 234)
+#define __NR_mq_getsetattr (__NR_Linux + 235)
+#define __NR_vserver (__NR_Linux + 236)
+#define __NR_waitid (__NR_Linux + 237)
+#define __NR_add_key (__NR_Linux + 239)
+#define __NR_request_key (__NR_Linux + 240)
+#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
+#define __NR_migrate_pages (__NR_Linux + 246)
+#define __NR_openat (__NR_Linux + 247)
+#define __NR_mkdirat (__NR_Linux + 248)
+#define __NR_mknodat (__NR_Linux + 249)
+#define __NR_fchownat (__NR_Linux + 250)
+#define __NR_futimesat (__NR_Linux + 251)
+#define __NR_newfstatat (__NR_Linux + 252)
+#define __NR_unlinkat (__NR_Linux + 253)
+#define __NR_renameat (__NR_Linux + 254)
+#define __NR_linkat (__NR_Linux + 255)
+#define __NR_symlinkat (__NR_Linux + 256)
+#define __NR_readlinkat (__NR_Linux + 257)
+#define __NR_fchmodat (__NR_Linux + 258)
+#define __NR_faccessat (__NR_Linux + 259)
+#define __NR_pselect6 (__NR_Linux + 260)
+#define __NR_ppoll (__NR_Linux + 261)
+#define __NR_unshare (__NR_Linux + 262)
+#define __NR_splice (__NR_Linux + 263)
+#define __NR_sync_file_range (__NR_Linux + 264)
+#define __NR_tee (__NR_Linux + 265)
+#define __NR_vmsplice (__NR_Linux + 266)
+#define __NR_move_pages (__NR_Linux + 267)
+#define __NR_set_robust_list (__NR_Linux + 268)
+#define __NR_get_robust_list (__NR_Linux + 269)
+#define __NR_kexec_load (__NR_Linux + 270)
+#define __NR_getcpu (__NR_Linux + 271)
+#define __NR_epoll_pwait (__NR_Linux + 272)
+#define __NR_ioprio_set (__NR_Linux + 273)
+#define __NR_ioprio_get (__NR_Linux + 274)
+#define __NR_utimensat (__NR_Linux + 275)
+#define __NR_signalfd (__NR_Linux + 276)
+#define __NR_timerfd (__NR_Linux + 277)
+#define __NR_eventfd (__NR_Linux + 278)
+#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
+#define __NR_signalfd4 (__NR_Linux + 283)
+#define __NR_eventfd2 (__NR_Linux + 284)
+#define __NR_epoll_create1 (__NR_Linux + 285)
+#define __NR_dup3 (__NR_Linux + 286)
+#define __NR_pipe2 (__NR_Linux + 287)
+#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
+#define __NR_perf_event_open (__NR_Linux + 292)
+#define __NR_accept4 (__NR_Linux + 293)
+#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
+#define __NR_name_to_handle_at (__NR_Linux + 298)
+#define __NR_open_by_handle_at (__NR_Linux + 299)
+#define __NR_clock_adjtime (__NR_Linux + 300)
+#define __NR_syncfs (__NR_Linux + 301)
+#define __NR_sendmmsg (__NR_Linux + 302)
+#define __NR_setns (__NR_Linux + 303)
+#define __NR_process_vm_readv (__NR_Linux + 304)
+#define __NR_process_vm_writev (__NR_Linux + 305)
+#define __NR_kcmp (__NR_Linux + 306)
+#define __NR_finit_module (__NR_Linux + 307)
+#define __NR_getdents64 (__NR_Linux + 308)
+#define __NR_sched_setattr (__NR_Linux + 309)
+#define __NR_sched_getattr (__NR_Linux + 310)
+#define __NR_renameat2 (__NR_Linux + 311)
+#define __NR_seccomp (__NR_Linux + 312)
+#define __NR_getrandom (__NR_Linux + 313)
+#define __NR_memfd_create (__NR_Linux + 314)
+#define __NR_bpf (__NR_Linux + 315)
+#define __NR_execveat (__NR_Linux + 316)
+#define __NR_userfaultfd (__NR_Linux + 317)
+#define __NR_membarrier (__NR_Linux + 318)
+#define __NR_mlock2 (__NR_Linux + 319)
+#define __NR_copy_file_range (__NR_Linux + 320)
+#define __NR_preadv2 (__NR_Linux + 321)
+#define __NR_pwritev2 (__NR_Linux + 322)
+#define __NR_pkey_mprotect (__NR_Linux + 323)
+#define __NR_pkey_alloc (__NR_Linux + 324)
+#define __NR_pkey_free (__NR_Linux + 325)
+#define __NR_statx (__NR_Linux + 326)
+#define __NR_rseq (__NR_Linux + 327)
+#define __NR_io_pgetevents (__NR_Linux + 328)
+#endif
diff --git a/libc/kernel/uapi/asm-generic/shmparam.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h
similarity index 86%
rename from libc/kernel/uapi/asm-generic/shmparam.h
rename to libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h
index d3f1453..2b74f63 100644
--- a/libc/kernel/uapi/asm-generic/shmparam.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h
@@ -16,7 +16,8 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __ASM_GENERIC_SHMPARAM_H
-#define __ASM_GENERIC_SHMPARAM_H
-#define SHMLBA PAGE_SIZE
+#ifndef _UAPI_ASM_MIPS_UNISTD_NR_N32_H
+#define _UAPI_ASM_MIPS_UNISTD_NR_N32_H
+#define __NR_N32_Linux 6000
+#define __NR_N32_Linux_syscalls 333
#endif
diff --git a/libc/kernel/uapi/asm-generic/shmparam.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h
similarity index 86%
copy from libc/kernel/uapi/asm-generic/shmparam.h
copy to libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h
index d3f1453..22300b2 100644
--- a/libc/kernel/uapi/asm-generic/shmparam.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h
@@ -16,7 +16,8 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __ASM_GENERIC_SHMPARAM_H
-#define __ASM_GENERIC_SHMPARAM_H
-#define SHMLBA PAGE_SIZE
+#ifndef _UAPI_ASM_MIPS_UNISTD_NR_N64_H
+#define _UAPI_ASM_MIPS_UNISTD_NR_N64_H
+#define __NR_64_Linux 5000
+#define __NR_64_Linux_syscalls 329
#endif
diff --git a/libc/kernel/uapi/asm-generic/shmparam.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h
similarity index 86%
copy from libc/kernel/uapi/asm-generic/shmparam.h
copy to libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h
index d3f1453..02cbd21 100644
--- a/libc/kernel/uapi/asm-generic/shmparam.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h
@@ -16,7 +16,8 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __ASM_GENERIC_SHMPARAM_H
-#define __ASM_GENERIC_SHMPARAM_H
-#define SHMLBA PAGE_SIZE
+#ifndef _UAPI_ASM_MIPS_UNISTD_NR_O32_H
+#define _UAPI_ASM_MIPS_UNISTD_NR_O32_H
+#define __NR_O32_Linux 4000
+#define __NR_O32_Linux_syscalls 369
#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_o32.h b/libc/kernel/uapi/asm-mips/asm/unistd_o32.h
new file mode 100644
index 0000000..bc248dd
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/unistd_o32.h
@@ -0,0 +1,389 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_MIPS_UNISTD_O32_H
+#define _UAPI_ASM_MIPS_UNISTD_O32_H
+#define __NR_syscall (__NR_Linux + 0)
+#define __NR_exit (__NR_Linux + 1)
+#define __NR_fork (__NR_Linux + 2)
+#define __NR_read (__NR_Linux + 3)
+#define __NR_write (__NR_Linux + 4)
+#define __NR_open (__NR_Linux + 5)
+#define __NR_close (__NR_Linux + 6)
+#define __NR_waitpid (__NR_Linux + 7)
+#define __NR_creat (__NR_Linux + 8)
+#define __NR_link (__NR_Linux + 9)
+#define __NR_unlink (__NR_Linux + 10)
+#define __NR_execve (__NR_Linux + 11)
+#define __NR_chdir (__NR_Linux + 12)
+#define __NR_time (__NR_Linux + 13)
+#define __NR_mknod (__NR_Linux + 14)
+#define __NR_chmod (__NR_Linux + 15)
+#define __NR_lchown (__NR_Linux + 16)
+#define __NR_break (__NR_Linux + 17)
+#define __NR_unused18 (__NR_Linux + 18)
+#define __NR_lseek (__NR_Linux + 19)
+#define __NR_getpid (__NR_Linux + 20)
+#define __NR_mount (__NR_Linux + 21)
+#define __NR_umount (__NR_Linux + 22)
+#define __NR_setuid (__NR_Linux + 23)
+#define __NR_getuid (__NR_Linux + 24)
+#define __NR_stime (__NR_Linux + 25)
+#define __NR_ptrace (__NR_Linux + 26)
+#define __NR_alarm (__NR_Linux + 27)
+#define __NR_unused28 (__NR_Linux + 28)
+#define __NR_pause (__NR_Linux + 29)
+#define __NR_utime (__NR_Linux + 30)
+#define __NR_stty (__NR_Linux + 31)
+#define __NR_gtty (__NR_Linux + 32)
+#define __NR_access (__NR_Linux + 33)
+#define __NR_nice (__NR_Linux + 34)
+#define __NR_ftime (__NR_Linux + 35)
+#define __NR_sync (__NR_Linux + 36)
+#define __NR_kill (__NR_Linux + 37)
+#define __NR_rename (__NR_Linux + 38)
+#define __NR_mkdir (__NR_Linux + 39)
+#define __NR_rmdir (__NR_Linux + 40)
+#define __NR_dup (__NR_Linux + 41)
+#define __NR_pipe (__NR_Linux + 42)
+#define __NR_times (__NR_Linux + 43)
+#define __NR_prof (__NR_Linux + 44)
+#define __NR_brk (__NR_Linux + 45)
+#define __NR_setgid (__NR_Linux + 46)
+#define __NR_getgid (__NR_Linux + 47)
+#define __NR_signal (__NR_Linux + 48)
+#define __NR_geteuid (__NR_Linux + 49)
+#define __NR_getegid (__NR_Linux + 50)
+#define __NR_acct (__NR_Linux + 51)
+#define __NR_umount2 (__NR_Linux + 52)
+#define __NR_lock (__NR_Linux + 53)
+#define __NR_ioctl (__NR_Linux + 54)
+#define __NR_fcntl (__NR_Linux + 55)
+#define __NR_mpx (__NR_Linux + 56)
+#define __NR_setpgid (__NR_Linux + 57)
+#define __NR_ulimit (__NR_Linux + 58)
+#define __NR_unused59 (__NR_Linux + 59)
+#define __NR_umask (__NR_Linux + 60)
+#define __NR_chroot (__NR_Linux + 61)
+#define __NR_ustat (__NR_Linux + 62)
+#define __NR_dup2 (__NR_Linux + 63)
+#define __NR_getppid (__NR_Linux + 64)
+#define __NR_getpgrp (__NR_Linux + 65)
+#define __NR_setsid (__NR_Linux + 66)
+#define __NR_sigaction (__NR_Linux + 67)
+#define __NR_sgetmask (__NR_Linux + 68)
+#define __NR_ssetmask (__NR_Linux + 69)
+#define __NR_setreuid (__NR_Linux + 70)
+#define __NR_setregid (__NR_Linux + 71)
+#define __NR_sigsuspend (__NR_Linux + 72)
+#define __NR_sigpending (__NR_Linux + 73)
+#define __NR_sethostname (__NR_Linux + 74)
+#define __NR_setrlimit (__NR_Linux + 75)
+#define __NR_getrlimit (__NR_Linux + 76)
+#define __NR_getrusage (__NR_Linux + 77)
+#define __NR_gettimeofday (__NR_Linux + 78)
+#define __NR_settimeofday (__NR_Linux + 79)
+#define __NR_getgroups (__NR_Linux + 80)
+#define __NR_setgroups (__NR_Linux + 81)
+#define __NR_reserved82 (__NR_Linux + 82)
+#define __NR_symlink (__NR_Linux + 83)
+#define __NR_unused84 (__NR_Linux + 84)
+#define __NR_readlink (__NR_Linux + 85)
+#define __NR_uselib (__NR_Linux + 86)
+#define __NR_swapon (__NR_Linux + 87)
+#define __NR_reboot (__NR_Linux + 88)
+#define __NR_readdir (__NR_Linux + 89)
+#define __NR_mmap (__NR_Linux + 90)
+#define __NR_munmap (__NR_Linux + 91)
+#define __NR_truncate (__NR_Linux + 92)
+#define __NR_ftruncate (__NR_Linux + 93)
+#define __NR_fchmod (__NR_Linux + 94)
+#define __NR_fchown (__NR_Linux + 95)
+#define __NR_getpriority (__NR_Linux + 96)
+#define __NR_setpriority (__NR_Linux + 97)
+#define __NR_profil (__NR_Linux + 98)
+#define __NR_statfs (__NR_Linux + 99)
+#define __NR_fstatfs (__NR_Linux + 100)
+#define __NR_ioperm (__NR_Linux + 101)
+#define __NR_socketcall (__NR_Linux + 102)
+#define __NR_syslog (__NR_Linux + 103)
+#define __NR_setitimer (__NR_Linux + 104)
+#define __NR_getitimer (__NR_Linux + 105)
+#define __NR_stat (__NR_Linux + 106)
+#define __NR_lstat (__NR_Linux + 107)
+#define __NR_fstat (__NR_Linux + 108)
+#define __NR_unused109 (__NR_Linux + 109)
+#define __NR_iopl (__NR_Linux + 110)
+#define __NR_vhangup (__NR_Linux + 111)
+#define __NR_idle (__NR_Linux + 112)
+#define __NR_vm86 (__NR_Linux + 113)
+#define __NR_wait4 (__NR_Linux + 114)
+#define __NR_swapoff (__NR_Linux + 115)
+#define __NR_sysinfo (__NR_Linux + 116)
+#define __NR_ipc (__NR_Linux + 117)
+#define __NR_fsync (__NR_Linux + 118)
+#define __NR_sigreturn (__NR_Linux + 119)
+#define __NR_clone (__NR_Linux + 120)
+#define __NR_setdomainname (__NR_Linux + 121)
+#define __NR_uname (__NR_Linux + 122)
+#define __NR_modify_ldt (__NR_Linux + 123)
+#define __NR_adjtimex (__NR_Linux + 124)
+#define __NR_mprotect (__NR_Linux + 125)
+#define __NR_sigprocmask (__NR_Linux + 126)
+#define __NR_create_module (__NR_Linux + 127)
+#define __NR_init_module (__NR_Linux + 128)
+#define __NR_delete_module (__NR_Linux + 129)
+#define __NR_get_kernel_syms (__NR_Linux + 130)
+#define __NR_quotactl (__NR_Linux + 131)
+#define __NR_getpgid (__NR_Linux + 132)
+#define __NR_fchdir (__NR_Linux + 133)
+#define __NR_bdflush (__NR_Linux + 134)
+#define __NR_sysfs (__NR_Linux + 135)
+#define __NR_personality (__NR_Linux + 136)
+#define __NR_afs_syscall (__NR_Linux + 137)
+#define __NR_setfsuid (__NR_Linux + 138)
+#define __NR_setfsgid (__NR_Linux + 139)
+#define __NR__llseek (__NR_Linux + 140)
+#define __NR_getdents (__NR_Linux + 141)
+#define __NR__newselect (__NR_Linux + 142)
+#define __NR_flock (__NR_Linux + 143)
+#define __NR_msync (__NR_Linux + 144)
+#define __NR_readv (__NR_Linux + 145)
+#define __NR_writev (__NR_Linux + 146)
+#define __NR_cacheflush (__NR_Linux + 147)
+#define __NR_cachectl (__NR_Linux + 148)
+#define __NR_sysmips (__NR_Linux + 149)
+#define __NR_unused150 (__NR_Linux + 150)
+#define __NR_getsid (__NR_Linux + 151)
+#define __NR_fdatasync (__NR_Linux + 152)
+#define __NR__sysctl (__NR_Linux + 153)
+#define __NR_mlock (__NR_Linux + 154)
+#define __NR_munlock (__NR_Linux + 155)
+#define __NR_mlockall (__NR_Linux + 156)
+#define __NR_munlockall (__NR_Linux + 157)
+#define __NR_sched_setparam (__NR_Linux + 158)
+#define __NR_sched_getparam (__NR_Linux + 159)
+#define __NR_sched_setscheduler (__NR_Linux + 160)
+#define __NR_sched_getscheduler (__NR_Linux + 161)
+#define __NR_sched_yield (__NR_Linux + 162)
+#define __NR_sched_get_priority_max (__NR_Linux + 163)
+#define __NR_sched_get_priority_min (__NR_Linux + 164)
+#define __NR_sched_rr_get_interval (__NR_Linux + 165)
+#define __NR_nanosleep (__NR_Linux + 166)
+#define __NR_mremap (__NR_Linux + 167)
+#define __NR_accept (__NR_Linux + 168)
+#define __NR_bind (__NR_Linux + 169)
+#define __NR_connect (__NR_Linux + 170)
+#define __NR_getpeername (__NR_Linux + 171)
+#define __NR_getsockname (__NR_Linux + 172)
+#define __NR_getsockopt (__NR_Linux + 173)
+#define __NR_listen (__NR_Linux + 174)
+#define __NR_recv (__NR_Linux + 175)
+#define __NR_recvfrom (__NR_Linux + 176)
+#define __NR_recvmsg (__NR_Linux + 177)
+#define __NR_send (__NR_Linux + 178)
+#define __NR_sendmsg (__NR_Linux + 179)
+#define __NR_sendto (__NR_Linux + 180)
+#define __NR_setsockopt (__NR_Linux + 181)
+#define __NR_shutdown (__NR_Linux + 182)
+#define __NR_socket (__NR_Linux + 183)
+#define __NR_socketpair (__NR_Linux + 184)
+#define __NR_setresuid (__NR_Linux + 185)
+#define __NR_getresuid (__NR_Linux + 186)
+#define __NR_query_module (__NR_Linux + 187)
+#define __NR_poll (__NR_Linux + 188)
+#define __NR_nfsservctl (__NR_Linux + 189)
+#define __NR_setresgid (__NR_Linux + 190)
+#define __NR_getresgid (__NR_Linux + 191)
+#define __NR_prctl (__NR_Linux + 192)
+#define __NR_rt_sigreturn (__NR_Linux + 193)
+#define __NR_rt_sigaction (__NR_Linux + 194)
+#define __NR_rt_sigprocmask (__NR_Linux + 195)
+#define __NR_rt_sigpending (__NR_Linux + 196)
+#define __NR_rt_sigtimedwait (__NR_Linux + 197)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
+#define __NR_rt_sigsuspend (__NR_Linux + 199)
+#define __NR_pread64 (__NR_Linux + 200)
+#define __NR_pwrite64 (__NR_Linux + 201)
+#define __NR_chown (__NR_Linux + 202)
+#define __NR_getcwd (__NR_Linux + 203)
+#define __NR_capget (__NR_Linux + 204)
+#define __NR_capset (__NR_Linux + 205)
+#define __NR_sigaltstack (__NR_Linux + 206)
+#define __NR_sendfile (__NR_Linux + 207)
+#define __NR_getpmsg (__NR_Linux + 208)
+#define __NR_putpmsg (__NR_Linux + 209)
+#define __NR_mmap2 (__NR_Linux + 210)
+#define __NR_truncate64 (__NR_Linux + 211)
+#define __NR_ftruncate64 (__NR_Linux + 212)
+#define __NR_stat64 (__NR_Linux + 213)
+#define __NR_lstat64 (__NR_Linux + 214)
+#define __NR_fstat64 (__NR_Linux + 215)
+#define __NR_pivot_root (__NR_Linux + 216)
+#define __NR_mincore (__NR_Linux + 217)
+#define __NR_madvise (__NR_Linux + 218)
+#define __NR_getdents64 (__NR_Linux + 219)
+#define __NR_fcntl64 (__NR_Linux + 220)
+#define __NR_reserved221 (__NR_Linux + 221)
+#define __NR_gettid (__NR_Linux + 222)
+#define __NR_readahead (__NR_Linux + 223)
+#define __NR_setxattr (__NR_Linux + 224)
+#define __NR_lsetxattr (__NR_Linux + 225)
+#define __NR_fsetxattr (__NR_Linux + 226)
+#define __NR_getxattr (__NR_Linux + 227)
+#define __NR_lgetxattr (__NR_Linux + 228)
+#define __NR_fgetxattr (__NR_Linux + 229)
+#define __NR_listxattr (__NR_Linux + 230)
+#define __NR_llistxattr (__NR_Linux + 231)
+#define __NR_flistxattr (__NR_Linux + 232)
+#define __NR_removexattr (__NR_Linux + 233)
+#define __NR_lremovexattr (__NR_Linux + 234)
+#define __NR_fremovexattr (__NR_Linux + 235)
+#define __NR_tkill (__NR_Linux + 236)
+#define __NR_sendfile64 (__NR_Linux + 237)
+#define __NR_futex (__NR_Linux + 238)
+#define __NR_sched_setaffinity (__NR_Linux + 239)
+#define __NR_sched_getaffinity (__NR_Linux + 240)
+#define __NR_io_setup (__NR_Linux + 241)
+#define __NR_io_destroy (__NR_Linux + 242)
+#define __NR_io_getevents (__NR_Linux + 243)
+#define __NR_io_submit (__NR_Linux + 244)
+#define __NR_io_cancel (__NR_Linux + 245)
+#define __NR_exit_group (__NR_Linux + 246)
+#define __NR_lookup_dcookie (__NR_Linux + 247)
+#define __NR_epoll_create (__NR_Linux + 248)
+#define __NR_epoll_ctl (__NR_Linux + 249)
+#define __NR_epoll_wait (__NR_Linux + 250)
+#define __NR_remap_file_pages (__NR_Linux + 251)
+#define __NR_set_tid_address (__NR_Linux + 252)
+#define __NR_restart_syscall (__NR_Linux + 253)
+#define __NR_fadvise64 (__NR_Linux + 254)
+#define __NR_statfs64 (__NR_Linux + 255)
+#define __NR_fstatfs64 (__NR_Linux + 256)
+#define __NR_timer_create (__NR_Linux + 257)
+#define __NR_timer_settime (__NR_Linux + 258)
+#define __NR_timer_gettime (__NR_Linux + 259)
+#define __NR_timer_getoverrun (__NR_Linux + 260)
+#define __NR_timer_delete (__NR_Linux + 261)
+#define __NR_clock_settime (__NR_Linux + 262)
+#define __NR_clock_gettime (__NR_Linux + 263)
+#define __NR_clock_getres (__NR_Linux + 264)
+#define __NR_clock_nanosleep (__NR_Linux + 265)
+#define __NR_tgkill (__NR_Linux + 266)
+#define __NR_utimes (__NR_Linux + 267)
+#define __NR_mbind (__NR_Linux + 268)
+#define __NR_get_mempolicy (__NR_Linux + 269)
+#define __NR_set_mempolicy (__NR_Linux + 270)
+#define __NR_mq_open (__NR_Linux + 271)
+#define __NR_mq_unlink (__NR_Linux + 272)
+#define __NR_mq_timedsend (__NR_Linux + 273)
+#define __NR_mq_timedreceive (__NR_Linux + 274)
+#define __NR_mq_notify (__NR_Linux + 275)
+#define __NR_mq_getsetattr (__NR_Linux + 276)
+#define __NR_vserver (__NR_Linux + 277)
+#define __NR_waitid (__NR_Linux + 278)
+#define __NR_add_key (__NR_Linux + 280)
+#define __NR_request_key (__NR_Linux + 281)
+#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+#define __NR_migrate_pages (__NR_Linux + 287)
+#define __NR_openat (__NR_Linux + 288)
+#define __NR_mkdirat (__NR_Linux + 289)
+#define __NR_mknodat (__NR_Linux + 290)
+#define __NR_fchownat (__NR_Linux + 291)
+#define __NR_futimesat (__NR_Linux + 292)
+#define __NR_fstatat64 (__NR_Linux + 293)
+#define __NR_unlinkat (__NR_Linux + 294)
+#define __NR_renameat (__NR_Linux + 295)
+#define __NR_linkat (__NR_Linux + 296)
+#define __NR_symlinkat (__NR_Linux + 297)
+#define __NR_readlinkat (__NR_Linux + 298)
+#define __NR_fchmodat (__NR_Linux + 299)
+#define __NR_faccessat (__NR_Linux + 300)
+#define __NR_pselect6 (__NR_Linux + 301)
+#define __NR_ppoll (__NR_Linux + 302)
+#define __NR_unshare (__NR_Linux + 303)
+#define __NR_splice (__NR_Linux + 304)
+#define __NR_sync_file_range (__NR_Linux + 305)
+#define __NR_tee (__NR_Linux + 306)
+#define __NR_vmsplice (__NR_Linux + 307)
+#define __NR_move_pages (__NR_Linux + 308)
+#define __NR_set_robust_list (__NR_Linux + 309)
+#define __NR_get_robust_list (__NR_Linux + 310)
+#define __NR_kexec_load (__NR_Linux + 311)
+#define __NR_getcpu (__NR_Linux + 312)
+#define __NR_epoll_pwait (__NR_Linux + 313)
+#define __NR_ioprio_set (__NR_Linux + 314)
+#define __NR_ioprio_get (__NR_Linux + 315)
+#define __NR_utimensat (__NR_Linux + 316)
+#define __NR_signalfd (__NR_Linux + 317)
+#define __NR_timerfd (__NR_Linux + 318)
+#define __NR_eventfd (__NR_Linux + 319)
+#define __NR_fallocate (__NR_Linux + 320)
+#define __NR_timerfd_create (__NR_Linux + 321)
+#define __NR_timerfd_gettime (__NR_Linux + 322)
+#define __NR_timerfd_settime (__NR_Linux + 323)
+#define __NR_signalfd4 (__NR_Linux + 324)
+#define __NR_eventfd2 (__NR_Linux + 325)
+#define __NR_epoll_create1 (__NR_Linux + 326)
+#define __NR_dup3 (__NR_Linux + 327)
+#define __NR_pipe2 (__NR_Linux + 328)
+#define __NR_inotify_init1 (__NR_Linux + 329)
+#define __NR_preadv (__NR_Linux + 330)
+#define __NR_pwritev (__NR_Linux + 331)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
+#define __NR_perf_event_open (__NR_Linux + 333)
+#define __NR_accept4 (__NR_Linux + 334)
+#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
+#define __NR_name_to_handle_at (__NR_Linux + 339)
+#define __NR_open_by_handle_at (__NR_Linux + 340)
+#define __NR_clock_adjtime (__NR_Linux + 341)
+#define __NR_syncfs (__NR_Linux + 342)
+#define __NR_sendmmsg (__NR_Linux + 343)
+#define __NR_setns (__NR_Linux + 344)
+#define __NR_process_vm_readv (__NR_Linux + 345)
+#define __NR_process_vm_writev (__NR_Linux + 346)
+#define __NR_kcmp (__NR_Linux + 347)
+#define __NR_finit_module (__NR_Linux + 348)
+#define __NR_sched_setattr (__NR_Linux + 349)
+#define __NR_sched_getattr (__NR_Linux + 350)
+#define __NR_renameat2 (__NR_Linux + 351)
+#define __NR_seccomp (__NR_Linux + 352)
+#define __NR_getrandom (__NR_Linux + 353)
+#define __NR_memfd_create (__NR_Linux + 354)
+#define __NR_bpf (__NR_Linux + 355)
+#define __NR_execveat (__NR_Linux + 356)
+#define __NR_userfaultfd (__NR_Linux + 357)
+#define __NR_membarrier (__NR_Linux + 358)
+#define __NR_mlock2 (__NR_Linux + 359)
+#define __NR_copy_file_range (__NR_Linux + 360)
+#define __NR_preadv2 (__NR_Linux + 361)
+#define __NR_pwritev2 (__NR_Linux + 362)
+#define __NR_pkey_mprotect (__NR_Linux + 363)
+#define __NR_pkey_alloc (__NR_Linux + 364)
+#define __NR_pkey_free (__NR_Linux + 365)
+#define __NR_statx (__NR_Linux + 366)
+#define __NR_rseq (__NR_Linux + 367)
+#define __NR_io_pgetevents (__NR_Linux + 368)
+#endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 8d65fd4..baa2e44 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -195,6 +195,12 @@
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
#define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0
#define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f
+#define AMDGPU_TILING_DCC_OFFSET_256B_SHIFT 5
+#define AMDGPU_TILING_DCC_OFFSET_256B_MASK 0xFFFFFF
+#define AMDGPU_TILING_DCC_PITCH_MAX_SHIFT 29
+#define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43
+#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
#define AMDGPU_TILING_SET(field,value) (((__u64) (value) & AMDGPU_TILING_ ##field ##_MASK) << AMDGPU_TILING_ ##field ##_SHIFT)
#define AMDGPU_TILING_GET(value,field) (((__u64) (value) >> AMDGPU_TILING_ ##field ##_SHIFT) & AMDGPU_TILING_ ##field ##_MASK)
#define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index df89cd1..d95bda0 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -75,6 +75,11 @@
#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y')
#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y')
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V')
+#define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V')
+#define DRM_FORMAT_Y0L0 fourcc_code('Y', '0', 'L', '0')
+#define DRM_FORMAT_X0L0 fourcc_code('X', '0', 'L', '0')
+#define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2')
+#define DRM_FORMAT_X0L2 fourcc_code('X', '0', 'L', '2')
#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index dff9f34..1944c9c 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -463,6 +463,12 @@
struct drm_mode_revoke_lease {
__u32 lessee_id;
};
+struct drm_mode_rect {
+ __s32 x1;
+ __s32 y1;
+ __s32 x2;
+ __s32 y2;
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 89fa529..b3fd9fd 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -281,6 +281,9 @@
typedef struct drm_i915_irq_wait {
int irq_seq;
} drm_i915_irq_wait_t;
+#define I915_GEM_PPGTT_NONE 0
+#define I915_GEM_PPGTT_ALIASING 1
+#define I915_GEM_PPGTT_FULL 2
#define I915_PARAM_IRQ_ACTIVE 1
#define I915_PARAM_ALLOW_BATCHBUFFER 2
#define I915_PARAM_LAST_DISPATCH 3
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index df8119f..f6bee3e 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -57,12 +57,16 @@
__u32 flags;
__u32 handle;
};
-#define MSM_INFO_IOVA 0x01
-#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
+#define MSM_INFO_GET_OFFSET 0x00
+#define MSM_INFO_GET_IOVA 0x01
+#define MSM_INFO_SET_NAME 0x02
+#define MSM_INFO_GET_NAME 0x03
struct drm_msm_gem_info {
__u32 handle;
- __u32 flags;
- __u64 offset;
+ __u32 info;
+ __u64 value;
+ __u32 len;
+ __u32 pad;
};
#define MSM_PREP_READ 0x01
#define MSM_PREP_WRITE 0x02
@@ -97,7 +101,8 @@
};
#define MSM_SUBMIT_BO_READ 0x0001
#define MSM_SUBMIT_BO_WRITE 0x0002
-#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE)
+#define MSM_SUBMIT_BO_DUMP 0x0004
+#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE | MSM_SUBMIT_BO_DUMP)
struct drm_msm_gem_submit_bo {
__u32 flags;
__u32 handle;
diff --git a/libc/kernel/uapi/drm/v3d_drm.h b/libc/kernel/uapi/drm/v3d_drm.h
index 8865911..985f327 100644
--- a/libc/kernel/uapi/drm/v3d_drm.h
+++ b/libc/kernel/uapi/drm/v3d_drm.h
@@ -28,12 +28,14 @@
#define DRM_V3D_MMAP_BO 0x03
#define DRM_V3D_GET_PARAM 0x04
#define DRM_V3D_GET_BO_OFFSET 0x05
+#define DRM_V3D_SUBMIT_TFU 0x06
#define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
#define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
#define DRM_IOCTL_V3D_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_CREATE_BO, struct drm_v3d_create_bo)
#define DRM_IOCTL_V3D_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_MMAP_BO, struct drm_v3d_mmap_bo)
#define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param)
#define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset)
+#define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu)
struct drm_v3d_submit_cl {
__u32 bcl_start;
__u32 bcl_end;
@@ -73,6 +75,7 @@
DRM_V3D_PARAM_V3D_CORE0_IDENT0,
DRM_V3D_PARAM_V3D_CORE0_IDENT1,
DRM_V3D_PARAM_V3D_CORE0_IDENT2,
+ DRM_V3D_PARAM_SUPPORTS_TFU,
};
struct drm_v3d_get_param {
__u32 param;
@@ -83,6 +86,19 @@
__u32 handle;
__u32 offset;
};
+struct drm_v3d_submit_tfu {
+ __u32 icfg;
+ __u32 iia;
+ __u32 iis;
+ __u32 ica;
+ __u32 iua;
+ __u32 ioa;
+ __u32 ios;
+ __u32 coef[4];
+ __u32 bo_handles[4];
+ __u32 in_sync;
+ __u32 out_sync;
+};
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/virtgpu_drm.h b/libc/kernel/uapi/drm/virtgpu_drm.h
index 84986e4..bc4aad4 100644
--- a/libc/kernel/uapi/drm/virtgpu_drm.h
+++ b/libc/kernel/uapi/drm/virtgpu_drm.h
@@ -31,6 +31,9 @@
#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07
#define DRM_VIRTGPU_WAIT 0x08
#define DRM_VIRTGPU_GET_CAPS 0x09
+#define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01
+#define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02
+#define VIRTGPU_EXECBUF_FLAGS (VIRTGPU_EXECBUF_FENCE_FD_IN | VIRTGPU_EXECBUF_FENCE_FD_OUT | 0)
struct drm_virtgpu_map {
__u64 offset;
__u32 handle;
@@ -42,7 +45,7 @@
__u64 command;
__u64 bo_handles;
__u32 num_bo_handles;
- __u32 pad;
+ __s32 fence_fd;
};
#define VIRTGPU_PARAM_3D_FEATURES 1
#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2
@@ -105,7 +108,7 @@
__u32 pad;
};
#define DRM_IOCTL_VIRTGPU_MAP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
-#define DRM_IOCTL_VIRTGPU_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER, struct drm_virtgpu_execbuffer)
+#define DRM_IOCTL_VIRTGPU_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER, struct drm_virtgpu_execbuffer)
#define DRM_IOCTL_VIRTGPU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM, struct drm_virtgpu_getparam)
#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE, struct drm_virtgpu_resource_create)
#define DRM_IOCTL_VIRTGPU_RESOURCE_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_INFO, struct drm_virtgpu_resource_info)
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 2d00a79..542cf1c 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -34,6 +34,7 @@
enum {
FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+ FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
};
#ifdef BINDER_IPC_32BIT
typedef __u32 binder_size_t;
@@ -120,6 +121,7 @@
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
+#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
enum transaction_flags {
TF_ONE_WAY = 0x01,
TF_ROOT_OBJECT = 0x04,
@@ -146,6 +148,10 @@
__u8 buf[8];
} data;
};
+struct binder_transaction_data_secctx {
+ struct binder_transaction_data transaction_data;
+ binder_uintptr_t secctx;
+};
struct binder_transaction_data_sg {
struct binder_transaction_data transaction_data;
binder_size_t buffers_size;
@@ -170,6 +176,7 @@
enum binder_driver_return_protocol {
BR_ERROR = _IOR('r', 0, __s32),
BR_OK = _IO('r', 1),
+ BR_TRANSACTION_SEC_CTX = _IOR('r', 2, struct binder_transaction_data_secctx),
BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
BR_ACQUIRE_RESULT = _IOR('r', 4, __s32),
diff --git a/libc/kernel/uapi/asm-generic/shmparam.h b/libc/kernel/uapi/linux/android/binderfs.h
similarity index 74%
copy from libc/kernel/uapi/asm-generic/shmparam.h
copy to libc/kernel/uapi/linux/android/binderfs.h
index d3f1453..d58c333 100644
--- a/libc/kernel/uapi/asm-generic/shmparam.h
+++ b/libc/kernel/uapi/linux/android/binderfs.h
@@ -16,7 +16,16 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __ASM_GENERIC_SHMPARAM_H
-#define __ASM_GENERIC_SHMPARAM_H
-#define SHMLBA PAGE_SIZE
+#ifndef _UAPI_LINUX_BINDERFS_H
+#define _UAPI_LINUX_BINDERFS_H
+#include <linux/android/binder.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define BINDERFS_MAX_NAME 255
+struct binderfs_device {
+ char name[BINDERFS_MAX_NAME + 1];
+ __u32 major;
+ __u32 minor;
+};
+#define BINDER_CTL_ADD _IOWR('b', 1, struct binderfs_device)
#endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 235a0e7..0698fc8 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -265,6 +265,7 @@
#define AUDIT_ARCH_ARM (EM_ARM | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARMEB (EM_ARM)
#define AUDIT_ARCH_CRIS (EM_CRIS | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_CSKY (EM_CSKY | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_FRV (EM_FRV)
#define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_IA64 (EM_IA_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
@@ -283,6 +284,8 @@
#define AUDIT_ARCH_PPC (EM_PPC)
#define AUDIT_ARCH_PPC64 (EM_PPC64 | __AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_PPC64LE (EM_PPC64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_RISCV32 (EM_RISCV | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_RISCV64 (EM_RISCV | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_S390 (EM_S390)
#define AUDIT_ARCH_S390X (EM_S390 | __AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_SH (EM_SH)
@@ -295,6 +298,7 @@
#define AUDIT_ARCH_TILEGX32 (EM_TILEGX | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_TILEPRO (EM_TILEPRO | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_XTENSA (EM_XTENSA)
#define AUDIT_PERM_EXEC 1
#define AUDIT_PERM_WRITE 2
#define AUDIT_PERM_READ 4
diff --git a/libc/kernel/uapi/linux/auto_fs.h b/libc/kernel/uapi/linux/auto_fs.h
index 0264b86..9a9dd65 100644
--- a/libc/kernel/uapi/linux/auto_fs.h
+++ b/libc/kernel/uapi/linux/auto_fs.h
@@ -24,7 +24,7 @@
#define AUTOFS_PROTO_VERSION 5
#define AUTOFS_MIN_PROTO_VERSION 3
#define AUTOFS_MAX_PROTO_VERSION 5
-#define AUTOFS_PROTO_SUBVERSION 3
+#define AUTOFS_PROTO_SUBVERSION 4
#if defined(__ia64__) || defined(__alpha__)
typedef unsigned long autofs_wqt_t;
#else
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index d70a409..894b9f7 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -169,6 +169,7 @@
#define BPF_F_ALLOW_OVERRIDE (1U << 0)
#define BPF_F_ALLOW_MULTI (1U << 1)
#define BPF_F_STRICT_ALIGNMENT (1U << 0)
+#define BPF_F_ANY_ALIGNMENT (1U << 1)
#define BPF_PSEUDO_MAP_FD 1
#define BPF_PSEUDO_CALL 1
#define BPF_ANY 0
@@ -177,11 +178,12 @@
#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)
#define BPF_F_STACK_BUILD_ID (1U << 5)
+#define BPF_F_ZERO_SEED (1U << 6)
+#define BPF_F_QUERY_EFFECTIVE (1U << 0)
enum bpf_stack_build_id_status {
BPF_STACK_BUILD_ID_EMPTY = 0,
BPF_STACK_BUILD_ID_VALID = 1,
@@ -233,6 +235,13 @@
char prog_name[BPF_OBJ_NAME_LEN];
__u32 prog_ifindex;
__u32 expected_attach_type;
+ __u32 prog_btf_fd;
+ __u32 func_info_rec_size;
+ __aligned_u64 func_info;
+ __u32 func_info_cnt;
+ __u32 line_info_rec_size;
+ __aligned_u64 line_info;
+ __u32 line_info_cnt;
};
struct {
__aligned_u64 pathname;
@@ -301,7 +310,7 @@
__u64 probe_addr;
} task_fd_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), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data),
+#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), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data), FN(msg_pop_data), FN(rc_pointer_rel),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -368,6 +377,8 @@
__u32 local_port;
__u32 data_meta;
__bpf_md_ptr(struct bpf_flow_keys *, flow_keys);
+ __u64 tstamp;
+ __u32 wire_len;
};
struct bpf_tunnel_key {
__u32 tunnel_id;
@@ -451,6 +462,7 @@
__u32 local_ip6[4];
__u32 remote_port;
__u32 local_port;
+ __u32 size;
};
struct sk_reuseport_md {
__bpf_md_ptr(void *, data);
@@ -483,6 +495,18 @@
__u32 nr_jited_func_lens;
__aligned_u64 jited_ksyms;
__aligned_u64 jited_func_lens;
+ __u32 btf_id;
+ __u32 func_info_rec_size;
+ __aligned_u64 func_info;
+ __u32 nr_func_info;
+ __u32 nr_line_info;
+ __aligned_u64 line_info;
+ __aligned_u64 jited_line_info;
+ __u32 nr_jited_line_info;
+ __u32 line_info_rec_size;
+ __u32 jited_line_info_rec_size;
+ __u32 nr_prog_tags;
+ __aligned_u64 prog_tags;
} __attribute__((aligned(8)));
struct bpf_map_info {
__u32 type;
@@ -678,4 +702,16 @@
};
};
};
+struct bpf_func_info {
+ __u32 insn_off;
+ __u32 type_id;
+};
+#define BPF_LINE_INFO_LINE_NUM(line_col) ((line_col) >> 10)
+#define BPF_LINE_INFO_LINE_COL(line_col) ((line_col) & 0x3ff)
+struct bpf_line_info {
+ __u32 insn_off;
+ __u32 file_name_off;
+ __u32 line_off;
+ __u32 line_col;
+};
#endif
diff --git a/libc/kernel/uapi/linux/btf.h b/libc/kernel/uapi/linux/btf.h
index 33dde5a..6e13631 100644
--- a/libc/kernel/uapi/linux/btf.h
+++ b/libc/kernel/uapi/linux/btf.h
@@ -44,6 +44,7 @@
};
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
+#define BTF_INFO_KFLAG(info) ((info) >> 31)
#define BTF_KIND_UNKN 0
#define BTF_KIND_INT 1
#define BTF_KIND_PTR 2
@@ -56,8 +57,10 @@
#define BTF_KIND_VOLATILE 9
#define BTF_KIND_CONST 10
#define BTF_KIND_RESTRICT 11
-#define BTF_KIND_MAX 11
-#define NR_BTF_KINDS 12
+#define BTF_KIND_FUNC 12
+#define BTF_KIND_FUNC_PROTO 13
+#define BTF_KIND_MAX 13
+#define NR_BTF_KINDS 14
#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
@@ -78,4 +81,10 @@
__u32 type;
__u32 offset;
};
+#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24)
+#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff)
+struct btf_param {
+ __u32 name_off;
+ __u32 type;
+};
#endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 2bb79d8..0dae543 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -173,6 +173,7 @@
#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
+#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID (1ULL << 10)
struct btrfs_ioctl_feature_flags {
__u64 compat_flags;
__u64 compat_ro_flags;
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index 6a461ec..0618f66 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -166,6 +166,7 @@
#define BTRFS_SUPER_FLAG_METADUMP (1ULL << 33)
#define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34)
#define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35)
+#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36)
struct btrfs_extent_item {
__le64 refs;
__le64 generation;
diff --git a/libc/kernel/uapi/linux/cryptouser.h b/libc/kernel/uapi/linux/cryptouser.h
index 816fb05..b32db64 100644
--- a/libc/kernel/uapi/linux/cryptouser.h
+++ b/libc/kernel/uapi/linux/cryptouser.h
@@ -65,45 +65,62 @@
__u32 cru_refcnt;
__u32 cru_flags;
};
-struct crypto_stat {
+struct crypto_stat_aead {
char type[CRYPTO_MAX_NAME];
- union {
- __u32 stat_encrypt_cnt;
- __u32 stat_compress_cnt;
- __u32 stat_generate_cnt;
- __u32 stat_hash_cnt;
- __u32 stat_setsecret_cnt;
- };
- union {
- __u64 stat_encrypt_tlen;
- __u64 stat_compress_tlen;
- __u64 stat_generate_tlen;
- __u64 stat_hash_tlen;
- };
- union {
- __u32 stat_akcipher_err_cnt;
- __u32 stat_cipher_err_cnt;
- __u32 stat_compress_err_cnt;
- __u32 stat_aead_err_cnt;
- __u32 stat_hash_err_cnt;
- __u32 stat_rng_err_cnt;
- __u32 stat_kpp_err_cnt;
- };
- union {
- __u32 stat_decrypt_cnt;
- __u32 stat_decompress_cnt;
- __u32 stat_seed_cnt;
- __u32 stat_generate_public_key_cnt;
- };
- union {
- __u64 stat_decrypt_tlen;
- __u64 stat_decompress_tlen;
- };
- union {
- __u32 stat_verify_cnt;
- __u32 stat_compute_shared_secret_cnt;
- };
- __u32 stat_sign_cnt;
+ __u64 stat_encrypt_cnt;
+ __u64 stat_encrypt_tlen;
+ __u64 stat_decrypt_cnt;
+ __u64 stat_decrypt_tlen;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_akcipher {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_encrypt_cnt;
+ __u64 stat_encrypt_tlen;
+ __u64 stat_decrypt_cnt;
+ __u64 stat_decrypt_tlen;
+ __u64 stat_verify_cnt;
+ __u64 stat_sign_cnt;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_cipher {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_encrypt_cnt;
+ __u64 stat_encrypt_tlen;
+ __u64 stat_decrypt_cnt;
+ __u64 stat_decrypt_tlen;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_compress {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_compress_cnt;
+ __u64 stat_compress_tlen;
+ __u64 stat_decompress_cnt;
+ __u64 stat_decompress_tlen;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_hash {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_hash_cnt;
+ __u64 stat_hash_tlen;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_kpp {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_setsecret_cnt;
+ __u64 stat_generate_public_key_cnt;
+ __u64 stat_compute_shared_secret_cnt;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_rng {
+ char type[CRYPTO_MAX_NAME];
+ __u64 stat_generate_cnt;
+ __u64 stat_generate_tlen;
+ __u64 stat_seed_cnt;
+ __u64 stat_err_cnt;
+};
+struct crypto_stat_larval {
+ char type[CRYPTO_MAX_NAME];
};
struct crypto_report_larval {
char type[CRYPTO_MAX_NAME];
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index ead40ad..7c55a0a 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -115,6 +115,10 @@
__DEVLINK_PARAM_CMODE_MAX,
DEVLINK_PARAM_CMODE_MAX = __DEVLINK_PARAM_CMODE_MAX - 1
};
+enum devlink_param_fw_load_policy_value {
+ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER,
+ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH,
+};
enum devlink_attr {
DEVLINK_ATTR_UNSPEC,
DEVLINK_ATTR_BUS_NAME,
diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h
index 5b54e18..99835ae 100644
--- a/libc/kernel/uapi/linux/elf-em.h
+++ b/libc/kernel/uapi/linux/elf-em.h
@@ -45,6 +45,7 @@
#define EM_M32R 88
#define EM_MN10300 89
#define EM_OPENRISC 92
+#define EM_XTENSA 94
#define EM_BLACKFIN 106
#define EM_ALTERA_NIOS2 113
#define EM_TI_C6000 140
@@ -54,6 +55,7 @@
#define EM_TILEGX 191
#define EM_RISCV 243
#define EM_BPF 247
+#define EM_CSKY 252
#define EM_FRV 0x5441
#define EM_ALPHA 0x9026
#define EM_CYGNUS_M32R 0x9041
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 1f69e1b..9845bd3 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -355,10 +355,12 @@
#define NT_ARM_HW_WATCH 0x403
#define NT_ARM_SYSTEM_CALL 0x404
#define NT_ARM_SVE 0x405
+#define NT_ARM_PAC_MASK 0x406
#define NT_ARC_V2 0x600
#define NT_VMCOREDD 0x700
#define NT_MIPS_DSP 0x800
#define NT_MIPS_FP_MODE 0x801
+#define NT_MIPS_MSA 0x802
typedef struct elf32_note {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 00a1871..4c33fde 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -24,9 +24,11 @@
#define FAN_CLOSE_WRITE 0x00000008
#define FAN_CLOSE_NOWRITE 0x00000010
#define FAN_OPEN 0x00000020
+#define FAN_OPEN_EXEC 0x00001000
#define FAN_Q_OVERFLOW 0x00004000
#define FAN_OPEN_PERM 0x00010000
#define FAN_ACCESS_PERM 0x00020000
+#define FAN_OPEN_EXEC_PERM 0x00040000
#define FAN_ONDIR 0x40000000
#define FAN_EVENT_ON_CHILD 0x08000000
#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
diff --git a/libc/kernel/uapi/linux/fb.h b/libc/kernel/uapi/linux/fb.h
index 9f6b139..38da042 100644
--- a/libc/kernel/uapi/linux/fb.h
+++ b/libc/kernel/uapi/linux/fb.h
@@ -320,4 +320,6 @@
struct fbcurpos hot;
struct fb_image image;
};
+#define FB_BACKLIGHT_LEVELS 128
+#define FB_BACKLIGHT_MAX 0xFF
#endif
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 5c237d8..84dc010 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -21,6 +21,7 @@
#include <linux/limits.h>
#include <linux/ioctl.h>
#include <linux/types.h>
+#include <linux/mount.h>
#undef NR_OPEN
#define INR_OPEN_CUR 1024
#define INR_OPEN_MAX 4096
@@ -74,40 +75,6 @@
long dummy[5];
};
#define NR_FILE 8192
-#define MS_RDONLY 1
-#define MS_NOSUID 2
-#define MS_NODEV 4
-#define MS_NOEXEC 8
-#define MS_SYNCHRONOUS 16
-#define MS_REMOUNT 32
-#define MS_MANDLOCK 64
-#define MS_DIRSYNC 128
-#define MS_NOATIME 1024
-#define MS_NODIRATIME 2048
-#define MS_BIND 4096
-#define MS_MOVE 8192
-#define MS_REC 16384
-#define MS_VERBOSE 32768
-#define MS_SILENT 32768
-#define MS_POSIXACL (1 << 16)
-#define MS_UNBINDABLE (1 << 17)
-#define MS_PRIVATE (1 << 18)
-#define MS_SLAVE (1 << 19)
-#define MS_SHARED (1 << 20)
-#define MS_RELATIME (1 << 21)
-#define MS_KERNMOUNT (1 << 22)
-#define MS_I_VERSION (1 << 23)
-#define MS_STRICTATIME (1 << 24)
-#define MS_LAZYTIME (1 << 25)
-#define MS_SUBMOUNT (1 << 26)
-#define MS_NOREMOTELOCK (1 << 27)
-#define MS_NOSEC (1 << 28)
-#define MS_BORN (1 << 29)
-#define MS_ACTIVE (1 << 30)
-#define MS_NOUSER (1 << 31)
-#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME)
-#define MS_MGC_VAL 0xC0ED0000
-#define MS_MGC_MSK 0xffff0000
struct fsxattr {
__u32 fsx_xflags;
__u32 fsx_extsize;
@@ -190,7 +157,8 @@
#define FS_POLICY_FLAGS_PAD_16 0x02
#define FS_POLICY_FLAGS_PAD_32 0x03
#define FS_POLICY_FLAGS_PAD_MASK 0x03
-#define FS_POLICY_FLAGS_VALID 0x03
+#define FS_POLICY_FLAG_DIRECT_KEY 0x04
+#define FS_POLICY_FLAGS_VALID 0x07
#define FS_ENCRYPTION_MODE_INVALID 0
#define FS_ENCRYPTION_MODE_AES_256_XTS 1
#define FS_ENCRYPTION_MODE_AES_256_GCM 2
@@ -200,6 +168,7 @@
#define FS_ENCRYPTION_MODE_AES_128_CTS 6
#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7
#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8
+#define FS_ENCRYPTION_MODE_ADIANTUM 9
struct fscrypt_policy {
__u8 version;
__u8 contents_encryption_mode;
diff --git a/libc/kernel/uapi/linux/hash_info.h b/libc/kernel/uapi/linux/hash_info.h
index 898e46f..824b71a 100644
--- a/libc/kernel/uapi/linux/hash_info.h
+++ b/libc/kernel/uapi/linux/hash_info.h
@@ -37,6 +37,8 @@
HASH_ALGO_TGR_160,
HASH_ALGO_TGR_192,
HASH_ALGO_SM3_256,
+ HASH_ALGO_STREEBOG_256,
+ HASH_ALGO_STREEBOG_512,
HASH_ALGO__LAST
};
#endif
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 7e6a72f..31683c1 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -237,4 +237,12 @@
__u64 mcast_bytes[BR_MCAST_DIR_SIZE];
__u64 mcast_packets[BR_MCAST_DIR_SIZE];
};
+enum br_boolopt_id {
+ BR_BOOLOPT_NO_LL_LEARN,
+ BR_BOOLOPT_MAX
+};
+struct br_boolopt_multi {
+ __u32 optval;
+ __u32 optmask;
+};
#endif
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 2c80d3d..416c48b 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -221,6 +221,7 @@
IFLA_BR_MCAST_IGMP_VERSION,
IFLA_BR_MCAST_MLD_VERSION,
IFLA_BR_VLAN_STATS_PER_PORT,
+ IFLA_BR_MULTI_BOOLOPT,
__IFLA_BR_MAX,
};
#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
@@ -426,6 +427,7 @@
IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE,
IFLA_VXLAN_TTL_INHERIT,
+ IFLA_VXLAN_DF,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
@@ -433,6 +435,13 @@
__be16 low;
__be16 high;
};
+enum ifla_vxlan_df {
+ VXLAN_DF_UNSET = 0,
+ VXLAN_DF_SET,
+ VXLAN_DF_INHERIT,
+ __VXLAN_DF_END,
+ VXLAN_DF_MAX = __VXLAN_DF_END - 1,
+};
enum {
IFLA_GENEVE_UNSPEC,
IFLA_GENEVE_ID,
@@ -447,9 +456,17 @@
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
IFLA_GENEVE_LABEL,
IFLA_GENEVE_TTL_INHERIT,
+ IFLA_GENEVE_DF,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+enum ifla_geneve_df {
+ GENEVE_DF_UNSET = 0,
+ GENEVE_DF_SET,
+ GENEVE_DF_INHERIT,
+ __GENEVE_DF_END,
+ GENEVE_DF_MAX = __GENEVE_DF_END - 1,
+};
enum {
IFLA_PPP_UNSPEC,
IFLA_PPP_DEV_FD,
diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h
index 6a3c75e..cb2d2d2 100644
--- a/libc/kernel/uapi/linux/if_tun.h
+++ b/libc/kernel/uapi/linux/if_tun.h
@@ -51,6 +51,7 @@
#define TUNGETVNETBE _IOR('T', 223, int)
#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
#define TUNSETFILTEREBPF _IOR('T', 225, int)
+#define TUNSETCARRIER _IOW('T', 226, int)
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NAPI 0x0010
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 78bd72a..9ed00b4 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -201,7 +201,7 @@
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(a) IN_CLASSD(a)
#define IN_MULTICAST_NET 0xe0000000
-#define IN_BADCLASS(a) (((long int) (a)) == (long int)0xffffffff)
+#define IN_BADCLASS(a) (((long int) (a)) == (long int) 0xffffffff)
#define IN_EXPERIMENTAL(a) IN_BADCLASS((a))
#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
#define IN_CLASSE_NET 0xffffffff
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 11e6d5b..1ca3cb0 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -623,6 +623,8 @@
#define REL_WHEEL 0x08
#define REL_MISC 0x09
#define REL_RESERVED 0x0a
+#define REL_WHEEL_HI_RES 0x0b
+#define REL_HWHEEL_HI_RES 0x0c
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX + 1)
#define ABS_X 0x00
diff --git a/libc/kernel/uapi/linux/input.h b/libc/kernel/uapi/linux/input.h
index 0a4b563..f138f64 100644
--- a/libc/kernel/uapi/linux/input.h
+++ b/libc/kernel/uapi/linux/input.h
@@ -24,13 +24,17 @@
#include <linux/types.h>
#include "input-event-codes.h"
struct input_event {
-#if (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL)
+#if __BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)
struct timeval time;
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
#else
__kernel_ulong_t __sec;
+#if defined(__sparc__) && defined(__arch64__)
+ unsigned int __usec;
+#else
__kernel_ulong_t __usec;
+#endif
#define input_event_sec __sec
#define input_event_usec __usec
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 525f672..5e20606 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -261,6 +261,20 @@
__u32 n_devices;
__u32 n_success;
};
+struct kfd_ioctl_get_dmabuf_info_args {
+ __u64 size;
+ __u64 metadata_ptr;
+ __u32 metadata_size;
+ __u32 gpu_id;
+ __u32 flags;
+ __u32 dmabuf_fd;
+};
+struct kfd_ioctl_import_dmabuf_args {
+ __u64 va_addr;
+ __u64 handle;
+ __u32 gpu_id;
+ __u32 dmabuf_fd;
+};
#define AMDKFD_IOCTL_BASE 'K'
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
#define AMDKFD_IOR(nr,type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
@@ -293,6 +307,8 @@
#define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU AMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args)
#define AMDKFD_IOC_SET_CU_MASK AMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args)
#define AMDKFD_IOC_GET_QUEUE_WAVE_STATE AMDKFD_IOWR(0x1B, struct kfd_ioctl_get_queue_wave_state_args)
+#define AMDKFD_IOC_GET_DMABUF_INFO AMDKFD_IOWR(0x1C, struct kfd_ioctl_get_dmabuf_info_args)
+#define AMDKFD_IOC_IMPORT_DMABUF AMDKFD_IOWR(0x1D, struct kfd_ioctl_import_dmabuf_args)
#define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x1C
+#define AMDKFD_COMMAND_END 0x1E
#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index b70bcd9..8cfa34d 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -367,6 +367,15 @@
__u64 padding2;
};
};
+struct kvm_clear_dirty_log {
+ __u32 slot;
+ __u32 num_pages;
+ __u64 first_page;
+ union {
+ void __user * dirty_bitmap;
+ __u64 padding2;
+ };
+};
struct kvm_signal_mask {
__u32 len;
__u8 sigset[0];
@@ -759,6 +768,8 @@
#define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
#define KVM_CAP_EXCEPTION_PAYLOAD 164
#define KVM_CAP_ARM_VM_IPA_SIZE 165
+#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166
+#define KVM_CAP_HYPERV_CPUID 167
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1070,6 +1081,8 @@
#define KVM_HYPERV_EVENTFD _IOW(KVMIO, 0xbd, struct kvm_hyperv_eventfd)
#define KVM_GET_NESTED_STATE _IOWR(KVMIO, 0xbe, struct kvm_nested_state)
#define KVM_SET_NESTED_STATE _IOW(KVMIO, 0xbf, struct kvm_nested_state)
+#define KVM_CLEAR_DIRTY_LOG _IOWR(KVMIO, 0xc0, struct kvm_clear_dirty_log)
+#define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2)
enum sev_cmd_id {
KVM_SEV_INIT = 0,
KVM_SEV_ES_INIT,
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index bf57a58..f3b337e 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -78,6 +78,7 @@
#define DAXFS_MAGIC 0x64646178
#define BINFMTFS_MAGIC 0x42494e4d
#define DEVPTS_SUPER_MAGIC 0x1cd1
+#define BINDERFS_SUPER_MAGIC 0x6c6f6f70
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define PIPEFS_MAGIC 0x50495045
#define PROC_SUPER_MAGIC 0x9fa0
diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h
new file mode 100644
index 0000000..54a4719
--- /dev/null
+++ b/libc/kernel/uapi/linux/mount.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_MOUNT_H
+#define _UAPI_LINUX_MOUNT_H
+#define MS_RDONLY 1
+#define MS_NOSUID 2
+#define MS_NODEV 4
+#define MS_NOEXEC 8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT 32
+#define MS_MANDLOCK 64
+#define MS_DIRSYNC 128
+#define MS_NOATIME 1024
+#define MS_NODIRATIME 2048
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_VERBOSE 32768
+#define MS_SILENT 32768
+#define MS_POSIXACL (1 << 16)
+#define MS_UNBINDABLE (1 << 17)
+#define MS_PRIVATE (1 << 18)
+#define MS_SLAVE (1 << 19)
+#define MS_SHARED (1 << 20)
+#define MS_RELATIME (1 << 21)
+#define MS_KERNMOUNT (1 << 22)
+#define MS_I_VERSION (1 << 23)
+#define MS_STRICTATIME (1 << 24)
+#define MS_LAZYTIME (1 << 25)
+#define MS_SUBMOUNT (1 << 26)
+#define MS_NOREMOTELOCK (1 << 27)
+#define MS_NOSEC (1 << 28)
+#define MS_BORN (1 << 29)
+#define MS_ACTIVE (1 << 30)
+#define MS_NOUSER (1 << 31)
+#define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME)
+#define MS_MGC_VAL 0xC0ED0000
+#define MS_MGC_MSK 0xffff0000
+#endif
diff --git a/libc/kernel/uapi/linux/msdos_fs.h b/libc/kernel/uapi/linux/msdos_fs.h
index 60ee22a..4b777db 100644
--- a/libc/kernel/uapi/linux/msdos_fs.h
+++ b/libc/kernel/uapi/linux/msdos_fs.h
@@ -57,12 +57,10 @@
#define MSDOS_SLOTS 21
#define MSDOS_DOT ". "
#define MSDOS_DOTDOT ".. "
-#define FAT_FIRST_ENT(s,x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
#define FAT_START_ENT 2
#define MAX_FAT12 0xFF4
#define MAX_FAT16 0xFFF4
#define MAX_FAT32 0x0FFFFFF6
-#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
#define BAD_FAT12 0xFF7
#define BAD_FAT16 0xFFF7
#define BAD_FAT32 0x0FFFFFF7
@@ -108,7 +106,7 @@
__u8 state;
__u8 signature;
__u8 vol_id[4];
- __u8 vol_label[11];
+ __u8 vol_label[MSDOS_NAME];
__u8 fs_type[8];
} fat16;
struct {
@@ -123,7 +121,7 @@
__u8 state;
__u8 signature;
__u8 vol_id[4];
- __u8 vol_label[11];
+ __u8 vol_label[MSDOS_NAME];
__u8 fs_type[8];
} fat32;
};
diff --git a/libc/kernel/uapi/linux/ncsi.h b/libc/kernel/uapi/linux/ncsi.h
index 23cdf1b..6334a8a 100644
--- a/libc/kernel/uapi/linux/ncsi.h
+++ b/libc/kernel/uapi/linux/ncsi.h
@@ -24,6 +24,8 @@
NCSI_CMD_SET_INTERFACE,
NCSI_CMD_CLEAR_INTERFACE,
NCSI_CMD_SEND_CMD,
+ NCSI_CMD_SET_PACKAGE_MASK,
+ NCSI_CMD_SET_CHANNEL_MASK,
__NCSI_CMD_AFTER_LAST,
NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
};
@@ -34,6 +36,9 @@
NCSI_ATTR_PACKAGE_ID,
NCSI_ATTR_CHANNEL_ID,
NCSI_ATTR_DATA,
+ NCSI_ATTR_MULTI_FLAG,
+ NCSI_ATTR_PACKAGE_MASK,
+ NCSI_ATTR_CHANNEL_MASK,
__NCSI_ATTR_AFTER_LAST,
NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
};
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index 6329211..4ce4736 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -42,6 +42,7 @@
NDA_MASTER,
NDA_LINK_NETNSID,
NDA_SRC_VNI,
+ NDA_PROTOCOL,
__NDA_MAX
};
#define NDA_MAX (__NDA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/net_namespace.h b/libc/kernel/uapi/linux/net_namespace.h
index b1d96f6..a54c9e1 100644
--- a/libc/kernel/uapi/linux/net_namespace.h
+++ b/libc/kernel/uapi/linux/net_namespace.h
@@ -24,6 +24,8 @@
NETNSA_NSID,
NETNSA_PID,
NETNSA_FD,
+ NETNSA_TARGET_NSID,
+ NETNSA_CURRENT_NSID,
__NETNSA_MAX,
};
#define NETNSA_MAX (__NETNSA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netfilter.h b/libc/kernel/uapi/linux/netfilter.h
index 5538869..345b197 100644
--- a/libc/kernel/uapi/linux/netfilter.h
+++ b/libc/kernel/uapi/linux/netfilter.h
@@ -35,8 +35,6 @@
#define NF_VERDICT_QBITS 16
#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
#define NF_DROP_ERR(x) (((- x) << 16) | NF_DROP)
-#define NFC_UNKNOWN 0x4000
-#define NFC_ALTERED 0x8000
#define NF_VERDICT_BITS 16
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
diff --git a/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h b/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
index 17107b7..2c5aeeb 100644
--- a/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
+++ b/libc/kernel/uapi/linux/netfilter/ipset/ip_set.h
@@ -19,7 +19,8 @@
#ifndef _UAPI_IP_SET_H
#define _UAPI_IP_SET_H
#include <linux/types.h>
-#define IPSET_PROTOCOL 6
+#define IPSET_PROTOCOL 7
+#define IPSET_PROTOCOL_MIN 6
#define IPSET_MAXNAMELEN 32
#define IPSET_MAX_COMMENT_SIZE 255
enum ipset_cmd {
@@ -37,6 +38,8 @@
IPSET_CMD_TEST,
IPSET_CMD_HEADER,
IPSET_CMD_TYPE,
+ IPSET_CMD_GET_BYNAME,
+ IPSET_CMD_GET_BYINDEX,
IPSET_MSG_MAX,
IPSET_CMD_RESTORE = IPSET_MSG_MAX,
IPSET_CMD_HELP,
@@ -59,6 +62,7 @@
IPSET_ATTR_LINENO,
IPSET_ATTR_PROTOCOL_MIN,
IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN,
+ IPSET_ATTR_INDEX,
__IPSET_ATTR_CMD_MAX,
};
#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netfilter_decnet.h b/libc/kernel/uapi/linux/netfilter_decnet.h
index a9dcdd3..c9c16ca 100644
--- a/libc/kernel/uapi/linux/netfilter_decnet.h
+++ b/libc/kernel/uapi/linux/netfilter_decnet.h
@@ -20,10 +20,6 @@
#define __LINUX_DECNET_NETFILTER_H
#include <linux/netfilter.h>
#include <limits.h>
-#define NFC_DN_SRC 0x0001
-#define NFC_DN_DST 0x0002
-#define NFC_DN_IF_IN 0x0004
-#define NFC_DN_IF_OUT 0x0008
#define NF_DN_NUMHOOKS 7
#define NF_DN_PRE_ROUTING 0
#define NF_DN_LOCAL_IN 1
diff --git a/libc/kernel/uapi/linux/netfilter_ipv4.h b/libc/kernel/uapi/linux/netfilter_ipv4.h
index 7eed768..bb2a1d9 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv4.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv4.h
@@ -20,18 +20,6 @@
#define _UAPI__LINUX_IP_NETFILTER_H
#include <linux/netfilter.h>
#include <limits.h>
-#define NFC_IP_SRC 0x0001
-#define NFC_IP_DST 0x0002
-#define NFC_IP_IF_IN 0x0004
-#define NFC_IP_IF_OUT 0x0008
-#define NFC_IP_TOS 0x0010
-#define NFC_IP_PROTO 0x0020
-#define NFC_IP_OPTIONS 0x0040
-#define NFC_IP_FRAG 0x0080
-#define NFC_IP_TCPFLAGS 0x0100
-#define NFC_IP_SRC_PT 0x0200
-#define NFC_IP_DST_PT 0x0400
-#define NFC_IP_PROTO_UNKNOWN 0x2000
#define NF_IP_PRE_ROUTING 0
#define NF_IP_LOCAL_IN 1
#define NF_IP_FORWARD 2
diff --git a/libc/kernel/uapi/linux/netfilter_ipv6.h b/libc/kernel/uapi/linux/netfilter_ipv6.h
index 2054532..f454eb6 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv6.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv6.h
@@ -20,18 +20,6 @@
#define _UAPI__LINUX_IP6_NETFILTER_H
#include <linux/netfilter.h>
#include <limits.h>
-#define NFC_IP6_SRC 0x0001
-#define NFC_IP6_DST 0x0002
-#define NFC_IP6_IF_IN 0x0004
-#define NFC_IP6_IF_OUT 0x0008
-#define NFC_IP6_TOS 0x0010
-#define NFC_IP6_PROTO 0x0020
-#define NFC_IP6_OPTIONS 0x0040
-#define NFC_IP6_FRAG 0x0080
-#define NFC_IP6_TCPFLAGS 0x0100
-#define NFC_IP6_SRC_PT 0x0200
-#define NFC_IP6_DST_PT 0x0400
-#define NFC_IP6_PROTO_UNKNOWN 0x2000
#define NF_IP6_PRE_ROUTING 0
#define NF_IP6_LOCAL_IN 1
#define NF_IP6_FORWARD 2
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 471e65f..29a7b66 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -164,6 +164,10 @@
NL80211_CMD_STA_OPMODE_CHANGED,
NL80211_CMD_CONTROL_PORT_FRAME,
NL80211_CMD_GET_FTM_RESPONDER_STATS,
+ NL80211_CMD_PEER_MEASUREMENT_START,
+ NL80211_CMD_PEER_MEASUREMENT_RESULT,
+ NL80211_CMD_PEER_MEASUREMENT_COMPLETE,
+ NL80211_CMD_NOTIFY_RADAR,
__NL80211_CMD_AFTER_LAST,
NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};
@@ -452,6 +456,8 @@
NL80211_ATTR_HE_CAPABILITY,
NL80211_ATTR_FTM_RESPONDER,
NL80211_ATTR_FTM_RESPONDER_STATS,
+ NL80211_ATTR_TIMEOUT,
+ NL80211_ATTR_PEER_MEASUREMENTS,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -621,6 +627,7 @@
NL80211_STA_INFO_ACK_SIGNAL_AVG,
NL80211_STA_INFO_RX_MPDUS,
NL80211_STA_INFO_FCS_ERROR_COUNT,
+ NL80211_STA_INFO_CONNECTED_TO_GATE,
__NL80211_STA_INFO_AFTER_LAST,
NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
};
@@ -878,6 +885,7 @@
NL80211_MESHCONF_POWER_MODE,
NL80211_MESHCONF_AWAKE_WINDOW,
NL80211_MESHCONF_PLINK_TIMEOUT,
+ NL80211_MESHCONF_CONNECTED_TO_GATE,
__NL80211_MESHCONF_ATTR_AFTER_LAST,
NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
};
@@ -1480,4 +1488,122 @@
__NL80211_FTM_STATS_AFTER_LAST,
NL80211_FTM_STATS_MAX = __NL80211_FTM_STATS_AFTER_LAST - 1
};
+enum nl80211_preamble {
+ NL80211_PREAMBLE_LEGACY,
+ NL80211_PREAMBLE_HT,
+ NL80211_PREAMBLE_VHT,
+ NL80211_PREAMBLE_DMG,
+};
+enum nl80211_peer_measurement_type {
+ NL80211_PMSR_TYPE_INVALID,
+ NL80211_PMSR_TYPE_FTM,
+ NUM_NL80211_PMSR_TYPES,
+ NL80211_PMSR_TYPE_MAX = NUM_NL80211_PMSR_TYPES - 1
+};
+enum nl80211_peer_measurement_status {
+ NL80211_PMSR_STATUS_SUCCESS,
+ NL80211_PMSR_STATUS_REFUSED,
+ NL80211_PMSR_STATUS_TIMEOUT,
+ NL80211_PMSR_STATUS_FAILURE,
+};
+enum nl80211_peer_measurement_req {
+ __NL80211_PMSR_REQ_ATTR_INVALID,
+ NL80211_PMSR_REQ_ATTR_DATA,
+ NL80211_PMSR_REQ_ATTR_GET_AP_TSF,
+ NUM_NL80211_PMSR_REQ_ATTRS,
+ NL80211_PMSR_REQ_ATTR_MAX = NUM_NL80211_PMSR_REQ_ATTRS - 1
+};
+enum nl80211_peer_measurement_resp {
+ __NL80211_PMSR_RESP_ATTR_INVALID,
+ NL80211_PMSR_RESP_ATTR_DATA,
+ NL80211_PMSR_RESP_ATTR_STATUS,
+ NL80211_PMSR_RESP_ATTR_HOST_TIME,
+ NL80211_PMSR_RESP_ATTR_AP_TSF,
+ NL80211_PMSR_RESP_ATTR_FINAL,
+ NL80211_PMSR_RESP_ATTR_PAD,
+ NUM_NL80211_PMSR_RESP_ATTRS,
+ NL80211_PMSR_RESP_ATTR_MAX = NUM_NL80211_PMSR_RESP_ATTRS - 1
+};
+enum nl80211_peer_measurement_peer_attrs {
+ __NL80211_PMSR_PEER_ATTR_INVALID,
+ NL80211_PMSR_PEER_ATTR_ADDR,
+ NL80211_PMSR_PEER_ATTR_CHAN,
+ NL80211_PMSR_PEER_ATTR_REQ,
+ NL80211_PMSR_PEER_ATTR_RESP,
+ NUM_NL80211_PMSR_PEER_ATTRS,
+ NL80211_PMSR_PEER_ATTR_MAX = NUM_NL80211_PMSR_PEER_ATTRS - 1,
+};
+enum nl80211_peer_measurement_attrs {
+ __NL80211_PMSR_ATTR_INVALID,
+ NL80211_PMSR_ATTR_MAX_PEERS,
+ NL80211_PMSR_ATTR_REPORT_AP_TSF,
+ NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR,
+ NL80211_PMSR_ATTR_TYPE_CAPA,
+ NL80211_PMSR_ATTR_PEERS,
+ NUM_NL80211_PMSR_ATTR,
+ NL80211_PMSR_ATTR_MAX = NUM_NL80211_PMSR_ATTR - 1
+};
+enum nl80211_peer_measurement_ftm_capa {
+ __NL80211_PMSR_FTM_CAPA_ATTR_INVALID,
+ NL80211_PMSR_FTM_CAPA_ATTR_ASAP,
+ NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP,
+ NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI,
+ NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC,
+ NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
+ NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
+ NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
+ NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
+ NUM_NL80211_PMSR_FTM_CAPA_ATTR,
+ NL80211_PMSR_FTM_CAPA_ATTR_MAX = NUM_NL80211_PMSR_FTM_CAPA_ATTR - 1
+};
+enum nl80211_peer_measurement_ftm_req {
+ __NL80211_PMSR_FTM_REQ_ATTR_INVALID,
+ NL80211_PMSR_FTM_REQ_ATTR_ASAP,
+ NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE,
+ NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP,
+ NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD,
+ NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION,
+ NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST,
+ NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES,
+ NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI,
+ NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
+ NUM_NL80211_PMSR_FTM_REQ_ATTR,
+ NL80211_PMSR_FTM_REQ_ATTR_MAX = NUM_NL80211_PMSR_FTM_REQ_ATTR - 1
+};
+enum nl80211_peer_measurement_ftm_failure_reasons {
+ NL80211_PMSR_FTM_FAILURE_UNSPECIFIED,
+ NL80211_PMSR_FTM_FAILURE_NO_RESPONSE,
+ NL80211_PMSR_FTM_FAILURE_REJECTED,
+ NL80211_PMSR_FTM_FAILURE_WRONG_CHANNEL,
+ NL80211_PMSR_FTM_FAILURE_PEER_NOT_CAPABLE,
+ NL80211_PMSR_FTM_FAILURE_INVALID_TIMESTAMP,
+ NL80211_PMSR_FTM_FAILURE_PEER_BUSY,
+ NL80211_PMSR_FTM_FAILURE_BAD_CHANGED_PARAMS,
+};
+enum nl80211_peer_measurement_ftm_resp {
+ __NL80211_PMSR_FTM_RESP_ATTR_INVALID,
+ NL80211_PMSR_FTM_RESP_ATTR_FAIL_REASON,
+ NL80211_PMSR_FTM_RESP_ATTR_BURST_INDEX,
+ NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS,
+ NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES,
+ NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME,
+ NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP,
+ NL80211_PMSR_FTM_RESP_ATTR_BURST_DURATION,
+ NL80211_PMSR_FTM_RESP_ATTR_FTMS_PER_BURST,
+ NL80211_PMSR_FTM_RESP_ATTR_RSSI_AVG,
+ NL80211_PMSR_FTM_RESP_ATTR_RSSI_SPREAD,
+ NL80211_PMSR_FTM_RESP_ATTR_TX_RATE,
+ NL80211_PMSR_FTM_RESP_ATTR_RX_RATE,
+ NL80211_PMSR_FTM_RESP_ATTR_RTT_AVG,
+ NL80211_PMSR_FTM_RESP_ATTR_RTT_VARIANCE,
+ NL80211_PMSR_FTM_RESP_ATTR_RTT_SPREAD,
+ NL80211_PMSR_FTM_RESP_ATTR_DIST_AVG,
+ NL80211_PMSR_FTM_RESP_ATTR_DIST_VARIANCE,
+ NL80211_PMSR_FTM_RESP_ATTR_DIST_SPREAD,
+ NL80211_PMSR_FTM_RESP_ATTR_LCI,
+ NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC,
+ NL80211_PMSR_FTM_RESP_ATTR_PAD,
+ NUM_NL80211_PMSR_FTM_RESP_ATTR,
+ NL80211_PMSR_FTM_RESP_ATTR_MAX = NUM_NL80211_PMSR_FTM_RESP_ATTR - 1
+};
#endif
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index ac80a0a..2018f0b 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -389,6 +389,10 @@
TCA_FLOWER_KEY_ENC_OPTS,
TCA_FLOWER_KEY_ENC_OPTS_MASK,
TCA_FLOWER_IN_HW_COUNT,
+ TCA_FLOWER_KEY_PORT_SRC_MIN,
+ TCA_FLOWER_KEY_PORT_SRC_MAX,
+ TCA_FLOWER_KEY_PORT_DST_MIN,
+ TCA_FLOWER_KEY_PORT_DST_MAX,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
@@ -410,6 +414,7 @@
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
};
+#define TCA_FLOWER_MASK_FLAGS_RANGE (1 << 0)
enum {
TCA_MATCHALL_UNSPEC,
TCA_MATCHALL_CLASSID,
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index e7d4942..dc0cd2f 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -195,9 +195,33 @@
TCA_GRED_DPS,
TCA_GRED_MAX_P,
TCA_GRED_LIMIT,
+ TCA_GRED_VQ_LIST,
__TCA_GRED_MAX,
};
#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
+enum {
+ TCA_GRED_VQ_ENTRY_UNSPEC,
+ TCA_GRED_VQ_ENTRY,
+ __TCA_GRED_VQ_ENTRY_MAX,
+};
+#define TCA_GRED_VQ_ENTRY_MAX (__TCA_GRED_VQ_ENTRY_MAX - 1)
+enum {
+ TCA_GRED_VQ_UNSPEC,
+ TCA_GRED_VQ_PAD,
+ TCA_GRED_VQ_DP,
+ TCA_GRED_VQ_STAT_BYTES,
+ TCA_GRED_VQ_STAT_PACKETS,
+ TCA_GRED_VQ_STAT_BACKLOG,
+ TCA_GRED_VQ_STAT_PROB_DROP,
+ TCA_GRED_VQ_STAT_PROB_MARK,
+ TCA_GRED_VQ_STAT_FORCED_DROP,
+ TCA_GRED_VQ_STAT_FORCED_MARK,
+ TCA_GRED_VQ_STAT_PDROP,
+ TCA_GRED_VQ_STAT_OTHER,
+ TCA_GRED_VQ_FLAGS,
+ __TCA_GRED_VQ_MAX
+};
+#define TCA_GRED_VQ_MAX (__TCA_GRED_VQ_MAX - 1)
struct tc_gred_qopt {
__u32 limit;
__u32 qth_min;
@@ -639,6 +663,7 @@
TCA_FQ_FLOW_REFILL_DELAY,
TCA_FQ_ORPHAN_MASK,
TCA_FQ_LOW_RATE_THRESHOLD,
+ TCA_FQ_CE_THRESHOLD,
__TCA_FQ_MAX
};
#define TCA_FQ_MAX (__TCA_FQ_MAX - 1)
@@ -655,6 +680,7 @@
__u32 inactive_flows;
__u32 throttled_flows;
__u32 unthrottle_latency_ns;
+ __u64 ce_mark;
};
enum {
TCA_HHF_UNSPEC,
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 44a088d..5031e8d 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -143,4 +143,10 @@
#define PR_SPEC_ENABLE (1UL << 1)
#define PR_SPEC_DISABLE (1UL << 2)
#define PR_SPEC_FORCE_DISABLE (1UL << 3)
+#define PR_PAC_RESET_KEYS 54
+#define PR_PAC_APIAKEY (1UL << 0)
+#define PR_PAC_APIBKEY (1UL << 1)
+#define PR_PAC_APDAKEY (1UL << 2)
+#define PR_PAC_APDBKEY (1UL << 3)
+#define PR_PAC_APGAKEY (1UL << 4)
#endif
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index f32dcf0..bef3fe2 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -56,6 +56,11 @@
unsigned int rsv[3];
struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
};
+struct ptp_sys_offset_extended {
+ unsigned int n_samples;
+ unsigned int rsv[3];
+ struct ptp_clock_time ts[PTP_MAX_SAMPLES][3];
+};
struct ptp_sys_offset_precise {
struct ptp_clock_time device;
struct ptp_clock_time sys_realtime;
@@ -84,6 +89,7 @@
#define PTP_PIN_GETFUNC _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
#define PTP_PIN_SETFUNC _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
#define PTP_SYS_OFFSET_PRECISE _IOWR(PTP_CLK_MAGIC, 8, struct ptp_sys_offset_precise)
+#define PTP_SYS_OFFSET_EXTENDED _IOWR(PTP_CLK_MAGIC, 9, struct ptp_sys_offset_extended)
struct ptp_extts_event {
struct ptp_clock_time t;
unsigned int index;
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index dc07d78..66fde70 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -83,6 +83,7 @@
#define SCTP_STREAM_SCHEDULER_VALUE 124
#define SCTP_INTERLEAVING_SUPPORTED 125
#define SCTP_SENDMSG_CONNECT 126
+#define SCTP_EVENT 127
#define SCTP_PR_SCTP_NONE 0x0000
#define SCTP_PR_SCTP_TTL 0x0010
#define SCTP_PR_SCTP_RTX 0x0020
@@ -360,6 +361,8 @@
};
enum sctp_sn_type {
SCTP_SN_TYPE_BASE = (1 << 15),
+ SCTP_DATA_IO_EVENT = SCTP_SN_TYPE_BASE,
+#define SCTP_DATA_IO_EVENT SCTP_DATA_IO_EVENT
SCTP_ASSOC_CHANGE,
#define SCTP_ASSOC_CHANGE SCTP_ASSOC_CHANGE
SCTP_PEER_ADDR_CHANGE,
@@ -384,6 +387,8 @@
#define SCTP_ASSOC_RESET_EVENT SCTP_ASSOC_RESET_EVENT
SCTP_STREAM_CHANGE_EVENT,
#define SCTP_STREAM_CHANGE_EVENT SCTP_STREAM_CHANGE_EVENT
+ SCTP_SN_TYPE_MAX = SCTP_STREAM_CHANGE_EVENT,
+#define SCTP_SN_TYPE_MAX SCTP_SN_TYPE_MAX
};
typedef enum sctp_sn_error {
SCTP_FAILED_THRESHOLD,
@@ -655,6 +660,11 @@
uint16_t sas_instrms;
uint16_t sas_outstrms;
};
+struct sctp_event {
+ sctp_assoc_t se_assoc_id;
+ uint16_t se_type;
+ uint8_t se_on;
+};
enum sctp_sched_type {
SCTP_SS_FCFS,
SCTP_SS_DEFAULT = SCTP_SS_FCFS,
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index fe63789..a1e577d 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -26,14 +26,17 @@
#define SECCOMP_SET_MODE_STRICT 0
#define SECCOMP_SET_MODE_FILTER 1
#define SECCOMP_GET_ACTION_AVAIL 2
+#define SECCOMP_GET_NOTIF_SIZES 3
#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
+#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
#define SECCOMP_RET_KILL_PROCESS 0x80000000U
#define SECCOMP_RET_KILL_THREAD 0x00000000U
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
#define SECCOMP_RET_TRAP 0x00030000U
#define SECCOMP_RET_ERRNO 0x00050000U
+#define SECCOMP_RET_USER_NOTIF 0x7fc00000U
#define SECCOMP_RET_TRACE 0x7ff00000U
#define SECCOMP_RET_LOG 0x7ffc0000U
#define SECCOMP_RET_ALLOW 0x7fff0000U
@@ -46,4 +49,29 @@
__u64 instruction_pointer;
__u64 args[6];
};
+struct seccomp_notif_sizes {
+ __u16 seccomp_notif;
+ __u16 seccomp_notif_resp;
+ __u16 seccomp_data;
+};
+struct seccomp_notif {
+ __u64 id;
+ __u32 pid;
+ __u32 flags;
+ struct seccomp_data data;
+};
+struct seccomp_notif_resp {
+ __u64 id;
+ __s64 val;
+ __s32 error;
+ __u32 flags;
+};
+#define SECCOMP_IOC_MAGIC '!'
+#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr)
+#define SECCOMP_IOR(nr,type) _IOR(SECCOMP_IOC_MAGIC, nr, type)
+#define SECCOMP_IOW(nr,type) _IOW(SECCOMP_IOC_MAGIC, nr, type)
+#define SECCOMP_IOWR(nr,type) _IOWR(SECCOMP_IOC_MAGIC, nr, type)
+#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif)
+#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, struct seccomp_notif_resp)
+#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOR(2, __u64)
#endif
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index f0f464b..b9af467 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -134,4 +134,5 @@
#define PORT_PIC32 115
#define PORT_MPS2UART 116
#define PORT_MTK_BTIF 117
+#define PORT_RDA 118
#endif
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index ae24f0f..75dea54 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -210,6 +210,7 @@
LINUX_MIB_TCPREQQFULLDROP,
LINUX_MIB_TCPRETRANSFAIL,
LINUX_MIB_TCPRCVCOALESCE,
+ LINUX_MIB_TCPBACKLOGCOALESCE,
LINUX_MIB_TCPOFOQUEUE,
LINUX_MIB_TCPOFODROP,
LINUX_MIB_TCPOFOMERGE,
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index 24d8362..ae0f44a 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -124,6 +124,7 @@
KERN_NMI_WATCHDOG = 75,
KERN_PANIC_ON_NMI = 76,
KERN_PANIC_ON_WARN = 77,
+ KERN_PANIC_PRINT = 78,
};
enum {
VM_UNUSED1 = 1,
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index d940f0f..ce3d735 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -207,6 +207,7 @@
TCP_NLA_BYTES_RETRANS,
TCP_NLA_DSACK_DUPS,
TCP_NLA_REORD_SEEN,
+ TCP_NLA_SRTT,
};
#define TCP_MD5SIG_MAXKEYLEN 80
#define TCP_MD5SIG_FLAG_PREFIX 1
diff --git a/libc/kernel/uapi/linux/udp.h b/libc/kernel/uapi/linux/udp.h
index 3cd286b..278cf6c 100644
--- a/libc/kernel/uapi/linux/udp.h
+++ b/libc/kernel/uapi/linux/udp.h
@@ -30,6 +30,7 @@
#define UDP_NO_CHECK6_TX 101
#define UDP_NO_CHECK6_RX 102
#define UDP_SEGMENT 103
+#define UDP_GRO 104
#define UDP_ENCAP_ESPINUDP_NON_IKE 1
#define UDP_ENCAP_ESPINUDP 2
#define UDP_ENCAP_L2TPINUDP 3
diff --git a/libc/kernel/uapi/linux/v4l2-common.h b/libc/kernel/uapi/linux/v4l2-common.h
index 779bda9..021be85 100644
--- a/libc/kernel/uapi/linux/v4l2-common.h
+++ b/libc/kernel/uapi/linux/v4l2-common.h
@@ -27,18 +27,9 @@
#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101
#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102
#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103
-#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP
-#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
-#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP
-#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE
-#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS
-#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
#define V4L2_SEL_FLAG_GE (1 << 0)
#define V4L2_SEL_FLAG_LE (1 << 1)
#define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2)
-#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE
-#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE
-#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG
struct v4l2_edid {
__u32 pad;
__u32 start_block;
@@ -46,4 +37,13 @@
__u32 reserved[5];
__u8 * edid;
};
+#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP
+#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
+#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE
+#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE
+#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG
#endif
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 6b1ef1b..43c04d1 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 267265
+#define LINUX_VERSION_CODE 327683
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index d282a52..b947abc 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -114,7 +114,20 @@
#define VFIO_DEVICE_GFX_LINK_STATE_UP 1
#define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
};
+#define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1)
+#define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1)
#define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3
+#define VFIO_REGION_INFO_CAP_NVLINK2_SSATGT 4
+struct vfio_region_info_cap_nvlink2_ssatgt {
+ struct vfio_info_cap_header header;
+ __u64 tgt;
+};
+#define VFIO_REGION_INFO_CAP_NVLINK2_LNKSPD 5
+struct vfio_region_info_cap_nvlink2_lnkspd {
+ struct vfio_info_cap_header header;
+ __u32 link_speed;
+ __u32 __pad;
+};
struct vfio_irq_info {
__u32 argsz;
__u32 flags;
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index e802e02..9e87e6e 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -18,71 +18,9 @@
****************************************************************************/
#ifndef _LINUX_VHOST_H
#define _LINUX_VHOST_H
+#include <linux/vhost_types.h>
#include <linux/types.h>
-#include <linux/compiler.h>
#include <linux/ioctl.h>
-#include <linux/virtio_config.h>
-#include <linux/virtio_ring.h>
-struct vhost_vring_state {
- unsigned int index;
- unsigned int num;
-};
-struct vhost_vring_file {
- unsigned int index;
- int fd;
-};
-struct vhost_vring_addr {
- unsigned int index;
- unsigned int flags;
-#define VHOST_VRING_F_LOG 0
- __u64 desc_user_addr;
- __u64 used_user_addr;
- __u64 avail_user_addr;
- __u64 log_guest_addr;
-};
-struct vhost_iotlb_msg {
- __u64 iova;
- __u64 size;
- __u64 uaddr;
-#define VHOST_ACCESS_RO 0x1
-#define VHOST_ACCESS_WO 0x2
-#define VHOST_ACCESS_RW 0x3
- __u8 perm;
-#define VHOST_IOTLB_MISS 1
-#define VHOST_IOTLB_UPDATE 2
-#define VHOST_IOTLB_INVALIDATE 3
-#define VHOST_IOTLB_ACCESS_FAIL 4
- __u8 type;
-};
-#define VHOST_IOTLB_MSG 0x1
-#define VHOST_IOTLB_MSG_V2 0x2
-struct vhost_msg {
- int type;
- union {
- struct vhost_iotlb_msg iotlb;
- __u8 padding[64];
- };
-};
-struct vhost_msg_v2 {
- __u32 type;
- __u32 reserved;
- union {
- struct vhost_iotlb_msg iotlb;
- __u8 padding[64];
- };
-};
-struct vhost_memory_region {
- __u64 guest_phys_addr;
- __u64 memory_size;
- __u64 userspace_addr;
- __u64 flags_padding;
-};
-#define VHOST_PAGE_SIZE 0x1000
-struct vhost_memory {
- __u32 nregions;
- __u32 padding;
- struct vhost_memory_region regions[0];
-};
#define VHOST_VIRTIO 0xAF
#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)
#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)
@@ -108,15 +46,6 @@
#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file)
-#define VHOST_F_LOG_ALL 26
-#define VHOST_NET_F_VIRTIO_NET_HDR 27
-#define VHOST_SCSI_ABI_VERSION 1
-struct vhost_scsi_target {
- int abi_version;
- char vhost_wwpn[224];
- unsigned short vhost_tpgt;
- unsigned short reserved;
-};
#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target)
#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target)
#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
new file mode 100644
index 0000000..646fcdc
--- /dev/null
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 _LINUX_VHOST_TYPES_H
+#define _LINUX_VHOST_TYPES_H
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
+struct vhost_vring_state {
+ unsigned int index;
+ unsigned int num;
+};
+struct vhost_vring_file {
+ unsigned int index;
+ int fd;
+};
+struct vhost_vring_addr {
+ unsigned int index;
+ unsigned int flags;
+#define VHOST_VRING_F_LOG 0
+ __u64 desc_user_addr;
+ __u64 used_user_addr;
+ __u64 avail_user_addr;
+ __u64 log_guest_addr;
+};
+struct vhost_iotlb_msg {
+ __u64 iova;
+ __u64 size;
+ __u64 uaddr;
+#define VHOST_ACCESS_RO 0x1
+#define VHOST_ACCESS_WO 0x2
+#define VHOST_ACCESS_RW 0x3
+ __u8 perm;
+#define VHOST_IOTLB_MISS 1
+#define VHOST_IOTLB_UPDATE 2
+#define VHOST_IOTLB_INVALIDATE 3
+#define VHOST_IOTLB_ACCESS_FAIL 4
+ __u8 type;
+};
+#define VHOST_IOTLB_MSG 0x1
+#define VHOST_IOTLB_MSG_V2 0x2
+struct vhost_msg {
+ int type;
+ union {
+ struct vhost_iotlb_msg iotlb;
+ __u8 padding[64];
+ };
+};
+struct vhost_msg_v2 {
+ __u32 type;
+ __u32 reserved;
+ union {
+ struct vhost_iotlb_msg iotlb;
+ __u8 padding[64];
+ };
+};
+struct vhost_memory_region {
+ __u64 guest_phys_addr;
+ __u64 memory_size;
+ __u64 userspace_addr;
+ __u64 flags_padding;
+};
+#define VHOST_PAGE_SIZE 0x1000
+struct vhost_memory {
+ __u32 nregions;
+ __u32 padding;
+ struct vhost_memory_region regions[0];
+};
+#define VHOST_SCSI_ABI_VERSION 1
+struct vhost_scsi_target {
+ int abi_version;
+ char vhost_wwpn[224];
+ unsigned short vhost_tpgt;
+ unsigned short reserved;
+};
+#define VHOST_F_LOG_ALL 26
+#define VHOST_NET_F_VIRTIO_NET_HDR 27
+#endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index ef89b08..74e591d 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -58,6 +58,7 @@
V4L2_BUF_TYPE_SDR_CAPTURE = 11,
V4L2_BUF_TYPE_SDR_OUTPUT = 12,
V4L2_BUF_TYPE_META_CAPTURE = 13,
+ V4L2_BUF_TYPE_META_OUTPUT = 14,
V4L2_BUF_TYPE_PRIVATE = 0x80,
};
#define V4L2_TYPE_IS_MULTIPLANAR(type) ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
@@ -179,6 +180,7 @@
#define V4L2_CAP_READWRITE 0x01000000
#define V4L2_CAP_ASYNCIO 0x02000000
#define V4L2_CAP_STREAMING 0x04000000
+#define V4L2_CAP_META_OUTPUT 0x08000000
#define V4L2_CAP_TOUCH 0x10000000
#define V4L2_CAP_DEVICE_CAPS 0x80000000
struct v4l2_pix_format {
@@ -356,6 +358,7 @@
#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1')
#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I')
#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2')
+#define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4')
#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b')
#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g')
#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G')
@@ -481,6 +484,7 @@
#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
+#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)
struct v4l2_plane {
__u32 bytesused;
__u32 length;
diff --git a/libc/kernel/uapi/linux/virtio_blk.h b/libc/kernel/uapi/linux/virtio_blk.h
index 2d53704..5197434 100644
--- a/libc/kernel/uapi/linux/virtio_blk.h
+++ b/libc/kernel/uapi/linux/virtio_blk.h
@@ -29,6 +29,8 @@
#define VIRTIO_BLK_F_BLK_SIZE 6
#define VIRTIO_BLK_F_TOPOLOGY 10
#define VIRTIO_BLK_F_MQ 12
+#define VIRTIO_BLK_F_DISCARD 13
+#define VIRTIO_BLK_F_WRITE_ZEROES 14
#ifndef VIRTIO_BLK_NO_LEGACY
#define VIRTIO_BLK_F_BARRIER 0
#define VIRTIO_BLK_F_SCSI 7
@@ -54,6 +56,13 @@
__u8 wce;
__u8 unused;
__u16 num_queues;
+ __u32 max_discard_sectors;
+ __u32 max_discard_seg;
+ __u32 discard_sector_alignment;
+ __u32 max_write_zeroes_sectors;
+ __u32 max_write_zeroes_seg;
+ __u8 write_zeroes_may_unmap;
+ __u8 unused1[3];
} __attribute__((packed));
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1
@@ -62,6 +71,8 @@
#endif
#define VIRTIO_BLK_T_FLUSH 4
#define VIRTIO_BLK_T_GET_ID 8
+#define VIRTIO_BLK_T_DISCARD 11
+#define VIRTIO_BLK_T_WRITE_ZEROES 13
#ifndef VIRTIO_BLK_NO_LEGACY
#define VIRTIO_BLK_T_BARRIER 0x80000000
#endif
@@ -70,6 +81,12 @@
__virtio32 ioprio;
__virtio64 sector;
};
+#define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001
+struct virtio_blk_discard_write_zeroes {
+ __le64 sector;
+ __le32 num_sectors;
+ __le32 flags;
+};
#ifndef VIRTIO_BLK_NO_LEGACY
struct virtio_scsi_inhdr {
__virtio32 errors;
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index ddf5e4e..c9ec83f 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -33,5 +33,7 @@
#endif
#define VIRTIO_F_VERSION_1 32
#define VIRTIO_F_IOMMU_PLATFORM 33
+#define VIRTIO_F_RING_PACKED 34
+#define VIRTIO_F_ORDER_PLATFORM 36
#define VIRTIO_F_SR_IOV 37
#endif
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
index 60dbf71..0ac7495 100644
--- a/libc/kernel/uapi/linux/virtio_gpu.h
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -20,6 +20,7 @@
#define VIRTIO_GPU_HW_H
#include <linux/types.h>
#define VIRTIO_GPU_F_VIRGL 0
+#define VIRTIO_GPU_F_EDID 1
enum virtio_gpu_ctrl_type {
VIRTIO_GPU_UNDEFINED = 0,
VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100,
@@ -32,6 +33,7 @@
VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING,
VIRTIO_GPU_CMD_GET_CAPSET_INFO,
VIRTIO_GPU_CMD_GET_CAPSET,
+ VIRTIO_GPU_CMD_GET_EDID,
VIRTIO_GPU_CMD_CTX_CREATE = 0x0200,
VIRTIO_GPU_CMD_CTX_DESTROY,
VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE,
@@ -46,6 +48,7 @@
VIRTIO_GPU_RESP_OK_DISPLAY_INFO,
VIRTIO_GPU_RESP_OK_CAPSET_INFO,
VIRTIO_GPU_RESP_OK_CAPSET,
+ VIRTIO_GPU_RESP_OK_EDID,
VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200,
VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY,
VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID,
@@ -207,6 +210,17 @@
struct virtio_gpu_ctrl_hdr hdr;
__u8 capset_data[];
};
+struct virtio_gpu_cmd_get_edid {
+ struct virtio_gpu_ctrl_hdr hdr;
+ __le32 scanout;
+ __le32 padding;
+};
+struct virtio_gpu_resp_edid {
+ struct virtio_gpu_ctrl_hdr hdr;
+ __le32 size;
+ __le32 padding;
+ __u8 edid[1024];
+};
#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0)
struct virtio_gpu_config {
__u32 events_read;
diff --git a/libc/kernel/uapi/linux/virtio_ring.h b/libc/kernel/uapi/linux/virtio_ring.h
index e3af401..ba75940 100644
--- a/libc/kernel/uapi/linux/virtio_ring.h
+++ b/libc/kernel/uapi/linux/virtio_ring.h
@@ -24,8 +24,14 @@
#define VRING_DESC_F_NEXT 1
#define VRING_DESC_F_WRITE 2
#define VRING_DESC_F_INDIRECT 4
+#define VRING_PACKED_DESC_F_AVAIL 7
+#define VRING_PACKED_DESC_F_USED 15
#define VRING_USED_F_NO_NOTIFY 1
#define VRING_AVAIL_F_NO_INTERRUPT 1
+#define VRING_PACKED_EVENT_FLAG_ENABLE 0x0
+#define VRING_PACKED_EVENT_FLAG_DISABLE 0x1
+#define VRING_PACKED_EVENT_FLAG_DESC 0x2
+#define VRING_PACKED_EVENT_F_WRAP_CTR 15
#define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX 29
struct vring_desc {
@@ -59,4 +65,14 @@
#define VRING_DESC_ALIGN_SIZE 16
#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
#define vring_avail_event(vr) (* (__virtio16 *) & (vr)->used->ring[(vr)->num])
+struct vring_packed_desc_event {
+ __le16 off_wrap;
+ __le16 flags;
+};
+struct vring_packed_desc {
+ __le64 addr;
+ __le32 len;
+ __le16 id;
+ __le16 flags;
+};
#endif
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_user.h b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
index 9148ed5..e74d837 100644
--- a/libc/kernel/uapi/rdma/hfi/hfi1_user.h
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
@@ -28,6 +28,7 @@
#define HFI1_CAP_SDMA_AHG (1UL << 2)
#define HFI1_CAP_EXTENDED_PSN (1UL << 3)
#define HFI1_CAP_HDRSUPP (1UL << 4)
+#define HFI1_CAP_TID_RDMA (1UL << 5)
#define HFI1_CAP_USE_SDMA_HEAD (1UL << 6)
#define HFI1_CAP_MULTI_PKT_EGR (1UL << 7)
#define HFI1_CAP_NODROP_RHQ_FULL (1UL << 8)
@@ -38,6 +39,7 @@
#define HFI1_CAP_NO_INTEGRITY (1UL << 13)
#define HFI1_CAP_PKEY_CHECK (1UL << 14)
#define HFI1_CAP_STATIC_RATE_CTRL (1UL << 15)
+#define HFI1_CAP_OPFN (1UL << 16)
#define HFI1_CAP_SDMA_HEAD_CHECK (1UL << 17)
#define HFI1_CAP_EARLY_CREDIT_RETURN (1UL << 18)
#define HFI1_RCVHDR_ENTSIZE_2 (1UL << 0)
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index 23bedf9..0bae0d4 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -27,6 +27,15 @@
__aligned_u64 cqn;
__aligned_u64 cap_flags;
};
+struct hns_roce_ib_create_srq {
+ __aligned_u64 buf_addr;
+ __aligned_u64 db_addr;
+ __aligned_u64 que_addr;
+};
+struct hns_roce_ib_create_srq_resp {
+ __u32 srqn;
+ __u32 reserved;
+};
struct hns_roce_ib_create_qp {
__aligned_u64 buf_addr;
__aligned_u64 db_addr;
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
index 69ded8e..ebf8b7c 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
@@ -44,6 +44,20 @@
UVERBS_ATTR_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
UVERBS_ATTR_UHW_OUT,
};
+enum uverbs_methods_device {
+ UVERBS_METHOD_INVOKE_WRITE,
+ UVERBS_METHOD_INFO_HANDLES,
+ UVERBS_METHOD_QUERY_PORT,
+};
+enum uverbs_attrs_invoke_write_cmd_attr_ids {
+ UVERBS_ATTR_CORE_IN,
+ UVERBS_ATTR_CORE_OUT,
+ UVERBS_ATTR_WRITE_CMD,
+};
+enum uverbs_attrs_query_port_cmd_attr_ids {
+ UVERBS_ATTR_QUERY_PORT_PORT_NUM,
+ UVERBS_ATTR_QUERY_PORT_RESP,
+};
enum uverbs_attrs_create_cq_cmd_attr_ids {
UVERBS_ATTR_CREATE_CQ_HANDLE,
UVERBS_ATTR_CREATE_CQ_CQE,
@@ -104,6 +118,17 @@
};
enum uverbs_methods_mr {
UVERBS_METHOD_DM_MR_REG,
+ UVERBS_METHOD_MR_DESTROY,
+ UVERBS_METHOD_ADVISE_MR,
+};
+enum uverbs_attrs_mr_destroy_ids {
+ UVERBS_ATTR_DESTROY_MR_HANDLE,
+};
+enum uverbs_attrs_advise_mr_cmd_attr_ids {
+ UVERBS_ATTR_ADVISE_MR_PD_HANDLE,
+ UVERBS_ATTR_ADVISE_MR_ADVICE,
+ UVERBS_ATTR_ADVISE_MR_FLAGS,
+ UVERBS_ATTR_ADVISE_MR_SGE_LIST,
};
enum uverbs_attrs_create_counters_cmd_attr_ids {
UVERBS_ATTR_CREATE_COUNTERS_HANDLE,
@@ -121,4 +146,45 @@
UVERBS_METHOD_COUNTERS_DESTROY,
UVERBS_METHOD_COUNTERS_READ,
};
+enum uverbs_attrs_info_handles_id {
+ UVERBS_ATTR_INFO_OBJECT_ID,
+ UVERBS_ATTR_INFO_TOTAL_HANDLES,
+ UVERBS_ATTR_INFO_HANDLES_LIST,
+};
+enum uverbs_methods_pd {
+ UVERBS_METHOD_PD_DESTROY,
+};
+enum uverbs_attrs_pd_destroy_ids {
+ UVERBS_ATTR_DESTROY_PD_HANDLE,
+};
+enum uverbs_methods_mw {
+ UVERBS_METHOD_MW_DESTROY,
+};
+enum uverbs_attrs_mw_destroy_ids {
+ UVERBS_ATTR_DESTROY_MW_HANDLE,
+};
+enum uverbs_methods_xrcd {
+ UVERBS_METHOD_XRCD_DESTROY,
+};
+enum uverbs_attrs_xrcd_destroy_ids {
+ UVERBS_ATTR_DESTROY_XRCD_HANDLE,
+};
+enum uverbs_methods_ah {
+ UVERBS_METHOD_AH_DESTROY,
+};
+enum uverbs_attrs_ah_destroy_ids {
+ UVERBS_ATTR_DESTROY_AH_HANDLE,
+};
+enum uverbs_methods_rwq_ind_tbl {
+ UVERBS_METHOD_RWQ_IND_TBL_DESTROY,
+};
+enum uverbs_attrs_rwq_ind_tbl_destroy_ids {
+ UVERBS_ATTR_DESTROY_RWQ_IND_TBL_HANDLE,
+};
+enum uverbs_methods_flow {
+ UVERBS_METHOD_FLOW_DESTROY,
+};
+enum uverbs_attrs_flow_destroy_ids {
+ UVERBS_ATTR_DESTROY_FLOW_HANDLE,
+};
#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
index 8bea1cb..47a548e 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -19,6 +19,7 @@
#ifndef IB_USER_IOCTL_VERBS_H
#define IB_USER_IOCTL_VERBS_H
#include <linux/types.h>
+#include <rdma/ib_user_verbs.h>
#ifndef RDMA_UAPI_PTR
#define RDMA_UAPI_PTR(_type,_name) __aligned_u64 _name
#endif
@@ -112,4 +113,16 @@
enum ib_uverbs_read_counters_flags {
IB_UVERBS_READ_COUNTERS_PREFER_CACHED = 1 << 0,
};
+enum ib_uverbs_advise_mr_advice {
+ IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH,
+ IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH_WRITE,
+};
+enum ib_uverbs_advise_mr_flag {
+ IB_UVERBS_ADVISE_MR_FLAG_FLUSH = 1 << 0,
+};
+struct ib_uverbs_query_port_resp_ex {
+ struct ib_uverbs_query_port_resp legacy_resp;
+ __u16 port_cap_flags2;
+ __u8 reserved[6];
+};
#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index 6ca4413..3154b7a 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -21,7 +21,7 @@
#include <linux/types.h>
#define IB_USER_VERBS_ABI_VERSION 6
#define IB_USER_VERBS_CMD_THRESHOLD 50
-enum {
+enum ib_uverbs_write_cmds {
IB_USER_VERBS_CMD_GET_CONTEXT,
IB_USER_VERBS_CMD_QUERY_DEVICE,
IB_USER_VERBS_CMD_QUERY_PORT,
@@ -111,6 +111,7 @@
struct ib_uverbs_get_context_resp {
__u32 async_fd;
__u32 num_comp_vectors;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_query_device {
__aligned_u64 response;
@@ -237,6 +238,7 @@
};
struct ib_uverbs_alloc_pd_resp {
__u32 pd_handle;
+ __u32 driver_data[0];
};
struct ib_uverbs_dealloc_pd {
__u32 pd_handle;
@@ -249,6 +251,7 @@
};
struct ib_uverbs_open_xrcd_resp {
__u32 xrcd_handle;
+ __u32 driver_data[0];
};
struct ib_uverbs_close_xrcd {
__u32 xrcd_handle;
@@ -266,6 +269,7 @@
__u32 mr_handle;
__u32 lkey;
__u32 rkey;
+ __u32 driver_data[0];
};
struct ib_uverbs_rereg_mr {
__aligned_u64 response;
@@ -276,10 +280,12 @@
__aligned_u64 hca_va;
__u32 pd_handle;
__u32 access_flags;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_rereg_mr_resp {
__u32 lkey;
__u32 rkey;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_dereg_mr {
__u32 mr_handle;
@@ -289,10 +295,12 @@
__u32 pd_handle;
__u8 mw_type;
__u8 reserved[3];
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_alloc_mw_resp {
__u32 mw_handle;
__u32 rkey;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_dealloc_mw {
__u32 mw_handle;
@@ -328,6 +336,7 @@
struct ib_uverbs_create_cq_resp {
__u32 cq_handle;
__u32 cqe;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_ex_create_cq_resp {
struct ib_uverbs_create_cq_resp base;
@@ -507,6 +516,7 @@
__u32 max_recv_sge;
__u32 max_inline_data;
__u32 reserved;
+ __u32 driver_data[0];
};
struct ib_uverbs_ex_create_qp_resp {
struct ib_uverbs_create_qp_resp base;
@@ -600,8 +610,6 @@
__u32 rate_limit;
__u32 reserved;
};
-struct ib_uverbs_modify_qp_resp {
-};
struct ib_uverbs_ex_modify_qp_resp {
__u32 comp_mask;
__u32 response_length;
@@ -709,9 +717,11 @@
__u32 pd_handle;
__u32 reserved;
struct ib_uverbs_ah_attr attr;
+ __aligned_u64 driver_data[0];
};
struct ib_uverbs_create_ah_resp {
__u32 ah_handle;
+ __u32 driver_data[0];
};
struct ib_uverbs_destroy_ah {
__u32 ah_handle;
@@ -970,6 +980,7 @@
__u32 max_wr;
__u32 max_sge;
__u32 srqn;
+ __u32 driver_data[0];
};
struct ib_uverbs_modify_srq {
__u32 srq_handle;
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 77e14f6..4c85c6c 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -31,6 +31,7 @@
MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC = 1 << 6,
MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC = 1 << 7,
MLX5_QP_FLAG_ALLOW_SCATTER_CQE = 1 << 8,
+ MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE = 1 << 9,
};
enum {
MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -162,6 +163,7 @@
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,
+ MLX5_IB_QUERY_DEV_RESP_PACKET_BASED_CREDIT_MODE = 1 << 2,
};
enum mlx5_ib_tunnel_offloads {
MLX5_IB_TUNNELED_OFFLOADS_VXLAN = 1 << 0,
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 902816b..dcc3d85 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -120,6 +120,7 @@
MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
MLX5_IB_ATTR_CREATE_FLOW_TAG,
+ MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
};
enum mlx5_ib_destoy_flow_attrs {
MLX5_IB_ATTR_DESTROY_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index 7b43e35..fc86778 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -47,6 +47,7 @@
PVRDMA_WR_MASKED_ATOMIC_FETCH_AND_ADD,
PVRDMA_WR_BIND_MW,
PVRDMA_WR_REG_SIG_MR,
+ PVRDMA_WR_ERROR,
};
enum pvrdma_wc_status {
PVRDMA_WC_SUCCESS,
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index 91289c0..67c010b 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -25,6 +25,7 @@
#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
+#define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL 0x7473636d
struct snd_firewire_event_common {
unsigned int type;
};
@@ -58,17 +59,28 @@
unsigned int type;
__u32 message;
};
+struct snd_firewire_tascam_change {
+ unsigned int index;
+ __be32 before;
+ __be32 after;
+};
+struct snd_firewire_event_tascam_control {
+ unsigned int type;
+ struct snd_firewire_tascam_change changes[0];
+};
union snd_firewire_event {
struct snd_firewire_event_common common;
struct snd_firewire_event_lock_status lock_status;
struct snd_firewire_event_dice_notification dice_notification;
struct snd_firewire_event_efw_response efw_response;
struct snd_firewire_event_digi00x_message digi00x_message;
+ struct snd_firewire_event_tascam_control tascam_control;
struct snd_firewire_event_motu_notification motu_notification;
};
#define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
#define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
#define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa)
+#define SNDRV_FIREWIRE_IOCTL_TASCAM_STATE _IOR('H', 0xfb, struct snd_firewire_tascam_state)
#define SNDRV_FIREWIRE_TYPE_DICE 1
#define SNDRV_FIREWIRE_TYPE_FIREWORKS 2
#define SNDRV_FIREWIRE_TYPE_BEBOB 3
@@ -83,4 +95,8 @@
unsigned char guid[8];
char device_name[16];
};
+#define SNDRV_FIREWIRE_TASCAM_STATE_COUNT 64
+struct snd_firewire_tascam_state {
+ __be32 data[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
+};
#endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 62aea27..e094967 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1481,7 +1481,7 @@
# Used by libandroid_net
android_getaddrinfofornet; # apex
- # Used by libandroid_runtime
+ # Used by libandroid_runtime and libmedia
android_mallopt; # apex
gMallocLeakZygoteChild; # apex
} LIBC_P;
@@ -1500,8 +1500,12 @@
__aeabi_cdcmpeq; # arm
__aeabi_cdcmple; # arm
__aeabi_cdrcmple; # arm
+ __aeabi_cfcmpeq; # arm
+ __aeabi_cfcmple; # arm
+ __aeabi_cfrcmple; # arm
__aeabi_d2f; # arm
__aeabi_d2iz; # arm
+ __aeabi_d2uiz; # arm
__aeabi_dadd; # arm
__aeabi_dcmpeq; # arm
__aeabi_dcmpge; # arm
@@ -1517,6 +1521,11 @@
__aeabi_f2iz; # arm
__aeabi_f2uiz; # arm
__aeabi_fadd; # arm
+ __aeabi_fcmpeq; # arm
+ __aeabi_fcmpge; # arm
+ __aeabi_fcmpgt; # arm
+ __aeabi_fcmple; # arm
+ __aeabi_fcmplt; # arm
__aeabi_fcmpun; # arm
__aeabi_fdiv; # arm
__aeabi_fmul; # arm
@@ -1563,15 +1572,18 @@
__bionic_brk; # arm x86 mips
__bionic_libcrt_compat_symbols; # arm x86
__cmpdf2; # arm
+ __cmpsf2; # arm
__divdf3; # arm
__divdi3; # arm x86 mips
__divsf3; # arm
__divsi3; # arm
__dso_handle; # arm
__eqdf2; # arm
+ __eqsf2; # arm
__extendsfdf2; # arm
__fixdfsi; # arm
__fixsfsi; # arm
+ __fixunsdfsi; # arm
__fixunssfsi; # arm
__floatdidf; # arm
__floatdisf; # arm
@@ -1584,6 +1596,7 @@
__futex_wait; # arm x86 mips
__futex_wake; # arm x86 mips
__gedf2; # arm
+ __gesf2; # arm
__get_thread; # arm x86 mips
__get_tls; # arm x86 mips
__getdents64; # arm x86 mips
@@ -1608,13 +1621,17 @@
__gnu_Unwind_Save_WMMXC; # arm
__gnu_Unwind_Save_WMMXD; # arm
__gtdf2; # arm
+ __gtsf2; # arm
__ledf2; # arm
+ __lesf2; # arm
__lshrdi3; # arm
__ltdf2; # arm
+ __ltsf2; # arm
__muldf3; # arm
__muldi3; # arm
__mulsf3; # arm
__nedf2; # arm
+ __nesf2; # arm
__open; # arm x86 mips
__page_shift; # arm x86 mips
__page_size; # arm x86 mips
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 0961a94..bcbd7da 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -123,6 +123,7 @@
static_libs: [
"libc_malloc_debug",
"libdemangle",
+ "libtinyxml2",
],
shared_libs: [
@@ -144,6 +145,8 @@
cc_test {
name: "malloc_debug_system_tests",
+ include_dirs: ["bionic/libc"],
+
srcs: [
"tests/malloc_debug_system_tests.cpp",
],
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index dd20b5c..dbd3eac 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -135,6 +135,9 @@
{
"abort_on_error", {ABORT_ON_ERROR, &Config::VerifyValueEmpty},
},
+ {
+ "verbose", {VERBOSE, &Config::VerifyValueEmpty},
+ },
};
bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value,
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index 011dc77..1b5c748 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -45,6 +45,7 @@
constexpr uint64_t RECORD_ALLOCS = 0x200;
constexpr uint64_t BACKTRACE_FULL = 0x400;
constexpr uint64_t ABORT_ON_ERROR = 0x800;
+constexpr uint64_t VERBOSE = 0x1000;
// In order to guarantee posix compliance, set the minimum alignment
// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 6e9d24f..617d128 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -105,8 +105,10 @@
error_log("Unable to set up backtrace signal enable function: %s", strerror(errno));
return false;
}
- info_log("%s: Run: 'kill -%d %d' to enable backtracing.", getprogname(),
- config.backtrace_signal(), getpid());
+ if (config.options() & VERBOSE) {
+ info_log("%s: Run: 'kill -%d %d' to enable backtracing.", getprogname(),
+ config.backtrace_signal(), getpid());
+ }
}
if (config.options() & BACKTRACE) {
@@ -117,8 +119,10 @@
error_log("Unable to set up backtrace dump signal function: %s", strerror(errno));
return false;
}
- info_log("%s: Run: 'kill -%d %d' to dump the backtrace.", getprogname(),
- config.backtrace_dump_signal(), getpid());
+ if (config.options() & VERBOSE) {
+ info_log("%s: Run: 'kill -%d %d' to dump the backtrace.", getprogname(),
+ config.backtrace_dump_signal(), getpid());
+ }
}
backtrace_dump_ = false;
@@ -492,6 +496,17 @@
}
}
+void PointerData::GetAllocList(std::vector<ListInfoType>* list) {
+ std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
+ std::lock_guard<std::mutex> frame_guard(frame_mutex_);
+
+ if (pointers_.empty()) {
+ return;
+ }
+
+ GetList(list, false);
+}
+
void PointerData::GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
size_t* total_memory, size_t* backtrace_size) {
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
@@ -590,9 +605,9 @@
}
void PointerData::PrepareFork() NO_THREAD_SAFETY_ANALYSIS {
+ free_pointer_mutex_.lock();
pointer_mutex_.lock();
frame_mutex_.lock();
- free_pointer_mutex_.lock();
}
void PointerData::PostForkParent() NO_THREAD_SAFETY_ANALYSIS {
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 6955c9a..24ca748 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -132,9 +132,6 @@
void PostForkParent();
void PostForkChild();
- static void GetList(std::vector<ListInfoType>* list, bool only_with_backtrace);
- static void GetUniqueList(std::vector<ListInfoType>* list, bool only_with_backtrace);
-
static size_t AddBacktrace(size_t num_frames);
static void RemoveBacktrace(size_t hash_index);
@@ -151,6 +148,7 @@
static void VerifyFreedPointer(const FreePointerInfoType& info);
static void VerifyAllFreed();
+ static void GetAllocList(std::vector<ListInfoType>* list);
static void LogLeaks();
static void DumpLiveToFile(FILE* fp);
@@ -165,6 +163,9 @@
static std::string GetHashString(uintptr_t* frames, size_t num_frames);
static void LogBacktrace(size_t hash_index);
+ static void GetList(std::vector<ListInfoType>* list, bool only_with_backtrace);
+ static void GetUniqueList(std::vector<ListInfoType>* list, bool only_with_backtrace);
+
size_t alloc_offset_ = 0;
std::vector<uint8_t> cmp_mem_;
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index 93b9b1e..bebc1c1 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -401,6 +401,21 @@
**NOTE**: If leak\_track is enabled, no abort occurs if leaks have been
detected when the process is exiting.
+### verbose
+As of Android Q, all info messages will be turned off by default. For example,
+in Android P and older, enabling malloc debug would result in this message
+in the log:
+
+ 08-16 15:54:16.060 26947 26947 I libc : /system/bin/app_process64: malloc debug enabled
+
+In android Q, this message will not be displayed because these info messages
+slow down process start up. However, if you want to re-enable these messages,
+add the verbose option. All of the "Run XXX" messages are also silenced unless
+the verbose option is specified. This is an example of the type
+of messages that are no longer displayed:
+
+ 09-10 01:03:50.070 557 557 I malloc_debug: /system/bin/audioserver: Run: 'kill -47 557' to dump the backtrace.
+
Additional Errors
-----------------
There are a few other error messages that might appear in the log.
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index aea2513..5c550c0 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -181,8 +181,10 @@
}
pthread_setspecific(key_, nullptr);
- info_log("%s: Run: 'kill -%d %d' to dump the allocation records.", getprogname(),
- config.record_allocs_signal(), getpid());
+ if (config.options() & VERBOSE) {
+ info_log("%s: Run: 'kill -%d %d' to dump the allocation records.", getprogname(),
+ config.record_allocs_signal(), getpid());
+ }
num_entries_ = config.record_allocs_num_entries();
entries_ = new const RecordEntry*[num_entries_];
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
index 2f590d0..8ed37fa 100644
--- a/libc/malloc_debug/exported32.map
+++ b/libc/malloc_debug/exported32.map
@@ -14,6 +14,7 @@
debug_malloc_backtrace;
debug_malloc_disable;
debug_malloc_enable;
+ debug_malloc_info;
debug_malloc_usable_size;
debug_mallopt;
debug_memalign;
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
index 08d36a5..cdff88b 100644
--- a/libc/malloc_debug/exported64.map
+++ b/libc/malloc_debug/exported64.map
@@ -14,6 +14,7 @@
debug_malloc_backtrace;
debug_malloc_disable;
debug_malloc_enable;
+ debug_malloc_info;
debug_malloc_usable_size;
debug_mallopt;
debug_memalign;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 2e6afff..1145796 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -29,6 +29,8 @@
#include <errno.h>
#include <inttypes.h>
#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/param.h>
@@ -41,6 +43,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <private/bionic_malloc_dispatch.h>
+#include <private/MallocXmlElem.h>
#include "Config.h"
#include "DebugData.h"
@@ -85,6 +88,7 @@
void* debug_calloc(size_t nmemb, size_t bytes);
struct mallinfo debug_mallinfo();
int debug_mallopt(int param, int value);
+int debug_malloc_info(int options, FILE* fp);
int debug_posix_memalign(void** memptr, size_t alignment, size_t size);
int debug_iterate(uintptr_t base, size_t size,
void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
@@ -249,6 +253,10 @@
// of different error cases.
backtrace_startup();
+ if (g_debug->config().options() & VERBOSE) {
+ info_log("%s: malloc debug enabled", getprogname());
+ }
+
return true;
}
@@ -725,11 +733,37 @@
return g_dispatch->mallopt(param, value);
}
+int debug_malloc_info(int options, FILE* fp) {
+ if (DebugCallsDisabled() || !g_debug->TrackPointers()) {
+ return g_dispatch->malloc_info(options, fp);
+ }
+
+ MallocXmlElem root(fp, "malloc", "version=\"debug-malloc-1\"");
+ std::vector<ListInfoType> list;
+ PointerData::GetAllocList(&list);
+
+ size_t alloc_num = 0;
+ for (size_t i = 0; i < list.size(); i++) {
+ MallocXmlElem alloc(fp, "allocation", "nr=\"%zu\"", alloc_num);
+
+ size_t total = 1;
+ size_t size = list[i].size;
+ while (i < list.size() - 1 && list[i + 1].size == size) {
+ i++;
+ total++;
+ }
+ MallocXmlElem(fp, "size").Contents("%zu", list[i].size);
+ MallocXmlElem(fp, "total").Contents("%zu", total);
+ alloc_num++;
+ }
+ return 0;
+}
+
void* debug_aligned_alloc(size_t alignment, size_t size) {
if (DebugCallsDisabled()) {
return g_dispatch->aligned_alloc(alignment, size);
}
- if (!powerof2(alignment)) {
+ if (!powerof2(alignment) || (size % alignment) != 0) {
errno = EINVAL;
return nullptr;
}
@@ -741,7 +775,7 @@
return g_dispatch->posix_memalign(memptr, alignment, size);
}
- if (!powerof2(alignment)) {
+ if (alignment < sizeof(void*) || !powerof2(alignment)) {
return EINVAL;
}
int saved_errno = errno;
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index fb54ee5..42d1415 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -743,3 +743,21 @@
"which does not take a value\n");
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
}
+
+TEST_F(MallocDebugConfigTest, verbose) {
+ ASSERT_TRUE(InitConfig("verbose")) << getFakeLogPrint();
+ ASSERT_EQ(VERBOSE, config->options());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, trigger_verbose_fail) {
+ ASSERT_FALSE(InitConfig("verbose=200")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg(
+ "6 malloc_debug malloc_testing: value set for option 'verbose' "
+ "which does not take a value\n");
+ ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index ccefb25..71e8ebf 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -37,13 +37,15 @@
#include <time.h>
#include <unistd.h>
+#include <android-base/stringprintf.h>
#include <gtest/gtest.h>
-
#include <log/log.h>
#include <string>
#include <vector>
+#include "private/bionic_malloc.h"
+
static constexpr time_t kTimeoutSeconds = 5;
static void Exec(const char* test_name, const char* debug_options, pid_t* pid) {
@@ -60,13 +62,15 @@
ASSERT_NE(0, dup2(fds[1], STDERR_FILENO));
std::vector<const char*> args;
- args.push_back(testing::internal::GetArgvs()[0].c_str());
+ // Get a copy of this argument so it doesn't disappear on us.
+ std::string exec(testing::internal::GetArgvs()[0]);
+ args.push_back(exec.c_str());
args.push_back("--gtest_also_run_disabled_tests");
std::string filter_arg = std::string("--gtest_filter=") + test_name;
args.push_back(filter_arg.c_str());
args.push_back(nullptr);
execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
- exit(1);
+ exit(20);
}
ASSERT_NE(-1, *pid);
close(fds[1]);
@@ -191,21 +195,222 @@
TEST(MallocDebugSystemTest, smoke) {
pid_t pid;
- ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_smoke", "backtrace", &pid));
+ ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_smoke", "verbose backtrace", &pid));
ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"}));
}
-TEST(MallocTests, DISABLED_leak_memory) {
+static void SetAllocationLimit() {
+ // Set to a large value, this is only to enable the limit code and
+ // verify that malloc debug is still called properly.
+ size_t limit = 500 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+}
+
+static void AlignedAlloc() {
+ void* ptr = aligned_alloc(64, 1152);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1152);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_aligned_alloc) {
+ AlignedAlloc();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_aligned_alloc) {
+ SetAllocationLimit();
+ AlignedAlloc();
+}
+
+static void Calloc() {
+ void* ptr = calloc(1, 1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 1, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_calloc) {
+ Calloc();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_calloc) {
+ SetAllocationLimit();
+ Calloc();
+}
+
+static void Malloc() {
void* ptr = malloc(1123);
ASSERT_TRUE(ptr != nullptr);
memset(ptr, 0, 1123);
}
-TEST(MallocDebugSystemTest, verify_leak) {
- pid_t pid;
- ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_leak_memory", "backtrace leak_track", &pid));
+TEST(MallocTests, DISABLED_leak_memory_malloc) {
+ Malloc();
+}
- ASSERT_NO_FATAL_FAILURE(FindStrings(
- pid, std::vector<const char*>{"malloc debug enabled", "leaked block of size 1123 at"}));
+TEST(MallocTests, DISABLED_leak_memory_limit_malloc) {
+ SetAllocationLimit();
+ Malloc();
+}
+
+static void Memalign() {
+ void* ptr = memalign(64, 1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_memalign) {
+ Memalign();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_memalign) {
+ SetAllocationLimit();
+ Memalign();
+}
+
+static void PosixMemalign() {
+ void* ptr;
+ ASSERT_EQ(0, posix_memalign(&ptr, 64, 1123));
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_posix_memalign) {
+ PosixMemalign();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_posix_memalign) {
+ SetAllocationLimit();
+ PosixMemalign();
+}
+
+static void Reallocarray() {
+ void* ptr = reallocarray(nullptr, 1, 1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_reallocarray) {
+ Reallocarray();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_reallocarray) {
+ SetAllocationLimit();
+ Reallocarray();
+}
+
+static void Realloc() {
+ void* ptr = realloc(nullptr, 1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_realloc) {
+ Realloc();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_realloc) {
+ SetAllocationLimit();
+ Realloc();
+}
+
+#if !defined(__LP64__)
+extern "C" void* pvalloc(size_t);
+
+static void Pvalloc() {
+ void* ptr = pvalloc(1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_pvalloc) {
+ Pvalloc();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_pvalloc) {
+ SetAllocationLimit();
+ Pvalloc();
+}
+
+extern "C" void* valloc(size_t);
+
+static void Valloc() {
+ void* ptr = valloc(1123);
+ ASSERT_TRUE(ptr != nullptr);
+ memset(ptr, 0, 1123);
+}
+
+TEST(MallocTests, DISABLED_leak_memory_valloc) {
+ Valloc();
+}
+
+TEST(MallocTests, DISABLED_leak_memory_limit_valloc) {
+ SetAllocationLimit();
+ Valloc();
+}
+#endif
+
+static void VerifyLeak(const char* test_prefix) {
+ struct FunctionInfo {
+ const char* name;
+ size_t size;
+ };
+ static FunctionInfo functions[] = {
+ {
+ "aligned_alloc",
+ 1152,
+ },
+ {
+ "calloc",
+ 1123,
+ },
+ {
+ "malloc",
+ 1123,
+ },
+ {
+ "memalign",
+ 1123,
+ },
+ {
+ "posix_memalign",
+ 1123,
+ },
+ {
+ "reallocarray",
+ 1123,
+ },
+ {
+ "realloc",
+ 1123,
+ },
+#if !defined(__LP64__)
+ {
+ "pvalloc",
+ 4096,
+ },
+ {
+ "valloc",
+ 1123,
+ }
+#endif
+ };
+
+ for (size_t i = 0; i < sizeof(functions) / sizeof(FunctionInfo); i++) {
+ pid_t pid;
+ SCOPED_TRACE(testing::Message() << functions[i].name << " expected size " << functions[i].size);
+ std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name;
+ EXPECT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track", &pid));
+
+ std::string expected_leak = android::base::StringPrintf("leaked block of size %zu at", functions[i].size);
+ EXPECT_NO_FATAL_FAILURE(FindStrings(
+ pid, std::vector<const char*>{"malloc debug enabled", expected_leak.c_str()}));
+ }
+}
+
+TEST(MallocDebugSystemTest, verify_leak) {
+ VerifyLeak("leak_memory_");
+}
+
+TEST(MallocDebugSystemTest, verify_leak_allocation_limit) {
+ VerifyLeak("leak_memory_limit_");
}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 6da95ca..f611f3d 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -16,6 +16,7 @@
#include <malloc.h>
#include <signal.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
@@ -25,10 +26,13 @@
#include <unistd.h>
#include <algorithm>
+#include <memory>
#include <thread>
#include <vector>
#include <utility>
+#include <tinyxml2.h>
+
#include <gtest/gtest.h>
#include <android-base/file.h>
@@ -62,6 +66,7 @@
struct mallinfo debug_mallinfo();
int debug_mallopt(int, int);
+int debug_malloc_info(int, FILE*);
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t);
@@ -136,6 +141,7 @@
nullptr,
mallopt,
aligned_alloc,
+ malloc_info,
};
std::string ShowDiffs(uint8_t* a, uint8_t* b, size_t size) {
@@ -148,7 +154,7 @@
return diff;
}
-void VerifyAllocCalls(bool backtrace_enabled) {
+void VerifyAllocCalls(bool all_options) {
size_t alloc_size = 1024;
// Verify debug_malloc.
@@ -203,21 +209,28 @@
ASSERT_STREQ("", getFakeLogBuf().c_str());
std::string expected_log;
- if (backtrace_enabled) {
+ if (all_options) {
+ expected_log += android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
+ SIGRTMAX - 19, getpid());
expected_log += android::base::StringPrintf(
"4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
SIGRTMAX - 17, getpid());
+ expected_log += android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
+ SIGRTMAX - 18, getpid());
}
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, fill_generic) {
- Init("fill");
+ Init("verbose fill");
VerifyAllocCalls(false);
}
TEST_F(MallocDebugTest, fill_on_alloc_generic) {
- Init("fill_on_alloc");
+ Init("verbose fill_on_alloc");
VerifyAllocCalls(false);
}
@@ -235,6 +248,46 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, verbose_only) {
+ Init("verbose");
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("4 malloc_debug malloc_testing: malloc debug enabled\n", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, verbose_backtrace_enable_on_signal) {
+ Init("verbose backtrace_enable_on_signal");
+
+ std::string expected_log = android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
+ SIGRTMAX - 19, getpid());
+ expected_log += android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
+ SIGRTMAX - 17, getpid());
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, verbose_backtrace) {
+ Init("verbose backtrace");
+
+ std::string expected_log = android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
+ SIGRTMAX - 17, getpid());
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, verbose_record_allocs) {
+ Init("verbose record_allocs");
+
+ std::string expected_log = android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
+ SIGRTMAX - 18, getpid());
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, fill_on_free) {
Init("fill_on_free free_track free_track_backtrace_num_frames=0");
@@ -296,7 +349,9 @@
}
TEST_F(MallocDebugTest, all_options) {
- Init("guard backtrace fill expand_alloc free_track leak_track");
+ Init(
+ "guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
+ "record_allocs verify_pointers abort_on_error verbose");
VerifyAllocCalls(true);
}
@@ -318,7 +373,7 @@
ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
debug_free(pointer);
- pointer = debug_aligned_alloc(128, 15);
+ pointer = debug_aligned_alloc(16, 16);
ASSERT_TRUE(pointer != nullptr);
ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
debug_free(pointer);
@@ -661,9 +716,6 @@
ASSERT_STREQ("", getFakeLogBuf().c_str());
std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- expected_log += android::base::StringPrintf(
"6 malloc_debug +++ malloc_testing leaked block of size 1024 at %p (leak 1 of 3)\n",
pointer3);
expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
@@ -1090,10 +1142,7 @@
ASSERT_EQ(0U, backtrace_size);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, get_malloc_leak_info_single) {
@@ -1137,10 +1186,7 @@
debug_free(pointer);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, get_malloc_leak_info_multi) {
@@ -1220,10 +1266,7 @@
debug_free(pointers[2]);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, get_malloc_backtrace_with_header) {
@@ -1255,10 +1298,7 @@
initialized = false;
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
static std::string SanitizeHeapData(const std::string& data) {
@@ -1369,9 +1409,6 @@
ASSERT_STREQ("", getFakeLogBuf().c_str());
std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- expected_log += android::base::StringPrintf(
"6 malloc_debug Dumping to file: /data/local/tmp/backtrace_heap.%d.txt\n\n", getpid());
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
@@ -1643,13 +1680,7 @@
debug_free_malloc_leak_info(info);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to enable backtracing.\n",
- SIGRTMAX - 19, getpid());
- expected_log += android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, backtrace_same_stack) {
@@ -1706,10 +1737,7 @@
debug_free(pointers[3]);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, backtrace_same_stack_zygote) {
@@ -1768,10 +1796,7 @@
debug_free(pointers[3]);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, backtrace_same_stack_mix_zygote) {
@@ -1838,10 +1863,7 @@
debug_free(pointers[3]);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, backtrace_frame_data_nullptr_same_size) {
@@ -1885,10 +1907,7 @@
debug_free(pointers[3]);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, overflow) {
@@ -2016,10 +2035,7 @@
debug_free(pointer);
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the backtrace.\n",
- SIGRTMAX - 17, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, max_size) {
@@ -2144,9 +2160,9 @@
debug_free(pointer);
expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
- pointer = debug_aligned_alloc(32, 50);
+ pointer = debug_aligned_alloc(32, 64);
ASSERT_TRUE(pointer != nullptr);
- expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
+ expected += android::base::StringPrintf("%d: memalign %p 32 64\n", getpid(), pointer);
debug_free(pointer);
expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
@@ -2187,10 +2203,7 @@
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
- SIGRTMAX - 18, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
debug_free(pointer);
}
@@ -2245,10 +2258,7 @@
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
- SIGRTMAX - 18, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
debug_free(pointer);
}
@@ -2287,10 +2297,7 @@
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
- std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
- SIGRTMAX - 18, getpid());
- ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
debug_free(pointer);
}
@@ -2342,9 +2349,6 @@
ASSERT_STREQ("", getFakeLogBuf().c_str());
std::string expected_log = android::base::StringPrintf(
- "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
- SIGRTMAX - 18, getpid());
- expected_log += android::base::StringPrintf(
"6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
RECORD_ALLOCS_FILE);
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
@@ -2465,3 +2469,82 @@
pointer[-get_tag_offset()] = tag_value;
}
+TEST_F(MallocDebugTest, malloc_info_no_pointer_tracking) {
+ Init("fill");
+
+ char* buffer;
+ size_t size;
+ FILE* memstream = open_memstream(&buffer, &size);
+ ASSERT_TRUE(memstream != nullptr);
+ ASSERT_EQ(0, debug_malloc_info(0, memstream));
+ ASSERT_EQ(0, fclose(memstream));
+
+ tinyxml2::XMLDocument doc;
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buffer));
+ auto root = doc.FirstChildElement();
+ ASSERT_TRUE(root != nullptr);
+ ASSERT_STREQ("malloc", root->Name());
+ // Don't care what the underyling implementation says, just that it's
+ // not generated by debug malloc.
+ ASSERT_STRNE("debug-malloc-1", root->Attribute("version"));
+}
+
+TEST_F(MallocDebugTest, malloc_info_with_pointer_tracking) {
+ Init("verify_pointers");
+
+ std::unique_ptr<void, decltype(debug_free)*> ptr1(debug_malloc(1000), debug_free);
+ ASSERT_TRUE(ptr1.get() != nullptr);
+ std::unique_ptr<void, decltype(debug_free)*> ptr2(debug_malloc(1000), debug_free);
+ ASSERT_TRUE(ptr2.get() != nullptr);
+ std::unique_ptr<void, decltype(debug_free)*> ptr3(debug_malloc(500), debug_free);
+ ASSERT_TRUE(ptr3.get() != nullptr);
+ std::unique_ptr<void, decltype(debug_free)*> ptr4(debug_malloc(1200), debug_free);
+ ASSERT_TRUE(ptr4.get() != nullptr);
+
+ char* buffer;
+ size_t size;
+ FILE* memstream = open_memstream(&buffer, &size);
+ ASSERT_TRUE(memstream != nullptr);
+ ASSERT_EQ(0, debug_malloc_info(0, memstream));
+ ASSERT_EQ(0, fclose(memstream));
+
+ SCOPED_TRACE(testing::Message() << "Output:\n" << buffer);
+
+ tinyxml2::XMLDocument doc;
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(buffer));
+ auto root = doc.FirstChildElement();
+ ASSERT_TRUE(root != nullptr);
+ ASSERT_STREQ("malloc", root->Name());
+ ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
+
+ auto alloc = root->FirstChildElement();
+ ASSERT_TRUE(alloc != nullptr);
+ ASSERT_STREQ("allocation", alloc->Name());
+ int val;
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
+ ASSERT_EQ(0, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
+ ASSERT_EQ(1200, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
+ ASSERT_EQ(1, val);
+
+ alloc = alloc->NextSiblingElement();
+ ASSERT_TRUE(alloc != nullptr);
+ ASSERT_STREQ("allocation", alloc->Name());
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
+ ASSERT_EQ(1, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
+ ASSERT_EQ(1000, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
+ ASSERT_EQ(2, val);
+
+ alloc = alloc->NextSiblingElement();
+ ASSERT_TRUE(alloc != nullptr);
+ ASSERT_STREQ("allocation", alloc->Name());
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->QueryIntAttribute("nr", &val));
+ ASSERT_EQ(2, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("size")->QueryIntText(&val));
+ ASSERT_EQ(500, val);
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, alloc->FirstChildElement("total")->QueryIntText(&val));
+ ASSERT_EQ(1, val);
+}
diff --git a/libc/malloc_hooks/Android.bp b/libc/malloc_hooks/Android.bp
index d4b5a2a..d119f89 100644
--- a/libc/malloc_hooks/Android.bp
+++ b/libc/malloc_hooks/Android.bp
@@ -39,14 +39,6 @@
// ==============================================================
cc_test {
name: "malloc_hooks_unit_tests",
- multilib: {
- lib32: {
- suffix: "32",
- },
- lib64: {
- suffix: "64",
- },
- },
srcs: [
"tests/malloc_hooks_tests.cpp",
diff --git a/libc/malloc_hooks/exported32.map b/libc/malloc_hooks/exported32.map
index bd3e547..293d9ac 100644
--- a/libc/malloc_hooks/exported32.map
+++ b/libc/malloc_hooks/exported32.map
@@ -13,6 +13,7 @@
hooks_malloc_backtrace;
hooks_malloc_disable;
hooks_malloc_enable;
+ hooks_malloc_info;
hooks_malloc_usable_size;
hooks_mallopt;
hooks_memalign;
diff --git a/libc/malloc_hooks/exported64.map b/libc/malloc_hooks/exported64.map
index 72465c4..340106b 100644
--- a/libc/malloc_hooks/exported64.map
+++ b/libc/malloc_hooks/exported64.map
@@ -13,6 +13,7 @@
hooks_malloc_backtrace;
hooks_malloc_disable;
hooks_malloc_enable;
+ hooks_malloc_info;
hooks_malloc_usable_size;
hooks_mallopt;
hooks_memalign;
diff --git a/libc/malloc_hooks/malloc_hooks.cpp b/libc/malloc_hooks/malloc_hooks.cpp
index f7bdd56..07b668f 100644
--- a/libc/malloc_hooks/malloc_hooks.cpp
+++ b/libc/malloc_hooks/malloc_hooks.cpp
@@ -29,6 +29,7 @@
#include <errno.h>
#include <malloc.h>
#include <stdint.h>
+#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <unistd.h>
@@ -57,6 +58,7 @@
void hooks_free_malloc_leak_info(uint8_t* info);
size_t hooks_malloc_usable_size(void* pointer);
void* hooks_malloc(size_t size);
+int hooks_malloc_info(int options, FILE* fp);
void hooks_free(void* pointer);
void* hooks_memalign(size_t alignment, size_t bytes);
void* hooks_aligned_alloc(size_t alignment, size_t bytes);
@@ -174,9 +176,13 @@
return g_dispatch->mallopt(param, value);
}
+int hooks_malloc_info(int options, FILE* fp) {
+ return g_dispatch->malloc_info(options, fp);
+}
+
void* hooks_aligned_alloc(size_t alignment, size_t size) {
if (__memalign_hook != nullptr && __memalign_hook != default_memalign_hook) {
- if (!powerof2(alignment)) {
+ if (!powerof2(alignment) || (size % alignment) != 0) {
errno = EINVAL;
return nullptr;
}
@@ -191,7 +197,7 @@
int hooks_posix_memalign(void** memptr, size_t alignment, size_t size) {
if (__memalign_hook != nullptr && __memalign_hook != default_memalign_hook) {
- if (!powerof2(alignment)) {
+ if (alignment < sizeof(void*) || !powerof2(alignment)) {
return EINVAL;
}
*memptr = __memalign_hook(alignment, size, __builtin_return_address(0));
diff --git a/libc/private/MallocXmlElem.h b/libc/private/MallocXmlElem.h
new file mode 100644
index 0000000..04d3eee
--- /dev/null
+++ b/libc/private/MallocXmlElem.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <private/bionic_macros.h>
+
+class MallocXmlElem {
+ public:
+ // Name must be valid throughout lifetime of the object.
+ explicit MallocXmlElem(FILE* fp, const char* name,
+ const char* attr_fmt = nullptr, ...) : fp_(fp), name_(name) {
+ fprintf(fp, "<%s", name_);
+ if (attr_fmt != nullptr) {
+ va_list args;
+ va_start(args, attr_fmt);
+ fputc(' ', fp_);
+ vfprintf(fp_, attr_fmt, args);
+ va_end(args);
+ }
+ fputc('>', fp_);
+ }
+
+ ~MallocXmlElem() noexcept {
+ fprintf(fp_, "</%s>", name_);
+ }
+
+ void Contents(const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(fp_, fmt, args);
+ va_end(args);
+ }
+
+private:
+ FILE* fp_;
+ const char* name_;
+
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(MallocXmlElem);
+};
diff --git a/libc/private/__bionic_get_shell_path.h b/libc/private/__bionic_get_shell_path.h
new file mode 100644
index 0000000..171c14a
--- /dev/null
+++ b/libc/private/__bionic_get_shell_path.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+extern "C" const char* __bionic_get_shell_path();
diff --git a/libc/private/bionic_constants.h b/libc/private/bionic_constants.h
index e64c826..09294b6 100644
--- a/libc/private/bionic_constants.h
+++ b/libc/private/bionic_constants.h
@@ -26,7 +26,6 @@
// guard region must be large enough that we can allocate an SCS_SIZE-aligned SCS while ensuring
// that there is at least one guard page after the SCS so that a stack overflow results in a SIGSEGV
// instead of corrupting the allocation that comes after it.
-// TODO(b/118642754): Use a larger guard region.
-#define SCS_GUARD_REGION_SIZE (SCS_SIZE * 2)
+#define SCS_GUARD_REGION_SIZE (16 * 1024 * 1024)
#endif // _BIONIC_CONSTANTS_H_
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 447b3b9..d73079e 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -55,6 +55,9 @@
// The malloc_dispatch_table is modified by malloc debug, malloc hooks,
// and heaprofd. Only one of these modes can be active at any given time.
_Atomic(const MallocDispatch*) current_dispatch_table;
+ // This pointer is only used by the allocation limit code when both a
+ // limit is enabled and some other hook is enabled at the same time.
+ _Atomic(const MallocDispatch*) default_dispatch_table;
MallocDispatch malloc_dispatch_table;
};
diff --git a/libc/private/bionic_malloc.h b/libc/private/bionic_malloc.h
index 5f4a75d..a1744aa 100644
--- a/libc/private/bionic_malloc.h
+++ b/libc/private/bionic_malloc.h
@@ -39,6 +39,12 @@
#define M_INIT_ZYGOTE_CHILD_PROFILING M_INIT_ZYGOTE_CHILD_PROFILING
M_RESET_HOOKS = 2,
#define M_RESET_HOOKS M_RESET_HOOKS
+ // Set an upper bound on the total size in bytes of all allocations made
+ // using the memory allocation APIs.
+ // arg = size_t*
+ // arg_size = sizeof(size_t)
+ M_SET_ALLOCATION_LIMIT_BYTES = 3,
+#define M_SET_ALLOCATION_LIMIT_BYTES M_SET_ALLOCATION_LIMIT_BYTES
};
// Manipulates bionic-specific handling of memory allocation APIs such as
diff --git a/libc/private/bionic_malloc_dispatch.h b/libc/private/bionic_malloc_dispatch.h
index 0dce03d..aea3a1c 100644
--- a/libc/private/bionic_malloc_dispatch.h
+++ b/libc/private/bionic_malloc_dispatch.h
@@ -31,6 +31,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <stdio.h>
#include <private/bionic_config.h>
// Entry in malloc dispatch table.
@@ -38,6 +39,7 @@
typedef void (*MallocFree)(void*);
typedef struct mallinfo (*MallocMallinfo)();
typedef void* (*MallocMalloc)(size_t);
+typedef int (*MallocMallocInfo)(int, FILE*);
typedef size_t (*MallocMallocUsableSize)(const void*);
typedef void* (*MallocMemalign)(size_t, size_t);
typedef int (*MallocPosixMemalign)(void**, size_t, size_t);
@@ -73,6 +75,7 @@
MallocMallocEnable malloc_enable;
MallocMallopt mallopt;
MallocAlignedAlloc aligned_alloc;
+ MallocMallocInfo malloc_info;
} __attribute__((aligned(32)));
#endif
diff --git a/libc/private/sigrtmin.h b/libc/private/sigrtmin.h
index 67bd864..d78d980 100644
--- a/libc/private/sigrtmin.h
+++ b/libc/private/sigrtmin.h
@@ -40,11 +40,12 @@
// 34 (__SIGRTMIN + 2) libcore
// 35 (__SIGRTMIN + 3) debuggerd -b
// 36 (__SIGRTMIN + 4) heapprofd
+// 37 (__SIGRTMIN + 5) coverage (libprofile-extras)
//
// If you change this, also change __ndk_legacy___libc_current_sigrtmin
// in <android/legacy_signal_inlines.h> to match.
-#define __SIGRT_RESERVED 5
+#define __SIGRT_RESERVED 6
static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigset, int how) {
int (*block)(sigset64_t*, int);
int (*unblock)(sigset64_t*, int);
@@ -70,5 +71,6 @@
unblock(&sigset, __SIGRTMIN + 2);
unblock(&sigset, __SIGRTMIN + 3);
unblock(&sigset, __SIGRTMIN + 4);
+ unblock(&sigset, __SIGRTMIN + 5);
return sigset;
}
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index d7b69dc..4cec757 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -52,6 +52,7 @@
#include "local.h"
#include "glue.h"
+#include "private/__bionic_get_shell_path.h"
#include "private/bionic_fortify.h"
#include "private/ErrnoRestorer.h"
#include "private/thread_private.h"
@@ -290,7 +291,7 @@
if (fcntl(fd, F_SETFL, fd_flags | O_APPEND) == -1) return nullptr;
}
- // Make sure O_CLOEXEC is set on the underlying fd if our mode has 'x'.
+ // Make sure O_CLOEXEC is set on the underlying fd if our mode has 'e'.
if ((mode_flags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) {
fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
}
@@ -1169,11 +1170,6 @@
return (__sfvwrite(fp, &uio) == 0) ? count : ((n - uio.uio_resid) / size);
}
-static int __close_if_popened(FILE* fp) {
- if (_EXT(fp)->_popen_pid > 0) close(fileno(fp));
- return 0;
-}
-
static FILE* __popen_fail(int fds[2]) {
ErrnoRestorer errno_restorer;
close(fds[0]);
@@ -1219,14 +1215,11 @@
if (pid == 0) {
close(fds[parent]);
- // POSIX says "The popen() function shall ensure that any streams from previous popen() calls
- // that remain open in the parent process are closed in the new child process."
- _fwalk(__close_if_popened);
// dup2 so that the child fd isn't closed on exec.
if (dup2(fds[child], desired_child_fd) == -1) _exit(127);
close(fds[child]);
if (bidirectional) dup2(STDOUT_FILENO, STDIN_FILENO);
- execl(_PATH_BSHELL, "sh", "-c", cmd, nullptr);
+ execl(__bionic_get_shell_path(), "sh", "-c", cmd, nullptr);
_exit(127);
}
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
index 6fcc09e..10245db 100644
--- a/libc/symbol_ordering
+++ b/libc/symbol_ordering
@@ -3,200 +3,209 @@
# symbols by size, we usually have less dirty pages at runtime, because small
# symbols are grouped together.
-_ZZ17__find_icu_symbolPKcE9found_icu
-_ZL24gHeapprofdInitInProgress
-_ZL27gHeapprofdInitHookInstalled
+ctl_initialized
+gGlobalsMutating
+global_hashtable_initialized
+gmtcheck.gmt_is_set
+had_conf_error
+je_background_thread_enabled_state
+je_log_init_done
je_opt_abort
je_opt_abort_conf
+je_opt_background_thread
je_opt_junk_alloc
je_opt_junk_free
+je_opt_stats_print
je_opt_utrace
je_opt_xmalloc
je_opt_zero
+je_tsd_booted
malloc_disabled_tcache
-had_conf_error
malloc_slow_flags
-je_opt_background_thread
-ctl_initialized
-je_log_init_done
mmap_flags
os_overcommits
-je_opt_stats_print
-je_tsd_booted
-global_hashtable_initialized
-gmtcheck.gmt_is_set
restartloop
-_ZZ12bindresvportE4port
-ru_counter
+_ZL24gHeapprofdInitInProgress
+_ZL27gHeapprofdInitHookInstalled
+_ZL29gMallocZygoteChildProfileable
+_ZZ17__find_icu_symbolPKcE9found_icu
ru_a
-ru_x
ru_b
-ru_seed
+ru_counter
ru_g
-ru_seed2
ru_msb
-je_narenas_auto
-je_ncpus
-je_init_system_thp_mode
-je_nhbins
-je_tsd_tsd
-optreset
-_rs_forked
-daylight
-gMallocLeakZygoteChild
-_ZL18netdClientInitOnce
-je_opt_narenas
-narenas_total
-je_malloc_disable.once_control
-je_opt_metadata_thp
-je_opt_thp
-stack_nelms
-tcaches_past
-ncleanups
-error_message_count
-error_one_per_line
-_ZZ13error_at_lineE9last_line
-_ZL13g_locale_once
-_ZL30g_propservice_protocol_version
-_res_cache_once
-_res_key
-_rs_forkdetect._rs_pid
-ru_pid
-lcl_is_set
-__cxa_finalize.call_depth
-seed48.sseed
-ether_aton.addr
-je_background_thread_info
-je_malloc_message
-je_tcache_bin_info
-je_tcache_maxclass
-je_tcaches
-optarg
-suboptarg
-timezone
-_ZGVZ17__find_icu_symbolPKcE9found_icu
-_ZL17g_libicuuc_handle
-__malloc_hook
-__realloc_hook
-__free_hook
-__memalign_hook
-je_malloc_conf
-malloc_initializer
+ru_seed
+ru_seed2
+ru_x
+_ZZ12bindresvportE4port
a0
-je_opt_dirty_decay_ms
-je_opt_muzzy_decay_ms
-dirty_decay_ms_default.0
-muzzy_decay_ms_default.0
+__atexit
+atexit_mutex
b0
ctl_arenas
ctl_stats
-je_hooks_arena_new_hook
-os_page
-tcaches_avail
-_ZN9prop_area8pa_size_E
-_ZN9prop_area13pa_data_size_E
-_ZL6g_lock
-_ZL6g_tags
-_ZZ8c16rtombE15__private_state
-_ZZ8c32rtombE15__private_state
+__cxa_finalize.call_depth
+daylight
+dirty_decay_ms_default.0
environ
+error_message_count
+error_one_per_line
error_print_progname
-_ZZ13error_at_lineE9last_file
-_ZZ14__icu_charTypejE10u_charType
-_ZGVZ14__icu_charTypejE10u_charType
-_ZZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
-_ZGVZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
-_ZZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
-_ZGVZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
-__progname
-_ZZ8mbrtoc16E15__private_state
-_ZZ8mbrtoc32E15__private_state
-_ZL14syslog_log_tag
-__system_property_area__
-_ZZ7mbrtowcE15__private_state
-_ZZ10mbsnrtowcsE15__private_state
-_ZZ7wcrtombE15__private_state
-_ZZ10wcsnrtombsE15__private_state
-_ZZ8iswcntrlE10u_charType
-_ZGVZ8iswcntrlE10u_charType
-_ZZ8iswdigitE9u_isdigit
-_ZGVZ8iswdigitE9u_isdigit
-_ZZ8iswpunctE9u_ispunct
-_ZGVZ8iswpunctE9u_ispunct
-_ZZ8towlowerE9u_tolower
-_ZGVZ8towlowerE9u_tolower
-_ZZ8towupperE9u_toupper
-_ZGVZ8towupperE9u_toupper
+__free_hook
+g_atexit_lock
+gGlobalsMutateLock
global_hashtable
+gMallocLeakZygoteChild
+gmtptr
handlers
-p5s
-ut
-rs
-rsx
+je_background_thread_info
+je_hooks_arena_new_hook
+je_init_system_thp_mode
+je_malloc_conf
+je_malloc_disable.once_control
+je_malloc_message
+je_narenas_auto
+je_ncpus
+je_nhbins
+je_opt_dirty_decay_ms
+je_opt_metadata_thp
+je_opt_muzzy_decay_ms
+je_opt_narenas
+je_opt_thp
+je_tcache_bin_info
+je_tcache_maxclass
+je_tcaches
+je_tsd_tsd
+lastenv
+lcl_is_set
+lclptr
+locallock
+malloc_disabled_lock
+__malloc_hook
+malloc_initializer
mbrlen.mbs
mbtowc.mbs
-wctomb.mbs
-ru_reseed
+__memalign_hook
+muzzy_decay_ms_default.0
+narenas_total
+ncleanups
+optarg
+optreset
+os_page
+p5s
+__progname
+random_mutex
+__realloc_hook
+_res_cache_list_lock
+_res_cache_once
+_res_key
+__res_randomid.__libc_mutex_random
+rs
+_rs_forkdetect._rs_pid
+_rs_forked
+rsx
+ru_pid
ru_prf
-tmpnam.tmpcount
-lastenv
-strtok.last
+ru_reseed
__stack_chk_guard
-lclptr
-gmtptr
-_ZGVZ14tzset_unlockedE20persist_sys_timezone
+stack_nelms
+strtok.last
+suboptarg
+__system_property_area__
+tcaches_avail
+tcaches_past
+timezone
+tmpnam.tmpcount
+ut
+wctomb.mbs
+_ZL11g_arc4_lock
+_ZL13g_locale_once
_ZL13g_thread_list
-__atexit
+_ZL14syslog_log_tag
+_ZL16gHeapprofdHandle
+_ZL17g_libicuuc_handle
+_ZL18netdClientInitOnce
+_ZL30g_propservice_protocol_version
+_ZN9prop_area13pa_data_size_E
+_ZN9prop_area8pa_size_E
+_ZZ10mbsnrtowcsE15__private_state
+_ZZ10wcsnrtombsE15__private_state
+_ZZ13error_at_lineE9last_file
+_ZZ13error_at_lineE9last_line
+_ZZ14__icu_charTypejE10u_charType
+_ZZ23__bionic_get_shell_pathE7sh_path
+_ZZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
+_ZZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
+_ZZ7mbrtowcE15__private_state
+_ZZ7wcrtombE15__private_state
+_ZZ8c16rtombE15__private_state
+_ZZ8c32rtombE15__private_state
+_ZZ8iswcntrlE10u_charType
+_ZZ8iswdigitE9u_isdigit
+_ZZ8iswpunctE9u_ispunct
+_ZZ8mbrtoc16E15__private_state
+_ZZ8mbrtoc32E15__private_state
+_ZZ8towlowerE9u_tolower
+_ZZ8towupperE9u_toupper
+ether_aton.addr
+seed48.sseed
+__dtoa_locks
+_ZGVZ14__icu_charTypejE10u_charType
+_ZGVZ14tzset_unlockedE20persist_sys_timezone
+_ZGVZ17__find_icu_symbolPKcE9found_icu
+_ZGVZ23__bionic_get_shell_pathE7sh_path
+_ZGVZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
+_ZGVZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
+_ZGVZ8iswcntrlE10u_charType
+_ZGVZ8iswdigitE9u_isdigit
+_ZGVZ8iswpunctE9u_ispunct
+_ZGVZ8towlowerE9u_tolower
+_ZGVZ8towupperE9u_toupper
+_ZL10gAllocated
+_ZL11gAllocLimit
+_ZL13g_atfork_list
+_ZL6g_lock
+_ZL6g_tags
je_opt_stats_print_opts
nuls
precsize_ntoa.retbuf
__p_secstodate.output
-_ZL13g_atfork_list
-inet_ntoa.b
ether_ntoa.buf
-__sym_ntos.unname
-__sym_ntop.unname
-__p_type.typebuf
+inet_ntoa.b
__p_class.classbuf
-malloc_disabled_lock
-_ZL11g_arc4_lock
-_res_cache_list_lock
+__p_type.typebuf
+__sym_ntop.unname
+__sym_ntos.unname
+_ZL10gFunctions
+_ZL12vendor_group
+_ZL13vendor_passwd
+freelist
__p_option.nbuf
__p_time.nbuf
-atexit_mutex
-random_mutex
-__res_randomid.__libc_mutex_random
-locallock
-g_atexit_lock
-_ZL10gFunctions
-_ZL13vendor_passwd
-_ZL12vendor_group
-tm
_ZL18g_thread_list_lock
-buf_asctime
-__dtoa_locks
-freelist
-__loc_ntoa.tmpbuf
+tm
_ZL8g_locale
+ctl_mtx
+init_lock
je_arenas_lock
je_background_thread_lock
-init_lock
-ctl_mtx
tcaches_mtx
je_tsd_init_head
+buf_asctime
+__loc_ntoa.tmpbuf
+utmp
_ZZ14tzset_unlockedE20persist_sys_timezone
arena_binind_div_info
__hexdig_D2A
lcl_TZname
-utmp
inet_nsap_ntoa_tmpbuf
-_ZL17system_properties
_ZL7key_map
+_ZL17system_properties
private_mem
+_res_cache_list
__libc_globals
tmpnam.buf
-_res_cache_list
-_nres
-je_extent_mutex_pool
-je_arenas
je_extents_rtree
+_nres
+je_arenas
+je_extent_mutex_pool
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index d78a5e7..9a3b95e 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -584,8 +584,15 @@
"kernel/uapi/asm-arm/asm/unistd-eabi.h",
"kernel/uapi/asm-arm/asm/unistd-oabi.h",
"kernel/uapi/asm-mips/asm/unistd.h",
+ "kernel/uapi/asm-mips/asm/unistd_n32.h",
+ "kernel/uapi/asm-mips/asm/unistd_n64.h",
+ "kernel/uapi/asm-mips/asm/unistd_nr_n32.h",
+ "kernel/uapi/asm-mips/asm/unistd_nr_n64.h",
+ "kernel/uapi/asm-mips/asm/unistd_nr_o32.h",
+ "kernel/uapi/asm-mips/asm/unistd_o32.h",
"kernel/uapi/asm-x86/asm/unistd_32.h",
- "kernel/uapi/asm-x86/asm/unistd_64.h"]:
+ "kernel/uapi/asm-x86/asm/unistd_64.h",
+ "kernel/uapi/asm-x86/asm/unistd_x32.h"]:
for line in open(os.path.join(bionic_libc_root, unistd_h)):
m = re.search(pattern, line)
if m:
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index 9051308..1742d79 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -228,13 +228,18 @@
if (fd >= 0) return fd;
#else
// On the host, we don't expect those locations to exist, and we're not
- // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT
- // and $ANDROID_ROOT to point us in the right direction.
+ // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT,
+ // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction.
char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
if (fd >= 0) return fd;
+ path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
+ fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
+ free(path);
+ if (fd >= 0) return fd;
+
path = make_path("ANDROID_RUNTIME_ROOT", "/etc/tz/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 0e9a7d3..41eaa9b 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -172,6 +172,12 @@
return (NULL);
break;
+ case 'F': /* The date as "%Y-%m-%d". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%Y-%m-%d", tm, cr)))
+ return (NULL);
+ continue;
+
case 'R': /* The time as "%H:%M". */
_LEGAL_ALT(0);
if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
@@ -190,6 +196,12 @@
return (NULL);
break;
+ case 'v': /* The date as "%e-%b-%Y". */
+ _LEGAL_ALT(0);
+ if (!(bp = _strptime(bp, "%e-%b-%Y", tm, cr)))
+ return (NULL);
+ break;
+
case 'X': /* The time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr)))
@@ -305,6 +317,7 @@
tm->tm_mon--;
break;
+ case 'P':
case 'p': /* The locale's equivalent of AM/PM. */
_LEGAL_ALT(0);
/* AM? */
@@ -377,6 +390,33 @@
return (NULL);
break;
+ case 'u': /* The day of week, monday = 1. */
+ _LEGAL_ALT(_ALT_O);
+ if (!(_conv_num(&bp, &i, 1, 7)))
+ return (NULL);
+ tm->tm_wday = i % 7;
+ continue;
+
+ case 'g': /* The year corresponding to the ISO week
+ * number but without the century.
+ */
+ if (!(_conv_num(&bp, &i, 0, 99)))
+ return (NULL);
+ continue;
+
+ case 'G': /* The year corresponding to the ISO week
+ * number with century.
+ */
+ do
+ bp++;
+ while (isdigit(*bp));
+ continue;
+
+ case 'V': /* The ISO 8601:1988 week number as decimal */
+ if (!(_conv_num(&bp, &i, 0, 53)))
+ return (NULL);
+ continue;
+
case 'Y': /* The year. */
_LEGAL_ALT(_ALT_E);
if (!(_conv_num(&bp, &i, 0, 9999)))
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 642cc7a..2e171d6 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -108,7 +108,6 @@
symbol_file: "libdl.map.txt",
versions: ["10000"],
},
- required: ["libdl.mountpoint"],
}
ndk_library {
diff --git a/libm/Android.bp b/libm/Android.bp
index ec319e2..8c32810 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -508,15 +508,10 @@
},
stl: "none",
- // TODO(ivanlozano): Remove after b/118321713
- no_libcrt: true,
- xom: false,
-
stubs: {
symbol_file: "libm.map.txt",
versions: ["10000"],
},
- required: ["libm.mountpoint"],
}
ndk_library {
diff --git a/libm/libm.map.txt b/libm/libm.map.txt
index 1f9a3f9..00ea7ee 100644
--- a/libm/libm.map.txt
+++ b/libm/libm.map.txt
@@ -301,58 +301,19 @@
___Unwind_RaiseException; # arm
___Unwind_Resume; # arm
___Unwind_Resume_or_Rethrow; # arm
- __adddf3; # arm
- __aeabi_cdcmpeq; # arm
- __aeabi_cdcmple; # arm
- __aeabi_cdrcmple; # arm
- __aeabi_cfcmpeq; # arm
- __aeabi_cfcmple; # arm
- __aeabi_cfrcmple; # arm
__aeabi_d2lz; # arm
- __aeabi_d2uiz; # arm
__aeabi_d2ulz; # arm
- __aeabi_dadd; # arm
- __aeabi_dcmpeq; # arm
- __aeabi_dcmpge; # arm
- __aeabi_dcmpgt; # arm
- __aeabi_dcmple; # arm
- __aeabi_dcmplt; # arm
- __aeabi_ddiv; # arm
- __aeabi_dmul; # arm
- __aeabi_drsub; # arm
- __aeabi_dsub; # arm
- __aeabi_f2d; # arm
__aeabi_f2lz; # arm
__aeabi_f2ulz; # arm
- __aeabi_fcmpeq; # arm
- __aeabi_fcmpge; # arm
- __aeabi_fcmpgt; # arm
- __aeabi_fcmple; # arm
- __aeabi_fcmplt; # arm
- __aeabi_i2d; # arm
__aeabi_l2d; # arm
- __aeabi_ui2d; # arm
- __aeabi_ul2d; # arm
__aeabi_unwind_cpp_pr0; # arm
__aeabi_unwind_cpp_pr1; # arm
__aeabi_unwind_cpp_pr2; # arm
- __cmpdf2; # arm
- __cmpsf2; # arm
- __divdf3; # arm
- __eqdf2; # arm
- __eqsf2; # arm
- __extendsfdf2; # arm
__fixdfdi; # arm mips
__fixsfdi; # arm mips
__fixunsdfdi; # arm mips
- __fixunsdfsi; # arm
__fixunssfdi; # arm mips
__floatdidf; # arm
- __floatsidf; # arm
- __floatundidf; # arm
- __floatunsidf; # arm
- __gedf2; # arm
- __gesf2; # arm
__gnu_Unwind_Backtrace; # arm
__gnu_unwind_execute; # arm
__gnu_Unwind_ForcedUnwind; # arm
@@ -370,17 +331,7 @@
__gnu_Unwind_Save_VFP_D_16_to_31; # arm
__gnu_Unwind_Save_WMMXC; # arm
__gnu_Unwind_Save_WMMXD; # arm
- __gtdf2; # arm
- __gtsf2; # arm
- __ledf2; # arm
- __lesf2; # arm
- __ltdf2; # arm
- __ltsf2; # arm
- __muldf3; # arm
- __nedf2; # arm
- __nesf2; # arm
__restore_core_regs; # arm
- __subdf3; # arm
_Unwind_Backtrace; # arm
_Unwind_Complete; # arm
_Unwind_DeleteException; # arm
diff --git a/linker/Android.bp b/linker/Android.bp
index 613be3d..73328da 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -283,8 +283,6 @@
name: "linker",
symlinks: ["linker_asan"],
- // The linker in the system partition is now only for bootstrapping
- relative_install_path: "bootstrap",
recovery_available: true,
multilib: {
lib32: {
@@ -307,7 +305,6 @@
},
compile_multilib: "both",
xom: false,
- required: ["linker.mountpoint"],
}
cc_library {
diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md
index 686d6be..faf5cc8 100644
--- a/linker/ld.config.format.md
+++ b/linker/ld.config.format.md
@@ -79,5 +79,8 @@
# and links it to default namespace
namespace.ns.links = default
namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
+
+# This defines what libraries are allowed to be loaded from ns1
+namespace.ns1.whitelisted = libsomething.so
```
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8a70ca9..306b800 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -415,11 +415,9 @@
//
// Intended to be called by libc's __gnu_Unwind_Find_exidx().
_Unwind_Ptr do_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
- for (soinfo* si = solist_get_head(); si != 0; si = si->next) {
- if ((pc >= si->base) && (pc < (si->base + si->size))) {
- *pcount = si->ARM_exidx_count;
- return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
- }
+ if (soinfo* si = find_containing_library(reinterpret_cast<void*>(pc))) {
+ *pcount = si->ARM_exidx_count;
+ return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
}
*pcount = 0;
return 0;
@@ -698,9 +696,9 @@
return elf_reader.Read(realpath, fd_, file_offset_, file_size);
}
- bool load() {
+ bool load(address_space_params* address_space) {
ElfReader& elf_reader = get_elf_reader();
- if (!elf_reader.Load(extinfo_)) {
+ if (!elf_reader.Load(address_space)) {
return false;
}
@@ -938,8 +936,18 @@
soinfo* find_containing_library(const void* p) {
ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
- if (address >= si->base && address - si->base < si->size) {
- return si;
+ if (address < si->base || address - si->base >= si->size) {
+ continue;
+ }
+ ElfW(Addr) vaddr = address - si->load_bias;
+ for (size_t i = 0; i != si->phnum; ++i) {
+ const ElfW(Phdr)* phdr = &si->phdr[i];
+ if (phdr->p_type != PT_LOAD) {
+ continue;
+ }
+ if (vaddr >= phdr->p_vaddr && vaddr < phdr->p_vaddr + phdr->p_memsz) {
+ return si;
+ }
}
}
return nullptr;
@@ -1116,7 +1124,7 @@
ZipArchiveCache* zip_archive_cache,
const char* name, soinfo *needed_by,
off64_t* file_offset, std::string* realpath) {
- TRACE("[ opening %s at namespace %s]", name, ns->get_name());
+ TRACE("[ opening %s from namespace %s ]", name, ns->get_name());
// If the name contains a slash, we should attempt to open it directly and not search the paths.
if (strchr(name, '/') != nullptr) {
@@ -1257,6 +1265,9 @@
const char* name = task->get_name();
const android_dlextinfo* extinfo = task->get_extinfo();
+ LD_LOG(kLogDlopen, "load_library(ns=%s, task=%s, flags=0x%x, realpath=%s)", ns->get_name(), name,
+ rtld_flags, realpath.c_str());
+
if ((file_offset % PAGE_SIZE) != 0) {
DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
return false;
@@ -1282,8 +1293,10 @@
if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
soinfo* si = nullptr;
if (find_loaded_library_by_inode(ns, file_stat, file_offset, search_linked_namespaces, &si)) {
- TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
- "will return existing soinfo", name, si->get_realpath());
+ LD_LOG(kLogDlopen,
+ "load_library(ns=%s, task=%s): Already loaded under different name/path \"%s\" - "
+ "will return existing soinfo",
+ ns->get_name(), name, si->get_realpath());
task->set_soinfo(si);
return true;
}
@@ -1384,6 +1397,8 @@
#endif
for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
+ LD_LOG(kLogDlopen, "load_library(ns=%s, task=%s): Adding DT_NEEDED task: %s",
+ ns->get_name(), task->get_name(), name);
load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
});
@@ -1499,17 +1514,24 @@
if (!namespace_link.is_accessible(soname.c_str())) {
// the library is not accessible via namespace_link
+ LD_LOG(kLogDlopen,
+ "find_library_in_linked_namespace(ns=%s, task=%s): Not accessible (soname=%s)",
+ ns->get_name(), task->get_name(), soname.c_str());
return false;
}
// if library is already loaded - return it
if (loaded) {
+ LD_LOG(kLogDlopen, "find_library_in_linked_namespace(ns=%s, task=%s): Already loaded",
+ ns->get_name(), task->get_name());
task->set_soinfo(candidate);
return true;
}
// returning true with empty soinfo means that the library is okay to be
// loaded in the namespace but has not yet been loaded there before.
+ LD_LOG(kLogDlopen, "find_library_in_linked_namespace(ns=%s, task=%s): Ok to load", ns->get_name(),
+ task->get_name());
task->set_soinfo(nullptr);
return true;
}
@@ -1523,14 +1545,17 @@
soinfo* candidate;
if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) {
+ LD_LOG(kLogDlopen,
+ "find_library_internal(ns=%s, task=%s): Already loaded (by soname): %s",
+ ns->get_name(), task->get_name(), candidate->get_realpath());
task->set_soinfo(candidate);
return true;
}
// Library might still be loaded, the accurate detection
// of this fact is done by load_library.
- TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
- task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
+ TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder... ]",
+ task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) {
return true;
@@ -1542,6 +1567,9 @@
// try the load again from there. The library could be loaded from the
// default namespace or from another namespace (e.g. runtime) that is linked
// from the default namespace.
+ LD_LOG(kLogDlopen,
+ "find_library_internal(ns=%s, task=%s): Greylisted library - trying namespace %s",
+ ns->get_name(), task->get_name(), g_default_namespace.get_name());
ns = &g_default_namespace;
if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags,
search_linked_namespaces)) {
@@ -1554,9 +1582,10 @@
// if a library was not found - look into linked namespaces
// preserve current dlerror in the case it fails.
DlErrorRestorer dlerror_restorer;
+ LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Trying %zu linked namespaces",
+ ns->get_name(), task->get_name(), ns->linked_namespaces().size());
for (auto& linked_namespace : ns->linked_namespaces()) {
- if (find_library_in_linked_namespace(linked_namespace,
- task)) {
+ if (find_library_in_linked_namespace(linked_namespace, task)) {
if (task->get_soinfo() == nullptr) {
// try to load the library - once namespace boundary is crossed
// we need to load a library within separate load_group
@@ -1567,6 +1596,9 @@
// Otherwise, the libs in the linked namespace won't get symbols from
// the global group.
if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
+ LD_LOG(
+ kLogDlopen, "find_library_internal(ns=%s, task=%s): Found in linked namespace %s",
+ ns->get_name(), task->get_name(), linked_namespace.linked_namespace()->get_name());
return true;
}
} else {
@@ -1654,6 +1686,9 @@
task->set_extinfo(is_dt_needed ? nullptr : extinfo);
task->set_dt_needed(is_dt_needed);
+ LD_LOG(kLogDlopen, "find_libraries(ns=%s): task=%s, is_dt_needed=%d", ns->get_name(),
+ task->get_name(), is_dt_needed);
+
// Note: start from the namespace that is stored in the LoadTask. This namespace
// is different from the current namespace when the LoadTask is for a transitive
// dependency and the lib that created the LoadTask is not found in the
@@ -1697,10 +1732,34 @@
load_list.push_back(task);
}
}
- shuffle(&load_list);
+ bool reserved_address_recursive = false;
+ if (extinfo) {
+ reserved_address_recursive = extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
+ }
+ if (!reserved_address_recursive) {
+ // Shuffle the load order in the normal case, but not if we are loading all
+ // the libraries to a reserved address range.
+ shuffle(&load_list);
+ }
+
+ // Set up address space parameters.
+ address_space_params extinfo_params, default_params;
+ size_t relro_fd_offset = 0;
+ if (extinfo) {
+ if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
+ extinfo_params.start_addr = extinfo->reserved_addr;
+ extinfo_params.reserved_size = extinfo->reserved_size;
+ extinfo_params.must_use_address = true;
+ } else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) {
+ extinfo_params.start_addr = extinfo->reserved_addr;
+ extinfo_params.reserved_size = extinfo->reserved_size;
+ }
+ }
for (auto&& task : load_list) {
- if (!task->load()) {
+ address_space_params* address_space =
+ (reserved_address_recursive || !task->is_dt_needed()) ? &extinfo_params : &default_params;
+ if (!task->load(address_space)) {
return false;
}
}
@@ -1810,7 +1869,7 @@
// we should avoid linking them (because if they are not linked -> they
// are in the local_group_roots and will be linked later).
if (!si->is_linked() && si->get_primary_namespace() == local_group_ns) {
- if (!si->link_image(global_group, local_group, extinfo) ||
+ if (!si->link_image(global_group, local_group, extinfo, &relro_fd_offset) ||
!get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
return false;
}
@@ -3101,7 +3160,7 @@
}
}
break;
-#endif // defined(R_GENERIC_TLSDESC)
+#endif // defined(__aarch64__)
#if defined(__aarch64__)
case R_AARCH64_ABS64:
@@ -3273,11 +3332,14 @@
}
}
+#if defined(__aarch64__)
+ // Bionic currently only implements TLSDESC for arm64.
for (const std::pair<TlsDescriptor*, size_t>& pair : deferred_tlsdesc_relocs) {
TlsDescriptor* desc = pair.first;
desc->func = tlsdesc_resolver_dynamic;
desc->arg = reinterpret_cast<size_t>(&tlsdesc_args_[pair.second]);
}
+#endif
return true;
}
@@ -3785,7 +3847,7 @@
}
bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
- const android_dlextinfo* extinfo) {
+ const android_dlextinfo* extinfo, size_t* relro_fd_offset) {
if (is_image_linked()) {
// already linked.
return true;
@@ -3925,14 +3987,14 @@
/* Handle serializing/sharing the RELRO segment */
if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
- extinfo->relro_fd) < 0) {
+ extinfo->relro_fd, relro_fd_offset) < 0) {
DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
get_realpath(), strerror(errno));
return false;
}
} else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
- extinfo->relro_fd) < 0) {
+ extinfo->relro_fd, relro_fd_offset) < 0) {
DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
get_realpath(), strerror(errno));
return false;
@@ -4048,6 +4110,7 @@
std::string ld_config_file_path = get_ld_config_file_path(executable_path);
+ INFO("[ Reading linker config \"%s\" ]", ld_config_file_path.c_str());
if (!Config::read_binary_config(ld_config_file_path.c_str(),
executable_path,
g_is_asan,
@@ -4093,6 +4156,7 @@
ns->set_isolated(ns_config->isolated());
ns->set_default_library_paths(ns_config->search_paths());
ns->set_permitted_paths(ns_config->permitted_paths());
+ ns->set_whitelisted_libs(ns_config->whitelisted_libs());
namespaces[ns_config->name()] = ns;
if (ns_config->visible()) {
diff --git a/linker/linker.h b/linker/linker.h
index 964c266..4c89ceb 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -188,3 +188,9 @@
void decrement_dso_handle_reference_counter(void* dso_handle);
void purge_unused_memory();
+
+struct address_space_params {
+ void* start_addr = nullptr;
+ size_t reserved_size = 0;
+ bool must_use_address = false;
+};
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index fdb4c85..1e2f9a2 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -134,7 +134,7 @@
FreeBlockInfo* first_block = reinterpret_cast<FreeBlockInfo*>(page->bytes);
first_block->next_block = free_block_list_;
- first_block->num_free_blocks = (kAllocateSize - sizeof(LinkerBlockAllocatorPage*))/block_size_;
+ first_block->num_free_blocks = sizeof(page->bytes) / block_size_;
free_block_list_ = first_block;
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 5a728d3..7741904 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -60,7 +60,7 @@
};
explicit ConfigParser(std::string&& content)
- : content_(content), p_(0), lineno_(0), was_end_of_file_(false) {}
+ : content_(std::move(content)), p_(0), lineno_(0), was_end_of_file_(false) {}
/*
* Possible return values
@@ -80,7 +80,7 @@
continue;
}
- if (line[0] == '[' && line[line.size() - 1] == ']') {
+ if (line[0] == '[' && line.back() == ']') {
*name = line.substr(1, line.size() - 2);
return kSection;
}
@@ -147,7 +147,7 @@
PropertyValue() = default;
PropertyValue(std::string&& value, size_t lineno)
- : value_(value), lineno_(lineno) {}
+ : value_(std::move(value)), lineno_(lineno) {}
const std::string& value() const {
return value_;
@@ -269,6 +269,8 @@
}
}
+ INFO("[ Using config section \"%s\" ]", section_name.c_str());
+
// skip everything until we meet a correct section
while (true) {
std::string name;
@@ -360,7 +362,7 @@
class Properties {
public:
explicit Properties(std::unordered_map<std::string, PropertyValue>&& properties)
- : properties_(properties), target_sdk_version_(__ANDROID_API__) {}
+ : properties_(std::move(properties)), target_sdk_version_(__ANDROID_API__) {}
std::vector<std::string> get_strings(const std::string& name, size_t* lineno = nullptr) const {
auto it = find_property(name, lineno);
@@ -409,7 +411,7 @@
static std::string vndk = Config::get_vndk_version_string('-');
params.push_back({ "VNDK_VER", vndk });
- for (auto&& path : paths) {
+ for (auto& path : paths) {
format_string(&path, params);
}
@@ -550,6 +552,12 @@
ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
+ std::string whitelisted =
+ properties.get_string(property_name_prefix + ".whitelisted", &lineno);
+ if (!whitelisted.empty()) {
+ ns_config->set_whitelisted_libs(android::base::Split(whitelisted, ":"));
+ }
+
// these are affected by is_asan flag
if (is_asan) {
property_name_prefix += ".asan";
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 49739ee..75d9378 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -92,6 +92,10 @@
return permitted_paths_;
}
+ const std::vector<std::string>& whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+
const std::vector<NamespaceLinkConfig>& links() const {
return namespace_links_;
}
@@ -110,11 +114,15 @@
}
void set_search_paths(std::vector<std::string>&& search_paths) {
- search_paths_ = search_paths;
+ search_paths_ = std::move(search_paths);
}
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
- permitted_paths_ = permitted_paths;
+ permitted_paths_ = std::move(permitted_paths);
+ }
+
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = std::move(whitelisted_libs);
}
private:
const std::string name_;
@@ -122,6 +130,7 @@
bool visible_;
std::vector<std::string> search_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
std::vector<NamespaceLinkConfig> namespace_links_;
DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index 6a55bb2..4937056 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -56,6 +56,7 @@
"enable.target.sdk.version = true\n"
"additional.namespaces=system\n"
"additional.namespaces+=vndk\n"
+ "additional.namespaces+=vndk_in_system\n"
"namespace.default.isolated = true\n"
"namespace.default.search.paths = /vendor/${LIB}\n"
"namespace.default.permitted.paths = /vendor/${LIB}\n"
@@ -82,6 +83,12 @@
"namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
"namespace.vndk.links = default\n"
"namespace.vndk.link.default.allow_all_shared_libs = true\n"
+ "namespace.vndk.link.vndk_in_system.allow_all_shared_libs = true\n"
+ "namespace.vndk_in_system.isolated = true\n"
+ "namespace.vndk_in_system.visible = true\n"
+ "namespace.vndk_in_system.search.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.permitted.paths = /system/${LIB}\n"
+ "namespace.vndk_in_system.whitelisted = libz.so:libyuv.so:libtinyxml2.so\n"
"\n";
static bool write_version(const std::string& path, uint32_t version) {
@@ -165,20 +172,24 @@
ASSERT_FALSE(default_ns_links[1].allow_all_shared_libs());
auto& ns_configs = config->namespace_configs();
- ASSERT_EQ(3U, ns_configs.size());
+ ASSERT_EQ(4U, ns_configs.size());
// find second namespace
const NamespaceConfig* ns_system = nullptr;
const NamespaceConfig* ns_vndk = nullptr;
+ const NamespaceConfig* ns_vndk_in_system = nullptr;
for (auto& ns : ns_configs) {
std::string ns_name = ns->name();
- ASSERT_TRUE(ns_name == "system" || ns_name == "default" || ns_name == "vndk")
+ ASSERT_TRUE(ns_name == "system" || ns_name == "default" ||
+ ns_name == "vndk" || ns_name == "vndk_in_system")
<< "unexpected ns name: " << ns->name();
if (ns_name == "system") {
ns_system = ns.get();
} else if (ns_name == "vndk") {
ns_vndk = ns.get();
+ } else if (ns_name == "vndk_in_system") {
+ ns_vndk_in_system = ns.get();
}
}
@@ -199,6 +210,11 @@
ASSERT_EQ(1U, ns_vndk_links.size());
ASSERT_EQ("default", ns_vndk_links[0].ns_name());
ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
+
+ ASSERT_TRUE(ns_vndk_in_system != nullptr) << "vndk_in_system namespace was not found";
+ ASSERT_EQ(
+ std::vector<std::string>({"libz.so", "libyuv.so", "libtinyxml2.so"}),
+ ns_vndk_in_system->whitelisted_libs());
}
TEST(linker_config, smoke) {
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index f9fc38e..fedbc05 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -49,7 +49,7 @@
LinkerLogger() : flags_(0) { }
void ResetState();
- void Log(const char* format, ...);
+ void Log(const char* format, ...) __printflike(2, 3);
uint32_t IsEnabled(uint32_t type) {
return flags_ & type;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 9129a52..6c762a9 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -165,7 +165,7 @@
si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
si->prelink_image();
- si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
+ si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr, nullptr);
// prevents accidental unloads...
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_NODELETE);
si->set_linked();
@@ -281,7 +281,8 @@
if (!elf_reader.Read(result.path.c_str(), fd.get(), file_offset, result.file_stat.st_size)) {
__linker_error("error: %s\n", linker_get_error_buffer());
}
- if (!elf_reader.Load(nullptr)) {
+ address_space_params address_space;
+ if (!elf_reader.Load(&address_space)) {
__linker_error("error: %s\n", linker_get_error_buffer());
}
@@ -352,6 +353,8 @@
// a C-style string to last until the program exits.
static std::string exe_path = exe_info.path;
+ INFO("[ Linking executable \"%s\" ]", exe_path.c_str());
+
// Initialize the main exe's soinfo.
soinfo* si = soinfo_alloc(&g_default_namespace,
exe_path.c_str(), &exe_info.file_stat,
@@ -448,7 +451,7 @@
&namespaces)) {
__linker_cannot_link(g_argv[0]);
} else if (needed_libraries_count == 0) {
- if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
+ if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr, nullptr)) {
__linker_cannot_link(g_argv[0]);
}
si->increment_ref_count();
@@ -623,7 +626,7 @@
// itself without having to look into local_group and (2) allocators
// are not yet initialized, and therefore we cannot use linked_list.push_*
// functions at this point.
- if (!tmp_linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args.argv[0]);
+ if (!tmp_linker_so.link_image(g_empty_list, g_empty_list, nullptr, nullptr)) __linker_cannot_link(args.argv[0]);
return __linker_init_post_relocation(args, tmp_linker_so);
}
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index fd72cdc..e870ef7 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -38,6 +38,14 @@
return true;
}
+ if (!whitelisted_libs_.empty()) {
+ const char *lib_name = basename(file.c_str());
+ if (std::find(whitelisted_libs_.begin(), whitelisted_libs_.end(),
+ lib_name) == whitelisted_libs_.end()) {
+ return false;
+ }
+ }
+
for (const auto& dir : ld_library_paths_) {
if (file_is_in_dir(file, dir)) {
return true;
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index cd8b09d..f4428eb 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -87,14 +87,14 @@
return ld_library_paths_;
}
void set_ld_library_paths(std::vector<std::string>&& library_paths) {
- ld_library_paths_ = library_paths;
+ ld_library_paths_ = std::move(library_paths);
}
const std::vector<std::string>& get_default_library_paths() const {
return default_library_paths_;
}
void set_default_library_paths(std::vector<std::string>&& library_paths) {
- default_library_paths_ = library_paths;
+ default_library_paths_ = std::move(library_paths);
}
void set_default_library_paths(const std::vector<std::string>& library_paths) {
default_library_paths_ = library_paths;
@@ -104,12 +104,22 @@
return permitted_paths_;
}
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
- permitted_paths_ = permitted_paths;
+ permitted_paths_ = std::move(permitted_paths);
}
void set_permitted_paths(const std::vector<std::string>& permitted_paths) {
permitted_paths_ = permitted_paths;
}
+ const std::vector<std::string>& get_whitelisted_libs() const {
+ return whitelisted_libs_;
+ }
+ void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
+ whitelisted_libs_ = std::move(whitelisted_libs);
+ }
+ void set_whitelisted_libs(const std::vector<std::string>& whitelisted_libs) {
+ whitelisted_libs_ = whitelisted_libs;
+ }
+
const std::vector<android_namespace_link_t>& linked_namespaces() const {
return linked_namespaces_;
}
@@ -157,6 +167,7 @@
std::vector<std::string> ld_library_paths_;
std::vector<std::string> default_library_paths_;
std::vector<std::string> permitted_paths_;
+ std::vector<std::string> whitelisted_libs_;
// Loader looks into linked namespace if it was not able
// to find a library in this namespace. Note that library
// lookup in linked namespaces are limited by the list of
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 34ac606..3534287 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -166,14 +166,12 @@
return did_read_;
}
-bool ElfReader::Load(const android_dlextinfo* extinfo) {
+bool ElfReader::Load(address_space_params* address_space) {
CHECK(did_read_);
if (did_load_) {
return true;
}
- if (ReserveAddressSpace(extinfo) &&
- LoadSegments() &&
- FindPhdr()) {
+ if (ReserveAddressSpace(address_space) && LoadSegments() && FindPhdr()) {
did_load_ = true;
}
@@ -559,7 +557,7 @@
// Reserve a virtual address range big enough to hold all loadable
// segments of a program header table. This is done by creating a
// private anonymous mmap() with PROT_NONE.
-bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
+bool ElfReader::ReserveAddressSpace(address_space_params* address_space) {
ElfW(Addr) min_vaddr;
load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
if (load_size_ == 0) {
@@ -569,22 +567,11 @@
uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
void* start;
- size_t reserved_size = 0;
- bool reserved_hint = true;
- if (extinfo != nullptr) {
- if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
- reserved_size = extinfo->reserved_size;
- reserved_hint = false;
- } else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) {
- reserved_size = extinfo->reserved_size;
- }
- }
-
- if (load_size_ > reserved_size) {
- if (!reserved_hint) {
+ if (load_size_ > address_space->reserved_size) {
+ if (address_space->must_use_address) {
DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
- reserved_size - load_size_, load_size_, name_.c_str());
+ load_size_ - address_space->reserved_size, load_size_, name_.c_str());
return false;
}
start = ReserveAligned(load_size_, kLibraryAlignment);
@@ -593,8 +580,12 @@
return false;
}
} else {
- start = extinfo->reserved_addr;
+ start = address_space->start_addr;
mapped_by_caller_ = true;
+
+ // Update the reserved address space to subtract the space used by this library.
+ address_space->start_addr = reinterpret_cast<uint8_t*>(address_space->start_addr) + load_size_;
+ address_space->reserved_size -= load_size_;
}
load_start_ = start;
@@ -840,16 +831,17 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* fd -> writable file descriptor to use
+ * file_offset -> pointer to offset into file descriptor to use/update
* Return:
* 0 on error, -1 on failure (error code in errno).
*/
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count,
ElfW(Addr) load_bias,
- int fd) {
+ int fd,
+ size_t* file_offset) {
const ElfW(Phdr)* phdr = phdr_table;
const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
- ssize_t file_offset = 0;
for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
if (phdr->p_type != PT_GNU_RELRO) {
@@ -865,11 +857,11 @@
return -1;
}
void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
- MAP_PRIVATE|MAP_FIXED, fd, file_offset);
+ MAP_PRIVATE|MAP_FIXED, fd, *file_offset);
if (map == MAP_FAILED) {
return -1;
}
- file_offset += size;
+ *file_offset += size;
}
return 0;
}
@@ -887,13 +879,15 @@
* phdr_count -> number of entries in tables
* load_bias -> load bias
* fd -> readable file descriptor to use
+ * file_offset -> pointer to offset into file descriptor to use/update
* Return:
* 0 on error, -1 on failure (error code in errno).
*/
int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count,
ElfW(Addr) load_bias,
- int fd) {
+ int fd,
+ size_t* file_offset) {
// Map the file at a temporary location so we can compare its contents.
struct stat file_stat;
if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
@@ -907,7 +901,6 @@
return -1;
}
}
- size_t file_offset = 0;
// Iterate over the relro segments and compare/remap the pages.
const ElfW(Phdr)* phdr = phdr_table;
@@ -921,12 +914,12 @@
ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
- char* file_base = static_cast<char*>(temp_mapping) + file_offset;
+ char* file_base = static_cast<char*>(temp_mapping) + *file_offset;
char* mem_base = reinterpret_cast<char*>(seg_page_start);
size_t match_offset = 0;
size_t size = seg_page_end - seg_page_start;
- if (file_size - file_offset < size) {
+ if (file_size - *file_offset < size) {
// File is too short to compare to this segment. The contents are likely
// different as well (it's probably for a different library version) so
// just don't bother checking.
@@ -950,7 +943,7 @@
// Map over similar pages.
if (mismatch_offset > match_offset) {
void* map = mmap(mem_base + match_offset, mismatch_offset - match_offset,
- PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, match_offset);
+ PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, *file_offset + match_offset);
if (map == MAP_FAILED) {
munmap(temp_mapping, file_size);
return -1;
@@ -961,7 +954,7 @@
}
// Add to the base file offset in case there are multiple relro segments.
- file_offset += size;
+ *file_offset += size;
}
munmap(temp_mapping, file_size);
return 0;
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 0eee089..5d1cfc2 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -43,7 +43,7 @@
ElfReader();
bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size);
- bool Load(const android_dlextinfo* extinfo);
+ bool Load(address_space_params* address_space);
const char* name() const { return name_.c_str(); }
size_t phdr_count() const { return phdr_num_; }
@@ -62,7 +62,7 @@
bool ReadProgramHeaders();
bool ReadSectionHeaders();
bool ReadDynamicSection();
- bool ReserveAddressSpace(const android_dlextinfo* extinfo);
+ bool ReserveAddressSpace(address_space_params* address_space);
bool LoadSegments();
bool FindPhdr();
bool CheckPhdr(ElfW(Addr));
@@ -119,10 +119,10 @@
ElfW(Addr) load_bias);
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, int fd);
+ ElfW(Addr) load_bias, int fd, size_t* file_offset);
int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, int fd);
+ ElfW(Addr) load_bias, int fd, size_t* file_offset);
#if defined(__arm__)
int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count, ElfW(Addr) load_bias,
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index dd9c6aa..80c51af 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -223,7 +223,7 @@
void call_pre_init_constructors();
bool prelink_image();
bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
- const android_dlextinfo* extinfo);
+ const android_dlextinfo* extinfo, size_t* relro_fd_offset);
bool protect_relro();
void add_child(soinfo* child);
diff --git a/tests/Android.bp b/tests/Android.bp
index b039f00..21acc36 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -153,6 +153,7 @@
"sys_epoll_test.cpp",
"sys_mman_test.cpp",
"sys_msg_test.cpp",
+ "sys_param_test.cpp",
"sys_personality_test.cpp",
"sys_prctl_test.cpp",
"sys_procfs_test.cpp",
@@ -194,7 +195,6 @@
include_dirs: [
"bionic/libc",
- "external/tinyxml2",
],
target: {
@@ -386,6 +386,7 @@
],
static_libs: [
"libmeminfo",
+ "libprocinfo",
"libziparchive",
"libLLVMObject",
"libLLVMBitReader",
@@ -425,6 +426,11 @@
cc_defaults {
name: "bionic_unit_tests_defaults",
host_supported: false,
+ gtest: false,
+
+ defaults: [
+ "bionic_tests_defaults",
+ ],
whole_static_libs: [
"libBionicTests",
@@ -436,12 +442,14 @@
"libtinyxml2",
"liblog",
"libbase",
+ "libgtest_isolated",
],
srcs: [
// TODO: Include __cxa_thread_atexit_test.cpp to glibc tests once it is upgraded (glibc 2.18+)
"__cxa_thread_atexit_test.cpp",
"gtest_globals.cpp",
+ "gtest_main.cpp",
"thread_local_test.cpp",
],
@@ -460,6 +468,7 @@
android: {
shared_libs: [
"ld-android",
+ "libandroidicu",
"libdl",
"libdl_preempt_test_1",
"libdl_preempt_test_2",
@@ -487,29 +496,6 @@
],
},
},
-}
-
-cc_test {
- name: "bionic-unit-tests",
- gtest: false,
- defaults: [
- "bionic_unit_tests_defaults",
- "bionic_tests_defaults",
- ],
-
- srcs: [
- "gtest_main.cpp",
- ],
-
- static_libs: [
- "libgtest_isolated",
- ],
-
- target: {
- android: {
- shared_libs: ["libicuuc"],
- },
- },
required: [
"cfi_test_helper",
@@ -528,6 +514,7 @@
"libdlext_test_different_soname",
"libdlext_test_fd",
"libdlext_test_norelro",
+ "libdlext_test_recursive",
"libdlext_test_runpath_zip_zipaligned",
"libdlext_test",
"libdlext_test_zip",
@@ -641,6 +628,8 @@
"libnstest_ns_a_public1_internal",
"libnstest_ns_b_public2",
"libnstest_ns_b_public3",
+ "libsegment_gap_inner",
+ "libsegment_gap_outer",
"ld_preload_test_helper",
"ld_preload_test_helper_lib1",
"ld_preload_test_helper_lib2",
@@ -651,6 +640,24 @@
],
}
+cc_test {
+ name: "bionic-unit-tests",
+ defaults: [
+ "bionic_unit_tests_defaults",
+ ],
+}
+
+cc_test {
+ name: "bionic-unit-tests-scudo",
+ defaults: [
+ "bionic_unit_tests_defaults",
+ ],
+
+ shared_libs: [
+ "libc_scudo",
+ ],
+}
+
// -----------------------------------------------------------------------------
// Tests for the device linked against bionic's static library. Run with:
// adb shell /data/nativetest/bionic-unit-tests-static/bionic-unit-tests-static
@@ -693,10 +700,6 @@
static_executable: true,
stl: "libc++_static",
-
- // libclang_rt.builtins does not work with libm
- // http://b/117167374
- no_libcrt: true,
}
// -----------------------------------------------------------------------------
diff --git a/tests/__aeabi_read_tp_test.cpp b/tests/__aeabi_read_tp_test.cpp
index 6974658..7209a75 100644
--- a/tests/__aeabi_read_tp_test.cpp
+++ b/tests/__aeabi_read_tp_test.cpp
@@ -38,6 +38,6 @@
#if defined(__arm__)
ASSERT_EQ(__aeabi_read_tp(), static_cast<void*>(__get_tls()));
#else
- GTEST_LOG_(INFO) << "__aeabi_read_tp is only available on arm32.\n";
+ GTEST_SKIP() << "__aeabi_read_tp is only available on arm32";
#endif
}
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index 4940e3a..6c4758e 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -104,7 +104,7 @@
async_safe_format_buffer(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
EXPECT_STREQ("a68719476736,6,7,8z", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -114,7 +114,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MAX);
EXPECT_STREQ("2147483647", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -124,7 +124,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MIN);
EXPECT_STREQ("-2147483648", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -138,7 +138,7 @@
EXPECT_STREQ("2147483647", buf);
#endif
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -152,7 +152,7 @@
EXPECT_STREQ("-2147483648", buf);
#endif
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -162,7 +162,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MAX);
EXPECT_STREQ("9223372036854775807", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -172,7 +172,7 @@
async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MIN);
EXPECT_STREQ("-9223372036854775808", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -196,6 +196,6 @@
ASSERT_EQ(4, async_safe_format_buffer(buf, 2, "xxxx"));
EXPECT_STREQ("x", buf);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 3bbddbb..f015b2c 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -27,7 +27,6 @@
#define __INTRODUCED_IN(x)
#define __INTRODUCED_IN_32(x)
#define __INTRODUCED_IN_64(x)
-#define __INTRODUCED_IN_FUTURE
#define __RENAME_LDBL(a,b,c)
#endif
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index 468ce3d..9e46394 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -138,7 +138,7 @@
TEST(dl, preinit_system_calls) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
+ SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
std::string helper = GetTestlibRoot() +
"/preinit_syscall_test_helper/preinit_syscall_test_helper";
chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
@@ -150,7 +150,7 @@
TEST(dl, preinit_getauxval) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan not initialized in preinit_array, b/124007027
+ SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
std::string helper = GetTestlibRoot() +
"/preinit_getauxval_test_helper/preinit_getauxval_test_helper";
chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
@@ -242,7 +242,7 @@
// whose search paths include the 'ns2/' subdir.
TEST(dl, exec_with_ld_config_file) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // libclang_rt.hwasan is not found with custom ld config
+ SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
if (!is_debuggable_build()) {
// LD_CONFIG_FILE is not supported on user build
return;
@@ -265,7 +265,7 @@
// additional namespaces other than the default namespace.
TEST(dl, exec_with_ld_config_file_with_ld_preload) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // libclang_rt.hwasan is not found with custom ld config
+ SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
if (!is_debuggable_build()) {
// LD_CONFIG_FILE is not supported on user build
return;
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index aff5e37..3af52d4 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -37,6 +37,7 @@
#include <sys/wait.h>
#include <meminfo/procmeminfo.h>
+#include <procinfo/process_map.h>
#include <ziparchive/zip_archive.h>
#include "gtest_globals.h"
@@ -59,13 +60,14 @@
typedef int (*fn)(void);
constexpr const char* kLibName = "libdlext_test.so";
+constexpr const char* kLibNameRecursive = "libdlext_test_recursive.so";
constexpr const char* kLibNameNoRelro = "libdlext_test_norelro.so";
constexpr const char* kLibZipSimpleZip = "libdir/libatest_simple_zip.so";
constexpr auto kLibSize = 1024 * 1024; // how much address space to reserve for it
class DlExtTest : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
handle_ = nullptr;
// verify that we don't have the library loaded already
void* h = dlopen(kLibName, RTLD_NOW | RTLD_NOLOAD);
@@ -76,7 +78,7 @@
ASSERT_EQ(std::string("dlopen failed: library \"") + kLibNameNoRelro + "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
}
- virtual void TearDown() {
+ void TearDown() override {
if (handle_ != nullptr) {
ASSERT_DL_ZERO(dlclose(handle_));
}
@@ -338,6 +340,48 @@
EXPECT_EQ(nullptr, handle_);
}
+TEST_F(DlExtTest, ReservedRecursive) {
+ void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_TRUE(start != MAP_FAILED);
+ android_dlextinfo extinfo;
+ extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
+ extinfo.reserved_addr = start;
+ extinfo.reserved_size = kLibSize;
+ handle_ = android_dlopen_ext(kLibNameRecursive, RTLD_NOW, &extinfo);
+ ASSERT_DL_NOTNULL(handle_);
+
+ fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_GE(reinterpret_cast<void*>(f), start);
+ EXPECT_LT(reinterpret_cast<void*>(f),
+ reinterpret_cast<char*>(start) + kLibSize);
+ EXPECT_EQ(4, f());
+
+ f = reinterpret_cast<fn>(dlsym(handle_, "getBiggerRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_GE(reinterpret_cast<void*>(f), start);
+ EXPECT_LT(reinterpret_cast<void*>(f),
+ reinterpret_cast<char*>(start) + kLibSize);
+ EXPECT_EQ(8, f());
+
+ uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
+ ASSERT_DL_NOTNULL(taxicab_number);
+ EXPECT_GE(reinterpret_cast<void*>(taxicab_number), start);
+ EXPECT_LT(reinterpret_cast<void*>(taxicab_number), reinterpret_cast<char*>(start) + kLibSize);
+ EXPECT_EQ(1729U, *taxicab_number);
+}
+
+TEST_F(DlExtTest, ReservedRecursiveTooSmall) {
+ void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_TRUE(start != MAP_FAILED);
+ android_dlextinfo extinfo;
+ extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
+ extinfo.reserved_addr = start;
+ extinfo.reserved_size = PAGE_SIZE;
+ handle_ = android_dlopen_ext(kLibNameRecursive, RTLD_NOW, &extinfo);
+ EXPECT_EQ(nullptr, handle_);
+}
+
TEST_F(DlExtTest, ReservedHint) {
void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_TRUE(start != MAP_FAILED);
@@ -374,7 +418,7 @@
class DlExtRelroSharingTest : public DlExtTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
DlExtTest::SetUp();
void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_TRUE(start != MAP_FAILED);
@@ -384,14 +428,18 @@
extinfo_.relro_fd = -1;
}
- virtual void TearDown() {
+ void TearDown() override {
DlExtTest::TearDown();
}
- void CreateRelroFile(const char* lib, const char* relro_file) {
+ void CreateRelroFile(const char* lib, const char* relro_file, bool recursive) {
int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
ASSERT_NOERROR(relro_fd);
+ if (recursive) {
+ extinfo_.flags |= ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
+ }
+
pid_t pid = fork();
if (pid == 0) {
// child process
@@ -402,7 +450,21 @@
fprintf(stderr, "in child: %s\n", dlerror());
exit(1);
}
- exit(0);
+ fn f = reinterpret_cast<fn>(dlsym(handle, "getRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(4, f());
+
+ if (recursive) {
+ fn f = reinterpret_cast<fn>(dlsym(handle, "getBiggerRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(8, f());
+ }
+
+ uint32_t* taxicab_number =
+ reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
+ ASSERT_DL_NOTNULL(taxicab_number);
+ EXPECT_EQ(1729U, *taxicab_number);
+ exit(testing::Test::HasFailure());
}
// continuing in parent
@@ -417,13 +479,19 @@
extinfo_.relro_fd = relro_fd;
}
- void TryUsingRelro(const char* lib) {
+ void TryUsingRelro(const char* lib, bool recursive) {
handle_ = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
ASSERT_DL_NOTNULL(handle_);
fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
ASSERT_DL_NOTNULL(f);
EXPECT_EQ(4, f());
+ if (recursive) {
+ fn f = reinterpret_cast<fn>(dlsym(handle_, "getBiggerRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(8, f());
+ }
+
uint32_t* taxicab_number =
reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
ASSERT_DL_NOTNULL(taxicab_number);
@@ -433,6 +501,8 @@
void SpawnChildrenAndMeasurePss(const char* lib, const char* relro_file, bool share_relro,
size_t* pss_out);
+ std::string FindMappingName(void* ptr);
+
android_dlextinfo extinfo_;
};
@@ -440,8 +510,29 @@
TemporaryFile tf; // Use tf to get an unique filename.
ASSERT_NOERROR(close(tf.fd));
- ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path));
- ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName));
+ ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path, false));
+ ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName, false));
+ void* relro_data = dlsym(handle_, "lots_of_relro");
+ ASSERT_DL_NOTNULL(relro_data);
+ EXPECT_EQ(tf.path, FindMappingName(relro_data));
+
+ // Use destructor of tf to close and unlink the file.
+ tf.fd = extinfo_.relro_fd;
+}
+
+TEST_F(DlExtRelroSharingTest, ChildWritesGoodDataRecursive) {
+ TemporaryFile tf; // Use tf to get an unique filename.
+ ASSERT_NOERROR(close(tf.fd));
+
+ ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameRecursive, tf.path, true));
+ ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibNameRecursive, true));
+ void* relro_data = dlsym(handle_, "lots_of_relro");
+ ASSERT_DL_NOTNULL(relro_data);
+ EXPECT_EQ(tf.path, FindMappingName(relro_data));
+ void* recursive_relro_data = dlsym(handle_, "lots_more_relro");
+ ASSERT_DL_NOTNULL(recursive_relro_data);
+ EXPECT_EQ(tf.path, FindMappingName(recursive_relro_data));
+
// Use destructor of tf to close and unlink the file.
tf.fd = extinfo_.relro_fd;
@@ -451,27 +542,24 @@
TemporaryFile tf; // // Use tf to get an unique filename.
ASSERT_NOERROR(close(tf.fd));
- ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameNoRelro, tf.path));
- ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibNameNoRelro));
+ ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameNoRelro, tf.path, false));
+ ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibNameNoRelro, false));
// Use destructor of tf to close and unlink the file.
tf.fd = extinfo_.relro_fd;
}
TEST_F(DlExtRelroSharingTest, RelroFileEmpty) {
- ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName));
+ ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName, false));
}
TEST_F(DlExtRelroSharingTest, VerifyMemorySaving) {
- if (geteuid() != 0) {
- GTEST_LOG_(INFO) << "This test must be run as root.\n";
- return;
- }
+ if (geteuid() != 0) GTEST_SKIP() << "This test must be run as root";
TemporaryFile tf; // Use tf to get an unique filename.
ASSERT_NOERROR(close(tf.fd));
- ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path));
+ ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path, false));
int pipefd[2];
ASSERT_NOERROR(pipe(pipefd));
@@ -586,6 +674,21 @@
}
}
+std::string DlExtRelroSharingTest::FindMappingName(void* ptr) {
+ uint64_t addr = reinterpret_cast<uint64_t>(ptr);
+ std::string found_name = "<not found>";
+
+ EXPECT_TRUE(android::procinfo::ReadMapFile(
+ "/proc/self/maps",
+ [&](uint64_t start, uint64_t end, uint16_t, uint16_t, ino_t, const char* name) {
+ if (addr >= start && addr < end) {
+ found_name = name;
+ }
+ }));
+
+ return found_name;
+}
+
// Testing namespaces
static const char* g_public_lib = "libnstest_public.so";
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 8a3b6f3..c6d7ddb 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -49,6 +49,12 @@
#pragma clang diagnostic pop
#endif // defined(__ANDROID__) && (defined(__arm__) || defined(__i386__))
+// Declared manually because the macro definitions in <elf.h> conflict with LLVM headers.
+#ifdef __arm__
+typedef uintptr_t _Unwind_Ptr;
+extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
+#endif
+
#define ASSERT_SUBSTR(needle, haystack) \
ASSERT_PRED_FORMAT2(::testing::IsSubstring, needle, haystack)
@@ -254,8 +260,7 @@
TEST(dlfcn, dlopen_vdso) {
#if __has_include(<sys/auxv.h>)
if (getauxval(AT_SYSINFO_EHDR) == 0) {
- GTEST_LOG_(INFO) << "getauxval(AT_SYSINFO_EHDR) == 0, skipping this test.";
- return;
+ GTEST_SKIP() << "getauxval(AT_SYSINFO_EHDR) == 0, skipping this test";
}
#endif
@@ -970,23 +975,23 @@
#if defined(__BIONIC__)
ASSERT_EQ(handle1, handle2);
#else
- GTEST_LOG_(INFO) << "Skipping ASSERT_EQ(handle1, handle2) for glibc: "
- "it loads a separate copy of the main executable "
- "on dlopen by absolute path.";
+ GTEST_SKIP() << "Skipping ASSERT_EQ(handle1, handle2) for glibc: "
+ "it loads a separate copy of the main executable "
+ "on dlopen by absolute path";
#endif
}
#if defined (__aarch64__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/arm64/"
+#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/arm64/"
#elif defined (__arm__)
#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/arm/"
#elif defined (__i386__)
#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/x86/"
#elif defined (__x86_64__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/x86_64/"
+#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/x86_64/"
#elif defined (__mips__)
#if defined(__LP64__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/mips64/"
+#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/mips64/"
#else
#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/mips/"
#endif
@@ -997,7 +1002,10 @@
#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
TEST(dlfcn, dladdr_libc) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc returns libc.so's ldconfig path, which is a symlink (not a realpath)";
+#endif
+
Dl_info info;
void* addr = reinterpret_cast<void*>(puts); // well-known libc function
ASSERT_TRUE(dladdr(addr, &info) != 0);
@@ -1019,10 +1027,6 @@
// TODO: add check for dfi_fbase
ASSERT_STREQ("puts", info.dli_sname);
ASSERT_EQ(addr, info.dli_saddr);
-#else
- GTEST_LOG_(INFO) << "This test does nothing for glibc. Glibc returns path from ldconfig "
- "for libc.so, which is symlink itself (not a realpath).\n";
-#endif
}
TEST(dlfcn, dladdr_invalid) {
@@ -1060,7 +1064,7 @@
ASSERT_STREQ("getRandomNumber", dlinfo.dli_sname);
ASSERT_SUBSTR("libgnu-hash-table-library.so", dlinfo.dli_fname);
#else
- GTEST_LOG_(INFO) << "This test does nothing for mips/mips64; mips toolchain does not support '--hash-style=gnu'\n";
+ GTEST_SKIP() << "mips toolchain does not support '--hash-style=gnu'";
#endif
}
@@ -1178,13 +1182,13 @@
// that calls dlopen(libc...). This is to test the situation
// described in b/7941716.
TEST(dlfcn, dlopen_dlopen_from_ctor) {
-#if defined(__BIONIC__)
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc segfaults if you try to call dlopen from a constructor";
+#endif
+
void* handle = dlopen("libtest_dlopen_from_ctor_main.so", RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
dlclose(handle);
-#else
- GTEST_LOG_(INFO) << "This test is disabled for glibc (glibc segfaults if you try to call dlopen from a constructor).\n";
-#endif
}
static std::string g_fini_call_order_str;
@@ -1732,4 +1736,28 @@
ASSERT_TRUE(handle != nullptr) << dlerror();
}
+TEST(dlfcn, segment_gap) {
+ void* handle = dlopen("libsegment_gap_outer.so", RTLD_NOW);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+
+ auto get_inner = reinterpret_cast<void* (*)()>(dlsym(handle, "get_inner"));
+ void* inner = get_inner();
+ (void)inner;
+
+#if __arm__
+ int count;
+ _Unwind_Ptr outer_exidx = dl_unwind_find_exidx(reinterpret_cast<_Unwind_Ptr>(get_inner), &count);
+ _Unwind_Ptr inner_exidx = dl_unwind_find_exidx(reinterpret_cast<_Unwind_Ptr>(inner), &count);
+ EXPECT_NE(0u, outer_exidx);
+ EXPECT_NE(0u, inner_exidx);
+ EXPECT_NE(inner_exidx, outer_exidx);
+#endif
+
+ Dl_info info;
+ int rc = dladdr(inner, &info);
+ ASSERT_NE(rc, 0);
+
+ EXPECT_NE(nullptr, strstr(info.dli_fname, "libsegment_gap_inner.so"));
+}
+
#endif
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 36bdc3b..88225d8 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -146,7 +146,7 @@
ASSERT_EQ(nullptr, missing_weak_dyn_tls_addr());
}).join();
#else
- GTEST_LOG_(INFO) << "This test is only run on TLSDESC-based targets.\n";
+ GTEST_SKIP() << "This test is only run on TLSDESC-based targets";
#endif
}
@@ -215,7 +215,7 @@
#undef LOAD_LIB
#else
- GTEST_LOG_(INFO) << "This test is skipped for glibc because it tests Bionic internals.";
+ GTEST_SKIP() << "test doesn't apply to glibc";
#endif
}
@@ -266,6 +266,6 @@
dlclose(lib);
}
#else
- GTEST_LOG_(INFO) << "This test is skipped for glibc because it tests Bionic internals.";
+ GTEST_SKIP() << "test doesn't apply to glibc";
#endif
}
diff --git a/tests/endian_test.cpp b/tests/endian_test.cpp
index 85d56f0..3d6dc4d 100644
--- a/tests/endian_test.cpp
+++ b/tests/endian_test.cpp
@@ -46,7 +46,7 @@
ASSERT_EQ(be32, htonl(le32));
ASSERT_EQ(be64, htonq(le64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have htons/htonl/htonq in <endian.h>";
#endif
}
@@ -56,7 +56,7 @@
ASSERT_EQ(le32, ntohl(be32));
ASSERT_EQ(le64, ntohq(be64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have ntohs/ntohl/ntohq in <endian.h>";
#endif
}
@@ -90,7 +90,7 @@
ASSERT_EQ(le32, betoh32(be32));
ASSERT_EQ(le64, betoh64(be64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have betoh16/betoh32/betoh64";
#endif
}
@@ -100,6 +100,6 @@
ASSERT_EQ(le32, letoh32(le32));
ASSERT_EQ(le64, letoh64(le64));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+ GTEST_SKIP() << "glibc doesn't have letoh16/letoh32/letoh64";
#endif
}
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index bc33251..489b701 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -143,7 +143,7 @@
ASSERT_FORTIFY(stpcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "stpcpy not available";
#endif // __BIONIC__
}
@@ -155,7 +155,7 @@
ASSERT_FORTIFY(strcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -167,7 +167,7 @@
ASSERT_FORTIFY(strcpy(myfoo.empty, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -179,7 +179,7 @@
ASSERT_FORTIFY(strcpy(myfoo.one, src));
free(src);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -191,7 +191,7 @@
ASSERT_FORTIFY(printf("%s", strchr(myfoo.a, 'a')));
ASSERT_FORTIFY(printf("%s", strchr(static_cast<const char*>(myfoo.a), 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -203,7 +203,7 @@
ASSERT_FORTIFY(printf("%s", strrchr(myfoo.a, 'a')));
ASSERT_FORTIFY(printf("%s", strrchr(static_cast<const char*>(myfoo.a), 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -215,7 +215,7 @@
ASSERT_FORTIFY(printf("%s", memchr(myfoo.a, 'a', asize)));
ASSERT_FORTIFY(printf("%s", memchr(static_cast<const void*>(myfoo.a), 'a', asize)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -227,7 +227,7 @@
ASSERT_FORTIFY(printf("%s", memrchr(myfoo.a, 'a', asize)));
ASSERT_FORTIFY(printf("%s", memrchr(static_cast<const void*>(myfoo.a), 'a', asize)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -238,7 +238,7 @@
size_t n = strlen(myfoo.a);
ASSERT_FORTIFY(strlcpy(myfoo.one, myfoo.a, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcpy not available";
#endif // __BIONIC__
}
@@ -250,7 +250,7 @@
size_t n = strlen(myfoo.a);
ASSERT_FORTIFY(strlcat(myfoo.one, myfoo.a, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcat not available";
#endif // __BIONIC__
}
@@ -315,7 +315,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -327,7 +327,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -339,7 +339,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -351,7 +351,7 @@
ASSERT_FORTIFY(strcpy(buf, orig));
free(orig);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -361,7 +361,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%zd", strlen(buf)));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -371,7 +371,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%s", strchr(buf, 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -381,7 +381,7 @@
memcpy(buf, "0123456789", sizeof(buf));
ASSERT_FORTIFY(printf("%s", strrchr(buf, 'a')));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
}
@@ -393,7 +393,7 @@
size_t n = strlen(bufa);
ASSERT_FORTIFY(strlcpy(bufb, bufa, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcpy not available";
#endif // __BIONIC__
}
@@ -406,7 +406,7 @@
size_t n = strlen(bufa);
ASSERT_FORTIFY(strlcat(bufb, bufa, n));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "strlcat not available";
#endif // __BIONIC__
}
diff --git a/tests/getauxval_test.cpp b/tests/getauxval_test.cpp
index aa21817..f4ec7f5 100644
--- a/tests/getauxval_test.cpp
+++ b/tests/getauxval_test.cpp
@@ -61,5 +61,5 @@
return;
}
#endif
- GTEST_LOG_(INFO) << "This test is only meaningful for 32-bit ARM code on 64-bit devices.\n";
+ GTEST_SKIP() << "This test is only meaningful for 32-bit ARM code on 64-bit devices";
}
diff --git a/tests/getcwd_test.cpp b/tests/getcwd_test.cpp
index 791ffae..97b1d4f 100644
--- a/tests/getcwd_test.cpp
+++ b/tests/getcwd_test.cpp
@@ -51,7 +51,7 @@
}
TEST(getcwd, auto_too_large) {
- SKIP_WITH_HWASAN; // allocation size too large
+ SKIP_WITH_HWASAN << "allocation size too large";
// If we ask the library to allocate an unreasonably large buffer, ERANGE.
errno = 0;
char* cwd = getcwd(nullptr, static_cast<size_t>(-1));
diff --git a/tests/grp_pwd_file_test.cpp b/tests/grp_pwd_file_test.cpp
index 66866fb..adcdbd6 100644
--- a/tests/grp_pwd_file_test.cpp
+++ b/tests/grp_pwd_file_test.cpp
@@ -103,7 +103,7 @@
EXPECT_FALSE(passwd_file.FindById(3, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -123,7 +123,7 @@
EXPECT_FALSE(group_file.FindById(3, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -161,7 +161,7 @@
EXPECT_FALSE(passwd_file.FindById(50, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -197,7 +197,7 @@
EXPECT_FALSE(group_file.FindById(799, nullptr));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -219,7 +219,7 @@
FindAndCheckPasswdEntry(&passwd_file, "vendor_name", 3, 4, "dir", "shell");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -241,6 +241,6 @@
FindAndCheckGroupEntry(&group_file, "vendor_name", 2);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index eb8fe2a..b46839b 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -138,17 +138,13 @@
#else // !defined(__BIONIC__)
-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 */,
bool /* check_username */) {
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
#endif
@@ -311,7 +307,7 @@
expect_ids(uids);
#else
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -382,16 +378,12 @@
#else // !defined(__BIONIC__)
-static void print_no_getgrnam_test_info() {
- GTEST_LOG_(INFO) << "This test is about gid/group_name translation for Android, which does nothing on libc other than bionic.\n";
-}
-
static void check_get_group(const char*, gid_t, bool) {
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
static void check_get_group(const char*, gid_t) {
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
}
#endif
@@ -501,7 +493,7 @@
check_group(grp[0], "root", 0);
check_group(grp[1], "system", 1000);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -521,7 +513,7 @@
check_group(grp[0], "root", 0);
check_group(grp[1], "system", 1000);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -561,7 +553,7 @@
expect_ids(gids);
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -590,7 +582,7 @@
TestAidNamePrefix("/vendor/etc/passwd");
#else
- print_no_getpwnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -602,6 +594,6 @@
TestAidNamePrefix("/vendor/etc/group");
#else
- print_no_getgrnam_test_info();
+ GTEST_SKIP() << "bionic-only test";
#endif
}
diff --git a/tests/libgen_test.cpp b/tests/libgen_test.cpp
index d5b5eb6..24f7923 100644
--- a/tests/libgen_test.cpp
+++ b/tests/libgen_test.cpp
@@ -78,7 +78,7 @@
TestBasename(".", ".", 1, buf, sizeof(buf), 0);
TestBasename("..", "..", 2, buf, sizeof(buf), 0);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "basename_r is only available on 32-bit bionic";
#endif // __BIONIC__
}
@@ -95,6 +95,6 @@
TestDirname(".", ".", 1, buf, sizeof(buf), 0);
TestDirname("..", ".", 1, buf, sizeof(buf), 0);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "dirname_r is only available on 32-bit bionic";
#endif // __BIONIC__
}
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index d58b6b8..422cd75 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -918,3 +918,18 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["exec_linker_helper_lib.cpp"],
}
+
+cc_test_library {
+ name: "libsegment_gap_outer",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["segment_gap_outer.cpp"],
+ ldflags: ["-Wl,-T,bionic/tests/libs/segment_gap_outer.lds"],
+}
+
+cc_test_library {
+ name: "libsegment_gap_inner",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["segment_gap_inner.cpp"],
+}
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index 5bd028d..c40277d 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -49,6 +49,21 @@
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
+# Library used by dlext tests - recursive use of RELRO sharing
+# -----------------------------------------------------------------------------
+libdlext_test_recursive_src_files := \
+ dlext_test_recursive_library.cpp \
+
+libdlext_test_recursive_ldflags := \
+ -Wl,-z,relro \
+
+libdlext_test_recursive_shared_libraries := libdlext_test
+
+module := libdlext_test_recursive
+module_tag := optional
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
# Library used by dlext tests - different name non-default location
# -----------------------------------------------------------------------------
module := libdlext_test_fd
diff --git a/tests/libs/dlext_test_recursive_library.cpp b/tests/libs/dlext_test_recursive_library.cpp
new file mode 100644
index 0000000..b37bd70
--- /dev/null
+++ b/tests/libs/dlext_test_recursive_library.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+extern "C" int getRandomNumber();
+
+class B {
+public:
+ virtual int getBiggerRandomNumber() {
+ // Call to the other library.
+ return getRandomNumber() * 2;
+ }
+
+ virtual ~B() {}
+};
+
+B b;
+
+// nested macros to make it easy to define a large amount of read-only data
+// which will require relocation.
+#define B_16 &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b, &b,
+#define B_128 B_16 B_16 B_16 B_16 B_16 B_16 B_16 B_16
+#define B_1024 B_128 B_128 B_128 B_128 B_128 B_128 B_128 B_128
+
+extern "C" B* const lots_more_relro[] = {
+ B_1024 B_1024 B_1024 B_1024 B_1024 B_1024 B_1024 B_1024
+};
+
+extern "C" int getBiggerRandomNumber() {
+ // access the relro section (twice, in fact, once for the pointer, and once
+ // for the vtable of B) to check it's actually there.
+ return lots_more_relro[0]->getBiggerRandomNumber();
+}
diff --git a/tests/libs/segment_gap_inner.cpp b/tests/libs/segment_gap_inner.cpp
new file mode 100644
index 0000000..f23b065
--- /dev/null
+++ b/tests/libs/segment_gap_inner.cpp
@@ -0,0 +1 @@
+extern "C" void inner() {}
diff --git a/tests/libs/segment_gap_outer.cpp b/tests/libs/segment_gap_outer.cpp
new file mode 100644
index 0000000..fb448e7
--- /dev/null
+++ b/tests/libs/segment_gap_outer.cpp
@@ -0,0 +1,25 @@
+#include <android/dlext.h>
+#include <dlfcn.h>
+#include <jni.h>
+#include <stdlib.h>
+
+extern "C" void text_before_start_of_gap() {}
+char end_of_gap[0x1000];
+
+extern "C" void* get_inner() {
+ android_dlextinfo info = {};
+ info.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
+
+ char* start_of_gap =
+ reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(text_before_start_of_gap) & ~0xfffull) +
+ 0x1000;
+ info.reserved_addr = start_of_gap;
+ info.reserved_size = end_of_gap - start_of_gap;
+
+ void *handle = android_dlopen_ext("libsegment_gap_inner.so", RTLD_NOW, &info);
+ if (!handle) {
+ __builtin_trap();
+ }
+
+ return dlsym(handle, "inner");
+}
diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds
new file mode 100644
index 0000000..f326aab
--- /dev/null
+++ b/tests/libs/segment_gap_outer.lds
@@ -0,0 +1,27 @@
+SECTIONS {
+ # This starts off fairly normal: rodata, text, data, relro, bss with
+ # appropriate alignment between them.
+ . = SIZEOF_HEADERS;
+ .rodata : {}
+ . = ALIGN(0x1000);
+ .text : {}
+ . = ALIGN(0x1000);
+ .data : {}
+ . = ALIGN(0x1000);
+ .data.rel.ro : {}
+ . = ALIGN(0x1000);
+ .bss : {}
+
+ # Now create the gap. We need a text segment first to prevent the linker from
+ # merging .bss with .bss.end_of_gap.
+ . = ALIGN(0x1000);
+ .text.text_before_start_of_gap : {
+ *(.text.text_before_start_of_gap);
+ }
+
+ # Place end_of_gap at the end of the gap.
+ . = 0x1000000;
+ .bss.end_of_gap : {
+ *(.bss.end_of_gap);
+ }
+}
diff --git a/tests/link_test.cpp b/tests/link_test.cpp
index 1bdee9f..cf5fc0b 100644
--- a/tests/link_test.cpp
+++ b/tests/link_test.cpp
@@ -231,6 +231,6 @@
}
ASSERT_TRUE(found);
#else
- GTEST_LOG_(INFO) << "dl_unwind_find_exidx is an ARM-only API\n";
+ GTEST_SKIP() << "dl_unwind_find_exidx is an ARM-only API";
#endif
}
diff --git a/tests/malloc_iterate_test.cpp b/tests/malloc_iterate_test.cpp
index 76583eb..9d4fe04 100644
--- a/tests/malloc_iterate_test.cpp
+++ b/tests/malloc_iterate_test.cpp
@@ -150,7 +150,7 @@
FreePtrs(&test_data);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -169,7 +169,7 @@
FreePtrs(&test_data);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -193,7 +193,7 @@
ASSERT_EQ(0UL, test_data.total_allocated_bytes);
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -222,6 +222,6 @@
ASSERT_NE(-1, wait_pid) << "Unknown failure in waitpid.";
ASSERT_EQ(0, wait_pid) << "malloc_disable did not prevent allocation calls.";
#else
- GTEST_LOG_(INFO) << "Skipping, this is a bionic only test.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 658f8bd..706de15 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -18,11 +18,17 @@
#include <elf.h>
#include <limits.h>
+#include <pthread.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <malloc.h>
#include <unistd.h>
+#include <atomic>
#include <tinyxml2.h>
#include <android-base/file.h>
@@ -88,7 +94,7 @@
}
TEST(malloc, memalign_multiple) {
- SKIP_WITH_HWASAN; // hwasan requires power of 2 alignment.
+ SKIP_WITH_HWASAN << "hwasan requires power of 2 alignment";
// Memalign test where the alignment is any value.
for (size_t i = 0; i <= 12; i++) {
for (size_t alignment = 1 << i; alignment < (1U << (i+1)); alignment++) {
@@ -335,6 +341,7 @@
TEST(malloc, malloc_info) {
#ifdef __BIONIC__
+ SKIP_WITH_HWASAN; // hwasan does not implement malloc_info
char* buf;
size_t bufsize;
FILE* memstream = open_memstream(&buf, &bufsize);
@@ -348,35 +355,42 @@
auto root = doc.FirstChildElement();
ASSERT_NE(nullptr, root);
ASSERT_STREQ("malloc", root->Name());
- ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
+ if (std::string(root->Attribute("version")) == "jemalloc-1") {
+ // Verify jemalloc version of this data.
+ ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
- auto arena = root->FirstChildElement();
- for (; arena != nullptr; arena = arena->NextSiblingElement()) {
- int val;
+ auto arena = root->FirstChildElement();
+ for (; arena != nullptr; arena = arena->NextSiblingElement()) {
+ int val;
- ASSERT_STREQ("heap", arena->Name());
- ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- arena->FirstChildElement("allocated-large")->QueryIntText(&val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- arena->FirstChildElement("bins-total")->QueryIntText(&val));
+ ASSERT_STREQ("heap", arena->Name());
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, arena->QueryIntAttribute("nr", &val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ arena->FirstChildElement("allocated-large")->QueryIntText(&val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ arena->FirstChildElement("allocated-huge")->QueryIntText(&val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ arena->FirstChildElement("allocated-bins")->QueryIntText(&val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ arena->FirstChildElement("bins-total")->QueryIntText(&val));
- auto bin = arena->FirstChildElement("bin");
- for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
- if (strcmp(bin->Name(), "bin") == 0) {
- ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- bin->FirstChildElement("allocated")->QueryIntText(&val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- bin->FirstChildElement("nmalloc")->QueryIntText(&val));
- ASSERT_EQ(tinyxml2::XML_SUCCESS,
- bin->FirstChildElement("ndalloc")->QueryIntText(&val));
+ auto bin = arena->FirstChildElement("bin");
+ for (; bin != nullptr; bin = bin ->NextSiblingElement()) {
+ if (strcmp(bin->Name(), "bin") == 0) {
+ ASSERT_EQ(tinyxml2::XML_SUCCESS, bin->QueryIntAttribute("nr", &val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ bin->FirstChildElement("allocated")->QueryIntText(&val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ bin->FirstChildElement("nmalloc")->QueryIntText(&val));
+ ASSERT_EQ(tinyxml2::XML_SUCCESS,
+ bin->FirstChildElement("ndalloc")->QueryIntText(&val));
+ }
}
}
+ } else {
+ // Only verify that this is debug-malloc-1, the malloc debug unit tests
+ // verify the output.
+ ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
}
#endif
}
@@ -518,24 +532,24 @@
TEST(malloc, mallopt_decay) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallopt
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
errno = 0;
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
TEST(malloc, mallopt_purge) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallopt
+ SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
errno = 0;
ASSERT_EQ(1, mallopt(M_PURGE, 0));
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -553,7 +567,7 @@
ASSERT_TRUE(reallocarray(nullptr, b, a) == nullptr);
ASSERT_EQ(ENOMEM, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+ GTEST_SKIP() << "reallocarray not available";
#endif
}
@@ -563,13 +577,13 @@
ASSERT_TRUE(p != nullptr);
ASSERT_GE(malloc_usable_size(p), 64U);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
+ GTEST_SKIP() << "reallocarray not available";
#endif
}
TEST(malloc, mallinfo) {
#if defined(__BIONIC__)
- SKIP_WITH_HWASAN; // hwasan does not implement mallinfo
+ SKIP_WITH_HWASAN << "hwasan does not implement mallinfo";
static size_t sizes[] = {
8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
};
@@ -608,7 +622,7 @@
<< kMaxAllocs << " allocations.";
}
#else
- GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif
}
@@ -619,7 +633,7 @@
EXPECT_EQ(false, android_mallopt(unrecognized_option, nullptr, 0));
EXPECT_EQ(ENOTSUP, errno);
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -665,6 +679,242 @@
EXPECT_EQ(ENOTSUP, errno);
}
#else
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
+#if defined(__BIONIC__)
+template <typename FuncType>
+void CheckAllocationFunction(FuncType func) {
+ // Assumes that no more than 108MB of memory is allocated before this.
+ size_t limit = 128 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+ if (!func(20 * 1024 * 1024))
+ exit(1);
+ if (func(128 * 1024 * 1024))
+ exit(1);
+ exit(0);
+}
+#endif
+
+TEST(android_mallopt, set_allocation_limit) {
+#if defined(__BIONIC__)
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(bytes, 1) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return calloc(1, bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return malloc(bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction(
+ [](size_t bytes) { return memalign(sizeof(void*), bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
+ void* ptr;
+ return posix_memalign(&ptr, sizeof(void *), bytes) == 0;
+ }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction(
+ [](size_t bytes) { return aligned_alloc(sizeof(void*), bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) {
+ void* p = malloc(1024 * 1024);
+ return realloc(p, bytes) != nullptr;
+ }),
+ testing::ExitedWithCode(0), "");
+#if !defined(__LP64__)
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return pvalloc(bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+ EXPECT_EXIT(CheckAllocationFunction([](size_t bytes) { return valloc(bytes) != nullptr; }),
+ testing::ExitedWithCode(0), "");
+#endif
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
+TEST(android_mallopt, set_allocation_limit_multiple) {
+#if defined(__BIONIC__)
+ // Only the first set should work.
+ size_t limit = 256 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+ limit = 32 * 1024 * 1024;
+ ASSERT_FALSE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
+#if defined(__BIONIC__)
+static constexpr size_t kAllocationSize = 8 * 1024 * 1024;
+
+static size_t GetMaxAllocations() {
+ size_t max_pointers = 0;
+ void* ptrs[20];
+ for (size_t i = 0; i < sizeof(ptrs) / sizeof(void*); i++) {
+ ptrs[i] = malloc(kAllocationSize);
+ if (ptrs[i] == nullptr) {
+ max_pointers = i;
+ break;
+ }
+ }
+ for (size_t i = 0; i < max_pointers; i++) {
+ free(ptrs[i]);
+ }
+ return max_pointers;
+}
+
+static void VerifyMaxPointers(size_t max_pointers) {
+ // Now verify that we can allocate the same number as before.
+ void* ptrs[20];
+ for (size_t i = 0; i < max_pointers; i++) {
+ ptrs[i] = malloc(kAllocationSize);
+ ASSERT_TRUE(ptrs[i] != nullptr) << "Failed to allocate on iteration " << i;
+ }
+
+ // Make sure the next allocation still fails.
+ ASSERT_TRUE(malloc(kAllocationSize) == nullptr);
+ for (size_t i = 0; i < max_pointers; i++) {
+ free(ptrs[i]);
+ }
+}
+#endif
+
+TEST(android_mallopt, set_allocation_limit_realloc_increase) {
+#if defined(__BIONIC__)
+ size_t limit = 128 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+
+ size_t max_pointers = GetMaxAllocations();
+ ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
+
+ void* memory = malloc(10 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+
+ // Increase size.
+ memory = realloc(memory, 20 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 40 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 60 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 80 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ // Now push past limit.
+ memory = realloc(memory, 130 * 1024 * 1024);
+ ASSERT_TRUE(memory == nullptr);
+
+ VerifyMaxPointers(max_pointers);
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
+TEST(android_mallopt, set_allocation_limit_realloc_decrease) {
+#if defined(__BIONIC__)
+ size_t limit = 100 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+
+ size_t max_pointers = GetMaxAllocations();
+ ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
+
+ void* memory = malloc(80 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+
+ // Decrease size.
+ memory = realloc(memory, 60 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 40 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 20 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ memory = realloc(memory, 10 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+ free(memory);
+
+ VerifyMaxPointers(max_pointers);
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
+TEST(android_mallopt, set_allocation_limit_realloc_free) {
+#if defined(__BIONIC__)
+ size_t limit = 100 * 1024 * 1024;
+ ASSERT_TRUE(android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit)));
+
+ size_t max_pointers = GetMaxAllocations();
+ ASSERT_TRUE(max_pointers != 0) << "Limit never reached.";
+
+ void* memory = malloc(60 * 1024 * 1024);
+ ASSERT_TRUE(memory != nullptr);
+
+ memory = realloc(memory, 0);
+ ASSERT_TRUE(memory == nullptr);
+
+ VerifyMaxPointers(max_pointers);
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
+#if defined(__BIONIC__)
+static void* SetAllocationLimit(void* data) {
+ std::atomic_bool* go = reinterpret_cast<std::atomic_bool*>(data);
+ while (!go->load()) {
+ }
+ size_t limit = 500 * 1024 * 1024;
+ if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
+ return reinterpret_cast<void*>(-1);
+ }
+ return nullptr;
+}
+
+static void SetAllocationLimitMultipleThreads() {
+ std::atomic_bool go;
+ go = false;
+
+ static constexpr size_t kNumThreads = 4;
+ pthread_t threads[kNumThreads];
+ for (size_t i = 0; i < kNumThreads; i++) {
+ ASSERT_EQ(0, pthread_create(&threads[i], nullptr, SetAllocationLimit, &go));
+ }
+
+ // Let them go all at once.
+ go = true;
+ ASSERT_EQ(0, kill(getpid(), __SIGRTMIN + 4));
+
+ size_t num_successful = 0;
+ for (size_t i = 0; i < kNumThreads; i++) {
+ void* result;
+ ASSERT_EQ(0, pthread_join(threads[i], &result));
+ if (result != nullptr) {
+ num_successful++;
+ }
+ }
+ ASSERT_EQ(1U, num_successful);
+ exit(0);
+}
+#endif
+
+TEST(android_mallopt, set_allocation_limit_multiple_threads) {
+#if defined(__BIONIC__)
+ if (IsDynamic()) {
+ ASSERT_TRUE(android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0));
+ }
+
+ // Run this a number of times as a stress test.
+ for (size_t i = 0; i < 100; i++) {
+ // Not using ASSERT_EXIT because errors messages are not displayed.
+ pid_t pid;
+ if ((pid = fork()) == 0) {
+ ASSERT_NO_FATAL_FAILURE(SetAllocationLimitMultipleThreads());
+ }
+ ASSERT_NE(-1, pid);
+ int status;
+ ASSERT_EQ(pid, wait(&status));
+ ASSERT_EQ(0, WEXITSTATUS(status));
+ }
+#else
+ GTEST_SKIP() << "bionic extension";
#endif
}
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index f816fad..1dd45b4 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -388,7 +388,7 @@
ASSERT_TRUE(__isnormal(123.0));
ASSERT_FALSE(__isnormal(double_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormal.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormal";
#endif // __BIONIC__
}
@@ -397,7 +397,7 @@
ASSERT_TRUE(__isnormalf(123.0f));
ASSERT_FALSE(__isnormalf(float_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormalf.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormalf";
#endif // __BIONIC__
}
@@ -406,7 +406,7 @@
ASSERT_TRUE(isnormalf(123.0f));
ASSERT_FALSE(isnormalf(float_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have isnormalf.\n";
+ GTEST_SKIP() << "glibc doesn't have isnormalf";
#endif // __BIONIC__
}
@@ -415,7 +415,7 @@
ASSERT_TRUE(__isnormall(123.0L));
ASSERT_FALSE(__isnormall(ldouble_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have __isnormall.\n";
+ GTEST_SKIP() << "glibc doesn't have __isnormall";
#endif // __BIONIC__
}
@@ -424,7 +424,7 @@
ASSERT_TRUE(isnormall(123.0L));
ASSERT_FALSE(isnormall(ldouble_subnormal()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have isnormall.\n";
+ GTEST_SKIP() << "glibc doesn't have isnormall";
#endif // __BIONIC__
}
@@ -1396,7 +1396,7 @@
ASSERT_DOUBLE_EQ(log(24.0), gamma_r(5.0, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have gamma_r.\n";
+ GTEST_SKIP() << "glibc doesn't have gamma_r";
#endif // __BIONIC__
}
@@ -1406,7 +1406,7 @@
ASSERT_FLOAT_EQ(logf(24.0f), gammaf_r(5.0f, &sign));
ASSERT_EQ(1, sign);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "glibc doesn't have gammaf_r.\n";
+ GTEST_SKIP() << "glibc doesn't have gammaf_r";
#endif // __BIONIC__
}
diff --git a/tests/membarrier_test.cpp b/tests/membarrier_test.cpp
index 9e871c7..6f650e7 100644
--- a/tests/membarrier_test.cpp
+++ b/tests/membarrier_test.cpp
@@ -46,8 +46,7 @@
TEST(membarrier, global_barrier) {
if (!HasMembarrier(MEMBARRIER_CMD_GLOBAL)) {
- GTEST_LOG_(INFO) << "MEMBARRIER_CMD_GLOBAL not supported, skipping test.";
- return;
+ GTEST_SKIP() << "MEMBARRIER_CMD_GLOBAL not supported";
}
ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
}
@@ -78,14 +77,10 @@
static void TestRegisterAndBarrierCommands(int membarrier_cmd_register,
int membarrier_cmd_barrier) {
if (!HasMembarrier(membarrier_cmd_register)) {
- GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_register)
- << " not supported, skipping test.";
- return;
+ GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_register) << " not supported";
}
if (!HasMembarrier(membarrier_cmd_barrier)) {
- GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_barrier)
- << " not supported, skipping test.";
- return;
+ GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_barrier) << " not supported";
}
ScopedErrnoCleaner errno_cleaner;
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 973ca53..7b64401 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -190,7 +190,7 @@
ASSERT_EQ(EINVAL, pthread_setspecific(key, nullptr));
ASSERT_EQ(EINVAL, pthread_key_delete(key));
#else
- GTEST_LOG_(INFO) << "This test tests bionic pthread key implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -986,8 +986,7 @@
test_pthread_rwlock_reader_wakeup_writer(
[&](pthread_rwlock_t* lock) { return pthread_rwlock_timedwrlock_monotonic_np(lock, &ts); });
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedwrlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1035,8 +1034,7 @@
test_pthread_rwlock_writer_wakeup_reader(
[&](pthread_rwlock_t* lock) { return pthread_rwlock_timedrdlock_monotonic_np(lock, &ts); });
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedrdlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1096,8 +1094,7 @@
pthread_rwlock_timedrdlock_timeout_helper(CLOCK_MONOTONIC,
pthread_rwlock_timedrdlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedrdlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedrdlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1133,8 +1130,7 @@
pthread_rwlock_timedwrlock_timeout_helper(CLOCK_MONOTONIC,
pthread_rwlock_timedwrlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_rwlock_timedwrlock_monotonic_np is "
- "only supported on bionic";
+ GTEST_SKIP() << "pthread_rwlock_timedwrlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1364,7 +1360,7 @@
ASSERT_EQ(0, pthread_condattr_getpshared(&attr, &pshared));
ASSERT_EQ(PTHREAD_PROCESS_SHARED, pshared);
#else // !defined(__BIONIC__)
- GTEST_LOG_(INFO) << "This tests a bionic implementation detail.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // !defined(__BIONIC__)
}
@@ -1480,8 +1476,7 @@
progress = SIGNALED;
ASSERT_EQ(0, pthread_cond_signal(&cond));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_cond_timedwait_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1516,8 +1511,7 @@
#if defined(__BIONIC__)
pthread_cond_timedwait_timeout_helper(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_cond_timedwait_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available";
#endif // __BIONIC__
}
@@ -1739,7 +1733,7 @@
ASSERT_EQ(t_gettid_result, t_pthread_gettid_np_result);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "pthread_gettid_np not available";
#endif
}
@@ -1934,7 +1928,7 @@
}
ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
#else
- GTEST_LOG_(INFO) << "This test does nothing as pi mutex count isn't limited.\n";
+ GTEST_SKIP() << "pi mutex count not limited to 64Ki";
#endif
}
@@ -2121,7 +2115,7 @@
// Bionic's pthread_mutex implementation on 32-bit devices uses 16 bits to represent owner tid.
ASSERT_LE(pid_max, 65536);
#else
- GTEST_LOG_(INFO) << "This test does nothing as 32-bit tid is supported by pthread_mutex.\n";
+ GTEST_SKIP() << "pthread_mutex supports 32-bit tid";
#endif
}
@@ -2164,8 +2158,7 @@
#if defined(__BIONIC__)
pthread_mutex_timedlock_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_mutex_timedlock_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -2216,8 +2209,7 @@
#if defined(__BIONIC__)
pthread_mutex_timedlock_pi_helper(CLOCK_MONOTONIC, pthread_mutex_timedlock_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing since pthread_mutex_timedlock_monotonic_np is only "
- "supported on bionic";
+ GTEST_SKIP() << "pthread_mutex_timedlock_monotonic_np not available";
#endif // __BIONIC__
}
@@ -2240,7 +2232,7 @@
ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT),
"pthread_mutex_destroy called on a destroyed mutex");
#else
- GTEST_LOG_(INFO) << "This test tests bionic pthread mutex implementation details.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -2297,7 +2289,7 @@
ASSERT_EQ(0, pthread_rwlock_destroy(rwlock));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details.";
+ GTEST_SKIP() << "bionic-only test";
#endif
}
@@ -2312,7 +2304,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EQ(EINVAL, pthread_mutex_lock(null_value));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+ GTEST_SKIP() << "32-bit bionic-only test";
#endif
}
@@ -2327,7 +2319,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EQ(EINVAL, pthread_mutex_unlock(null_value));
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+ GTEST_SKIP() << "32-bit bionic-only test";
#endif
}
@@ -2336,7 +2328,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EXIT(pthread_mutex_lock(null_value), testing::KilledBySignal(SIGSEGV), "");
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+ GTEST_SKIP() << "64-bit bionic-only test";
#endif
}
@@ -2345,7 +2337,7 @@
pthread_mutex_t* null_value = nullptr;
ASSERT_EXIT(pthread_mutex_unlock(null_value), testing::KilledBySignal(SIGSEGV), "");
#else
- GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+ GTEST_SKIP() << "64-bit bionic-only test";
#endif
}
@@ -2658,10 +2650,7 @@
TEST(pthread, pthread_attr_setinheritsched_PTHREAD_INHERIT_SCHED_takes_effect) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
@@ -2682,10 +2671,7 @@
TEST(pthread, pthread_attr_setinheritsched_PTHREAD_EXPLICIT_SCHED_takes_effect) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
@@ -2707,10 +2693,7 @@
TEST(pthread, pthread_attr_setinheritsched__takes_effect_despite_SCHED_RESET_ON_FORK) {
sched_param param = { .sched_priority = sched_get_priority_min(SCHED_FIFO) };
int rc = pthread_setschedparam(pthread_self(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m);
- if (rc == EPERM) {
- GTEST_LOG_(INFO) << "pthread_setschedparam failed with EPERM, skipping test\n";
- return;
- }
+ if (rc == EPERM) GTEST_SKIP() << "pthread_setschedparam failed with EPERM";
ASSERT_EQ(0, rc);
pthread_attr_t attr;
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 75f228c..29f86f1 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -109,8 +109,7 @@
cpu_set_t cpus;
ASSERT_EQ(0, sched_getaffinity(0, sizeof(cpu_set_t), &cpus));
if (CPU_COUNT(&cpus) < 2) {
- GTEST_LOG_(INFO) << "This test tests bug happens only on multiprocessors.";
- return;
+ GTEST_SKIP() << "This bug only happens on multiprocessors";
}
constexpr uint32_t TEST_DATA_COUNT = 2000000;
diff --git a/tests/run-on-host.sh b/tests/run-on-host.sh
index c47bc4f..c8a30f5 100755
--- a/tests/run-on-host.sh
+++ b/tests/run-on-host.sh
@@ -3,32 +3,33 @@
. $(dirname $0)/../build/run-on-host.sh
if [ "$1" = glibc ]; then
- m -j bionic-unit-tests-glibc
- (
- cd ${ANDROID_BUILD_TOP}
- export ANDROID_DATA=${TARGET_OUT_DATA}
- export ANDROID_ROOT=${TARGET_OUT}
- ${HOST_OUT}/nativetest64/bionic-unit-tests-glibc/bionic-unit-tests-glibc $@
- )
- exit 0
+ shift
+ m -j bionic-unit-tests-glibc
+ (
+ cd ${ANDROID_BUILD_TOP}
+ export ANDROID_DATA=${TARGET_OUT_DATA}
+ export ANDROID_ROOT=${TARGET_OUT}
+ ${HOST_OUT}/nativetest64/bionic-unit-tests-glibc/bionic-unit-tests-glibc $@
+ )
+ exit 0
elif [ "$1" != 32 -a "$1" != 64 ]; then
- echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
- exit 1
+ echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
+ exit 1
fi
if [ ${HOST_OS}-${HOST_ARCH} = linux-x86 -o ${HOST_OS}-${HOST_ARCH} = linux-x86_64 ]; then
- prepare $1 bionic-unit-tests
+ prepare $1 bionic-unit-tests
- if [ ${TARGET_ARCH} = x86 -o ${TARGET_ARCH} = x86_64 ]; then
- (
- cd ${ANDROID_BUILD_TOP}
- export ANDROID_DATA=${TARGET_OUT_DATA}
- export ANDROID_DNS_MODE=local
- export ANDROID_ROOT=${TARGET_OUT}
- ${NATIVETEST}/bionic-unit-tests/bionic-unit-tests $@
- )
- else
- echo "$0 not supported on TARGET_ARCH=$TARGET_ARCH"
- fi
+ if [ ${TARGET_ARCH} = x86 -o ${TARGET_ARCH} = x86_64 ]; then
+ (
+ cd ${ANDROID_BUILD_TOP}
+ export ANDROID_DATA=${TARGET_OUT_DATA}
+ export ANDROID_DNS_MODE=local
+ export ANDROID_ROOT=${TARGET_OUT}
+ ${NATIVETEST}/bionic-unit-tests/bionic-unit-tests $@
+ )
+ else
+ echo "$0 not supported on TARGET_ARCH=$TARGET_ARCH"
+ fi
fi
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 9184026..9309a7f 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -47,7 +47,7 @@
// See https://sourceware.org/bugzilla/show_bug.cgi?id=10311 for more details.
TEST(sched, clone) {
// In order to enumerate all possible tests for CTS, create an empty test.
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc is broken";
}
#endif
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index 690e886..7addf6d 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -141,8 +141,7 @@
#if defined(__BIONIC__)
sem_timedwait_helper(CLOCK_MONOTONIC, sem_timedwait_monotonic_np);
#else // __BIONIC__
- GTEST_LOG_(INFO)
- << "This test does nothing since sem_timedwait_monotonic_np is only supported on bionic";
+ GTEST_SKIP() << "sem_timedwait_monotonic_np is only supported on bionic";
#endif // __BIONIC__
}
@@ -218,7 +217,7 @@
ASSERT_EQ(0, pthread_join(thread, &result));
ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(result));
#else
- GTEST_LOG_(INFO) << "This test tests sem_wait's compatibility for old sdk versions";
+ GTEST_SKIP() << "This test tests sem_wait's compatibility for old sdk versions";
#endif
}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 77b004f..1ae174a 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -582,7 +582,7 @@
ASSERT_TRUE(sys_signame[0] == nullptr);
ASSERT_STREQ("HUP", sys_signame[SIGHUP]);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "glibc doesn't have sys_signame";
#endif
}
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index 7a85cc3..9fe7bb1 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -95,7 +95,7 @@
ASSERT_NE(0, gettid());
ASSERT_NE(0U, __stack_chk_guard);
#else
- GTEST_LOG_(INFO) << "glibc doesn't have a global __stack_chk_guard.\n";
+ GTEST_SKIP() << "glibc doesn't have a global __stack_chk_guard";
#endif
}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index d84fda0..fce600a 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -193,7 +193,7 @@
TEST(stdio_ext, __fseterr) {
#if defined(__GLIBC__)
- GTEST_LOG_(INFO) << "glibc doesn't have __fseterr, but gnulib will use it";
+ GTEST_SKIP() << "glibc doesn't have __fseterr, but gnulib will use it";
#else
FILE* fp = fopen("/dev/null", "w");
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index ad6ed45..65a942c 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -330,7 +330,7 @@
int i = 1234;
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";
+ GTEST_SKIP() << "glibc does allow %n";
#endif
}
@@ -1897,7 +1897,7 @@
ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
+ GTEST_SKIP() << "glibc is broken";
#endif
}
@@ -2157,7 +2157,7 @@
fclose(fp);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2167,7 +2167,7 @@
ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2195,7 +2195,7 @@
EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno);
EXPECT_EQ(0xfedcba12345678, pos64);
#else
- GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
+ GTEST_SKIP() << "glibc uses fopencookie instead";
#endif
}
@@ -2234,7 +2234,7 @@
EXPECT_EQ(offset, static_cast<off64_t>(pos));
EXPECT_EQ(offset, static_cast<off64_t>(pos64));
#else
- GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n";
+ GTEST_SKIP() << "glibc's fpos_t is opaque";
#endif
}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 408a9c7..ff4cb71 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -272,11 +272,11 @@
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)
+ ASSERT_TRUE(aligned_alloc(fail_align, fail_align) == nullptr)
<< "Unexpected success at align " << fail_align;
ASSERT_EQ(EINVAL, errno) << "Unexpected errno at align " << fail_align;
}
- void* ptr = aligned_alloc(align, 256);
+ void* ptr = aligned_alloc(align, 2 * align);
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;
@@ -292,11 +292,11 @@
TEST(stdlib, aligned_alloc_size_not_multiple_of_alignment) {
SKIP_WITH_HWASAN;
- 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);
- }
+
+ ASSERT_TRUE(aligned_alloc(2048, 1) == nullptr);
+ ASSERT_TRUE(aligned_alloc(4, 3) == nullptr);
+ ASSERT_TRUE(aligned_alloc(4, 7) == nullptr);
+ ASSERT_TRUE(aligned_alloc(16, 8) == nullptr);
}
TEST(stdlib, realpath__NULL_filename) {
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index b27ca87..335d33b 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -85,7 +85,7 @@
ASSERT_STREQ("Unknown error 1001", strerror1001);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "Skipping test, requires a thread safe strerror.";
+ GTEST_SKIP() << "thread-safe strerror not available";
#endif // __BIONIC__
}
@@ -578,7 +578,7 @@
}
}
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
@@ -610,7 +610,7 @@
(memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0));
}
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1139,7 +1139,7 @@
#if defined(STRLCPY_SUPPORTED)
RunSrcDstBufferAlignTest(LARGE, DoStrlcpyTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1147,7 +1147,7 @@
#if defined(STRLCPY_SUPPORTED)
RunSrcDstBufferOverreadTest(DoStrlcpyTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcpy not supported on this platform.";
+ GTEST_SKIP() << "strlcpy not available";
#endif
}
@@ -1275,7 +1275,7 @@
#if defined(STRLCAT_SUPPORTED)
RunSrcDstBufferAlignTest(MEDIUM, DoStrlcatTest, LargeSetIncrement);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
@@ -1283,7 +1283,7 @@
#if defined(STRLCAT_SUPPORTED)
RunSrcDstBufferOverreadTest(DoStrlcatTest);
#else
- GTEST_LOG_(INFO) << "Skipping test, strlcat not supported on this platform.";
+ GTEST_SKIP() << "strlcat not available";
#endif
}
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index 8b3623e..200f654 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -35,8 +35,7 @@
TEST(sys_msg, smoke) {
if (msgctl(-1, IPC_STAT, nullptr) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/msg.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/msg.h> support in this kernel";
}
// Create a queue.
diff --git a/tests/sys_param_test.cpp b/tests/sys_param_test.cpp
new file mode 100644
index 0000000..e4bbf42
--- /dev/null
+++ b/tests/sys_param_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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 <gtest/gtest.h>
+#include <sys/param.h>
+
+TEST(sys_param_test, powerof2_positives) {
+ ASSERT_TRUE(powerof2(1));
+ ASSERT_TRUE(powerof2(2));
+ ASSERT_TRUE(powerof2(4));
+ ASSERT_TRUE(powerof2(8));
+ ASSERT_FALSE(powerof2(3));
+ ASSERT_FALSE(powerof2(5));
+ ASSERT_FALSE(powerof2(7));
+ ASSERT_FALSE(powerof2(9));
+ ASSERT_FALSE(powerof2(10));
+}
+
+TEST(sys_param_test, powerof2_zero) {
+ // 0 isn't a power of 2, but for compatibility, we assume it is.
+ ASSERT_TRUE(powerof2(0));
+ uint32_t zero = 0;
+ ASSERT_TRUE(powerof2(zero));
+}
+
+TEST(sys_param_test, powerof2_negatives) {
+ // negative numbers can never be a power of 2, but for compatibility,
+ // we assume they can be.
+ int32_t min32 = INT32_MIN;
+ int64_t min64 = INT64_MIN;
+ ASSERT_TRUE(powerof2(min32));
+ ASSERT_FALSE(powerof2(min32 + 1));
+ ASSERT_TRUE(powerof2(min64));
+ ASSERT_FALSE(powerof2(min64 + 1));
+}
diff --git a/tests/sys_prctl_test.cpp b/tests/sys_prctl_test.cpp
index cd23c0a..6d1fa1d 100644
--- a/tests/sys_prctl_test.cpp
+++ b/tests/sys_prctl_test.cpp
@@ -61,7 +61,7 @@
ASSERT_EQ(0, munmap(p, page_size * 3));
#else
- GTEST_LOG_(INFO) << "This test does nothing as it tests an Android specific kernel feature.";
+ GTEST_SKIP() << "PR_SET_VMA not available";
#endif
}
@@ -112,7 +112,6 @@
EXPECT_EQ(-1, err);
EXPECT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO)
- << "Skipping test that requires host support for PR_CAP_AMBIENT.";
+ GTEST_SKIP() << "PR_CAP_AMBIENT not available";
#endif
}
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 04dcd4e..90539fe 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -62,14 +62,13 @@
enum class HwFeature { Watchpoint, Breakpoint };
-static bool is_hw_feature_supported(pid_t child, HwFeature feature) {
+static void check_hw_feature_supported(pid_t child, HwFeature feature) {
#if defined(__arm__)
long capabilities;
long result = ptrace(PTRACE_GETHBPREGS, child, 0, &capabilities);
if (result == -1) {
EXPECT_EQ(EIO, errno);
- GTEST_LOG_(INFO) << "Hardware debug support disabled at kernel configuration time.";
- return false;
+ GTEST_SKIP() << "Hardware debug support disabled at kernel configuration time";
}
uint8_t hb_count = capabilities & 0xff;
capabilities >>= 8;
@@ -77,19 +76,12 @@
capabilities >>= 8;
uint8_t max_wp_size = capabilities & 0xff;
if (max_wp_size == 0) {
- GTEST_LOG_(INFO)
- << "Kernel reports zero maximum watchpoint size. Hardware debug support missing.";
- return false;
+ GTEST_SKIP() << "Kernel reports zero maximum watchpoint size";
+ } else if (feature == HwFeature::Watchpoint && wp_count == 0) {
+ GTEST_SKIP() << "Kernel reports zero hardware watchpoints";
+ } else if (feature == HwFeature::Breakpoint && hb_count == 0) {
+ GTEST_SKIP() << "Kernel reports zero hardware breakpoints";
}
- if (feature == HwFeature::Watchpoint && wp_count == 0) {
- GTEST_LOG_(INFO) << "Kernel reports zero hardware watchpoints";
- return false;
- }
- if (feature == HwFeature::Breakpoint && hb_count == 0) {
- GTEST_LOG_(INFO) << "Kernel reports zero hardware breakpoints";
- return false;
- }
- return true;
#elif defined(__aarch64__)
user_hwdebug_state dreg_state;
iovec iov;
@@ -99,20 +91,13 @@
long result = ptrace(PTRACE_GETREGSET, child,
feature == HwFeature::Watchpoint ? NT_ARM_HW_WATCH : NT_ARM_HW_BREAK, &iov);
if (result == -1) {
- EXPECT_EQ(EINVAL, errno);
- return false;
+ ASSERT_EQ(EINVAL, errno);
}
- return (dreg_state.dbg_info & 0xff) > 0;
-#elif defined(__i386__) || defined(__x86_64__)
+ if ((dreg_state.dbg_info & 0xff) == 0) GTEST_SKIP() << "hardware support missing";
+#else
// We assume watchpoints and breakpoints are always supported on x86.
UNUSED(child);
UNUSED(feature);
- return true;
-#else
- // TODO: mips support.
- UNUSED(child);
- UNUSED(feature);
- return false;
#endif
}
@@ -190,10 +175,7 @@
ASSERT_TRUE(WIFSTOPPED(status)) << "Status was: " << status;
ASSERT_EQ(SIGSTOP, WSTOPSIG(status)) << "Status was: " << status;
- if (!is_hw_feature_supported(child, HwFeature::Watchpoint)) {
- GTEST_LOG_(INFO) << "Skipping test because hardware support is not available.\n";
- return;
- }
+ check_hw_feature_supported(child, HwFeature::Watchpoint);
set_watchpoint(child, uintptr_t(untag_address(&data)) + offset, size);
@@ -360,10 +342,7 @@
ASSERT_TRUE(WIFSTOPPED(status)) << "Status was: " << status;
ASSERT_EQ(SIGSTOP, WSTOPSIG(status)) << "Status was: " << status;
- if (!is_hw_feature_supported(child, HwFeature::Breakpoint)) {
- GTEST_LOG_(INFO) << "Skipping test because hardware support is not available.\n";
- return;
- }
+ check_hw_feature_supported(child, HwFeature::Breakpoint);
set_breakpoint(child);
@@ -423,7 +402,7 @@
}
}
- ~PtraceResumptionTest() {
+ ~PtraceResumptionTest() override {
}
void AssertDeath(int signo);
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
index 78cbf4a..2e2665b 100644
--- a/tests/sys_random_test.cpp
+++ b/tests/sys_random_test.cpp
@@ -43,7 +43,7 @@
ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -53,7 +53,7 @@
ASSERT_EQ(-1, getentropy(nullptr, 1));
ASSERT_EQ(EFAULT, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -66,7 +66,7 @@
ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
ASSERT_EQ(EIO, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -79,7 +79,7 @@
ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -89,7 +89,7 @@
ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
ASSERT_EQ(EFAULT, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
@@ -100,6 +100,6 @@
ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+ GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index 0b6b6ef..b1e8b1a 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -30,7 +30,7 @@
class SysResourceTest : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32_));
ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64_));
ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, nullptr, &pr_l32_));
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index dff34c8..b98926b 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -35,8 +35,7 @@
TEST(sys_sem, smoke) {
if (semctl(-1, 0, IPC_RMID) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/sem.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/sem.h> support in this kernel";
}
// Create a semaphore.
diff --git a/tests/sys_shm_test.cpp b/tests/sys_shm_test.cpp
index 15abe05..fd5d424 100644
--- a/tests/sys_shm_test.cpp
+++ b/tests/sys_shm_test.cpp
@@ -34,8 +34,7 @@
TEST(sys_shm, smoke) {
if (shmctl(-1, IPC_STAT, nullptr) == -1 && errno == ENOSYS) {
- GTEST_LOG_(INFO) << "no <sys/shm.h> support in this kernel\n";
- return;
+ GTEST_SKIP() << "no <sys/shm.h> support in this kernel";
}
// Create a segment.
diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp
index 70ad451..97bf580 100644
--- a/tests/sys_stat_test.cpp
+++ b/tests/sys_stat_test.cpp
@@ -82,7 +82,7 @@
unlink(path.c_str());
} else {
// SELinux policy forbids us from creating FIFOs. http://b/17646702.
- GTEST_LOG_(INFO) << "This test only performs a test when run as root.";
+ GTEST_SKIP() << "SELinux policy forbids non-root from creating FIFOs";
}
}
diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp
index 3b50896..245e42f 100644
--- a/tests/system_properties_test.cpp
+++ b/tests/system_properties_test.cpp
@@ -121,7 +121,7 @@
ASSERT_EQ(5, system_properties.Get(name, propvalue));
ASSERT_STREQ(propvalue, "value");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -156,7 +156,7 @@
ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
ASSERT_STREQ(propvalue, "value6");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -202,7 +202,7 @@
ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -219,7 +219,7 @@
ASSERT_EQ(0, system_properties.Foreach(foreach_test_callback, &count));
ASSERT_EQ(3U, count);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -248,7 +248,7 @@
ASSERT_TRUE(system_properties.FindNth(i) == nullptr);
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -307,7 +307,7 @@
}
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -328,7 +328,7 @@
ASSERT_EQ(-1, system_properties.Add("name", 4, "value", PROP_VALUE_MAX));
ASSERT_EQ(-1, system_properties.Update(NULL, "value", PROP_VALUE_MAX));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -344,7 +344,7 @@
ASSERT_EQ(0, system_properties.Update(const_cast<prop_info*>(pi), "value2", 6));
ASSERT_NE(serial, system_properties.Serial(pi));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -375,7 +375,7 @@
thread.join();
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -408,7 +408,7 @@
thread.join();
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -436,7 +436,7 @@
ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), "");
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -508,7 +508,7 @@
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -523,6 +523,6 @@
ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/system_properties_test2.cpp b/tests/system_properties_test2.cpp
index e6e7ef2..c061faa 100644
--- a/tests/system_properties_test2.cpp
+++ b/tests/system_properties_test2.cpp
@@ -124,7 +124,7 @@
ASSERT_EQ(expected_name, legacy_name);
ASSERT_STREQ("value2", propvalue);
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
@@ -143,6 +143,6 @@
}
#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "bionic-only test";
#endif // __BIONIC__
}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 50830ee..c890358 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -296,6 +296,69 @@
EXPECT_STREQ("09:41:53", buf);
}
+TEST(time, strptime_F) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("2019-03-26", "%F", &tm));
+ EXPECT_EQ(119, tm.tm_year);
+ EXPECT_EQ(2, tm.tm_mon);
+ EXPECT_EQ(26, tm.tm_mday);
+}
+
+TEST(time, strptime_P_p) {
+ setenv("TZ", "UTC", 1);
+
+ // For parsing, %P and %p are the same: case doesn't matter.
+
+ struct tm tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("AM", "%p", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("am", "%p", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("AM", "%P", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+
+ tm = {.tm_hour = 12};
+ ASSERT_EQ('\0', *strptime("am", "%P", &tm));
+ EXPECT_EQ(0, tm.tm_hour);
+}
+
+TEST(time, strptime_u) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("2", "%u", &tm));
+ EXPECT_EQ(2, tm.tm_wday);
+}
+
+TEST(time, strptime_v) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("26-Mar-1980", "%v", &tm));
+ EXPECT_EQ(80, tm.tm_year);
+ EXPECT_EQ(2, tm.tm_mon);
+ EXPECT_EQ(26, tm.tm_mday);
+}
+
+TEST(time, strptime_V_G_g) {
+ setenv("TZ", "UTC", 1);
+
+ // %V (ISO-8601 week number), %G (year of week number, without century), and
+ // %g (year of week number) have no effect when parsed, and are supported
+ // solely so that it's possible for strptime(3) to parse everything that
+ // strftime(3) can output.
+ struct tm tm = {};
+ ASSERT_EQ('\0', *strptime("1 2 3", "%V %G %g", &tm));
+ struct tm zero = {};
+ EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
+}
+
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;
@@ -912,6 +975,6 @@
ASSERT_EQ(0, timespec_get(&ts, 123));
ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
#else
- GTEST_LOG_(INFO) << "glibc doesn't have timespec_get until 2.21\n";
+ GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
#endif
}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index cb94e45..10c1710 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -628,6 +628,45 @@
ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
}
+static void optimization_barrier(void* arg) {
+ asm volatile("" : : "r"(arg) : "memory");
+}
+
+__attribute__((noinline)) static void HwasanVforkTestChild() {
+ // Allocate a tagged region on stack and leave it there.
+ char x[10000];
+ optimization_barrier(x);
+ _exit(0);
+}
+
+__attribute__((noinline)) static void HwasanReadMemory(const char* p, size_t size) {
+ // Read memory byte-by-byte. This will blow up if the pointer tag in p does not match any memory
+ // tag in [p, p+size).
+ volatile char z;
+ for (size_t i = 0; i < size; ++i) {
+ z = p[i];
+ }
+}
+
+__attribute__((noinline, no_sanitize("hwaddress"))) static void HwasanVforkTestParent() {
+ // Allocate a region on stack, but don't tag it (see the function attribute).
+ // This depends on unallocated stack space at current function entry being untagged.
+ char x[10000];
+ optimization_barrier(x);
+ // Verify that contents of x[] are untagged.
+ HwasanReadMemory(x, sizeof(x));
+}
+
+TEST(UNISTD_TEST, hwasan_vfork) {
+ // Test hwasan annotation in vfork. This test is only interesting when built with hwasan, but it
+ // is supposed to work correctly either way.
+ if (vfork()) {
+ HwasanVforkTestParent();
+ } else {
+ HwasanVforkTestChild();
+ }
+}
+
class UNISTD_DEATHTEST : public BionicDeathTest {};
TEST_F(UNISTD_DEATHTEST, abort) {
diff --git a/tests/utils.h b/tests/utils.h
index cc1aa8c..fe41019 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -64,7 +64,7 @@
return &__hwasan_init != 0;
}
-#define SKIP_WITH_HWASAN if (running_with_hwasan()) { return; }
+#define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
static inline void* untag_address(void* addr) {
#if defined(__LP64__)
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 9aef800..9b4fc4f 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -713,7 +713,7 @@
ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
+ GTEST_SKIP() << "This test is bionic-specific";
#endif
}
diff --git a/tests/wctype_test.cpp b/tests/wctype_test.cpp
index 06e1571..85a46aa 100644
--- a/tests/wctype_test.cpp
+++ b/tests/wctype_test.cpp
@@ -111,7 +111,7 @@
EXPECT_EQ(wint_t(L'δ'), towlower(L'δ'));
EXPECT_EQ(wint_t(L'δ'), towlower(L'Δ'));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towlower tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -127,7 +127,7 @@
EXPECT_EQ(wint_t(L'δ'), towlower_l(L'δ', l.l));
EXPECT_EQ(wint_t(L'δ'), towlower_l(L'Δ', l.l));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towlower_l tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -142,7 +142,7 @@
EXPECT_EQ(wint_t(L'Δ'), towupper(L'δ'));
EXPECT_EQ(wint_t(L'Δ'), towupper(L'Δ'));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towupper tests";
+ GTEST_SKIP() << "icu not available";
}
}
@@ -158,7 +158,7 @@
EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'δ', l.l));
EXPECT_EQ(wint_t(L'Δ'), towupper_l(L'Δ', l.l));
} else {
- GTEST_LOG_(INFO) << "skipping unicode towupper_l tests";
+ GTEST_SKIP() << "icu not available";
}
}
diff --git a/tools/versioner/src/Arch.h b/tools/versioner/src/Arch.h
index bac9ec4..16fa265 100644
--- a/tools/versioner/src/Arch.h
+++ b/tools/versioner/src/Arch.h
@@ -138,7 +138,7 @@
{ Arch::x86_64, "x86_64-linux-android" },
};
-static const std::set<int> default_levels = { 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28 };
+static const std::set<int> default_levels = { 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29 };
static const ArchMap<int> arch_min_api = {
{ Arch::arm, 9 },
@@ -149,8 +149,6 @@
{ Arch::x86_64, 21 },
};
-static constexpr int future_api = 10000;
-
static const std::unordered_map<std::string, int> api_codename_map{
{"G", 9},
{"I", 14},
@@ -166,5 +164,5 @@
{"O", 26},
{"O-MR1", 27},
{"P", 28},
- {"Q", 9001},
+ {"Q", 29},
};
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index d9cff17..0ba51d1 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -147,9 +147,6 @@
llvm::StringRef annotation = attr->getAnnotation();
if (annotation == "versioner_no_guard") {
no_guard = true;
- } else if (annotation == "introduced_in_future") {
- // Tag the compiled-for arch, since this can vary across archs.
- availability.arch_availability[type.arch].future = true;
} else {
llvm::SmallVector<llvm::StringRef, 2> fragments;
annotation.split(fragments, "=");
@@ -345,10 +342,6 @@
std::string to_string(const AvailabilityValues& av) {
std::stringstream ss;
- if (av.future) {
- ss << "future, ";
- }
-
if (av.introduced != 0) {
ss << "introduced = " << av.introduced << ", ";
}
diff --git a/tools/versioner/src/DeclarationDatabase.h b/tools/versioner/src/DeclarationDatabase.h
index 0daa2cd..4496ee9 100644
--- a/tools/versioner/src/DeclarationDatabase.h
+++ b/tools/versioner/src/DeclarationDatabase.h
@@ -42,13 +42,12 @@
};
struct AvailabilityValues {
- bool future = false;
int introduced = 0;
int deprecated = 0;
int obsoleted = 0;
bool empty() const {
- return !(future || introduced || deprecated || obsoleted);
+ return !(introduced || deprecated || obsoleted);
}
bool operator==(const AvailabilityValues& rhs) const {
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index 6062240..3927480 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -62,7 +62,7 @@
: header_database(header_database), type(type) {
}
- virtual void HandleTranslationUnit(ASTContext& ctx) override {
+ void HandleTranslationUnit(ASTContext& ctx) override {
header_database->parseAST(type, ctx);
}
};
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index a7f289b..9eac2ab 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -190,13 +190,6 @@
int version = avail.arch_availability[*it.second.begin()].introduced;
- // Assume that the entire declaration is declared __INTRODUCED_IN_FUTURE if one arch is.
- bool future = avail.arch_availability[*it.second.begin()].future;
-
- if (future) {
- return "__ANDROID_API__ >= __ANDROID_API_FUTURE__";
- }
-
// The maximum min_version of the set.
int max_min_version = 0;
for (Arch arch : archs) {
diff --git a/tools/versioner/src/SymbolFileParser.cpp b/tools/versioner/src/SymbolFileParser.cpp
index 33308d9..c312b48 100644
--- a/tools/versioner/src/SymbolFileParser.cpp
+++ b/tools/versioner/src/SymbolFileParser.cpp
@@ -257,10 +257,6 @@
intro_arch = true;
continue;
}
-
- if (tag == "future") {
- return compilation_type.api_level == future_api;
- }
}
if (intro.empty() && api_level.empty()) {
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 73eff0e..d3c2f7c 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -397,10 +397,6 @@
should_be_available = false;
}
- if (arch_availability.future) {
- continue;
- }
-
// The function declaration might be (validly) missing for the given CompilationType.
if (!symbol_it.second.hasDeclaration(type)) {
should_be_available = false;
diff --git a/tools/versioner/tests/future/headers/foo.h b/tools/versioner/tests/future/headers/foo.h
deleted file mode 100644
index 51a3a1c..0000000
--- a/tools/versioner/tests/future/headers/foo.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int foo() __INTRODUCED_IN_FUTURE;
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/future/platforms/libc.map.txt b/tools/versioner/tests/future/platforms/libc.map.txt
deleted file mode 100644
index e69de29..0000000
--- a/tools/versioner/tests/future/platforms/libc.map.txt
+++ /dev/null
diff --git a/tools/versioner/tests/future/run.sh b/tools/versioner/tests/future/run.sh
deleted file mode 100644
index 041b047..0000000
--- a/tools/versioner/tests/future/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner -v headers -p platforms -r arm -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/future_arch/headers/foo.h b/tools/versioner/tests/future_arch/headers/foo.h
deleted file mode 100644
index a3258e7..0000000
--- a/tools/versioner/tests/future_arch/headers/foo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if defined(__arm__)
-int foo() __INTRODUCED_IN(9);
-#else
-int foo() __INTRODUCED_IN_FUTURE;
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/tools/versioner/tests/future_arch/platforms/libc.map.txt b/tools/versioner/tests/future_arch/platforms/libc.map.txt
deleted file mode 100644
index f56190e..0000000
--- a/tools/versioner/tests/future_arch/platforms/libc.map.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBC {
- global:
- foo; # arm
-};
diff --git a/tools/versioner/tests/future_arch/run.sh b/tools/versioner/tests/future_arch/run.sh
deleted file mode 100644
index ad8f430..0000000
--- a/tools/versioner/tests/future_arch/run.sh
+++ /dev/null
@@ -1 +0,0 @@
-versioner -v headers -p platforms -r arm -r x86 -a 9 -i
\ No newline at end of file
diff --git a/tools/versioner/tests/preprocessor/expected/foo.h b/tools/versioner/tests/preprocessor/expected/foo.h
index cb719f0..61e6056 100644
--- a/tools/versioner/tests/preprocessor/expected/foo.h
+++ b/tools/versioner/tests/preprocessor/expected/foo.h
@@ -74,11 +74,6 @@
-#if __ANDROID_API__ >= __ANDROID_API_FUTURE__
-int future() __INTRODUCED_IN_FUTURE;
-#endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */
-
-
#if defined(__cplusplus)
}
#endif
diff --git a/tools/versioner/tests/preprocessor/headers/foo.h b/tools/versioner/tests/preprocessor/headers/foo.h
index 2429334..349e5e6 100644
--- a/tools/versioner/tests/preprocessor/headers/foo.h
+++ b/tools/versioner/tests/preprocessor/headers/foo.h
@@ -45,8 +45,6 @@
int group_lp32() __INTRODUCED_IN_ARM(12) __INTRODUCED_IN_X86(12) __INTRODUCED_IN_MIPS(12);
-int future() __INTRODUCED_IN_FUTURE;
-
#if defined(__cplusplus)
}
#endif